From c318a92c20ec5fa5b44d1f1a6837108b8cca3c9f Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Fri, 1 Apr 2022 20:52:04 +0200 Subject: [PATCH 01/67] re #9437 initial lauterbach debugger client structure setup --- ld_client/LDClient/LDClient.csproj | 20 +++++++++++++ ld_client/LDClient/Program.cs | 11 +++++++ ld_client/LDClientTests/LDClientTests.csproj | 17 +++++++++++ ld_client/LDClientTests/UnitTest1.cs | 15 ++++++++++ ld_client/LauterbachDebuggerClient.sln | 31 ++++++++++++++++++++ 5 files changed, 94 insertions(+) create mode 100644 ld_client/LDClient/LDClient.csproj create mode 100644 ld_client/LDClient/Program.cs create mode 100644 ld_client/LDClientTests/LDClientTests.csproj create mode 100644 ld_client/LDClientTests/UnitTest1.cs create mode 100644 ld_client/LauterbachDebuggerClient.sln diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj new file mode 100644 index 0000000..9b3c77f --- /dev/null +++ b/ld_client/LDClient/LDClient.csproj @@ -0,0 +1,20 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net6.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + </PropertyGroup> + + <ItemGroup> + <Reference Include="t32apinet"> + <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath> + </Reference> + </ItemGroup> + + <ItemGroup> + <Folder Include="NewFolder\" /> + </ItemGroup> + +</Project> diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs new file mode 100644 index 0000000..22069e5 --- /dev/null +++ b/ld_client/LDClient/Program.cs @@ -0,0 +1,11 @@ +using System; + + +class Program { + + // Main Method + static public void Main() { + + Console.WriteLine("Main Method"); + } +} \ No newline at end of file diff --git a/ld_client/LDClientTests/LDClientTests.csproj b/ld_client/LDClientTests/LDClientTests.csproj new file mode 100644 index 0000000..5085235 --- /dev/null +++ b/ld_client/LDClientTests/LDClientTests.csproj @@ -0,0 +1,17 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net6.0</TargetFramework> + <Nullable>enable</Nullable> + + <IsPackable>false</IsPackable> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" /> + <PackageReference Include="NUnit" Version="3.13.2" /> + <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" /> + <PackageReference Include="coverlet.collector" Version="3.1.0" /> + </ItemGroup> + +</Project> diff --git a/ld_client/LDClientTests/UnitTest1.cs b/ld_client/LDClientTests/UnitTest1.cs new file mode 100644 index 0000000..03cf433 --- /dev/null +++ b/ld_client/LDClientTests/UnitTest1.cs @@ -0,0 +1,15 @@ +using NUnit.Framework; + +namespace LDClientTests { + public class Tests { + [SetUp] + public void Setup() { + + } + + [Test] + public void Test1() { + Assert.Pass(); + } + } +} \ No newline at end of file diff --git a/ld_client/LauterbachDebuggerClient.sln b/ld_client/LauterbachDebuggerClient.sln new file mode 100644 index 0000000..d62277c --- /dev/null +++ b/ld_client/LauterbachDebuggerClient.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32210.238 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClient", "LDClient\LDClient.csproj", "{26616C14-A61B-4611-8CD0-D29837FA34E7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {26616C14-A61B-4611-8CD0-D29837FA34E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26616C14-A61B-4611-8CD0-D29837FA34E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26616C14-A61B-4611-8CD0-D29837FA34E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26616C14-A61B-4611-8CD0-D29837FA34E7}.Release|Any CPU.Build.0 = Release|Any CPU + {5A1DB888-70E5-41E8-A900-FC22B51727F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A1DB888-70E5-41E8-A900-FC22B51727F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A1DB888-70E5-41E8-A900-FC22B51727F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A1DB888-70E5-41E8-A900-FC22B51727F8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {189367A8-6FB6-4C6C-85EF-FEA949122C26} + EndGlobalSection +EndGlobal -- GitLab From db562f60458ab53733eb190e590dec2f1c7065a8 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 2 Apr 2022 01:27:27 +0200 Subject: [PATCH 02/67] re #9440 initial config manager definition --- ld_client/LDClient/LDClient.csproj | 13 ++++- ld_client/LDClient/appsettings.json | 17 ++++++ ld_client/LDClient/utils/ConfigLoader.cs | 72 ++++++++++++++++++++++++ ld_client/LauterbachDebuggerClient.sln | 2 +- 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 ld_client/LDClient/appsettings.json create mode 100644 ld_client/LDClient/utils/ConfigLoader.cs diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj index 9b3c77f..3db4860 100644 --- a/ld_client/LDClient/LDClient.csproj +++ b/ld_client/LDClient/LDClient.csproj @@ -7,6 +7,16 @@ <Nullable>enable</Nullable> </PropertyGroup> + <ItemGroup> + <None Remove="appsettings.json" /> + </ItemGroup> + + <ItemGroup> + <EmbeddedResource Include="appsettings.json"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </EmbeddedResource> + </ItemGroup> + <ItemGroup> <Reference Include="t32apinet"> <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath> @@ -14,7 +24,8 @@ </ItemGroup> <ItemGroup> - <Folder Include="NewFolder\" /> + <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> + <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" /> </ItemGroup> </Project> diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json new file mode 100644 index 0000000..505db61 --- /dev/null +++ b/ld_client/LDClient/appsettings.json @@ -0,0 +1,17 @@ +{ + "Logging": { + "ColorConsole": { + "LogLevels": { + "Information": "DarkGreen", + "Warning": "Cyan", + "Error": "Red" + } + }, + "LogChunkSize": 1000, + "LogChunkMaxCount": 1, + "LogArchiveMaxCount": 1, + "LogCleanupPeriod": 1000, + "LogVerbosityType": 2, + "LogFlowType": 1 + } +} \ No newline at end of file diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs new file mode 100644 index 0000000..d6502ac --- /dev/null +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Json; + +namespace LDClient { + internal class ConfigurationLoader { + + private readonly string LOGGING_SECTION = "Logging"; + + + public int LogChunkSize { get; set; } + public int LogChunkMaxCount { get; set; } + public int LogArchiveMaxCount { get; set; } + + public int LogCleanupPeriod { get; set; } + + private LogVerbosity _logVerbosity = LogVerbosity.Full; + public LogVerbosity LogVerbosityType { + get { + return _logVerbosity; + } + set + { _logVerbosity = value; + } + } + + private LogFlow _logFlowType = LogFlow.Console; + public LogFlow LogFlowType { + get { + return _logFlowType; + } + set { + _logFlowType = value; + } + } + + public ConfigurationLoader() { + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + ReadAllSettings(configuration); + } + + void ReadAllSettings(IConfigurationRoot configuration) { + + try { + var logging = configuration.GetSection(LOGGING_SECTION); + //TODO: Exception handling + LogChunkSize = Int32.Parse(logging["LogChunkSize"]); + LogChunkMaxCount = Int32.Parse(logging["LogChunkMaxCount"]); + LogArchiveMaxCount = Int32.Parse(logging["LogArchiveMaxCount"]); + LogCleanupPeriod = Int32.Parse(logging["LogCleanupPeriod"]); + LogFlowType = (LogFlow)Int32.Parse(logging["LogFlowType"]); + LogVerbosityType = (LogVerbosity)Int32.Parse(logging["LogVerbosityType"]); + + + Console.WriteLine("Configuration successfully loaded!"); + } catch (FormatException e) { + //Console.WriteLine("Error reading app settings"); + //TODO: remove stacktrace print in production + Console.WriteLine("Error during reading of configuration occured!" + e); + throw new IOException("Reading of configuration file failed! " + e); + } + } + + } +} diff --git a/ld_client/LauterbachDebuggerClient.sln b/ld_client/LauterbachDebuggerClient.sln index d62277c..6e2f143 100644 --- a/ld_client/LauterbachDebuggerClient.sln +++ b/ld_client/LauterbachDebuggerClient.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClient", "LDClient\LDClient.csproj", "{26616C14-A61B-4611-8CD0-D29837FA34E7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution -- GitLab From 715205760dd3f78b9f7056f92f1d102cc6f736c6 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 2 Apr 2022 15:07:38 +0200 Subject: [PATCH 03/67] re #9439 Implementation of console and rotating file logger --- ld_client/LDClient/Program.cs | 12 +- ld_client/LDClient/utils/Logger.cs | 225 +++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 ld_client/LDClient/utils/Logger.cs diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 22069e5..2d372d9 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -1,11 +1,19 @@ -using System; +using LDClient; +using System; class Program { + public static LDClient.ConfigLoader Config { get; set; } + // Main Method static public void Main() { + Config = new LDClient.ConfigLoader(); - Console.WriteLine("Main Method"); + while (true) { + Logger.Current.Info("Ok"); + Logger.Current.Debug("Debug"); + Logger.Current.Error("Error"); + } } } \ No newline at end of file diff --git a/ld_client/LDClient/utils/Logger.cs b/ld_client/LDClient/utils/Logger.cs new file mode 100644 index 0000000..aaf0ea1 --- /dev/null +++ b/ld_client/LDClient/utils/Logger.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient { + enum LogVerbosity { + None = 0, + Exceptions, + Full + } + + public enum LogType { + Info = 0, + Debug, + Error + } + + enum LogFlow { + Console = 0, + File + } + + + public abstract class Logger : IDisposable { + + private LogVerbosity _verbosity; + private LogFlow _logFlow; + + private Queue<Action> _queue = new Queue<Action>(); + private ManualResetEvent _hasNewItems = new ManualResetEvent(false); + private ManualResetEvent _terminate = new ManualResetEvent(false); + private ManualResetEvent _waiting = new ManualResetEvent(false); + private Thread _loggingThread; + + private static readonly Lazy<Logger> _lazyLog = new Lazy<Logger>(() + => { + switch (Program.Config.LogFlowType) { + case LogFlow.File: + return new FileLogger(); + case LogFlow.Console: + default: + return new ConsoleLogger(); + + } + } + ); + + public static Logger Current => _lazyLog.Value; + + protected Logger() { + _verbosity = (LogVerbosity)Program.Config.LogVerbosityType; + _logFlow = (LogFlow)Program.Config.LogFlowType; + _loggingThread = new Thread(new ThreadStart(ProcessQueue)) { IsBackground = true }; + _loggingThread.Start(); + } + + public void Info(string message) { + Log(message, LogType.Info); + } + + public void Debug(string message) { + Log(message, LogType.Debug); + } + + public void Error(string message) { + Log(message, LogType.Error); + } + + public void Error(Exception e) { + if (_verbosity != LogVerbosity.None) { + Log(UnwrapExceptionMessages(e), LogType.Error); + } + } + + public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, "; + + protected abstract void CreateLog(string message); + + public void Flush() => _waiting.WaitOne(); + + public void Dispose() { + _terminate.Set(); + _loggingThread.Join(); + } + + protected virtual string ComposeLogRow(string message, LogType logType) => + $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}"; + + protected virtual string UnwrapExceptionMessages(Exception ex) { + if (ex == null) + return string.Empty; + + return $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} "; + } + + private void ProcessQueue() { + while (true) { + _waiting.Set(); + int i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate }); + if (i == 1) return; + _hasNewItems.Reset(); + _waiting.Reset(); + + Queue<Action> queueCopy; + lock (_queue) { + queueCopy = new Queue<Action>(_queue); + _queue.Clear(); + } + + foreach (var log in queueCopy) { + log(); + } + } + } + + private void Log(string message, LogType logType) { + if (string.IsNullOrEmpty(message)) + return; + + var logRow = ComposeLogRow(message, logType); + System.Diagnostics.Debug.WriteLine(logRow); + + if (_verbosity == LogVerbosity.Full) { + lock (_queue) + _queue.Enqueue(() => CreateLog(logRow)); + + _hasNewItems.Set(); + } + } + } + + class ConsoleLogger : Logger { + protected override void CreateLog(string message) { + Console.WriteLine(message); + } + } + + + class FileLogger : Logger { + + private const string LogFolderName = "logs"; + private const string LogFileName = "app_info.log"; + private readonly int _logChunkSize = Program.Config.LogChunkSize; + private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount; + private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount; + private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod; + + private readonly string logFolderPath = Path.Combine(Path.GetTempPath(), $"ldClient\\{LogFolderName}"); + + private bool _logDirExists = false; + + protected override void CreateLog(string message) { + + if (!_logDirExists) { + _logDirExists = Directory.Exists(logFolderPath); + if (!_logDirExists) { + Directory.CreateDirectory(logFolderPath); + _logDirExists = true; + } + } + + var logFilePath = Path.Combine(logFolderPath, LogFileName); + + Rotate(logFilePath); + + using (var sw = File.AppendText(logFilePath)) { + sw.WriteLine(message); + } + } + + private void Rotate(string filePath) { + if (!File.Exists(filePath)) + return; + + var fileInfo = new FileInfo(filePath); + if (fileInfo.Length < _logChunkSize) + return; + + var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff"); + var rotatedPath = filePath.Replace(".log", $".{fileTime}"); + File.Move(filePath, rotatedPath); + + var folderPath = Path.GetDirectoryName(rotatedPath); + var logFolderContent = new DirectoryInfo(folderPath).GetFileSystemInfos(); + + var chunks = logFolderContent.Where(x => !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)); + + if (chunks.Count() <= _logChunkMaxCount) + return; + + var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath), $"{LogFolderName}_{fileTime}")); + + foreach (var chunk in chunks) { + var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name); + Directory.Move(chunk.FullName, destination); + } + + ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath, $"{LogFolderName}_{fileTime}.zip")); + Directory.Delete(archiveFolderInfo.FullName, true); + + var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray(); + + if (archives.Count() <= _logArchiveMaxCount) + return; + + var oldestArchive = archives.OrderBy(x => x.CreationTime).First(); + var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod); + if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) { + foreach (var file in logFolderContent) { + file.Delete(); + } + } else + File.Delete(oldestArchive.FullName); + + } + + public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]"; + } + + +} -- GitLab From d0cf94768067a25abd98e78c3775d418c154774e Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 2 Apr 2022 01:27:27 +0200 Subject: [PATCH 04/67] re #9440 initial config manager definition --- ld_client/LDClient/LDClient.csproj | 13 ++++- ld_client/LDClient/appsettings.json | 17 ++++++ ld_client/LDClient/utils/ConfigLoader.cs | 72 ++++++++++++++++++++++++ ld_client/LauterbachDebuggerClient.sln | 2 +- 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 ld_client/LDClient/appsettings.json create mode 100644 ld_client/LDClient/utils/ConfigLoader.cs diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj index 9b3c77f..3db4860 100644 --- a/ld_client/LDClient/LDClient.csproj +++ b/ld_client/LDClient/LDClient.csproj @@ -7,6 +7,16 @@ <Nullable>enable</Nullable> </PropertyGroup> + <ItemGroup> + <None Remove="appsettings.json" /> + </ItemGroup> + + <ItemGroup> + <EmbeddedResource Include="appsettings.json"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </EmbeddedResource> + </ItemGroup> + <ItemGroup> <Reference Include="t32apinet"> <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath> @@ -14,7 +24,8 @@ </ItemGroup> <ItemGroup> - <Folder Include="NewFolder\" /> + <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> + <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" /> </ItemGroup> </Project> diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json new file mode 100644 index 0000000..505db61 --- /dev/null +++ b/ld_client/LDClient/appsettings.json @@ -0,0 +1,17 @@ +{ + "Logging": { + "ColorConsole": { + "LogLevels": { + "Information": "DarkGreen", + "Warning": "Cyan", + "Error": "Red" + } + }, + "LogChunkSize": 1000, + "LogChunkMaxCount": 1, + "LogArchiveMaxCount": 1, + "LogCleanupPeriod": 1000, + "LogVerbosityType": 2, + "LogFlowType": 1 + } +} \ No newline at end of file diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs new file mode 100644 index 0000000..d6502ac --- /dev/null +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Json; + +namespace LDClient { + internal class ConfigurationLoader { + + private readonly string LOGGING_SECTION = "Logging"; + + + public int LogChunkSize { get; set; } + public int LogChunkMaxCount { get; set; } + public int LogArchiveMaxCount { get; set; } + + public int LogCleanupPeriod { get; set; } + + private LogVerbosity _logVerbosity = LogVerbosity.Full; + public LogVerbosity LogVerbosityType { + get { + return _logVerbosity; + } + set + { _logVerbosity = value; + } + } + + private LogFlow _logFlowType = LogFlow.Console; + public LogFlow LogFlowType { + get { + return _logFlowType; + } + set { + _logFlowType = value; + } + } + + public ConfigurationLoader() { + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + ReadAllSettings(configuration); + } + + void ReadAllSettings(IConfigurationRoot configuration) { + + try { + var logging = configuration.GetSection(LOGGING_SECTION); + //TODO: Exception handling + LogChunkSize = Int32.Parse(logging["LogChunkSize"]); + LogChunkMaxCount = Int32.Parse(logging["LogChunkMaxCount"]); + LogArchiveMaxCount = Int32.Parse(logging["LogArchiveMaxCount"]); + LogCleanupPeriod = Int32.Parse(logging["LogCleanupPeriod"]); + LogFlowType = (LogFlow)Int32.Parse(logging["LogFlowType"]); + LogVerbosityType = (LogVerbosity)Int32.Parse(logging["LogVerbosityType"]); + + + Console.WriteLine("Configuration successfully loaded!"); + } catch (FormatException e) { + //Console.WriteLine("Error reading app settings"); + //TODO: remove stacktrace print in production + Console.WriteLine("Error during reading of configuration occured!" + e); + throw new IOException("Reading of configuration file failed! " + e); + } + } + + } +} diff --git a/ld_client/LauterbachDebuggerClient.sln b/ld_client/LauterbachDebuggerClient.sln index d62277c..6e2f143 100644 --- a/ld_client/LauterbachDebuggerClient.sln +++ b/ld_client/LauterbachDebuggerClient.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClient", "LDClient\LDClient.csproj", "{26616C14-A61B-4611-8CD0-D29837FA34E7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution -- GitLab From 74bd1e40820cf9bf2c808f4946a0dec8f2013d0c Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 2 Apr 2022 18:19:27 +0200 Subject: [PATCH 05/67] re #9439 logger code refactoring --- ld_client/LDClient/Program.cs | 19 +- ld_client/LDClient/appsettings.json | 8 +- ld_client/LDClient/utils/ConfigLoader.cs | 55 ++--- ld_client/LDClient/utils/Logger.cs | 225 ------------------ ld_client/LDClient/utils/loggers/ALogger.cs | 109 +++++++++ .../LDClient/utils/loggers/ConsoleLogger.cs | 7 + .../LDClient/utils/loggers/FileLogger.cs | 95 ++++++++ ld_client/LDClient/utils/loggers/LogFlow.cs | 6 + ld_client/LDClient/utils/loggers/LogType.cs | 7 + .../LDClient/utils/loggers/LogVerbosity.cs | 7 + 10 files changed, 261 insertions(+), 277 deletions(-) delete mode 100644 ld_client/LDClient/utils/Logger.cs create mode 100644 ld_client/LDClient/utils/loggers/ALogger.cs create mode 100644 ld_client/LDClient/utils/loggers/ConsoleLogger.cs create mode 100644 ld_client/LDClient/utils/loggers/FileLogger.cs create mode 100644 ld_client/LDClient/utils/loggers/LogFlow.cs create mode 100644 ld_client/LDClient/utils/loggers/LogType.cs create mode 100644 ld_client/LDClient/utils/loggers/LogVerbosity.cs diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 2d372d9..4030157 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -1,19 +1,20 @@ -using LDClient; -using System; +using LDClient.utils; +using LDClient.utils.loggers; +namespace LDClient; -class Program { +internal class Program { - public static LDClient.ConfigLoader Config { get; set; } + public static ConfigLoader Config { get; set; } = null!; // Main Method - static public void Main() { - Config = new LDClient.ConfigLoader(); + public static void Main() { + Config = new ConfigLoader(); while (true) { - Logger.Current.Info("Ok"); - Logger.Current.Debug("Debug"); - Logger.Current.Error("Error"); + ALogger.Current.Info("Ok"); + ALogger.Current.Debug("Debug"); + ALogger.Current.Error("Error"); } } } \ No newline at end of file diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 505db61..01b0de4 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -7,10 +7,10 @@ "Error": "Red" } }, - "LogChunkSize": 1000, - "LogChunkMaxCount": 1, - "LogArchiveMaxCount": 1, - "LogCleanupPeriod": 1000, + "LogChunkSize": 2097152, + "LogChunkMaxCount": 2, + "LogArchiveMaxCount": 10, + "LogCleanupPeriod": 10, "LogVerbosityType": 2, "LogFlowType": 1 } diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index d6502ac..8005130 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -1,16 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using LDClient.utils.loggers; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Configuration.Json; -namespace LDClient { - internal class ConfigurationLoader { - - private readonly string LOGGING_SECTION = "Logging"; +namespace LDClient.utils { + internal class ConfigLoader { + private const string LoggingSection = "Logging"; public int LogChunkSize { get; set; } @@ -19,51 +12,35 @@ namespace LDClient { public int LogCleanupPeriod { get; set; } - private LogVerbosity _logVerbosity = LogVerbosity.Full; - public LogVerbosity LogVerbosityType { - get { - return _logVerbosity; - } - set - { _logVerbosity = value; - } - } + public LogVerbosity LogVerbosityType { get; set; } = LogVerbosity.Full; - private LogFlow _logFlowType = LogFlow.Console; - public LogFlow LogFlowType { - get { - return _logFlowType; - } - set { - _logFlowType = value; - } - } + public LogFlow LogFlowType { get; set; } = LogFlow.Console; - public ConfigurationLoader() { + public ConfigLoader() { var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); ReadAllSettings(configuration); } - void ReadAllSettings(IConfigurationRoot configuration) { + private void ReadAllSettings(IConfigurationRoot configuration) { try { - var logging = configuration.GetSection(LOGGING_SECTION); + var logging = configuration.GetSection(LoggingSection); //TODO: Exception handling - LogChunkSize = Int32.Parse(logging["LogChunkSize"]); - LogChunkMaxCount = Int32.Parse(logging["LogChunkMaxCount"]); - LogArchiveMaxCount = Int32.Parse(logging["LogArchiveMaxCount"]); - LogCleanupPeriod = Int32.Parse(logging["LogCleanupPeriod"]); - LogFlowType = (LogFlow)Int32.Parse(logging["LogFlowType"]); - LogVerbosityType = (LogVerbosity)Int32.Parse(logging["LogVerbosityType"]); + LogChunkSize = int.Parse(logging["LogChunkSize"]); + LogChunkMaxCount = int.Parse(logging["LogChunkMaxCount"]); + LogArchiveMaxCount = int.Parse(logging["LogArchiveMaxCount"]); + LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]); + LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]); + LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]); Console.WriteLine("Configuration successfully loaded!"); } catch (FormatException e) { //Console.WriteLine("Error reading app settings"); //TODO: remove stacktrace print in production - Console.WriteLine("Error during reading of configuration occured!" + e); + Console.WriteLine("Error during reading of configuration occurred!" + e); throw new IOException("Reading of configuration file failed! " + e); } } diff --git a/ld_client/LDClient/utils/Logger.cs b/ld_client/LDClient/utils/Logger.cs deleted file mode 100644 index aaf0ea1..0000000 --- a/ld_client/LDClient/utils/Logger.cs +++ /dev/null @@ -1,225 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO.Compression; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LDClient { - enum LogVerbosity { - None = 0, - Exceptions, - Full - } - - public enum LogType { - Info = 0, - Debug, - Error - } - - enum LogFlow { - Console = 0, - File - } - - - public abstract class Logger : IDisposable { - - private LogVerbosity _verbosity; - private LogFlow _logFlow; - - private Queue<Action> _queue = new Queue<Action>(); - private ManualResetEvent _hasNewItems = new ManualResetEvent(false); - private ManualResetEvent _terminate = new ManualResetEvent(false); - private ManualResetEvent _waiting = new ManualResetEvent(false); - private Thread _loggingThread; - - private static readonly Lazy<Logger> _lazyLog = new Lazy<Logger>(() - => { - switch (Program.Config.LogFlowType) { - case LogFlow.File: - return new FileLogger(); - case LogFlow.Console: - default: - return new ConsoleLogger(); - - } - } - ); - - public static Logger Current => _lazyLog.Value; - - protected Logger() { - _verbosity = (LogVerbosity)Program.Config.LogVerbosityType; - _logFlow = (LogFlow)Program.Config.LogFlowType; - _loggingThread = new Thread(new ThreadStart(ProcessQueue)) { IsBackground = true }; - _loggingThread.Start(); - } - - public void Info(string message) { - Log(message, LogType.Info); - } - - public void Debug(string message) { - Log(message, LogType.Debug); - } - - public void Error(string message) { - Log(message, LogType.Error); - } - - public void Error(Exception e) { - if (_verbosity != LogVerbosity.None) { - Log(UnwrapExceptionMessages(e), LogType.Error); - } - } - - public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, "; - - protected abstract void CreateLog(string message); - - public void Flush() => _waiting.WaitOne(); - - public void Dispose() { - _terminate.Set(); - _loggingThread.Join(); - } - - protected virtual string ComposeLogRow(string message, LogType logType) => - $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}"; - - protected virtual string UnwrapExceptionMessages(Exception ex) { - if (ex == null) - return string.Empty; - - return $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} "; - } - - private void ProcessQueue() { - while (true) { - _waiting.Set(); - int i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate }); - if (i == 1) return; - _hasNewItems.Reset(); - _waiting.Reset(); - - Queue<Action> queueCopy; - lock (_queue) { - queueCopy = new Queue<Action>(_queue); - _queue.Clear(); - } - - foreach (var log in queueCopy) { - log(); - } - } - } - - private void Log(string message, LogType logType) { - if (string.IsNullOrEmpty(message)) - return; - - var logRow = ComposeLogRow(message, logType); - System.Diagnostics.Debug.WriteLine(logRow); - - if (_verbosity == LogVerbosity.Full) { - lock (_queue) - _queue.Enqueue(() => CreateLog(logRow)); - - _hasNewItems.Set(); - } - } - } - - class ConsoleLogger : Logger { - protected override void CreateLog(string message) { - Console.WriteLine(message); - } - } - - - class FileLogger : Logger { - - private const string LogFolderName = "logs"; - private const string LogFileName = "app_info.log"; - private readonly int _logChunkSize = Program.Config.LogChunkSize; - private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount; - private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount; - private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod; - - private readonly string logFolderPath = Path.Combine(Path.GetTempPath(), $"ldClient\\{LogFolderName}"); - - private bool _logDirExists = false; - - protected override void CreateLog(string message) { - - if (!_logDirExists) { - _logDirExists = Directory.Exists(logFolderPath); - if (!_logDirExists) { - Directory.CreateDirectory(logFolderPath); - _logDirExists = true; - } - } - - var logFilePath = Path.Combine(logFolderPath, LogFileName); - - Rotate(logFilePath); - - using (var sw = File.AppendText(logFilePath)) { - sw.WriteLine(message); - } - } - - private void Rotate(string filePath) { - if (!File.Exists(filePath)) - return; - - var fileInfo = new FileInfo(filePath); - if (fileInfo.Length < _logChunkSize) - return; - - var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff"); - var rotatedPath = filePath.Replace(".log", $".{fileTime}"); - File.Move(filePath, rotatedPath); - - var folderPath = Path.GetDirectoryName(rotatedPath); - var logFolderContent = new DirectoryInfo(folderPath).GetFileSystemInfos(); - - var chunks = logFolderContent.Where(x => !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)); - - if (chunks.Count() <= _logChunkMaxCount) - return; - - var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath), $"{LogFolderName}_{fileTime}")); - - foreach (var chunk in chunks) { - var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name); - Directory.Move(chunk.FullName, destination); - } - - ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath, $"{LogFolderName}_{fileTime}.zip")); - Directory.Delete(archiveFolderInfo.FullName, true); - - var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray(); - - if (archives.Count() <= _logArchiveMaxCount) - return; - - var oldestArchive = archives.OrderBy(x => x.CreationTime).First(); - var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod); - if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) { - foreach (var file in logFolderContent) { - file.Delete(); - } - } else - File.Delete(oldestArchive.FullName); - - } - - public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]"; - } - - -} diff --git a/ld_client/LDClient/utils/loggers/ALogger.cs b/ld_client/LDClient/utils/loggers/ALogger.cs new file mode 100644 index 0000000..260a03d --- /dev/null +++ b/ld_client/LDClient/utils/loggers/ALogger.cs @@ -0,0 +1,109 @@ +using System.Globalization; + +namespace LDClient.utils.loggers { + + public abstract class ALogger : IDisposable { + + private readonly LogVerbosity _verbosity; + private readonly LogFlow _logFlow; + + private readonly Queue<Action> _queue = new(); + private readonly ManualResetEvent _hasNewItems = new(false); + private readonly ManualResetEvent _terminate = new(false); + private readonly ManualResetEvent _waiting = new(false); + private readonly Thread _loggingThread; + + private static readonly Lazy<ALogger> LazyLog = new(() + => { + switch (Program.Config.LogFlowType) { + case LogFlow.File: + return new FileLogger(); + case LogFlow.Console: + default: + return new ConsoleLogger(); + + } + } + ); + + public static ALogger Current => LazyLog.Value; + + protected ALogger() { + _verbosity = Program.Config.LogVerbosityType; + _logFlow = Program.Config.LogFlowType; + _loggingThread = new Thread(ProcessQueue) { IsBackground = true }; + _loggingThread.Start(); + } + + public void Info(string message) { + Log(message, LogType.Info); + } + + public void Debug(string message) { + Log(message, LogType.Debug); + } + + public void Error(string message) { + Log(message, LogType.Error); + } + + public void Error(Exception e) { + if (_verbosity != LogVerbosity.None) { + Log(UnwrapExceptionMessages(e), LogType.Error); + } + } + + public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, "; + + protected abstract void CreateLog(string message); + + public void Flush() => _waiting.WaitOne(); + + public void Dispose() { + _terminate.Set(); + _loggingThread.Join(); + } + + protected virtual string ComposeLogRow(string message, LogType logType) => + $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}"; + + protected virtual string UnwrapExceptionMessages(Exception? ex) => + ex == null ? string.Empty : $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} "; + + + private void ProcessQueue() { + while (true) { + _waiting.Set(); + var i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate }); + if (i == 1) return; + _hasNewItems.Reset(); + _waiting.Reset(); + + Queue<Action> queueCopy; + lock (_queue) { + queueCopy = new Queue<Action>(_queue); + _queue.Clear(); + } + + foreach (var log in queueCopy) { + log(); + } + } + } + + private void Log(string message, LogType logType) { + if (string.IsNullOrEmpty(message)) + return; + + var logRow = ComposeLogRow(message, logType); + System.Diagnostics.Debug.WriteLine(logRow); + + if (_verbosity == LogVerbosity.Full) { + lock (_queue) + _queue.Enqueue(() => CreateLog(logRow)); + + _hasNewItems.Set(); + } + } + } +} diff --git a/ld_client/LDClient/utils/loggers/ConsoleLogger.cs b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs new file mode 100644 index 0000000..b108ed6 --- /dev/null +++ b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs @@ -0,0 +1,7 @@ +namespace LDClient.utils.loggers { + public class ConsoleLogger : ALogger { + protected override void CreateLog(string message) { + Console.WriteLine(message); + } + } +} diff --git a/ld_client/LDClient/utils/loggers/FileLogger.cs b/ld_client/LDClient/utils/loggers/FileLogger.cs new file mode 100644 index 0000000..d63ab05 --- /dev/null +++ b/ld_client/LDClient/utils/loggers/FileLogger.cs @@ -0,0 +1,95 @@ +using System.IO.Compression; + +namespace LDClient.utils.loggers; + +public class FileLogger : ALogger { + + private const string LogFolderName = "logs"; + private const string LogFileName = "app_info.log"; + private readonly int _logChunkSize = Program.Config.LogChunkSize; + private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount; + private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount; + private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod; + + private const string LogFolderPath = $"ldClient\\{LogFolderName}"; + + private bool _logDirExists; + + protected override void CreateLog(string message) { + + if (!_logDirExists) { + _logDirExists = Directory.Exists(LogFolderPath); + if (!_logDirExists) { + Directory.CreateDirectory(LogFolderPath); + _logDirExists = true; + } + } + + var logFilePath = Path.Combine(LogFolderPath, LogFileName); + + Rotate(logFilePath); + + using var sw = File.AppendText(logFilePath); + sw.WriteLine(message); + } + + private void Rotate(string filePath) { + if (!File.Exists(filePath)) { + return; + } + + var fileInfo = new FileInfo(filePath); + if (fileInfo.Length < _logChunkSize) { + return; + } + var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff"); + var rotatedPath = filePath.Replace(".log", $".{fileTime}"); + File.Move(filePath, rotatedPath); + + var folderPath = Path.GetDirectoryName(rotatedPath); + var logFolderContent = new DirectoryInfo(folderPath ?? string.Empty).GetFileSystemInfos(); + + var chunks = logFolderContent.Where(x => + !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)); + + if (chunks.Count() <= _logChunkMaxCount) { + return; + } + + Archive(chunks, rotatedPath, fileTime, folderPath); + DeleteOldArchives(logFolderContent); + } + + private void Archive(IEnumerable<FileSystemInfo> chunks, string rotatedPath, string fileTime, string? folderPath) { + + var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath) ?? LogFolderPath, $"{LogFolderName}_{fileTime}")); + + foreach (var chunk in chunks) { + var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name); + Directory.Move(chunk.FullName, destination); + } + + ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath ?? LogFolderPath, $"{LogFolderName}_{fileTime}.zip")); + Directory.Delete(archiveFolderInfo.FullName, true); + } + + private void DeleteOldArchives(FileSystemInfo[] logFolderContent) { + + var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray(); + + if (archives.Length <= _logArchiveMaxCount) + return; + + var oldestArchive = archives.OrderBy(x => x.CreationTime).First(); + var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod); + if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) { + foreach (var file in logFolderContent) { + file.Delete(); + } + } else { + File.Delete(oldestArchive.FullName); + } + } + + public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]"; +} \ No newline at end of file diff --git a/ld_client/LDClient/utils/loggers/LogFlow.cs b/ld_client/LDClient/utils/loggers/LogFlow.cs new file mode 100644 index 0000000..5041b12 --- /dev/null +++ b/ld_client/LDClient/utils/loggers/LogFlow.cs @@ -0,0 +1,6 @@ +namespace LDClient.utils.loggers { + public enum LogFlow { + Console = 0, + File + } +} diff --git a/ld_client/LDClient/utils/loggers/LogType.cs b/ld_client/LDClient/utils/loggers/LogType.cs new file mode 100644 index 0000000..370057f --- /dev/null +++ b/ld_client/LDClient/utils/loggers/LogType.cs @@ -0,0 +1,7 @@ +namespace LDClient.utils.loggers { + public enum LogType { + Info = 0, + Debug, + Error + } +} diff --git a/ld_client/LDClient/utils/loggers/LogVerbosity.cs b/ld_client/LDClient/utils/loggers/LogVerbosity.cs new file mode 100644 index 0000000..03c292b --- /dev/null +++ b/ld_client/LDClient/utils/loggers/LogVerbosity.cs @@ -0,0 +1,7 @@ +namespace LDClient.utils.loggers { + public enum LogVerbosity { + None = 0, + Exceptions, + Full + } +} -- GitLab From 58cf6a6f304a0b4de9ce5529e788b1ca69411094 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 9 Apr 2022 22:12:50 +0200 Subject: [PATCH 06/67] re #9438 Added api configuration values --- ld_client/LDClient/appsettings.json | 14 ++++++++++++-- ld_client/LDClient/utils/ConfigLoader.cs | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 01b0de4..68c8b0b 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -12,6 +12,16 @@ "LogArchiveMaxCount": 10, "LogCleanupPeriod": 10, "LogVerbosityType": 2, - "LogFlowType": 1 - } + "LogFlowType": 0 + }, + + "Network": { + "ApiBaseAddress": "http://192.168.0.22", + "ApiLDEndPoint": "/lauterbach-debugger-logs/", + "ApiPort": 8000, + "ApiRetryPeriod": 1, + + "DebuggerAddress": "localhost", + "DebuggerPort": 20000 + } } \ No newline at end of file diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index 8005130..681165a 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration; namespace LDClient.utils { internal class ConfigLoader { private const string LoggingSection = "Logging"; + private const string NetworkSection = "Network"; public int LogChunkSize { get; set; } @@ -16,6 +17,14 @@ namespace LDClient.utils { public LogFlow LogFlowType { get; set; } = LogFlow.Console; + public string ApiBaseAddress { get; set; } + public string ApiUsbEndPoint { get; set; } + public uint ApiPort { get; set; } + public uint ApiRetryPeriod { get; set; } + + public string DebuggerAddress { get; set; } + public int DebuggerPort { get; set; } + public ConfigLoader() { var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") @@ -34,7 +43,16 @@ namespace LDClient.utils { LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]); LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]); LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]); + + var network = configuration.GetSection(NetworkSection); + ApiBaseAddress = network["ApiBaseAddress"]; + ApiUsbEndPoint = network["ApiLDEndPoint"]; + ApiPort = uint.Parse(network["ApiPort"]); + ApiRetryPeriod = uint.Parse(network["ApiRetryPeriod"]); + + DebuggerAddress = network["DebuggerAddress"]; + DebuggerPort = int.Parse(network["DebuggerPort"]); Console.WriteLine("Configuration successfully loaded!"); } catch (FormatException e) { -- GitLab From 202135f9cdbffb5cc7ef7079a87b9dce97e91257 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 9 Apr 2022 22:42:33 +0200 Subject: [PATCH 07/67] re #9438 Added api data definition --- .../LDClient/network/data/ConnectionStatus.cs | 11 +++++++ .../LDClient/network/data/DebuggerInfo.cs | 9 ++++++ ld_client/LDClient/network/data/Payload.cs | 29 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 ld_client/LDClient/network/data/ConnectionStatus.cs create mode 100644 ld_client/LDClient/network/data/DebuggerInfo.cs create mode 100644 ld_client/LDClient/network/data/Payload.cs diff --git a/ld_client/LDClient/network/data/ConnectionStatus.cs b/ld_client/LDClient/network/data/ConnectionStatus.cs new file mode 100644 index 0000000..f5ea275 --- /dev/null +++ b/ld_client/LDClient/network/data/ConnectionStatus.cs @@ -0,0 +1,11 @@ +using System.Runtime.Serialization; + +namespace LDClient.network.data { + public enum ConnectionStatus { + [EnumMember(Value = "connected")] + Connected, + [EnumMember(Value = "disconnected")] + Disconnected + + } +} diff --git a/ld_client/LDClient/network/data/DebuggerInfo.cs b/ld_client/LDClient/network/data/DebuggerInfo.cs new file mode 100644 index 0000000..cb38d91 --- /dev/null +++ b/ld_client/LDClient/network/data/DebuggerInfo.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace LDClient.network.data { + public class DebuggerInfo { + + [JsonPropertyName("serial_number")] + public string SerialNumber { get; set; } + } +} diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs new file mode 100644 index 0000000..1e65c6d --- /dev/null +++ b/ld_client/LDClient/network/data/Payload.cs @@ -0,0 +1,29 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace LDClient.network.data { + [JsonObject(MemberSerialization.OptIn)] + public class Payload { + + [JsonPropertyName("username")] + public string UserName { get; set; } + + [JsonPropertyName("hostname")] + public string HostName { get; set; } + + [JsonPropertyName("timestamp")] + //[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd HH:mm:ss.ffffff")] + public DateTime TimeStamp { get; set; } + + [JsonPropertyName("head_device")] + public DebuggerInfo HeadDevice { get; set; } + + + [JsonPropertyName("body_device")] + public DebuggerInfo BodyDevice { get; set; } + + [JsonPropertyName("status")] + //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] + public ConnectionStatus Status { get; set; } + } +} -- GitLab From 3c82c2ade08466fb88410bfa551bdb0534adf65a Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 9 Apr 2022 22:45:40 +0200 Subject: [PATCH 08/67] re #9438 Added API client + example data --- ld_client/LDClient/network/ApiClient.cs | 75 ++++++++++++++++++++++++ ld_client/LDClient/network/IApiClient.cs | 7 +++ 2 files changed, 82 insertions(+) create mode 100644 ld_client/LDClient/network/ApiClient.cs create mode 100644 ld_client/LDClient/network/IApiClient.cs diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs new file mode 100644 index 0000000..d56582e --- /dev/null +++ b/ld_client/LDClient/network/ApiClient.cs @@ -0,0 +1,75 @@ +using System.Diagnostics; +using System.Net.Http.Json; +using System.Text.Json; +using System.Text.Json.Serialization; +using LDClient.network.data; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace LDClient.network { + public class ApiClient : IApiClient { + + public static readonly Payload ExampleInfo = new() { + UserName = "honikCz", + HostName = "Bramborak", + TimeStamp = DateTime.Parse("2022-03-21 18:05:00.168895"), + HeadDevice = new DebuggerInfo { + SerialNumber = "C12345678912" + }, + BodyDevice = new DebuggerInfo { + SerialNumber = "C98765432198" + }, + Status = ConnectionStatus.Connected + }; + + + private readonly string _uri; + private readonly HttpClient _client; + private readonly uint _retryPeriod; + + + public ApiClient(string url, uint port, string path, uint retryPeriod) { + _uri = $"{url}:{port}{path}"; + _retryPeriod = retryPeriod; + + _client = new HttpClient(); + + } + + public async Task SendPayloadAsync(Payload payload) { + try { + Stopwatch stopWatch = new(); + stopWatch.Start(); + + var json = JsonConvert.SerializeObject(ExampleInfo); + if (json is null) { + Program.DefaultLogger.Error($"Failed to serialize object: {ExampleInfo}"); + return; + } + var response = await _client.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions { + Converters = { + new JsonStringEnumConverter( JsonNamingPolicy.CamelCase) + } + + }); + stopWatch.Stop(); + Response2Log(json, response, stopWatch.ElapsedMilliseconds); + + response.EnsureSuccessStatusCode(); + var serverResponse = await response.Content.ReadAsStringAsync(); + CheckResponse(serverResponse); + } catch (Exception e) { + Program.DefaultLogger.Error($"Failed to send {payload} to the server. Due to: {e.Message}"); + } + } + + private static bool CheckResponse(string response) { + dynamic json = JObject.Parse(response); + + if (json.statusCode < 400) { + return true; + } + throw new Exception($"Server responded with error code: {json.statusCode}"); + } + } +} diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs new file mode 100644 index 0000000..fc7ceaa --- /dev/null +++ b/ld_client/LDClient/network/IApiClient.cs @@ -0,0 +1,7 @@ +using LDClient.network.data; + +namespace LDClient.network { + public interface IApiClient { + public Task SendPayloadAsync(Payload payload); + } +} -- GitLab From 4b0f0b3608268d8dd95cec53292e70003b6f9899 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 9 Apr 2022 22:47:24 +0200 Subject: [PATCH 09/67] re #9438 project structure definition + main example --- ld_client/LDClient/LDClient.csproj | 3 +++ ld_client/LDClient/Program.cs | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj index 3db4860..10ede20 100644 --- a/ld_client/LDClient/LDClient.csproj +++ b/ld_client/LDClient/LDClient.csproj @@ -24,7 +24,10 @@ </ItemGroup> <ItemGroup> + <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> + <PackageReference Include="Newtonsoft.Json" Version="9.0.1" /> + <PackageReference Include="RestSharp" Version="107.3.0" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" /> </ItemGroup> diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 4030157..a05e5e5 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -1,20 +1,20 @@ -using LDClient.utils; +using LDClient.network; +using LDClient.utils; using LDClient.utils.loggers; namespace LDClient; internal class Program { - public static ConfigLoader Config { get; set; } = null!; + public static ConfigLoader Config { get; set; } = new(); + public static ALogger DefaultLogger { get; } = ALogger.Current; - // Main Method - public static void Main() { - Config = new ConfigLoader(); + public static IApiClient DefaultApiClient { get; set; } = new ApiClient(Config.ApiBaseAddress, + Config.ApiPort, Config.ApiUsbEndPoint, Config.ApiRetryPeriod); - while (true) { - ALogger.Current.Info("Ok"); - ALogger.Current.Debug("Debug"); - ALogger.Current.Error("Error"); - } + // Main Method + public static async Task Main() { + await DefaultApiClient.SendPayloadAsync(ApiClient.ExampleInfo); + Console.WriteLine("Finished!"); } } \ No newline at end of file -- GitLab From 0ba79cc3867c606a7245f5a1e501ebaea11756a5 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 9 Apr 2022 23:03:16 +0200 Subject: [PATCH 10/67] re #9438 added function for logging of server response --- ld_client/LDClient/network/ApiClient.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index d56582e..532fe3c 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -71,5 +71,18 @@ namespace LDClient.network { } throw new Exception($"Server responded with error code: {json.statusCode}"); } + + private static void Response2Log(string json, HttpResponseMessage response, long durationMs) { + var responseToLog = new { + statusCode = response.StatusCode, + content = response.Content, + headers = response.Headers, + errorMessage = response.RequestMessage, + }; + + Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" + + $"Request body: {json},\n" + + $"Response: {JsonConvert.SerializeObject(responseToLog)}"); + } } } -- GitLab From c2cc7813c0259a24fabc8b65f09de399ccc0c479 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 19:48:12 +0200 Subject: [PATCH 11/67] re #9441 Added configuration properties + library added to project structure --- ld_client/LDClient/LDClient.csproj | 2 ++ ld_client/LDClient/appsettings.json | 17 ++++++++---- ld_client/LDClient/utils/ConfigLoader.cs | 34 +++++++++++++++++++----- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj index 10ede20..c575ea0 100644 --- a/ld_client/LDClient/LDClient.csproj +++ b/ld_client/LDClient/LDClient.csproj @@ -24,11 +24,13 @@ </ItemGroup> <ItemGroup> + <PackageReference Include="DiskQueue" Version="1.5.0" /> <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> <PackageReference Include="Newtonsoft.Json" Version="9.0.1" /> <PackageReference Include="RestSharp" Version="107.3.0" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" /> + <PackageReference Include="System.Management" Version="6.0.0" /> </ItemGroup> </Project> diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 68c8b0b..7884a5e 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -16,12 +16,19 @@ }, "Network": { - "ApiBaseAddress": "http://192.168.0.22", + "ApiBaseAddress": "http://127.0.0.1", "ApiLDEndPoint": "/lauterbach-debugger-logs/", - "ApiPort": 8000, - "ApiRetryPeriod": 1, - + "ApiPort": 8000 + }, + "Cache": { + "RetryPeriod": 1, + "MaxEntries": 20, + "MaxRetries": 5, + "CacheFileName": "cache" + }, + "DebuggerDetection": { "DebuggerAddress": "localhost", - "DebuggerPort": 20000 + "DebuggerPort": 20000, + "DebuggerProcessName": "t32mtc" } } \ No newline at end of file diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index 681165a..9ef7ed9 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -5,8 +5,10 @@ namespace LDClient.utils { internal class ConfigLoader { private const string LoggingSection = "Logging"; private const string NetworkSection = "Network"; + private const string CacheSection = "Cache"; + private const string DDSection = "DebuggerDetection"; - + #region Logger public int LogChunkSize { get; set; } public int LogChunkMaxCount { get; set; } public int LogArchiveMaxCount { get; set; } @@ -16,14 +18,27 @@ namespace LDClient.utils { public LogVerbosity LogVerbosityType { get; set; } = LogVerbosity.Full; public LogFlow LogFlowType { get; set; } = LogFlow.Console; + #endregion + #region Api public string ApiBaseAddress { get; set; } public string ApiUsbEndPoint { get; set; } public uint ApiPort { get; set; } - public uint ApiRetryPeriod { get; set; } + #endregion + + #region Cache + public string CacheFileName { get; set; } + public uint MaxRetries { get; set; } + public uint MaxEntries { get; set; } + public uint RetryPeriod { get; set; } + #endregion + + #region Detection public string DebuggerAddress { get; set; } public int DebuggerPort { get; set; } + public string DebuggerProcessName { get; set; } + #endregion public ConfigLoader() { var configuration = new ConfigurationBuilder() @@ -48,11 +63,19 @@ namespace LDClient.utils { ApiBaseAddress = network["ApiBaseAddress"]; ApiUsbEndPoint = network["ApiLDEndPoint"]; ApiPort = uint.Parse(network["ApiPort"]); - ApiRetryPeriod = uint.Parse(network["ApiRetryPeriod"]); - DebuggerAddress = network["DebuggerAddress"]; - DebuggerPort = int.Parse(network["DebuggerPort"]); + var cache = configuration.GetSection(CacheSection); + RetryPeriod = uint.Parse(cache["RetryPeriod"]); + MaxEntries = uint.Parse(cache["MaxEntries"]); + MaxRetries = uint.Parse(cache["MaxRetries"]); + CacheFileName = cache["CacheFileName"]; + + + var debugger = configuration.GetSection(DDSection); + DebuggerAddress = debugger["DebuggerAddress"]; + DebuggerPort = int.Parse(debugger["DebuggerPort"]); + DebuggerProcessName = debugger["DebuggerProcessName"]; Console.WriteLine("Configuration successfully loaded!"); } catch (FormatException e) { @@ -62,6 +85,5 @@ namespace LDClient.utils { throw new IOException("Reading of configuration file failed! " + e); } } - } } -- GitLab From 88eab964e5194d198574a198888740b5744205e0 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 19:58:37 +0200 Subject: [PATCH 12/67] re #9441 definition of new Api client functions, implementation and added needed variables --- ld_client/LDClient/network/ApiClient.cs | 30 ++++++++++++++++++++---- ld_client/LDClient/network/IApiClient.cs | 2 ++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index 532fe3c..15e38e4 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -1,10 +1,10 @@ using System.Diagnostics; using System.Net.Http.Json; +using System.Text; using System.Text.Json; using System.Text.Json.Serialization; +using DiskQueue; using LDClient.network.data; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace LDClient.network { public class ApiClient : IApiClient { @@ -22,17 +22,27 @@ namespace LDClient.network { Status = ConnectionStatus.Connected }; + private bool _running; + private readonly string _uri; private readonly HttpClient _client; + private readonly IPersistentQueue _cache; private readonly uint _retryPeriod; + private readonly uint _maxEntries; + private readonly uint _maxRetries; + - public ApiClient(string url, uint port, string path, uint retryPeriod) { + public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, + string cacheFilename) { _uri = $"{url}:{port}{path}"; _retryPeriod = retryPeriod; - + _maxEntries = maxEntries; + _maxRetries = maxRetries; + _client = new HttpClient(); + _cache = new PersistentQueue(cacheFilename); } @@ -83,6 +93,18 @@ namespace LDClient.network { Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" + $"Request body: {json},\n" + $"Response: {JsonConvert.SerializeObject(responseToLog)}"); + + public async void Run() { + Program.DefaultLogger.Info("Api Client thread has started"); + _running = true; + while (_running) { + await ResendPayloadsAsync(); + Thread.Sleep((int)_retryPeriod); + } + } + + public void Stop() { + _running = false; } } } diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs index fc7ceaa..f5ea700 100644 --- a/ld_client/LDClient/network/IApiClient.cs +++ b/ld_client/LDClient/network/IApiClient.cs @@ -3,5 +3,7 @@ namespace LDClient.network { public interface IApiClient { public Task SendPayloadAsync(Payload payload); + public void Run(); + public void Stop(); } } -- GitLab From eda1e8c74a34dde8184b960627c82cc7083d482d Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 19:59:33 +0200 Subject: [PATCH 13/67] re #9441 Added core of cache manager --- ld_client/LDClient/network/ApiClient.cs | 39 +++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index 15e38e4..152a962 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -94,6 +94,45 @@ namespace LDClient.network { $"Request body: {json},\n" + $"Response: {JsonConvert.SerializeObject(responseToLog)}"); + private async Task ResendPayloadsAsync() { + var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue); + var payloads = new List<Payload>(); + + using (var session = _cache.OpenSession()) { + for (var i = 0; i < numberOfPayloadsToResend; i++) { + var rawBytes = session.Dequeue(); + var payload = JsonSerializer.Deserialize<Payload>(rawBytes); + if (payload is not null) { + payloads.Add(payload); + } + } + session.Flush(); + } + + if (payloads.Count > 0) { + Program.DefaultLogger.Debug($"ResendPayloadAsync -> {payloads.Count} unsent payloads"); + var tasks = new List<Task>(); + foreach (var payload in payloads) { + Program.DefaultLogger.Info($"Resending {payload}."); + tasks.Add(SendPayloadAsync(payload)); + } + await Task.WhenAll(tasks); + } + } + + + private void CachePayload(Payload payload) { + Program.DefaultLogger.Info($"Storing {payload} into the cache."); + var numberOfCachedPayloads = _cache.EstimatedCountOfItemsInQueue; + using var session = _cache.OpenSession(); + if (numberOfCachedPayloads >= _maxEntries) { + session.Dequeue(); + } + var payloadJson = JsonSerializer.Serialize(payload); + session.Enqueue(Encoding.UTF8.GetBytes(payloadJson)); + session.Flush(); + } + public async void Run() { Program.DefaultLogger.Info("Api Client thread has started"); _running = true; -- GitLab From 522ba9b4be3d9a9deeccdfe61b1685661b8e7f32 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 20:01:04 +0200 Subject: [PATCH 14/67] re #9441 manager refactoring - removal of useless functions and variables --- ld_client/LDClient/network/ApiClient.cs | 29 +++++++------------------ 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index 152a962..dbbbf7b 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -50,12 +50,7 @@ namespace LDClient.network { try { Stopwatch stopWatch = new(); stopWatch.Start(); - - var json = JsonConvert.SerializeObject(ExampleInfo); - if (json is null) { - Program.DefaultLogger.Error($"Failed to serialize object: {ExampleInfo}"); - return; - } + var response = await _client.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions { Converters = { new JsonStringEnumConverter( JsonNamingPolicy.CamelCase) @@ -63,26 +58,16 @@ namespace LDClient.network { }); stopWatch.Stop(); - Response2Log(json, response, stopWatch.ElapsedMilliseconds); + CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds); response.EnsureSuccessStatusCode(); - var serverResponse = await response.Content.ReadAsStringAsync(); - CheckResponse(serverResponse); } catch (Exception e) { Program.DefaultLogger.Error($"Failed to send {payload} to the server. Due to: {e.Message}"); + CachePayload(payload); } } - - private static bool CheckResponse(string response) { - dynamic json = JObject.Parse(response); - if (json.statusCode < 400) { - return true; - } - throw new Exception($"Server responded with error code: {json.statusCode}"); - } - - private static void Response2Log(string json, HttpResponseMessage response, long durationMs) { + private static void CreateRequestLog(Payload payload, HttpResponseMessage response, long durationMs) { var responseToLog = new { statusCode = response.StatusCode, content = response.Content, @@ -91,8 +76,10 @@ namespace LDClient.network { }; Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" + - $"Request body: {json},\n" + - $"Response: {JsonConvert.SerializeObject(responseToLog)}"); + $"Request body: {payload},\n" + + $"Response: {responseToLog}"); + } + private async Task ResendPayloadsAsync() { var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue); -- GitLab From aaad9ad4328109c8f294c8d7e44e6d78f9b40630 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 20:05:10 +0200 Subject: [PATCH 15/67] re #9441 Main example + Payload feature for better manipulation --- ld_client/LDClient/Program.cs | 23 +++++++++++++++++++--- ld_client/LDClient/network/data/Payload.cs | 23 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index a05e5e5..3f4b77f 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -1,4 +1,4 @@ -using LDClient.network; +using LDClient.network; using LDClient.utils; using LDClient.utils.loggers; @@ -10,11 +10,28 @@ internal class Program { public static ALogger DefaultLogger { get; } = ALogger.Current; public static IApiClient DefaultApiClient { get; set; } = new ApiClient(Config.ApiBaseAddress, - Config.ApiPort, Config.ApiUsbEndPoint, Config.ApiRetryPeriod); + Config.ApiPort, Config.ApiUsbEndPoint, Config.RetryPeriod, Config.MaxEntries, + Config.MaxRetries, Config.CacheFileName); // Main Method public static async Task Main() { + + var apiClientThread = new Thread(DefaultApiClient.Run) { + IsBackground = true + }; + apiClientThread.Start(); + + DefaultLogger.Debug("Main -> starting SendPayloadAsync"); await DefaultApiClient.SendPayloadAsync(ApiClient.ExampleInfo); - Console.WriteLine("Finished!"); + + + DefaultLogger.Debug("Main -> lets slack for a bit"); + Thread.Sleep(30000); + + DefaultLogger.Debug("Main -> stopping the ApiClient"); + DefaultApiClient.Stop(); + apiClientThread.Join(); + DefaultLogger.Debug("Main -> finished"); + } } } \ No newline at end of file diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs index 1e65c6d..30672d7 100644 --- a/ld_client/LDClient/network/data/Payload.cs +++ b/ld_client/LDClient/network/data/Payload.cs @@ -1,5 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json; +using System.Text.Json.Serialization; using Newtonsoft.Json; +using JsonSerializer = System.Text.Json.JsonSerializer; namespace LDClient.network.data { [JsonObject(MemberSerialization.OptIn)] @@ -25,5 +27,24 @@ namespace LDClient.network.data { [JsonPropertyName("status")] //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] public ConnectionStatus Status { get; set; } + + + public override string ToString() { + return ParseToJson(this); + } + + public string ParseToJson() { + return Payload.ParseToJson(this); + } + + public static string ParseToJson(Payload payload) { + var options = new JsonSerializerOptions { + Converters = { + new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) + } + }; + + return JsonSerializer.Serialize(payload, options); + } } } -- GitLab From 914776bd00caddafaf81be8bb5d2e3f48f186169 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 22:57:37 +0200 Subject: [PATCH 16/67] re #9433 Added needed configuration for detection --- ld_client/LDClient/appsettings.json | 12 +++++++----- ld_client/LDClient/utils/ConfigLoader.cs | 18 +++++++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 7884a5e..910d880 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -21,14 +21,16 @@ "ApiPort": 8000 }, "Cache": { - "RetryPeriod": 1, + "RetryPeriod": 10000, "MaxEntries": 20, "MaxRetries": 5, "CacheFileName": "cache" }, "DebuggerDetection": { - "DebuggerAddress": "localhost", - "DebuggerPort": 20000, - "DebuggerProcessName": "t32mtc" - } + "T32Address": "localhost", + "T32Port": 20000, + "T32ProcessName": "t32mtc", + "T32InfoLocation": "C:\\app\\tools\\T32\\results\\ldResult.txt", + "DetectionPeriod": 5000 + } } \ No newline at end of file diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index 9ef7ed9..b45b9f8 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -35,9 +35,11 @@ namespace LDClient.utils { #endregion #region Detection - public string DebuggerAddress { get; set; } - public int DebuggerPort { get; set; } - public string DebuggerProcessName { get; set; } + public string T32Address { get; set; } + public int T32Port { get; set; } + public string T32ProcessName { get; set; } + public uint DetectionPeriod { get; set; } + public string T32InfoLocation { get; set; } #endregion public ConfigLoader() { @@ -58,7 +60,7 @@ namespace LDClient.utils { LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]); LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]); LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]); - + var network = configuration.GetSection(NetworkSection); ApiBaseAddress = network["ApiBaseAddress"]; ApiUsbEndPoint = network["ApiLDEndPoint"]; @@ -73,9 +75,11 @@ namespace LDClient.utils { var debugger = configuration.GetSection(DDSection); - DebuggerAddress = debugger["DebuggerAddress"]; - DebuggerPort = int.Parse(debugger["DebuggerPort"]); - DebuggerProcessName = debugger["DebuggerProcessName"]; + T32Address = debugger["T32Address"]; + T32Port = int.Parse(debugger["T32Port"]); + T32ProcessName = debugger["T32ProcessName"]; + T32InfoLocation = debugger["T32InfoLocation"]; + DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]); Console.WriteLine("Configuration successfully loaded!"); } catch (FormatException e) { -- GitLab From 4056867185713b32bf144b32a6a17cff78e961a5 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 23:00:05 +0200 Subject: [PATCH 17/67] re #9433 Abstract detection definition added --- ld_client/LDClient/detection/IDetection.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 ld_client/LDClient/detection/IDetection.cs diff --git a/ld_client/LDClient/detection/IDetection.cs b/ld_client/LDClient/detection/IDetection.cs new file mode 100644 index 0000000..4d42eea --- /dev/null +++ b/ld_client/LDClient/detection/IDetection.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.detection { + internal interface IDetection { + + public void DetectAsync(); + + public void RunPeriodicDetection(); + public void StopPeriodicDetection(); + } +} -- GitLab From ad51fa1a94cbb500dfb71b490e6c5b0b1f0384d2 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 23:00:48 +0200 Subject: [PATCH 18/67] re #9433 Added possible detection by process name --- .../LDClient/detection/ProcessDetection.cs | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 ld_client/LDClient/detection/ProcessDetection.cs diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs new file mode 100644 index 0000000..77ebca2 --- /dev/null +++ b/ld_client/LDClient/detection/ProcessDetection.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System; +using System.Management; + +namespace LDClient.detection { + public class ProcessDetection : IDetection { + + private const string ProcessStartQuery = "SELECT * FROM Win32_ProcessStartTrace"; + private const string ProcessStopQuery = "SELECT * FROM Win32_ProcessStopTrace"; + + private ManagementEventWatcher _stopWatch; + + private bool _isRunning; + + private readonly string _processName; + private readonly uint _detectionPeriod; + private bool _processActive; + public ProcessDetection(string processName, uint detectionPeriod) { + this._processName = processName; + this._detectionPeriod = detectionPeriod; + } + + + public void DetectAsync() { + var processes = Process.GetProcessesByName(_processName); + Program.DefaultLogger.Info($"Found {processes.Length} processes with name: {_processName}"); + var processFound = false; + foreach (var process in processes) { + if (process.ProcessName.Equals(_processName)) { + if (!_processActive) { + Program.DefaultLogger.Info($"Process started: {_processName}"); + } + _processActive = true; + processFound = true; + break; + } + Console.WriteLine(process); + } + + if (!processFound) { + if (_processActive) { + Program.DefaultLogger.Info($"Process stopped: {_processName}"); + } + _processActive = false; + } + } + + + public void RunPeriodicDetection() { + + Program.DefaultLogger.Info("Process periodic detector has started"); + _isRunning = true; + while (_isRunning) { + DetectAsync(); + Thread.Sleep((int)_detectionPeriod); + } + } + + public void StopPeriodicDetection() { + _isRunning = false; + } + + + public void RegisterProcessListeners() { + ManagementEventWatcher startWatch = new ManagementEventWatcher( + new WqlEventQuery(ProcessStartQuery)); + startWatch.EventArrived += startWatch_EventArrived; + startWatch.Start(); + + _stopWatch = new ManagementEventWatcher( + new WqlEventQuery(ProcessStopQuery)); + _stopWatch.EventArrived += stopWatch_EventArrived; + _stopWatch.Start(); + } + + void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) { + var processName = e.NewEvent.Properties["ProcessName"].Value.ToString(); + if (processName.Equals(_processName + ".exe")) { + Program.DefaultLogger.Info($"Process stopped: {processName}"); + } + } + + void startWatch_EventArrived(object sender, EventArrivedEventArgs e) { + var processName = e.NewEvent.Properties["ProcessName"].Value.ToString(); + if (processName.Equals(_processName + ".exe")) { + Program.DefaultLogger.Info($"Process started: {processName}"); + } + } + } +} -- GitLab From 56f7f54615ae955d4f533863fc5072dfa7bb2336 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 23:01:27 +0200 Subject: [PATCH 19/67] re #9433 Added possible detection by port listening --- .../LDClient/detection/NetworkDetection.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 ld_client/LDClient/detection/NetworkDetection.cs diff --git a/ld_client/LDClient/detection/NetworkDetection.cs b/ld_client/LDClient/detection/NetworkDetection.cs new file mode 100644 index 0000000..83b0bcc --- /dev/null +++ b/ld_client/LDClient/detection/NetworkDetection.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.detection { + public class NetworkDetection : IDetection { + + private readonly uint _port; + + private bool _isRunning; + + private readonly uint _detectionPeriod; + + public NetworkDetection(uint port, uint detectionPeriod) { + this._port = port; + this._detectionPeriod = detectionPeriod; + } + + public void DetectAsync() { + + var listeners = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners(); + + Program.DefaultLogger.Debug($"NetworkDetection -> Checking all currently listening."); + foreach (var listener in listeners) { + //Program.DefaultLogger.Debug($"{listener.Address}:{listener.Port}"); + if (listener.Port == _port) { + Program.DefaultLogger.Info($"Found some process listening on {listener.Address}:{_port}"); + } + } + + } + + + public void RunPeriodicDetection() { + Program.DefaultLogger.Info("Network periodic detector has started"); + _isRunning = true; + while (_isRunning) { + DetectAsync(); + Thread.Sleep((int)_detectionPeriod); + } + } + + public void StopPeriodicDetection() { + _isRunning = false; + } + } +} -- GitLab From f5a08dd55a0848dc146f6f9d70ebfbd415daf981 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 10 Apr 2022 23:02:09 +0200 Subject: [PATCH 20/67] re #9433 detection definition in Main --- ld_client/LDClient/Program.cs | 39 +++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 3f4b77f..0eb6443 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -1,8 +1,11 @@ +using System.Runtime.InteropServices; +using System.Security.Principal; +using LDClient.detection; using LDClient.network; using LDClient.utils; using LDClient.utils.loggers; -namespace LDClient; +namespace LDClient; internal class Program { @@ -13,25 +16,49 @@ internal class Program { Config.ApiPort, Config.ApiUsbEndPoint, Config.RetryPeriod, Config.MaxEntries, Config.MaxRetries, Config.CacheFileName); + + private static NetworkDetection _netDetect = new(Config.ApiPort, Config.DetectionPeriod); + private static ProcessDetection _procDetect = new(Config.T32ProcessName, Config.DetectionPeriod); + + // Main Method public static async Task Main() { - var apiClientThread = new Thread(DefaultApiClient.Run) { IsBackground = true }; + DefaultLogger.Debug("Main -> starting the ApiClient"); apiClientThread.Start(); - DefaultLogger.Debug("Main -> starting SendPayloadAsync"); - await DefaultApiClient.SendPayloadAsync(ApiClient.ExampleInfo); + var admin = IsAdministrator(); + DefaultLogger.Debug($"Is program executed with admin rights? {admin}"); + var networkTread = new Thread(_netDetect.RunPeriodicDetection); + networkTread.Start(); + if (admin) { + _procDetect.RegisterProcessListeners(); - DefaultLogger.Debug("Main -> lets slack for a bit"); - Thread.Sleep(30000); + } else { + var processThread = new Thread(_procDetect.RunPeriodicDetection); + processThread.Start(); + processThread.Join(); + } + + networkTread.Join(); DefaultLogger.Debug("Main -> stopping the ApiClient"); DefaultApiClient.Stop(); apiClientThread.Join(); DefaultLogger.Debug("Main -> finished"); } + + public static bool IsAdministrator() { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { + var identity = WindowsIdentity.GetCurrent(); + var principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + + } else { + return false; + } } } \ No newline at end of file -- GitLab From bab6f59d70db4045421ad2f1705b60f59d1b0073 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Fri, 15 Apr 2022 14:24:08 +0200 Subject: [PATCH 21/67] re #9565 Implemented DebuggerInfoParser, added IoUtils for reading the content of a file --- .../LDClient/detection/DebuggerInfoParser.cs | 21 +++++++++++++++++++ ld_client/LDClient/utils/IoUtils.cs | 9 ++++++++ 2 files changed, 30 insertions(+) create mode 100644 ld_client/LDClient/detection/DebuggerInfoParser.cs create mode 100644 ld_client/LDClient/utils/IoUtils.cs diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs new file mode 100644 index 0000000..3f07e32 --- /dev/null +++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs @@ -0,0 +1,21 @@ +using System.Text.RegularExpressions; + +namespace LDClient.detection { + + public static class DebuggerInfoParser { + + private const int ExpectedNumberOfMatches = 2; + + private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)"); + + public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) { + var matches = SerialNumberRegex.Matches(dataTxt); + + if (matches.Count != ExpectedNumberOfMatches) { + throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})"); + } + + return (matches[0].ToString(), matches[1].ToString()); + } + } +} \ No newline at end of file diff --git a/ld_client/LDClient/utils/IoUtils.cs b/ld_client/LDClient/utils/IoUtils.cs new file mode 100644 index 0000000..7bf3a65 --- /dev/null +++ b/ld_client/LDClient/utils/IoUtils.cs @@ -0,0 +1,9 @@ +namespace LDClient.utils { + + public static class IoUtils { + + public static string ReadFile(string filename) { + return File.ReadAllLines(filename).Aggregate("", (current, line) => $"{current}{line}\n"); + } + } +} \ No newline at end of file -- GitLab From 30c849e48a7421a525b5aa6685c5b5ed26d8bb92 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Sat, 16 Apr 2022 11:26:19 +0200 Subject: [PATCH 22/67] re #9567 Made sure that there is only one running process of the application. --- ld_client/LDClient/Program.cs | 62 +++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 0eb6443..a161b8d 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -5,40 +5,52 @@ using LDClient.network; using LDClient.utils; using LDClient.utils.loggers; +using static System.Diagnostics.Process; +using static System.Reflection.Assembly; + namespace LDClient; -internal class Program { +internal static class Program { - public static ConfigLoader Config { get; set; } = new(); + public static ConfigLoader Config { get; } = new(); public static ALogger DefaultLogger { get; } = ALogger.Current; - - public static IApiClient DefaultApiClient { get; set; } = new ApiClient(Config.ApiBaseAddress, - Config.ApiPort, Config.ApiUsbEndPoint, Config.RetryPeriod, Config.MaxEntries, - Config.MaxRetries, Config.CacheFileName); - - - private static NetworkDetection _netDetect = new(Config.ApiPort, Config.DetectionPeriod); - private static ProcessDetection _procDetect = new(Config.T32ProcessName, Config.DetectionPeriod); - - + private static IApiClient? DefaultApiClient { get; set; } + private static readonly NetworkDetection NetDetect = new(Config.ApiPort, Config.DetectionPeriod); + private static readonly ProcessDetection ProcDetect = new(Config.T32ProcessName, Config.DetectionPeriod); + // Main Method - public static async Task Main() { + public static int Main() { + var exists = GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1; + if (exists) { + DefaultLogger.Error("Another instance of the application is already running"); + return 1; + } + + DefaultApiClient = new ApiClient( + Config.ApiBaseAddress, + Config.ApiPort, + Config.ApiUsbEndPoint, + Config.RetryPeriod, Config.MaxEntries, + Config.MaxRetries, + Config.CacheFileName + ); + + DefaultLogger.Debug("Main -> starting the ApiClient"); var apiClientThread = new Thread(DefaultApiClient.Run) { IsBackground = true }; - DefaultLogger.Debug("Main -> starting the ApiClient"); apiClientThread.Start(); var admin = IsAdministrator(); DefaultLogger.Debug($"Is program executed with admin rights? {admin}"); - var networkTread = new Thread(_netDetect.RunPeriodicDetection); + var networkTread = new Thread(NetDetect.RunPeriodicDetection); networkTread.Start(); + if (admin) { - _procDetect.RegisterProcessListeners(); - + ProcDetect.RegisterProcessListeners(); } else { - var processThread = new Thread(_procDetect.RunPeriodicDetection); + var processThread = new Thread(ProcDetect.RunPeriodicDetection); processThread.Start(); processThread.Join(); } @@ -49,16 +61,16 @@ internal class Program { DefaultApiClient.Stop(); apiClientThread.Join(); DefaultLogger.Debug("Main -> finished"); + + return 0; } - public static bool IsAdministrator() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var identity = WindowsIdentity.GetCurrent(); - var principal = new WindowsPrincipal(identity); - return principal.IsInRole(WindowsBuiltInRole.Administrator); - - } else { + private static bool IsAdministrator() { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return false; } + var identity = WindowsIdentity.GetCurrent(); + var principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); } } \ No newline at end of file -- GitLab From 4a9e70db3786db264ffb03947b3e835a67654731 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Sun, 17 Apr 2022 10:03:06 +0200 Subject: [PATCH 23/67] re #9566 Created mocks for simulating an LD-debugger --- ld_client/Mock/ld/CMakeLists.txt | 7 ++++ ld_client/Mock/ld/ld_mock.cpp | 11 ++++++ ld_client/Mock/t32rem/CMakeLists.txt | 7 ++++ ld_client/Mock/t32rem/t32rem_mock.cpp | 57 +++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 ld_client/Mock/ld/CMakeLists.txt create mode 100644 ld_client/Mock/ld/ld_mock.cpp create mode 100644 ld_client/Mock/t32rem/CMakeLists.txt create mode 100644 ld_client/Mock/t32rem/t32rem_mock.cpp diff --git a/ld_client/Mock/ld/CMakeLists.txt b/ld_client/Mock/ld/CMakeLists.txt new file mode 100644 index 0000000..9886e96 --- /dev/null +++ b/ld_client/Mock/ld/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.0) + +project(ld_mock) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(${PROJECT_NAME} ld_mock.cpp) diff --git a/ld_client/Mock/ld/ld_mock.cpp b/ld_client/Mock/ld/ld_mock.cpp new file mode 100644 index 0000000..78e7b5b --- /dev/null +++ b/ld_client/Mock/ld/ld_mock.cpp @@ -0,0 +1,11 @@ +#include <chrono> +#include <thread> + +static constexpr int LOOP_DELAY_S = 10; + +int main() { + while (true) { + std::this_thread::sleep_for(std::chrono::milliseconds(LOOP_DELAY_S * 1000)); + } + return 0; +} diff --git a/ld_client/Mock/t32rem/CMakeLists.txt b/ld_client/Mock/t32rem/CMakeLists.txt new file mode 100644 index 0000000..916a768 --- /dev/null +++ b/ld_client/Mock/t32rem/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.0) + +project(t32rem_mock) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(${PROJECT_NAME} t32rem_mock.cpp) diff --git a/ld_client/Mock/t32rem/t32rem_mock.cpp b/ld_client/Mock/t32rem/t32rem_mock.cpp new file mode 100644 index 0000000..5c05734 --- /dev/null +++ b/ld_client/Mock/t32rem/t32rem_mock.cpp @@ -0,0 +1,57 @@ +// t32rem.exe localhost port=20000 VERSION.HARDWARE +#include <chrono> +#include <thread> +#include <random> +#include <fstream> +#include <iostream> +#include <cstring> + +static constexpr int EXPECTED_NUMBER_OF_ARGUMENTS = 4; +static constexpr const char *OUTPUT_FILE_NAME = "output.txt"; +static constexpr const char *DEBUGGER_INFO = + "B::version.hardware\n" + "PowerDebug USB 3.0 via USB 3.0\n" + " Serial Number: C21070308132\n" + " Firmware R.2021.02 (136263)\n" + " Instance: 1.\n" + " Automotive Debug Cable\n" + " Serial Number: C17040231820\n"; + +static constexpr int MIN_SEC_DELAY = 1; +static constexpr int MAX_SEC_DELAY = 10; + +int main(int argc, char *argv[]) { + if (argc != EXPECTED_NUMBER_OF_ARGUMENTS) { + std::cout << "Invalid number of arguments\n"; + std::cout << "The mock is meant to be called with the following arguments: localhost port=20000 VERSION.HARDWARE\n"; + return 1; + } + if (strcmp(argv[1], "localhost") != 0) { + std::cout << "Invalid first argument (expected 'localhost')\n"; + return 2; + } + if (strcmp(argv[2], "port=20000") != 0) { + std::cout << "Invalid second argument (expected 'port=20000')\n"; + return 2; + } + if (strcmp(argv[3], "VERSION.HARDWARE") != 0) { + std::cout << "Invalid third argument (expected 'VERSION.HARDWARE')\n"; + return 2; + } + + std::random_device rd; + std::mt19937 mt(rd()); + std::uniform_int_distribution<uint32_t> distribution(MIN_SEC_DELAY, MAX_SEC_DELAY); + uint32_t delay_s = distribution(mt); + std::this_thread::sleep_for(std::chrono::milliseconds(delay_s * 1000)); + + std::ofstream file(OUTPUT_FILE_NAME); + if (!file) { + std::cout << "Fail to open the output file\n"; + return 3; + } + file << DEBUGGER_INFO; + file.close(); + + return 0; +} -- GitLab From f281acacfc4892b73d2f71743167be2c1ebb1a84 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Sun, 17 Apr 2022 12:08:38 +0200 Subject: [PATCH 24/67] re #9566 Added InfoFetcher.cs, modified some other files (a bit of refactoring) --- ld_client/LDClient/Program.cs | 52 ++++------- ld_client/LDClient/appsettings.json | 5 +- ld_client/LDClient/detection/IDetection.cs | 15 --- .../LDClient/detection/IProcessDetection.cs | 7 ++ ld_client/LDClient/detection/InfoFetcher.cs | 72 +++++++++++++++ .../LDClient/detection/NetworkDetection.cs | 49 ---------- .../LDClient/detection/ProcessDetection.cs | 92 ------------------- .../detection/ProcessProcessDetection.cs | 87 ++++++++++++++++++ ld_client/LDClient/network/ApiClient.cs | 35 +------ ld_client/LDClient/network/IApiClient.cs | 3 +- ld_client/LDClient/network/data/Payload.cs | 10 +- ld_client/LDClient/utils/ConfigLoader.cs | 53 +++++------ 12 files changed, 225 insertions(+), 255 deletions(-) delete mode 100644 ld_client/LDClient/detection/IDetection.cs create mode 100644 ld_client/LDClient/detection/IProcessDetection.cs create mode 100644 ld_client/LDClient/detection/InfoFetcher.cs delete mode 100644 ld_client/LDClient/detection/NetworkDetection.cs delete mode 100644 ld_client/LDClient/detection/ProcessDetection.cs create mode 100644 ld_client/LDClient/detection/ProcessProcessDetection.cs diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index a161b8d..577a284 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; -using System.Security.Principal; using LDClient.detection; using LDClient.network; using LDClient.utils; @@ -15,10 +13,13 @@ internal static class Program { public static ConfigLoader Config { get; } = new(); public static ALogger DefaultLogger { get; } = ALogger.Current; private static IApiClient? DefaultApiClient { get; set; } - private static readonly NetworkDetection NetDetect = new(Config.ApiPort, Config.DetectionPeriod); - private static readonly ProcessDetection ProcDetect = new(Config.T32ProcessName, Config.DetectionPeriod); - // Main Method + private static readonly InfoFetcher InfoFetcher = new( + 5, + 1000, + "output.txt" + ); + public static int Main() { var exists = GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1; if (exists) { @@ -35,42 +36,27 @@ internal static class Program { Config.CacheFileName ); + IProcessDetection processProcessDetection = new ProcessProcessDetection( + Config.T32ProcessName, + Config.DetectionPeriod, + InfoFetcher, + DefaultApiClient + ); + DefaultLogger.Debug("Main -> starting the ApiClient"); var apiClientThread = new Thread(DefaultApiClient.Run) { IsBackground = true }; apiClientThread.Start(); - var admin = IsAdministrator(); - DefaultLogger.Debug($"Is program executed with admin rights? {admin}"); + var processThread = new Thread(processProcessDetection.RunPeriodicDetection) { + IsBackground = true + }; + processThread.Start(); - var networkTread = new Thread(NetDetect.RunPeriodicDetection); - networkTread.Start(); - - if (admin) { - ProcDetect.RegisterProcessListeners(); - } else { - var processThread = new Thread(ProcDetect.RunPeriodicDetection); - processThread.Start(); - processThread.Join(); + while (true) { + Thread.Sleep(10 * 1000); } - - networkTread.Join(); - - DefaultLogger.Debug("Main -> stopping the ApiClient"); - DefaultApiClient.Stop(); - apiClientThread.Join(); - DefaultLogger.Debug("Main -> finished"); - return 0; } - - private static bool IsAdministrator() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - return false; - } - var identity = WindowsIdentity.GetCurrent(); - var principal = new WindowsPrincipal(identity); - return principal.IsInRole(WindowsBuiltInRole.Administrator); - } } \ No newline at end of file diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 910d880..ad06abf 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -14,7 +14,6 @@ "LogVerbosityType": 2, "LogFlowType": 0 }, - "Network": { "ApiBaseAddress": "http://127.0.0.1", "ApiLDEndPoint": "/lauterbach-debugger-logs/", @@ -27,9 +26,7 @@ "CacheFileName": "cache" }, "DebuggerDetection": { - "T32Address": "localhost", - "T32Port": 20000, - "T32ProcessName": "t32mtc", + "T32ProcessName": "ld_mock", "T32InfoLocation": "C:\\app\\tools\\T32\\results\\ldResult.txt", "DetectionPeriod": 5000 } diff --git a/ld_client/LDClient/detection/IDetection.cs b/ld_client/LDClient/detection/IDetection.cs deleted file mode 100644 index 4d42eea..0000000 --- a/ld_client/LDClient/detection/IDetection.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LDClient.detection { - internal interface IDetection { - - public void DetectAsync(); - - public void RunPeriodicDetection(); - public void StopPeriodicDetection(); - } -} diff --git a/ld_client/LDClient/detection/IProcessDetection.cs b/ld_client/LDClient/detection/IProcessDetection.cs new file mode 100644 index 0000000..26782e1 --- /dev/null +++ b/ld_client/LDClient/detection/IProcessDetection.cs @@ -0,0 +1,7 @@ +namespace LDClient.detection { + + internal interface IProcessDetection { + + public void RunPeriodicDetection(); + } +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs new file mode 100644 index 0000000..c224b31 --- /dev/null +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -0,0 +1,72 @@ +using System.Diagnostics; +using LDClient.utils; + +namespace LDClient.detection { + + public class InfoFetcher { + + private const string F32RemExecutable = "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock"; + private const string F32RemArguments = "localhost port=20000 VERSION.HARDWARE"; + private const string UndefinedSerialNumber = "number"; + + private readonly int _maxAttempts; + private readonly int _waitPeriodMs; + private readonly string _infoFilePath; + + public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber; + public string BodySerialNumber { get; private set; } = UndefinedSerialNumber; + + public InfoFetcher(int maxAttempts, int waitPeriodMs, string infoFilePath) { + _maxAttempts = maxAttempts; + _waitPeriodMs = waitPeriodMs; + _infoFilePath = infoFilePath; + } + + public async Task<bool> FetchDataAsync() { + Program.DefaultLogger.Info("Fetching data from the debugger."); + var success = await SendRetrieveInfoCommandAsync(F32RemExecutable, F32RemArguments); + if (!success) { + Program.DefaultLogger.Error("Failed to fetch data from the debugger."); + return false; + } + for (var i = 0; i < _maxAttempts; i++) { + Program.DefaultLogger.Info($"{i}. attempt to parse the info file."); + if (RetrieveDebuggerInfo(_infoFilePath)) { + Program.DefaultLogger.Info($"Info file has been parsed successfully."); + return true; + } + await Task.Delay(_waitPeriodMs); + } + Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created."); + return false; + } + + private bool RetrieveDebuggerInfo(string filePath) { + try { + var fileContent = IoUtils.ReadFile(filePath); + var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent); + HeadSerialNumber = headSerialNumber; + BodySerialNumber = bodySerialNumber; + File.Delete(filePath); + } catch (Exception exception) { + Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}"); + return false; + } + return true; + } + + private static async Task<bool> SendRetrieveInfoCommandAsync(string executableFile, string arguments) { + var t32RemProcess = new Process(); + t32RemProcess.StartInfo.FileName = executableFile; + t32RemProcess.StartInfo.Arguments = arguments; + try { + t32RemProcess.Start(); + await t32RemProcess.WaitForExitAsync(); + } catch (Exception exception) { + Program.DefaultLogger.Error($"Failed to run {executableFile}. {exception.Message}"); + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/NetworkDetection.cs b/ld_client/LDClient/detection/NetworkDetection.cs deleted file mode 100644 index 83b0bcc..0000000 --- a/ld_client/LDClient/detection/NetworkDetection.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LDClient.detection { - public class NetworkDetection : IDetection { - - private readonly uint _port; - - private bool _isRunning; - - private readonly uint _detectionPeriod; - - public NetworkDetection(uint port, uint detectionPeriod) { - this._port = port; - this._detectionPeriod = detectionPeriod; - } - - public void DetectAsync() { - - var listeners = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners(); - - Program.DefaultLogger.Debug($"NetworkDetection -> Checking all currently listening."); - foreach (var listener in listeners) { - //Program.DefaultLogger.Debug($"{listener.Address}:{listener.Port}"); - if (listener.Port == _port) { - Program.DefaultLogger.Info($"Found some process listening on {listener.Address}:{_port}"); - } - } - - } - - - public void RunPeriodicDetection() { - Program.DefaultLogger.Info("Network periodic detector has started"); - _isRunning = true; - while (_isRunning) { - DetectAsync(); - Thread.Sleep((int)_detectionPeriod); - } - } - - public void StopPeriodicDetection() { - _isRunning = false; - } - } -} diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs deleted file mode 100644 index 77ebca2..0000000 --- a/ld_client/LDClient/detection/ProcessDetection.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System; -using System.Management; - -namespace LDClient.detection { - public class ProcessDetection : IDetection { - - private const string ProcessStartQuery = "SELECT * FROM Win32_ProcessStartTrace"; - private const string ProcessStopQuery = "SELECT * FROM Win32_ProcessStopTrace"; - - private ManagementEventWatcher _stopWatch; - - private bool _isRunning; - - private readonly string _processName; - private readonly uint _detectionPeriod; - private bool _processActive; - public ProcessDetection(string processName, uint detectionPeriod) { - this._processName = processName; - this._detectionPeriod = detectionPeriod; - } - - - public void DetectAsync() { - var processes = Process.GetProcessesByName(_processName); - Program.DefaultLogger.Info($"Found {processes.Length} processes with name: {_processName}"); - var processFound = false; - foreach (var process in processes) { - if (process.ProcessName.Equals(_processName)) { - if (!_processActive) { - Program.DefaultLogger.Info($"Process started: {_processName}"); - } - _processActive = true; - processFound = true; - break; - } - Console.WriteLine(process); - } - - if (!processFound) { - if (_processActive) { - Program.DefaultLogger.Info($"Process stopped: {_processName}"); - } - _processActive = false; - } - } - - - public void RunPeriodicDetection() { - - Program.DefaultLogger.Info("Process periodic detector has started"); - _isRunning = true; - while (_isRunning) { - DetectAsync(); - Thread.Sleep((int)_detectionPeriod); - } - } - - public void StopPeriodicDetection() { - _isRunning = false; - } - - - public void RegisterProcessListeners() { - ManagementEventWatcher startWatch = new ManagementEventWatcher( - new WqlEventQuery(ProcessStartQuery)); - startWatch.EventArrived += startWatch_EventArrived; - startWatch.Start(); - - _stopWatch = new ManagementEventWatcher( - new WqlEventQuery(ProcessStopQuery)); - _stopWatch.EventArrived += stopWatch_EventArrived; - _stopWatch.Start(); - } - - void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) { - var processName = e.NewEvent.Properties["ProcessName"].Value.ToString(); - if (processName.Equals(_processName + ".exe")) { - Program.DefaultLogger.Info($"Process stopped: {processName}"); - } - } - - void startWatch_EventArrived(object sender, EventArrivedEventArgs e) { - var processName = e.NewEvent.Properties["ProcessName"].Value.ToString(); - if (processName.Equals(_processName + ".exe")) { - Program.DefaultLogger.Info($"Process started: {processName}"); - } - } - } -} diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessProcessDetection.cs new file mode 100644 index 0000000..d30f311 --- /dev/null +++ b/ld_client/LDClient/detection/ProcessProcessDetection.cs @@ -0,0 +1,87 @@ +using System.Diagnostics; +using LDClient.network; +using LDClient.network.data; + +namespace LDClient.detection { + + public class ProcessProcessDetection : IProcessDetection { + + private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss"; + + private readonly string _processName; + private readonly uint _detectionPeriodMs; + private bool _processIsActive; + private bool _failedToRetrieveData; + private Payload? _lastlyConnected; + + private readonly InfoFetcher _infoFetcher; + private readonly IApiClient _apiClient; + + public ProcessProcessDetection(string processName, uint detectionPeriodMs, InfoFetcher infoFetcher, IApiClient apiClient) { + _processName = processName; + _detectionPeriodMs = detectionPeriodMs; + _infoFetcher = infoFetcher; + _apiClient = apiClient; + _failedToRetrieveData = false; + } + + private async Task<bool> RetrieveDataFromDebugger() { + var success = await _infoFetcher.FetchDataAsync(); + if (success) { + _lastlyConnected = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat); + } + return success; + } + + private async Task DebuggerDisconnected() { + if (_lastlyConnected is not null) { + _lastlyConnected.Status = ConnectionStatus.Disconnected; + _lastlyConnected.TimeStamp = DateTime.Now.ToString(DatetimeFormat); + await _apiClient.SendPayloadAsync(_lastlyConnected); + _lastlyConnected = null; + } + } + + private async Task DetectProcessAsync() { + var processExists = Process.GetProcessesByName(_processName).Length > 0; + + if (processExists && !_processIsActive) { + Program.DefaultLogger.Info($"Process started: {_processName}"); + if (!_failedToRetrieveData) { + _failedToRetrieveData = !await RetrieveDataFromDebugger(); + } + } else if (!processExists && _processIsActive) { + Program.DefaultLogger.Info($"Process stopped: {_processName}"); + _failedToRetrieveData = false; + await DebuggerDisconnected(); + } + _processIsActive = processExists; + } + + private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) { + Payload payload = new() { + UserName = Environment.UserName, + HostName = Environment.MachineName, + TimeStamp = DateTime.Now.ToString(datetimeFormat), + HeadDevice = new DebuggerInfo { + SerialNumber = headSerialNumber + }, + BodyDevice = new DebuggerInfo { + SerialNumber = bodySerialNumber + }, + Status = ConnectionStatus.Connected + }; + await _apiClient.SendPayloadAsync(payload); + return payload; + } + + public async void RunPeriodicDetection() { + Program.DefaultLogger.Info("Process periodic detector has started"); + while (true) { + await DetectProcessAsync(); + Thread.Sleep((int)_detectionPeriodMs); + } + // ReSharper disable once FunctionNeverReturns + } + } +} diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index dbbbf7b..61766cf 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -7,24 +7,9 @@ using DiskQueue; using LDClient.network.data; namespace LDClient.network { + public class ApiClient : IApiClient { - public static readonly Payload ExampleInfo = new() { - UserName = "honikCz", - HostName = "Bramborak", - TimeStamp = DateTime.Parse("2022-03-21 18:05:00.168895"), - HeadDevice = new DebuggerInfo { - SerialNumber = "C12345678912" - }, - BodyDevice = new DebuggerInfo { - SerialNumber = "C98765432198" - }, - Status = ConnectionStatus.Connected - }; - - private bool _running; - - private readonly string _uri; private readonly HttpClient _client; private readonly IPersistentQueue _cache; @@ -32,8 +17,6 @@ namespace LDClient.network { private readonly uint _maxEntries; private readonly uint _maxRetries; - - public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, string cacheFilename) { _uri = $"{url}:{port}{path}"; @@ -43,7 +26,6 @@ namespace LDClient.network { _client = new HttpClient(); _cache = new PersistentQueue(cacheFilename); - } public async Task SendPayloadAsync(Payload payload) { @@ -55,7 +37,6 @@ namespace LDClient.network { Converters = { new JsonStringEnumConverter( JsonNamingPolicy.CamelCase) } - }); stopWatch.Stop(); CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds); @@ -80,7 +61,6 @@ namespace LDClient.network { $"Response: {responseToLog}"); } - private async Task ResendPayloadsAsync() { var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue); var payloads = new List<Payload>(); @@ -106,8 +86,7 @@ namespace LDClient.network { await Task.WhenAll(tasks); } } - - + private void CachePayload(Payload payload) { Program.DefaultLogger.Info($"Storing {payload} into the cache."); var numberOfCachedPayloads = _cache.EstimatedCountOfItemsInQueue; @@ -122,15 +101,11 @@ namespace LDClient.network { public async void Run() { Program.DefaultLogger.Info("Api Client thread has started"); - _running = true; - while (_running) { + while (true) { await ResendPayloadsAsync(); - Thread.Sleep((int)_retryPeriod); + Thread.Sleep((int) _retryPeriod); } - } - - public void Stop() { - _running = false; + // ReSharper disable once FunctionNeverReturns } } } diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs index f5ea700..5574d23 100644 --- a/ld_client/LDClient/network/IApiClient.cs +++ b/ld_client/LDClient/network/IApiClient.cs @@ -1,9 +1,10 @@ using LDClient.network.data; namespace LDClient.network { + public interface IApiClient { + public Task SendPayloadAsync(Payload payload); public void Run(); - public void Stop(); } } diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs index 30672d7..57b5755 100644 --- a/ld_client/LDClient/network/data/Payload.cs +++ b/ld_client/LDClient/network/data/Payload.cs @@ -8,21 +8,21 @@ namespace LDClient.network.data { public class Payload { [JsonPropertyName("username")] - public string UserName { get; set; } + public string? UserName { get; set; } [JsonPropertyName("hostname")] - public string HostName { get; set; } + public string? HostName { get; set; } [JsonPropertyName("timestamp")] //[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd HH:mm:ss.ffffff")] - public DateTime TimeStamp { get; set; } + public string? TimeStamp { get; set; } [JsonPropertyName("head_device")] - public DebuggerInfo HeadDevice { get; set; } + public DebuggerInfo? HeadDevice { get; set; } [JsonPropertyName("body_device")] - public DebuggerInfo BodyDevice { get; set; } + public DebuggerInfo? BodyDevice { get; set; } [JsonPropertyName("status")] //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index b45b9f8..a84708d 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -2,44 +2,47 @@ using Microsoft.Extensions.Configuration; namespace LDClient.utils { + internal class ConfigLoader { + private const string LoggingSection = "Logging"; private const string NetworkSection = "Network"; private const string CacheSection = "Cache"; - private const string DDSection = "DebuggerDetection"; + private const string DdSection = "DebuggerDetection"; #region Logger - public int LogChunkSize { get; set; } - public int LogChunkMaxCount { get; set; } - public int LogArchiveMaxCount { get; set; } - - public int LogCleanupPeriod { get; set; } - - public LogVerbosity LogVerbosityType { get; set; } = LogVerbosity.Full; - - public LogFlow LogFlowType { get; set; } = LogFlow.Console; + + public int LogChunkSize { get; private set; } + public int LogChunkMaxCount { get; private set; } + public int LogArchiveMaxCount { get; private set; } + + public int LogCleanupPeriod { get; private set; } + public LogVerbosity LogVerbosityType { get; private set; } = LogVerbosity.Full; + public LogFlow LogFlowType { get; private set; } = LogFlow.Console; + #endregion #region Api - public string ApiBaseAddress { get; set; } - public string ApiUsbEndPoint { get; set; } - public uint ApiPort { get; set; } + + public string ApiBaseAddress { get; private set; } + public string ApiUsbEndPoint { get; private set; } + public uint ApiPort { get; private set; } #endregion #region Cache - public string CacheFileName { get; set; } - public uint MaxRetries { get; set; } - public uint MaxEntries { get; set; } - public uint RetryPeriod { get; set; } + + public string CacheFileName { get; private set; } + public uint MaxRetries { get; private set; } + public uint MaxEntries { get; private set; } + public uint RetryPeriod { get; private set; } + #endregion #region Detection - public string T32Address { get; set; } - public int T32Port { get; set; } - public string T32ProcessName { get; set; } - public uint DetectionPeriod { get; set; } - public string T32InfoLocation { get; set; } + public string T32ProcessName { get; private set; } + public uint DetectionPeriod { get; private set; } + public string T32InfoLocation { get; private set; } #endregion public ConfigLoader() { @@ -49,7 +52,7 @@ namespace LDClient.utils { ReadAllSettings(configuration); } - private void ReadAllSettings(IConfigurationRoot configuration) { + private void ReadAllSettings(IConfiguration configuration) { try { var logging = configuration.GetSection(LoggingSection); @@ -74,9 +77,7 @@ namespace LDClient.utils { CacheFileName = cache["CacheFileName"]; - var debugger = configuration.GetSection(DDSection); - T32Address = debugger["T32Address"]; - T32Port = int.Parse(debugger["T32Port"]); + var debugger = configuration.GetSection(DdSection); T32ProcessName = debugger["T32ProcessName"]; T32InfoLocation = debugger["T32InfoLocation"]; DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]); -- GitLab From 6dab02506aa03a14324e3633765716e1f8bbbff3 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Sun, 17 Apr 2022 18:20:02 +0200 Subject: [PATCH 25/67] re #9566 Moved magic values into the configuration file. --- ld_client/LDClient/Program.cs | 17 ++++++++++------- ld_client/LDClient/appsettings.json | 8 ++++++-- ld_client/LDClient/detection/InfoFetcher.cs | 19 +++++++++++-------- .../detection/ProcessProcessDetection.cs | 19 ++++++++++--------- ld_client/LDClient/utils/ConfigLoader.cs | 19 +++++++++++++------ ld_client/Mock/t32rem/t32rem_mock.cpp | 2 +- 6 files changed, 51 insertions(+), 33 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 577a284..253ec64 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -10,19 +10,22 @@ namespace LDClient; internal static class Program { + private const int MainLoopDelayMs = 30000; + public static ConfigLoader Config { get; } = new(); public static ALogger DefaultLogger { get; } = ALogger.Current; private static IApiClient? DefaultApiClient { get; set; } private static readonly InfoFetcher InfoFetcher = new( - 5, - 1000, - "output.txt" + Config.FetchInfoMaxAttempts, + Config.FetchInfoAttemptPeriod, + Config.T32InfoLocation, + Config.F32RemExecutable, + Config.F32RemArguments ); public static int Main() { - var exists = GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1; - if (exists) { + if (GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1) { DefaultLogger.Error("Another instance of the application is already running"); return 1; } @@ -43,7 +46,6 @@ internal static class Program { DefaultApiClient ); - DefaultLogger.Debug("Main -> starting the ApiClient"); var apiClientThread = new Thread(DefaultApiClient.Run) { IsBackground = true }; @@ -55,8 +57,9 @@ internal static class Program { processThread.Start(); while (true) { - Thread.Sleep(10 * 1000); + Thread.Sleep(MainLoopDelayMs); } + return 0; } } \ No newline at end of file diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index ad06abf..f882d0c 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -26,8 +26,12 @@ "CacheFileName": "cache" }, "DebuggerDetection": { + "F32RemExecutable": "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock", + "F32RemArguments": "localhost port=20000 VERSION.HARDWARE", "T32ProcessName": "ld_mock", - "T32InfoLocation": "C:\\app\\tools\\T32\\results\\ldResult.txt", - "DetectionPeriod": 5000 + "T32InfoLocation": "ldResult.txt", + "DetectionPeriod": 5000, + "FetchInfoMaxAttempts": 5, + "FetchInfoAttemptPeriod": 1000 } } \ No newline at end of file diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs index c224b31..0a5d3e6 100644 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -4,27 +4,30 @@ using LDClient.utils; namespace LDClient.detection { public class InfoFetcher { - - private const string F32RemExecutable = "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock"; - private const string F32RemArguments = "localhost port=20000 VERSION.HARDWARE"; + private const string UndefinedSerialNumber = "number"; - private readonly int _maxAttempts; - private readonly int _waitPeriodMs; + private readonly string _f32RemExecutable; + private readonly string _f32RemArguments; + + private readonly uint _maxAttempts; + private readonly uint _waitPeriodMs; private readonly string _infoFilePath; public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber; public string BodySerialNumber { get; private set; } = UndefinedSerialNumber; - public InfoFetcher(int maxAttempts, int waitPeriodMs, string infoFilePath) { + public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string f32RemArguments) { _maxAttempts = maxAttempts; _waitPeriodMs = waitPeriodMs; _infoFilePath = infoFilePath; + _f32RemExecutable = f32RemExecutable; + _f32RemArguments = f32RemArguments; } public async Task<bool> FetchDataAsync() { Program.DefaultLogger.Info("Fetching data from the debugger."); - var success = await SendRetrieveInfoCommandAsync(F32RemExecutable, F32RemArguments); + var success = await SendRetrieveInfoCommandAsync(_f32RemExecutable, _f32RemArguments); if (!success) { Program.DefaultLogger.Error("Failed to fetch data from the debugger."); return false; @@ -35,7 +38,7 @@ namespace LDClient.detection { Program.DefaultLogger.Info($"Info file has been parsed successfully."); return true; } - await Task.Delay(_waitPeriodMs); + await Task.Delay((int)_waitPeriodMs); } Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created."); return false; diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessProcessDetection.cs index d30f311..69ab0dc 100644 --- a/ld_client/LDClient/detection/ProcessProcessDetection.cs +++ b/ld_client/LDClient/detection/ProcessProcessDetection.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.Text.Json; using LDClient.network; using LDClient.network.data; @@ -7,12 +8,12 @@ namespace LDClient.detection { public class ProcessProcessDetection : IProcessDetection { private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss"; - + private readonly string _processName; private readonly uint _detectionPeriodMs; private bool _processIsActive; private bool _failedToRetrieveData; - private Payload? _lastlyConnected; + private Payload? _lastConnectedPayload; private readonly InfoFetcher _infoFetcher; private readonly IApiClient _apiClient; @@ -28,17 +29,17 @@ namespace LDClient.detection { private async Task<bool> RetrieveDataFromDebugger() { var success = await _infoFetcher.FetchDataAsync(); if (success) { - _lastlyConnected = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat); + _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat); } return success; } - + private async Task DebuggerDisconnected() { - if (_lastlyConnected is not null) { - _lastlyConnected.Status = ConnectionStatus.Disconnected; - _lastlyConnected.TimeStamp = DateTime.Now.ToString(DatetimeFormat); - await _apiClient.SendPayloadAsync(_lastlyConnected); - _lastlyConnected = null; + if (_lastConnectedPayload is not null) { + _lastConnectedPayload.Status = ConnectionStatus.Disconnected; + _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat); + await _apiClient.SendPayloadAsync(_lastConnectedPayload); + _lastConnectedPayload = null; } } diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index a84708d..5709adc 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -1,4 +1,5 @@ -using LDClient.utils.loggers; +using System.Runtime.InteropServices; +using LDClient.utils.loggers; using Microsoft.Extensions.Configuration; namespace LDClient.utils { @@ -15,7 +16,6 @@ namespace LDClient.utils { public int LogChunkSize { get; private set; } public int LogChunkMaxCount { get; private set; } public int LogArchiveMaxCount { get; private set; } - public int LogCleanupPeriod { get; private set; } public LogVerbosity LogVerbosityType { get; private set; } = LogVerbosity.Full; public LogFlow LogFlowType { get; private set; } = LogFlow.Console; @@ -43,6 +43,11 @@ namespace LDClient.utils { public string T32ProcessName { get; private set; } public uint DetectionPeriod { get; private set; } public string T32InfoLocation { get; private set; } + public string F32RemExecutable { get; private set; } + public string F32RemArguments { get; private set; } + public uint FetchInfoMaxAttempts { get; private set; } + public uint FetchInfoAttemptPeriod { get; private set; } + #endregion public ConfigLoader() { @@ -68,19 +73,21 @@ namespace LDClient.utils { ApiBaseAddress = network["ApiBaseAddress"]; ApiUsbEndPoint = network["ApiLDEndPoint"]; ApiPort = uint.Parse(network["ApiPort"]); - - + var cache = configuration.GetSection(CacheSection); RetryPeriod = uint.Parse(cache["RetryPeriod"]); MaxEntries = uint.Parse(cache["MaxEntries"]); MaxRetries = uint.Parse(cache["MaxRetries"]); CacheFileName = cache["CacheFileName"]; - - + var debugger = configuration.GetSection(DdSection); T32ProcessName = debugger["T32ProcessName"]; T32InfoLocation = debugger["T32InfoLocation"]; DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]); + F32RemExecutable = debugger["F32RemExecutable"]; + F32RemArguments = debugger["F32RemArguments"]; + FetchInfoMaxAttempts = uint.Parse(debugger["FetchInfoMaxAttempts"]); + FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]); Console.WriteLine("Configuration successfully loaded!"); } catch (FormatException e) { diff --git a/ld_client/Mock/t32rem/t32rem_mock.cpp b/ld_client/Mock/t32rem/t32rem_mock.cpp index 5c05734..0d601f4 100644 --- a/ld_client/Mock/t32rem/t32rem_mock.cpp +++ b/ld_client/Mock/t32rem/t32rem_mock.cpp @@ -7,7 +7,7 @@ #include <cstring> static constexpr int EXPECTED_NUMBER_OF_ARGUMENTS = 4; -static constexpr const char *OUTPUT_FILE_NAME = "output.txt"; +static constexpr const char *OUTPUT_FILE_NAME = "ldResult.txt"; static constexpr const char *DEBUGGER_INFO = "B::version.hardware\n" "PowerDebug USB 3.0 via USB 3.0\n" -- GitLab From 08616eff184beaa5e3f8c3668b9612f7febfce82 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Mon, 18 Apr 2022 09:59:54 +0200 Subject: [PATCH 26/67] re #9566 Removed IoUtils.cs since it was being used only in one place. --- ld_client/LDClient/detection/InfoFetcher.cs | 3 +-- ld_client/LDClient/detection/ProcessProcessDetection.cs | 3 +-- ld_client/LDClient/utils/IoUtils.cs | 9 --------- 3 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 ld_client/LDClient/utils/IoUtils.cs diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs index 0a5d3e6..f5a0dde 100644 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using LDClient.utils; namespace LDClient.detection { @@ -46,7 +45,7 @@ namespace LDClient.detection { private bool RetrieveDebuggerInfo(string filePath) { try { - var fileContent = IoUtils.ReadFile(filePath); + var fileContent = File.ReadAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n"); var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent); HeadSerialNumber = headSerialNumber; BodySerialNumber = bodySerialNumber; diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessProcessDetection.cs index 69ab0dc..0ca4007 100644 --- a/ld_client/LDClient/detection/ProcessProcessDetection.cs +++ b/ld_client/LDClient/detection/ProcessProcessDetection.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Text.Json; using LDClient.network; using LDClient.network.data; @@ -33,7 +32,7 @@ namespace LDClient.detection { } return success; } - + private async Task DebuggerDisconnected() { if (_lastConnectedPayload is not null) { _lastConnectedPayload.Status = ConnectionStatus.Disconnected; diff --git a/ld_client/LDClient/utils/IoUtils.cs b/ld_client/LDClient/utils/IoUtils.cs deleted file mode 100644 index 7bf3a65..0000000 --- a/ld_client/LDClient/utils/IoUtils.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace LDClient.utils { - - public static class IoUtils { - - public static string ReadFile(string filename) { - return File.ReadAllLines(filename).Aggregate("", (current, line) => $"{current}{line}\n"); - } - } -} \ No newline at end of file -- GitLab From e51590bee040f5acacedb7f3a1b58c951bc4b3f1 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Thu, 21 Apr 2022 09:53:04 +0200 Subject: [PATCH 27/67] re #9568 Fixed a typo in the filename. --- .../detection/{ProcessProcessDetection.cs => ProcessDetection.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ld_client/LDClient/detection/{ProcessProcessDetection.cs => ProcessDetection.cs} (100%) diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs similarity index 100% rename from ld_client/LDClient/detection/ProcessProcessDetection.cs rename to ld_client/LDClient/detection/ProcessDetection.cs -- GitLab From 4dcc6c07a7c03999e5fefeea3314cbb01300167b Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Thu, 21 Apr 2022 10:58:24 +0200 Subject: [PATCH 28/67] re #9568 Added all 4 commands (arguments) to be sent to the debugger into the configuration file. --- ld_client/LDClient/Program.cs | 4 ++- ld_client/LDClient/appsettings.json | 13 ++++++-- ld_client/LDClient/detection/InfoFetcher.cs | 37 ++++++++++++++------- ld_client/LDClient/utils/ConfigLoader.cs | 10 ++++-- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 253ec64..c58d5b8 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -21,7 +21,9 @@ internal static class Program { Config.FetchInfoAttemptPeriod, Config.T32InfoLocation, Config.F32RemExecutable, - Config.F32RemArguments + Config.F32RemArguments, + Config.T32RemSuccessExitCode, + Config.T32RemWaitTimeoutMs ); public static int Main() { diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index f882d0c..0104ce2 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -26,12 +26,19 @@ "CacheFileName": "cache" }, "DebuggerDetection": { + "F32RemArguments" : [ + "localhost port=20000 printer.filetype ASCIIE", + "localhost port=20000 printer.open C:\\Users\\pulta\\Desktop\\testResult.txt", + "localhost port=20000 WinPrint.version.hardware", + "localhost port=20000 printer.close" + ], "F32RemExecutable": "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock", - "F32RemArguments": "localhost port=20000 VERSION.HARDWARE", "T32ProcessName": "ld_mock", - "T32InfoLocation": "ldResult.txt", + "T32InfoLocation": "C:\\Users\\pulta\\Desktop\\testResult.txt", "DetectionPeriod": 5000, "FetchInfoMaxAttempts": 5, - "FetchInfoAttemptPeriod": 1000 + "FetchInfoAttemptPeriod": 1000, + "T32RemSuccessExitCode": 0, + "T32RemWaitTimeoutMs": 2000 } } \ No newline at end of file diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs index f5a0dde..ffa36b7 100644 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -7,7 +7,9 @@ namespace LDClient.detection { private const string UndefinedSerialNumber = "number"; private readonly string _f32RemExecutable; - private readonly string _f32RemArguments; + private readonly string[] _f32RemArguments; + private readonly int _f32SuccessExitCode; + private readonly int _f32WaitTimeoutMs; private readonly uint _maxAttempts; private readonly uint _waitPeriodMs; @@ -16,17 +18,19 @@ namespace LDClient.detection { public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber; public string BodySerialNumber { get; private set; } = UndefinedSerialNumber; - public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string f32RemArguments) { + public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) { _maxAttempts = maxAttempts; _waitPeriodMs = waitPeriodMs; _infoFilePath = infoFilePath; _f32RemExecutable = f32RemExecutable; _f32RemArguments = f32RemArguments; + _f32SuccessExitCode = f32SuccessExitCode; + _f32WaitTimeoutMs = f32WaitTimeoutMs; } public async Task<bool> FetchDataAsync() { Program.DefaultLogger.Info("Fetching data from the debugger."); - var success = await SendRetrieveInfoCommandAsync(_f32RemExecutable, _f32RemArguments); + var success = SendRetrieveInfoCommands(_f32RemExecutable, _f32RemArguments, _f32SuccessExitCode, _f32WaitTimeoutMs); if (!success) { Program.DefaultLogger.Error("Failed to fetch data from the debugger."); return false; @@ -57,17 +61,26 @@ namespace LDClient.detection { return true; } - private static async Task<bool> SendRetrieveInfoCommandAsync(string executableFile, string arguments) { - var t32RemProcess = new Process(); - t32RemProcess.StartInfo.FileName = executableFile; - t32RemProcess.StartInfo.Arguments = arguments; - try { - t32RemProcess.Start(); - await t32RemProcess.WaitForExitAsync(); - } catch (Exception exception) { - Program.DefaultLogger.Error($"Failed to run {executableFile}. {exception.Message}"); + private static bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int successExitCode, int waitTimeoutMs) { + if (arguments == null) { + Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given"); return false; } + foreach (var argument in arguments) { + var t32RemProcess = new Process(); + t32RemProcess.StartInfo.FileName = executableFile; + t32RemProcess.StartInfo.Arguments = argument; + try { + t32RemProcess.Start(); + t32RemProcess.WaitForExit(waitTimeoutMs); + if (t32RemProcess.ExitCode != successExitCode) { + return false; + } + } catch (Exception exception) { + Program.DefaultLogger.Error($"Failed to run {executableFile} {argument}. {exception.Message}"); + return false; + } + } return true; } } diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index 5709adc..b4ff02f 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -44,10 +44,12 @@ namespace LDClient.utils { public uint DetectionPeriod { get; private set; } public string T32InfoLocation { get; private set; } public string F32RemExecutable { get; private set; } - public string F32RemArguments { get; private set; } public uint FetchInfoMaxAttempts { get; private set; } public uint FetchInfoAttemptPeriod { get; private set; } - + public string[] F32RemArguments { get; private set; } + public int T32RemSuccessExitCode { get; private set; } + public int T32RemWaitTimeoutMs { get; private set; } + #endregion public ConfigLoader() { @@ -85,9 +87,11 @@ namespace LDClient.utils { T32InfoLocation = debugger["T32InfoLocation"]; DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]); F32RemExecutable = debugger["F32RemExecutable"]; - F32RemArguments = debugger["F32RemArguments"]; FetchInfoMaxAttempts = uint.Parse(debugger["FetchInfoMaxAttempts"]); FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]); + T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]); + T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]); + F32RemArguments = configuration.GetSection($"{DdSection}:F32RemCommands").GetChildren().Select(key => key.Value).ToArray(); Console.WriteLine("Configuration successfully loaded!"); } catch (FormatException e) { -- GitLab From b10bb2634e9ecc275dae86d67902fb5193a6f6ba Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Fri, 22 Apr 2022 08:58:50 +0200 Subject: [PATCH 29/67] re #9568 Broke config loader down into separate methods. --- ld_client/LDClient/Program.cs | 2 - .../LDClient/network/data/ConnectionStatus.cs | 3 +- .../LDClient/network/data/DebuggerInfo.cs | 2 +- ld_client/LDClient/network/data/Payload.cs | 3 +- ld_client/LDClient/utils/ConfigLoader.cs | 69 ++++++++++++------- 5 files changed, 50 insertions(+), 29 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index c58d5b8..fc2fb03 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -61,7 +61,5 @@ internal static class Program { while (true) { Thread.Sleep(MainLoopDelayMs); } - - return 0; } } \ No newline at end of file diff --git a/ld_client/LDClient/network/data/ConnectionStatus.cs b/ld_client/LDClient/network/data/ConnectionStatus.cs index f5ea275..9cd1ded 100644 --- a/ld_client/LDClient/network/data/ConnectionStatus.cs +++ b/ld_client/LDClient/network/data/ConnectionStatus.cs @@ -1,11 +1,12 @@ using System.Runtime.Serialization; namespace LDClient.network.data { + public enum ConnectionStatus { + [EnumMember(Value = "connected")] Connected, [EnumMember(Value = "disconnected")] Disconnected - } } diff --git a/ld_client/LDClient/network/data/DebuggerInfo.cs b/ld_client/LDClient/network/data/DebuggerInfo.cs index cb38d91..9402110 100644 --- a/ld_client/LDClient/network/data/DebuggerInfo.cs +++ b/ld_client/LDClient/network/data/DebuggerInfo.cs @@ -4,6 +4,6 @@ namespace LDClient.network.data { public class DebuggerInfo { [JsonPropertyName("serial_number")] - public string SerialNumber { get; set; } + public string? SerialNumber { get; set; } } } diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs index 57b5755..ae7302a 100644 --- a/ld_client/LDClient/network/data/Payload.cs +++ b/ld_client/LDClient/network/data/Payload.cs @@ -4,6 +4,7 @@ using Newtonsoft.Json; using JsonSerializer = System.Text.Json.JsonSerializer; namespace LDClient.network.data { + [JsonObject(MemberSerialization.OptIn)] public class Payload { @@ -14,7 +15,6 @@ namespace LDClient.network.data { public string? HostName { get; set; } [JsonPropertyName("timestamp")] - //[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd HH:mm:ss.ffffff")] public string? TimeStamp { get; set; } [JsonPropertyName("head_device")] @@ -25,7 +25,6 @@ namespace LDClient.network.data { public DebuggerInfo? BodyDevice { get; set; } [JsonPropertyName("status")] - //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] public ConnectionStatus Status { get; set; } diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index b4ff02f..b57a506 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -1,10 +1,12 @@ -using System.Runtime.InteropServices; -using LDClient.utils.loggers; +using LDClient.utils.loggers; using Microsoft.Extensions.Configuration; namespace LDClient.utils { internal class ConfigLoader { + + private const int ErrorExitCode = 1; + private const string ConfigFile = "appsettings.json"; private const string LoggingSection = "Logging"; private const string NetworkSection = "Network"; @@ -24,15 +26,15 @@ namespace LDClient.utils { #region Api - public string ApiBaseAddress { get; private set; } - public string ApiUsbEndPoint { get; private set; } + public string ApiBaseAddress { get; private set; } = null!; + public string ApiUsbEndPoint { get; private set; } = null!; public uint ApiPort { get; private set; } #endregion #region Cache - public string CacheFileName { get; private set; } + public string CacheFileName { get; private set; } = null!; public uint MaxRetries { get; private set; } public uint MaxEntries { get; private set; } public uint RetryPeriod { get; private set; } @@ -40,13 +42,13 @@ namespace LDClient.utils { #endregion #region Detection - public string T32ProcessName { get; private set; } + public string T32ProcessName { get; private set; } = null!; public uint DetectionPeriod { get; private set; } - public string T32InfoLocation { get; private set; } - public string F32RemExecutable { get; private set; } + public string T32InfoLocation { get; private set; } = null!; + public string F32RemExecutable { get; private set; } = null!; public uint FetchInfoMaxAttempts { get; private set; } public uint FetchInfoAttemptPeriod { get; private set; } - public string[] F32RemArguments { get; private set; } + public string[] F32RemArguments { get; private set; } = null!; public int T32RemSuccessExitCode { get; private set; } public int T32RemWaitTimeoutMs { get; private set; } @@ -54,34 +56,59 @@ namespace LDClient.utils { public ConfigLoader() { var configuration = new ConfigurationBuilder() - .AddJsonFile("appsettings.json") + .AddJsonFile(ConfigFile) .Build(); - ReadAllSettings(configuration); - } - private void ReadAllSettings(IConfiguration configuration) { + ReadLoggerSection(configuration); + ReadApiSection(configuration); + ReadCacheSection(configuration); + ReadDebuggerSection(configuration); + + Console.WriteLine("Configuration successfully loaded!"); + } + private void ReadLoggerSection(IConfiguration configuration) { try { var logging = configuration.GetSection(LoggingSection); - //TODO: Exception handling LogChunkSize = int.Parse(logging["LogChunkSize"]); LogChunkMaxCount = int.Parse(logging["LogChunkMaxCount"]); LogArchiveMaxCount = int.Parse(logging["LogArchiveMaxCount"]); LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]); LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]); LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]); + } catch (Exception e) { + Console.WriteLine(e.Message); + Environment.Exit(ErrorExitCode); + } + } + private void ReadApiSection(IConfiguration configuration) { + try { var network = configuration.GetSection(NetworkSection); ApiBaseAddress = network["ApiBaseAddress"]; ApiUsbEndPoint = network["ApiLDEndPoint"]; ApiPort = uint.Parse(network["ApiPort"]); - + } catch (Exception e) { + Console.WriteLine(e.Message); + Environment.Exit(ErrorExitCode); + } + } + + private void ReadCacheSection(IConfiguration configuration) { + try { var cache = configuration.GetSection(CacheSection); RetryPeriod = uint.Parse(cache["RetryPeriod"]); MaxEntries = uint.Parse(cache["MaxEntries"]); MaxRetries = uint.Parse(cache["MaxRetries"]); CacheFileName = cache["CacheFileName"]; - + } catch (Exception e) { + Console.WriteLine(e.Message); + Environment.Exit(ErrorExitCode); + } + } + + private void ReadDebuggerSection(IConfiguration configuration) { + try { var debugger = configuration.GetSection(DdSection); T32ProcessName = debugger["T32ProcessName"]; T32InfoLocation = debugger["T32InfoLocation"]; @@ -92,13 +119,9 @@ namespace LDClient.utils { T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]); T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]); F32RemArguments = configuration.GetSection($"{DdSection}:F32RemCommands").GetChildren().Select(key => key.Value).ToArray(); - - Console.WriteLine("Configuration successfully loaded!"); - } catch (FormatException e) { - //Console.WriteLine("Error reading app settings"); - //TODO: remove stacktrace print in production - Console.WriteLine("Error during reading of configuration occurred!" + e); - throw new IOException("Reading of configuration file failed! " + e); + } catch (Exception e) { + Console.WriteLine(e); + Environment.Exit(ErrorExitCode); } } } -- GitLab From 33c231a4432727c0fed200278aadc43c61a1228b Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Sat, 23 Apr 2022 14:49:19 +0200 Subject: [PATCH 30/67] re #9568 Fixed formatting --- ld_client/LDClient/detection/InfoFetcher.cs | 1 - ld_client/LDClient/detection/ProcessDetection.cs | 8 ++++---- ld_client/LDClient/network/ApiClient.cs | 5 ++--- ld_client/LDClient/utils/ConfigLoader.cs | 1 - 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs index ffa36b7..86f601e 100644 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -10,7 +10,6 @@ namespace LDClient.detection { private readonly string[] _f32RemArguments; private readonly int _f32SuccessExitCode; private readonly int _f32WaitTimeoutMs; - private readonly uint _maxAttempts; private readonly uint _waitPeriodMs; private readonly string _infoFilePath; diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs index 0ca4007..fb68c65 100644 --- a/ld_client/LDClient/detection/ProcessDetection.cs +++ b/ld_client/LDClient/detection/ProcessDetection.cs @@ -4,19 +4,19 @@ using LDClient.network.data; namespace LDClient.detection { - public class ProcessProcessDetection : IProcessDetection { + public sealed class ProcessProcessDetection : IProcessDetection { private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss"; private readonly string _processName; private readonly uint _detectionPeriodMs; + private readonly InfoFetcher _infoFetcher; + private readonly IApiClient _apiClient; + private bool _processIsActive; private bool _failedToRetrieveData; private Payload? _lastConnectedPayload; - private readonly InfoFetcher _infoFetcher; - private readonly IApiClient _apiClient; - public ProcessProcessDetection(string processName, uint detectionPeriodMs, InfoFetcher infoFetcher, IApiClient apiClient) { _processName = processName; _detectionPeriodMs = detectionPeriodMs; diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index 61766cf..01043bf 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -8,7 +8,7 @@ using LDClient.network.data; namespace LDClient.network { - public class ApiClient : IApiClient { + public sealed class ApiClient : IApiClient { private readonly string _uri; private readonly HttpClient _client; @@ -17,8 +17,7 @@ namespace LDClient.network { private readonly uint _maxEntries; private readonly uint _maxRetries; - public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, - string cacheFilename) { + public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, string cacheFilename) { _uri = $"{url}:{port}{path}"; _retryPeriod = retryPeriod; _maxEntries = maxEntries; diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index b57a506..a2a5627 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -7,7 +7,6 @@ namespace LDClient.utils { private const int ErrorExitCode = 1; private const string ConfigFile = "appsettings.json"; - private const string LoggingSection = "Logging"; private const string NetworkSection = "Network"; private const string CacheSection = "Cache"; -- GitLab From 19c2a5c43d5f8e4972e82fb2764e55f96251a27a Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 23 Apr 2022 15:26:37 +0200 Subject: [PATCH 31/67] re #9568 Fixed a typo in the config file --- ld_client/LDClient/appsettings.json | 12 ++++++------ ld_client/LDClient/detection/InfoFetcher.cs | 7 ++++++- ld_client/LDClient/utils/ConfigLoader.cs | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 0104ce2..4826407 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -26,15 +26,15 @@ "CacheFileName": "cache" }, "DebuggerDetection": { - "F32RemArguments" : [ + "F32RemArguments": [ "localhost port=20000 printer.filetype ASCIIE", - "localhost port=20000 printer.open C:\\Users\\pulta\\Desktop\\testResult.txt", + "localhost port=20000 printer.open C:\\app\\result.txt", "localhost port=20000 WinPrint.version.hardware", - "localhost port=20000 printer.close" + "localhost port=20000 printer.close " ], - "F32RemExecutable": "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock", - "T32ProcessName": "ld_mock", - "T32InfoLocation": "C:\\Users\\pulta\\Desktop\\testResult.txt", + "F32RemExecutable": "c:\\app\\tools\\T32\\bin\\windows64\\t32rem.exe", + "T32ProcessName": "t32mtc", + "T32InfoLocation": "C:\\app\\result.txt", "DetectionPeriod": 5000, "FetchInfoMaxAttempts": 5, "FetchInfoAttemptPeriod": 1000, diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs index 86f601e..0d2a206 100644 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using LDClient.utils.loggers; namespace LDClient.detection { @@ -71,8 +72,12 @@ namespace LDClient.detection { t32RemProcess.StartInfo.Arguments = argument; try { t32RemProcess.Start(); - t32RemProcess.WaitForExit(waitTimeoutMs); + if (!t32RemProcess.WaitForExit(waitTimeoutMs)) { + Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {waitTimeoutMs} ms"); + return false; + } if (t32RemProcess.ExitCode != successExitCode) { + Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}"); return false; } } catch (Exception exception) { diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index a2a5627..251e663 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -117,7 +117,7 @@ namespace LDClient.utils { FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]); T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]); T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]); - F32RemArguments = configuration.GetSection($"{DdSection}:F32RemCommands").GetChildren().Select(key => key.Value).ToArray(); + F32RemArguments = configuration.GetSection($"{DdSection}:F32RemArguments").GetChildren().Select(key => key.Value).ToArray(); } catch (Exception e) { Console.WriteLine(e); Environment.Exit(ErrorExitCode); -- GitLab From 1413374d99651ee252e421493bc54ab5ae7f261f Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 24 Apr 2022 22:23:25 +0200 Subject: [PATCH 32/67] re #9571 Added installation readme to the LD client --- ld_client/readme.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 ld_client/readme.md diff --git a/ld_client/readme.md b/ld_client/readme.md new file mode 100644 index 0000000..13bb880 --- /dev/null +++ b/ld_client/readme.md @@ -0,0 +1,44 @@ +# Automatic detection and documentation of connected Lauterbach Debugger and connected head device - LD Client - Bug Thugs + +--- + +- [Description](#description) +- [Requirements](#requirements) + * [Windows](#windows) +- [Build](#build) +- [Execution](#execution) + +--- + +## Description + +This client application periodically searches for running process of TRACE32 PowerView. +Upon detection the application tries to execute t32rem.exe program with specific parameters which generates info file about currently connected Lauterbach Debbuger and connected head device. +The serial numbers from the info file is parsed and along with a timestamp and computer-related information, is sent to the server (API). +If the application fails to send the data, it will store the payload in a disk-based cache. +The client then periodically accesses the cache in order to resend the failed payloads to the server. + +## Requirements + +In order to successfully run the application, the user needs to have .NET 6.0 installed on their machine. +It can be downloaded from the official site of the Microsoft (https://dotnet.microsoft.com/en-us/download/dotnet/6.0). + +## Build/Publish + +If you have .NET 6.0 installed on your machine and its binaries are included in the system variables, you can simply execute following command in the LDClient subfolder: +``` +dotnet publish -c Release -o build -p:PublishSingleFile=true --self-contained true -r win-x86 +``` + +If everything goes well, a file called `LDClient.exe` with all its needed dependencies should be created under 'build'. + +You can also build this application by opening the solution of this project in MSVC a using one of its build tools. + +## Execution + + +After everything is successfully setup, you can simply run the application by running the following command from the terminal. + +``` +LDClient.exe +``` \ No newline at end of file -- GitLab From c73d715c82735311aa531fa020fbc2645097aa58 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 24 Apr 2022 22:30:02 +0200 Subject: [PATCH 33/67] re #9571 fixed typo and text refactoring --- ld_client/readme.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ld_client/readme.md b/ld_client/readme.md index 13bb880..80347ad 100644 --- a/ld_client/readme.md +++ b/ld_client/readme.md @@ -1,4 +1,4 @@ -# Automatic detection and documentation of connected Lauterbach Debugger and connected head device - LD Client - Bug Thugs +# Automatic detection and documentation of connected Lauterbach Debugger and its head device - LD Client - Bug Thugs --- @@ -13,15 +13,15 @@ ## Description This client application periodically searches for running process of TRACE32 PowerView. -Upon detection the application tries to execute t32rem.exe program with specific parameters which generates info file about currently connected Lauterbach Debbuger and connected head device. -The serial numbers from the info file is parsed and along with a timestamp and computer-related information, is sent to the server (API). +Upon detection the application tries to execute t32rem.exe program with specific parameters which generates info file about currently connected Lauterbach Debbuger and its head device. +The serial numbers from the info file are then parsed and along with a timestamp and computer-related information, is sent to the server (API). If the application fails to send the data, it will store the payload in a disk-based cache. The client then periodically accesses the cache in order to resend the failed payloads to the server. ## Requirements -In order to successfully run the application, the user needs to have .NET 6.0 installed on their machine. -It can be downloaded from the official site of the Microsoft (https://dotnet.microsoft.com/en-us/download/dotnet/6.0). +In order to successfully run the application the user needs to have .NET 6.0 installed on their machine. +It can be simply downloaded from the official site of the Microsoft (https://dotnet.microsoft.com/en-us/download/dotnet/6.0). ## Build/Publish @@ -30,9 +30,9 @@ If you have .NET 6.0 installed on your machine and its binaries are included in dotnet publish -c Release -o build -p:PublishSingleFile=true --self-contained true -r win-x86 ``` -If everything goes well, a file called `LDClient.exe` with all its needed dependencies should be created under 'build'. +If everything goes well, a file called `LDClient.exe` with all its needed dependencies and configuration files should be created under folder 'build'. -You can also build this application by opening the solution of this project in MSVC a using one of its build tools. +You can also build this application by opening the solution of this project in MSVC and using one of its build tools. ## Execution -- GitLab From 0932a9e214cb251a9e986c9fcaea8d14354ce5b8 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Mon, 25 Apr 2022 22:36:16 +0200 Subject: [PATCH 34/67] re #9443 refactoring of detection classes --- .../LDClient/detection/DebuggerInfoParser.cs | 2 +- ld_client/LDClient/detection/IInfoFetcher.cs | 15 +++++++ ld_client/LDClient/detection/IProcessUtils.cs | 13 ++++++ ld_client/LDClient/detection/InfoFetcher.cs | 37 ++++++++--------- .../LDClient/detection/ProcessDetection.cs | 18 +++++---- ld_client/LDClient/detection/ProcessUtils.cs | 40 +++++++++++++++++++ 6 files changed, 96 insertions(+), 29 deletions(-) create mode 100644 ld_client/LDClient/detection/IInfoFetcher.cs create mode 100644 ld_client/LDClient/detection/IProcessUtils.cs create mode 100644 ld_client/LDClient/detection/ProcessUtils.cs diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs index 3f07e32..dec8bd0 100644 --- a/ld_client/LDClient/detection/DebuggerInfoParser.cs +++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs @@ -15,7 +15,7 @@ namespace LDClient.detection { throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})"); } - return (matches[0].ToString(), matches[1].ToString()); + return (matches[1].ToString().Trim(), matches[0].ToString().Trim()); } } } \ No newline at end of file diff --git a/ld_client/LDClient/detection/IInfoFetcher.cs b/ld_client/LDClient/detection/IInfoFetcher.cs new file mode 100644 index 0000000..e48005c --- /dev/null +++ b/ld_client/LDClient/detection/IInfoFetcher.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.detection { + public interface IInfoFetcher { + + public string HeadSerialNumber { get; set; } + public string BodySerialNumber { get; set; } + + public Task<bool> FetchDataAsync(); + } +} diff --git a/ld_client/LDClient/detection/IProcessUtils.cs b/ld_client/LDClient/detection/IProcessUtils.cs new file mode 100644 index 0000000..b900375 --- /dev/null +++ b/ld_client/LDClient/detection/IProcessUtils.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.detection { + public interface IProcessUtils { + public bool IsProcessRunning(string name); + + public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode); + } +} diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs index 0d2a206..07ddba1 100644 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -1,9 +1,10 @@ using System.Diagnostics; +using LDClient.utils; using LDClient.utils.loggers; namespace LDClient.detection { - public class InfoFetcher { + public class InfoFetcher : IInfoFetcher { private const string UndefinedSerialNumber = "number"; @@ -15,10 +16,15 @@ namespace LDClient.detection { private readonly uint _waitPeriodMs; private readonly string _infoFilePath; - public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber; - public string BodySerialNumber { get; private set; } = UndefinedSerialNumber; + public IProcessUtils ProcessUtils; + public IFileUtils FileUtils; - public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) { + public string HeadSerialNumber { get; set; } = UndefinedSerialNumber; + public string BodySerialNumber { get; set; } = UndefinedSerialNumber; + + + public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, + string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) { _maxAttempts = maxAttempts; _waitPeriodMs = waitPeriodMs; _infoFilePath = infoFilePath; @@ -26,6 +32,9 @@ namespace LDClient.detection { _f32RemArguments = f32RemArguments; _f32SuccessExitCode = f32SuccessExitCode; _f32WaitTimeoutMs = f32WaitTimeoutMs; + ProcessUtils = new ProcessUtils(); + FileUtils = new FileUtils(); + } public async Task<bool> FetchDataAsync() { @@ -49,7 +58,7 @@ namespace LDClient.detection { private bool RetrieveDebuggerInfo(string filePath) { try { - var fileContent = File.ReadAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n"); + var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n"); var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent); HeadSerialNumber = headSerialNumber; BodySerialNumber = bodySerialNumber; @@ -61,27 +70,13 @@ namespace LDClient.detection { return true; } - private static bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int successExitCode, int waitTimeoutMs) { + private bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int desiredExitCode, int waitTimeoutMs) { if (arguments == null) { Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given"); return false; } foreach (var argument in arguments) { - var t32RemProcess = new Process(); - t32RemProcess.StartInfo.FileName = executableFile; - t32RemProcess.StartInfo.Arguments = argument; - try { - t32RemProcess.Start(); - if (!t32RemProcess.WaitForExit(waitTimeoutMs)) { - Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {waitTimeoutMs} ms"); - return false; - } - if (t32RemProcess.ExitCode != successExitCode) { - Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}"); - return false; - } - } catch (Exception exception) { - Program.DefaultLogger.Error($"Failed to run {executableFile} {argument}. {exception.Message}"); + if (!ProcessUtils.ExecuteNewProcess(executableFile, argument, waitTimeoutMs, desiredExitCode)) { return false; } } diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs index fb68c65..27d5333 100644 --- a/ld_client/LDClient/detection/ProcessDetection.cs +++ b/ld_client/LDClient/detection/ProcessDetection.cs @@ -4,25 +4,29 @@ using LDClient.network.data; namespace LDClient.detection { - public sealed class ProcessProcessDetection : IProcessDetection { + public sealed class ProcessDetection : IProcessDetection { private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss"; private readonly string _processName; private readonly uint _detectionPeriodMs; - private readonly InfoFetcher _infoFetcher; + private readonly IInfoFetcher _infoFetcher; private readonly IApiClient _apiClient; - + private readonly IProcessUtils _processUtils; + private bool _processIsActive; private bool _failedToRetrieveData; private Payload? _lastConnectedPayload; - public ProcessProcessDetection(string processName, uint detectionPeriodMs, InfoFetcher infoFetcher, IApiClient apiClient) { + public bool DetectionRunning = false; + + public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, IApiClient apiClient, IProcessUtils processUtils) { _processName = processName; _detectionPeriodMs = detectionPeriodMs; _infoFetcher = infoFetcher; _apiClient = apiClient; _failedToRetrieveData = false; + _processUtils = processUtils; } private async Task<bool> RetrieveDataFromDebugger() { @@ -43,7 +47,7 @@ namespace LDClient.detection { } private async Task DetectProcessAsync() { - var processExists = Process.GetProcessesByName(_processName).Length > 0; + var processExists = _processUtils.IsProcessRunning(_processName); if (processExists && !_processIsActive) { Program.DefaultLogger.Info($"Process started: {_processName}"); @@ -77,11 +81,11 @@ namespace LDClient.detection { public async void RunPeriodicDetection() { Program.DefaultLogger.Info("Process periodic detector has started"); - while (true) { + DetectionRunning = true; + while (DetectionRunning) { await DetectProcessAsync(); Thread.Sleep((int)_detectionPeriodMs); } - // ReSharper disable once FunctionNeverReturns } } } diff --git a/ld_client/LDClient/detection/ProcessUtils.cs b/ld_client/LDClient/detection/ProcessUtils.cs new file mode 100644 index 0000000..b707f66 --- /dev/null +++ b/ld_client/LDClient/detection/ProcessUtils.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.detection { + public class ProcessUtils : IProcessUtils{ + + public bool IsProcessRunning(string name) { + return Process.GetProcessesByName(name).Length > 0; + } + + + public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) { + + var t32RemProcess = new Process(); + t32RemProcess.StartInfo.FileName = fileName; + t32RemProcess.StartInfo.Arguments = argument; + try { + t32RemProcess.Start(); + if (!t32RemProcess.WaitForExit(timeout)) { + Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms"); + return false; + } + if (t32RemProcess.ExitCode != desiredExitCode) { + Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}"); + return false; + } + } catch (Exception exception) { + Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}"); + return false; + } + + return true; + } + + } +} -- GitLab From afafbc228e11c3ded27483ae225f9da1496d6f43 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Mon, 25 Apr 2022 22:37:59 +0200 Subject: [PATCH 35/67] re #9443 refactoring of network and other utils for the purpose of testing --- ld_client/LDClient/Program.cs | 5 ++-- ld_client/LDClient/appsettings.json | 4 +-- ld_client/LDClient/network/ApiClient.cs | 16 +++++------- ld_client/LDClient/network/HttpClient.cs | 32 +++++++++++++++++++++++ ld_client/LDClient/network/IHttpClient.cs | 13 +++++++++ ld_client/LDClient/utils/FileUtils.cs | 13 +++++++++ ld_client/LDClient/utils/IFileUtils.cs | 12 +++++++++ 7 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 ld_client/LDClient/network/HttpClient.cs create mode 100644 ld_client/LDClient/network/IHttpClient.cs create mode 100644 ld_client/LDClient/utils/FileUtils.cs create mode 100644 ld_client/LDClient/utils/IFileUtils.cs diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index fc2fb03..bbd4322 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -41,11 +41,12 @@ internal static class Program { Config.CacheFileName ); - IProcessDetection processProcessDetection = new ProcessProcessDetection( + IProcessDetection processProcessDetection = new ProcessDetection( Config.T32ProcessName, Config.DetectionPeriod, InfoFetcher, - DefaultApiClient + DefaultApiClient, + new ProcessUtils() ); var apiClientThread = new Thread(DefaultApiClient.Run) { diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 4826407..3a3a702 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -15,8 +15,8 @@ "LogFlowType": 0 }, "Network": { - "ApiBaseAddress": "http://127.0.0.1", - "ApiLDEndPoint": "/lauterbach-debugger-logs/", + "ApiBaseAddress": "http://192.168.0.22", + "ApiLDEndPoint": "/api/v1/ld-logs", "ApiPort": 8000 }, "Cache": { diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index 01043bf..c06a69f 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -10,20 +10,20 @@ namespace LDClient.network { public sealed class ApiClient : IApiClient { - private readonly string _uri; - private readonly HttpClient _client; - private readonly IPersistentQueue _cache; + public IHttpClient _client; + public IPersistentQueue _cache; + private readonly uint _retryPeriod; private readonly uint _maxEntries; private readonly uint _maxRetries; public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, string cacheFilename) { - _uri = $"{url}:{port}{path}"; + var uri = $"{url}:{port}{path}"; _retryPeriod = retryPeriod; _maxEntries = maxEntries; _maxRetries = maxRetries; - _client = new HttpClient(); + _client = new HttpClient(uri); _cache = new PersistentQueue(cacheFilename); } @@ -32,11 +32,7 @@ namespace LDClient.network { Stopwatch stopWatch = new(); stopWatch.Start(); - var response = await _client.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions { - Converters = { - new JsonStringEnumConverter( JsonNamingPolicy.CamelCase) - } - }); + var response = await _client.PostAsJsonAsync(payload); stopWatch.Stop(); CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds); diff --git a/ld_client/LDClient/network/HttpClient.cs b/ld_client/LDClient/network/HttpClient.cs new file mode 100644 index 0000000..fa6f3d1 --- /dev/null +++ b/ld_client/LDClient/network/HttpClient.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Json; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using LDClient.network.data; + +namespace LDClient.network { + public class HttpClient : IHttpClient{ + + private readonly System.Net.Http.HttpClient _httpClient; + + private readonly string _uri; + public HttpClient(string uri) { + + _httpClient = new System.Net.Http.HttpClient(); + _uri = uri; + } + + public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload) { + return _httpClient.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions { + Converters = { + new JsonStringEnumConverter( JsonNamingPolicy.CamelCase) + } + }); + + } + } +} diff --git a/ld_client/LDClient/network/IHttpClient.cs b/ld_client/LDClient/network/IHttpClient.cs new file mode 100644 index 0000000..daf0c60 --- /dev/null +++ b/ld_client/LDClient/network/IHttpClient.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using LDClient.network.data; + +namespace LDClient.network { + public interface IHttpClient { + + public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload); + } +} diff --git a/ld_client/LDClient/utils/FileUtils.cs b/ld_client/LDClient/utils/FileUtils.cs new file mode 100644 index 0000000..abd3e98 --- /dev/null +++ b/ld_client/LDClient/utils/FileUtils.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.utils { + public class FileUtils : IFileUtils { + public string[] ReadFileAllLines(string file) { + return File.ReadAllLines(file); + } + } +} diff --git a/ld_client/LDClient/utils/IFileUtils.cs b/ld_client/LDClient/utils/IFileUtils.cs new file mode 100644 index 0000000..f3daf17 --- /dev/null +++ b/ld_client/LDClient/utils/IFileUtils.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.utils { + public interface IFileUtils { + + public string[] ReadFileAllLines(string file); + } +} -- GitLab From df1c36d1c7266507db0b1f466ec3e17c2c2e96d1 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Mon, 25 Apr 2022 23:13:22 +0200 Subject: [PATCH 36/67] re #9443 added implemented tests for DebuggerInfoParser --- .../detection/DebuggerInfoParserTests.cs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs diff --git a/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs new file mode 100644 index 0000000..6f6fa52 --- /dev/null +++ b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs @@ -0,0 +1,66 @@ +using System; +using LDClient.detection; +using NUnit.Framework; + +namespace LDClientTests.detection { + public class DebuggerInfoParserTests { + + public static readonly string CorrectFileContent = + "B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C12345678912 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C98765432198 "; + + public static readonly string HeadSerialNumber = "C98765432198"; + public static readonly string BodySerialNumber = "C12345678912"; + + + [Test] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C12345678912 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C12345678912 ", "C12345678912", "C12345678912")] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C1awfaw484 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C16468551", "C16468551", "C1awfaw484")] + public void Parse_CorrectValues_ReturnSerials(string file, string expectedHead, string expectedBody) { + var (headResult, bodyResult) = DebuggerInfoParser.Parse(file); + + Assert.AreEqual(expectedHead, headResult); + Assert.AreEqual(expectedBody, bodyResult); + } + + + [Test] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C12345678912 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C12345678912 \n" + + " Serial Number: C12345678912 ")] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C1awfaw484 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Numbeeeer: C16468551")] + public void Parse_IncorrectValues_ThrowException(string file) { + Assert.Throws<ArgumentException>(() => DebuggerInfoParser.Parse(file)); + } + + + } +} -- GitLab From cbf3b0c6f3564e7edf3e23519fe6732187a9179e Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Mon, 25 Apr 2022 23:55:54 +0200 Subject: [PATCH 37/67] re #9443 Added implementation of InfoFetcher tests --- ld_client/LDClientTests/LDClientTests.csproj | 5 + ld_client/LDClientTests/UnitTest1.cs | 15 --- .../detection/DebuggerInfoParserTests.cs | 106 ++++++++-------- .../detection/InfoFetcherTests.cs | 117 ++++++++++++++++++ 4 files changed, 175 insertions(+), 68 deletions(-) delete mode 100644 ld_client/LDClientTests/UnitTest1.cs create mode 100644 ld_client/LDClientTests/detection/InfoFetcherTests.cs diff --git a/ld_client/LDClientTests/LDClientTests.csproj b/ld_client/LDClientTests/LDClientTests.csproj index 5085235..6ba14ca 100644 --- a/ld_client/LDClientTests/LDClientTests.csproj +++ b/ld_client/LDClientTests/LDClientTests.csproj @@ -9,9 +9,14 @@ <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" /> + <PackageReference Include="Moq" Version="4.17.2" /> <PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" /> <PackageReference Include="coverlet.collector" Version="3.1.0" /> </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\LDClient\LDClient.csproj" /> + </ItemGroup> + </Project> diff --git a/ld_client/LDClientTests/UnitTest1.cs b/ld_client/LDClientTests/UnitTest1.cs deleted file mode 100644 index 03cf433..0000000 --- a/ld_client/LDClientTests/UnitTest1.cs +++ /dev/null @@ -1,15 +0,0 @@ -using NUnit.Framework; - -namespace LDClientTests { - public class Tests { - [SetUp] - public void Setup() { - - } - - [Test] - public void Test1() { - Assert.Pass(); - } - } -} \ No newline at end of file diff --git a/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs index 6f6fa52..e6fa016 100644 --- a/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs +++ b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs @@ -2,65 +2,65 @@ using LDClient.detection; using NUnit.Framework; -namespace LDClientTests.detection { - public class DebuggerInfoParserTests { +namespace LDClientTests.detection; - public static readonly string CorrectFileContent = - "B::version.hardware \r\n\r\n" + - "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + - " Serial Number: C12345678912 \r\n\r\n" + - " Firmware R.2021.02 (136263) \r\n\r\n" + - " Instance: 1. \r\n\r\n" + - " Automotive Debug Cable \r\n\r\n" + - " Serial Number: C98765432198 "; +public class DebuggerInfoParserTests { - public static readonly string HeadSerialNumber = "C98765432198"; - public static readonly string BodySerialNumber = "C12345678912"; + public static readonly string CorrectFileContent = + "B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C12345678912 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C98765432198 "; + public static readonly string HeadSerialNumber = "C98765432198"; + public static readonly string BodySerialNumber = "C12345678912"; - [Test] - [TestCase("B::version.hardware \r\n\r\n" + - "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + - " Serial Number: C12345678912 \r\n\r\n" + - " Firmware R.2021.02 (136263) \r\n\r\n" + - " Instance: 1. \r\n\r\n" + - " Automotive Debug Cable \r\n\r\n" + - " Serial Number: C12345678912 ", "C12345678912", "C12345678912")] - [TestCase("B::version.hardware \r\n\r\n" + - "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + - " Serial Number: C1awfaw484 \r\n\r\n" + - " Firmware R.2021.02 (136263) \r\n\r\n" + - " Instance: 1. \r\n\r\n" + - " Automotive Debug Cable \r\n\r\n" + - " Serial Number: C16468551", "C16468551", "C1awfaw484")] - public void Parse_CorrectValues_ReturnSerials(string file, string expectedHead, string expectedBody) { - var (headResult, bodyResult) = DebuggerInfoParser.Parse(file); - Assert.AreEqual(expectedHead, headResult); - Assert.AreEqual(expectedBody, bodyResult); - } + [Test] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C12345678912 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C12345678912 ", "C12345678912", "C12345678912")] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C1awfaw484 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C16468551", "C16468551", "C1awfaw484")] + public void Parse_CorrectValues_ReturnSerials(string file, string expectedHead, string expectedBody) { + var (headResult, bodyResult) = DebuggerInfoParser.Parse(file); - - [Test] - [TestCase("B::version.hardware \r\n\r\n" + - "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + - " Serial Number: C12345678912 \r\n\r\n" + - " Firmware R.2021.02 (136263) \r\n\r\n" + - " Instance: 1. \r\n\r\n" + - " Automotive Debug Cable \r\n\r\n" + - " Serial Number: C12345678912 \n" + - " Serial Number: C12345678912 ")] - [TestCase("B::version.hardware \r\n\r\n" + - "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + - " Serial Number: C1awfaw484 \r\n\r\n" + - " Firmware R.2021.02 (136263) \r\n\r\n" + - " Instance: 1. \r\n\r\n" + - " Automotive Debug Cable \r\n\r\n" + - " Serial Numbeeeer: C16468551")] - public void Parse_IncorrectValues_ThrowException(string file) { - Assert.Throws<ArgumentException>(() => DebuggerInfoParser.Parse(file)); - } + Assert.AreEqual(expectedHead, headResult); + Assert.AreEqual(expectedBody, bodyResult); + } + [Test] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C12345678912 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Number: C12345678912 \n" + + " Serial Number: C12345678912 ")] + [TestCase("B::version.hardware \r\n\r\n" + + "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" + + " Serial Number: C1awfaw484 \r\n\r\n" + + " Firmware R.2021.02 (136263) \r\n\r\n" + + " Instance: 1. \r\n\r\n" + + " Automotive Debug Cable \r\n\r\n" + + " Serial Numbeeeer: C16468551")] + public void Parse_IncorrectValues_ThrowException(string file) { + Assert.Throws<ArgumentException>(() => DebuggerInfoParser.Parse(file)); } -} + + +} \ No newline at end of file diff --git a/ld_client/LDClientTests/detection/InfoFetcherTests.cs b/ld_client/LDClientTests/detection/InfoFetcherTests.cs new file mode 100644 index 0000000..03c62a9 --- /dev/null +++ b/ld_client/LDClientTests/detection/InfoFetcherTests.cs @@ -0,0 +1,117 @@ +using System.IO; +using System.Threading.Tasks; +using LDClient.detection; +using LDClient.utils; +using Moq; +using NUnit.Framework; + +namespace LDClientTests.detection; + +internal class InfoFetcherTests { + private InfoFetcher _defaultFetcher; + private InfoFetcher _fetcherWithoutPars; + + + private readonly string[] _defaultArguments = new[] { "argument 1", "argument 2" , "argument 3"}; + private const uint DefaultMaxAttempts = 5; + + private Mock<IProcessUtils> _mockProcessUtils; + private Mock<IFileUtils> _mockFileUtils; + + [SetUp] + public void Setup() { + _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict); + + _mockFileUtils = new Mock<IFileUtils>(MockBehavior.Strict); + + + _defaultFetcher = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe", + _defaultArguments, 0, 50) { + FileUtils = _mockFileUtils.Object, + ProcessUtils = _mockProcessUtils.Object + }; + + + _fetcherWithoutPars = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe", + null, 0, 50) { + FileUtils = _mockFileUtils.Object, + ProcessUtils = _mockProcessUtils.Object + }; + } + + [Test] + public async Task FetchDataAsync_ExecuteAll_ExecutedAndFetched() { + + _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>())).Returns(true); + _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())). + Returns(DebuggerInfoParserTests.CorrectFileContent.Split("\n")); + + + var result = await _defaultFetcher.FetchDataAsync(); + + Assert.IsTrue(result); + _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(_defaultArguments.Length)); + + Assert.AreEqual(DebuggerInfoParserTests.BodySerialNumber, _defaultFetcher.BodySerialNumber); + Assert.AreEqual(DebuggerInfoParserTests.HeadSerialNumber, _defaultFetcher.HeadSerialNumber); + + } + + + + [Test] + public async Task FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed() { + + _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>())).Returns(false); + _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())). + Returns(new []{""}); + + + var result = await _defaultFetcher.FetchDataAsync(); + + + Assert.IsFalse(result); + _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(1)); + _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Never); + } + + [Test] + public async Task FetchDataAsync_ExecuteWithoutParameters_NotExecuted() { + _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>())).Returns(false); + _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())). + Returns(new[] { "" }); + + var result = await _fetcherWithoutPars.FetchDataAsync(); + + Assert.IsFalse(result); + _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>()), Times.Never); + _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Never); + + } + + + [Test] + public async Task FetchDataAsync_ExecuteInfoNotCreated_FetchFailed() { + _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>())).Returns(true); + _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).Throws(new FileNotFoundException()); + + var result = await _defaultFetcher.FetchDataAsync(); + Assert.IsFalse(result); + + _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), + It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(_defaultArguments.Length)); + _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Exactly((int)DefaultMaxAttempts)); + + } + + + + +} \ No newline at end of file -- GitLab From e979e18d05fe0abbae145662d978fe3d42c3c1f8 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Mon, 25 Apr 2022 23:56:25 +0200 Subject: [PATCH 38/67] re #9443 Added implementation of ProcessDetection tests --- .../detection/ProcessDetectionTests.cs | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 ld_client/LDClientTests/detection/ProcessDetectionTests.cs diff --git a/ld_client/LDClientTests/detection/ProcessDetectionTests.cs b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs new file mode 100644 index 0000000..6c6a2da --- /dev/null +++ b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs @@ -0,0 +1,132 @@ +using System.Threading; +using System.Threading.Tasks; +using LDClient.detection; +using LDClient.network; +using LDClient.network.data; +using Moq; +using NUnit.Framework; + +namespace LDClientTests.detection; + +public class ProcessDetectionTests { + + private ProcessDetection _processDetection; + + + private Mock<IApiClient> _mockApiClient; + private Mock<IInfoFetcher> _mockInfoFetcher; + private Mock<IProcessUtils> _mockProcessUtils; + + private readonly string _defaultSerialNumber = "C12345678912"; + + + [SetUp] + public void Setup() { + _mockApiClient = new Mock<IApiClient>(MockBehavior.Strict); + _mockApiClient.Setup(x => x.SendPayloadAsync(It.IsAny<Payload>())).Returns(Task.CompletedTask); + + + _mockInfoFetcher = new Mock<IInfoFetcher>(MockBehavior.Strict); + _mockInfoFetcher.Setup(x => x.BodySerialNumber).Returns(_defaultSerialNumber); + _mockInfoFetcher.Setup(x => x.HeadSerialNumber).Returns(_defaultSerialNumber); + + _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict); + + + _processDetection = new ProcessDetection("process", 50, _mockInfoFetcher.Object, _mockApiClient.Object, _mockProcessUtils.Object); + } + + + private void StartAndStopDetection(int timeout) { + var detectionThread = new Thread(_processDetection.RunPeriodicDetection); + + detectionThread.Start(); + + Thread.Sleep(timeout); + + _processDetection.DetectionRunning = false; + detectionThread.Join(); + } + + [Test] + [Timeout(1000)] + public void RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent() { + _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(false)); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true); + + + StartAndStopDetection(500); + + _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Never); + _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once); + } + + [Test] + [Timeout(1000)] + public void RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent() { + _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true)); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true); + + + StartAndStopDetection(500); + + _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Once); + _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once); + } + + + + [Test] + [Timeout(1000)] + public void RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent() { + _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true)); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true); + + var detectionThread = new Thread(_processDetection.RunPeriodicDetection); + + detectionThread.Start(); + + Thread.Sleep(250); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false); + + Thread.Sleep(250); + + _processDetection.DetectionRunning = false; + detectionThread.Join(); + + _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Exactly(2)); + _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once); + } + + + + [Test] + [Timeout(2000)] + public void RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent() { + _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true)); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true); + + var detectionThread = new Thread(_processDetection.RunPeriodicDetection); + + detectionThread.Start(); + + Thread.Sleep(200); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false); + + Thread.Sleep(200); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true); + + + Thread.Sleep(200); + _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false); + Thread.Sleep(200); + + _processDetection.DetectionRunning = false; + detectionThread.Join(); + + _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Exactly(4)); + _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Exactly(2)); + } + + +} \ No newline at end of file -- GitLab From fa084fc4f32997f4fc3c6c989cb95bd4968bf44a Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Mon, 25 Apr 2022 23:57:30 +0200 Subject: [PATCH 39/67] re #9443 ApiClient refactoring for better testing --- ld_client/LDClient/Program.cs | 3 ++- ld_client/LDClient/network/ApiClient.cs | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index bbd4322..d8a7cb4 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -1,3 +1,4 @@ +using DiskQueue; using LDClient.detection; using LDClient.network; using LDClient.utils; @@ -38,7 +39,7 @@ internal static class Program { Config.ApiUsbEndPoint, Config.RetryPeriod, Config.MaxEntries, Config.MaxRetries, - Config.CacheFileName + new PersistentQueue(Config.CacheFileName) ); IProcessDetection processProcessDetection = new ProcessDetection( diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index c06a69f..b5ca456 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -11,20 +11,22 @@ namespace LDClient.network { public sealed class ApiClient : IApiClient { public IHttpClient _client; - public IPersistentQueue _cache; - + + public bool ClientRunning; + private readonly uint _retryPeriod; private readonly uint _maxEntries; private readonly uint _maxRetries; - - public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, string cacheFilename) { + private readonly IPersistentQueue _cache; + + public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache) { var uri = $"{url}:{port}{path}"; _retryPeriod = retryPeriod; _maxEntries = maxEntries; _maxRetries = maxRetries; _client = new HttpClient(uri); - _cache = new PersistentQueue(cacheFilename); + _cache = cache; } public async Task SendPayloadAsync(Payload payload) { @@ -59,8 +61,8 @@ namespace LDClient.network { private async Task ResendPayloadsAsync() { var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue); var payloads = new List<Payload>(); - - using (var session = _cache.OpenSession()) { + if (numberOfPayloadsToResend > 0) { + using var session = _cache.OpenSession(); for (var i = 0; i < numberOfPayloadsToResend; i++) { var rawBytes = session.Dequeue(); var payload = JsonSerializer.Deserialize<Payload>(rawBytes); @@ -96,11 +98,11 @@ namespace LDClient.network { public async void Run() { Program.DefaultLogger.Info("Api Client thread has started"); - while (true) { + ClientRunning = true; + while (ClientRunning) { await ResendPayloadsAsync(); Thread.Sleep((int) _retryPeriod); } - // ReSharper disable once FunctionNeverReturns } } } -- GitLab From 22974ce09c5e1e7fd6cf30b6bfc1a2a06f7d365c Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Tue, 26 Apr 2022 21:29:21 +0200 Subject: [PATCH 40/67] re #9443 Added implementation of tests for ApiClient --- ld_client/LDClientTests/LDClientTests.csproj | 2 +- .../LDClientTests/network/ApiClientTests.cs | 167 ++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 ld_client/LDClientTests/network/ApiClientTests.cs diff --git a/ld_client/LDClientTests/LDClientTests.csproj b/ld_client/LDClientTests/LDClientTests.csproj index 6ba14ca..59f6a24 100644 --- a/ld_client/LDClientTests/LDClientTests.csproj +++ b/ld_client/LDClientTests/LDClientTests.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> diff --git a/ld_client/LDClientTests/network/ApiClientTests.cs b/ld_client/LDClientTests/network/ApiClientTests.cs new file mode 100644 index 0000000..5210030 --- /dev/null +++ b/ld_client/LDClientTests/network/ApiClientTests.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Json; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using DiskQueue; +using LDClient.network; +using LDClient.network.data; +using Moq; +using Newtonsoft.Json.Serialization; +using NUnit.Framework; +using NUnit.Framework.Internal; + + +namespace LDClientTests.network { + internal class ApiClientTests { + + private ApiClient _client; + + + private Mock<IHttpClient> _httpClientMock; + + private Mock<IPersistentQueue> _cacheMock; + private Mock<IPersistentQueueSession> _cacheSessionMock; + + public static readonly Payload ExamplePayload = new() { + UserName = "honikCz", + HostName = "Bramborak", + TimeStamp = "2022-03-21 18:05:00", + HeadDevice = new DebuggerInfo { + SerialNumber = "C12345678912" + }, + BodyDevice = new DebuggerInfo { + SerialNumber = "C98765432198" + }, + Status = ConnectionStatus.Connected + }; + + public static readonly string ApiUrl = "http://127.0.0.1"; + public static readonly string ApiEndPoint = "/lauterbach-debugger-logs/"; + public static readonly uint ApiPort = 8000; + public static readonly uint ApiRetryPeriod = 50; + public static readonly uint ApiMaxEntries = 10; + public static readonly uint ApiMaxRetries = 5; + + + [SetUp] + public void Setup() { + + _httpClientMock = new Mock<IHttpClient>(MockBehavior.Strict); + _cacheMock = new Mock<IPersistentQueue>(MockBehavior.Strict); + + _cacheSessionMock = new Mock<IPersistentQueueSession>(MockBehavior.Strict); + _cacheSessionMock.Setup(x => x.Dequeue()).Returns(JsonSerializer.SerializeToUtf8Bytes(ExamplePayload)); + _cacheSessionMock.Setup(x => x.Dispose()).Callback(() => { }); + _cacheSessionMock.Setup(p => p.Enqueue(It.IsAny<byte[]>())).Callback(() => { }); + _cacheSessionMock.Setup(p => p.Flush()).Callback(() => { }); + + _cacheMock.Setup(p => p.OpenSession()).Returns(_cacheSessionMock.Object); + + _client = new ApiClient(ApiUrl, ApiPort, ApiEndPoint, ApiRetryPeriod, ApiMaxEntries, ApiMaxRetries, _cacheMock.Object) { + _client = _httpClientMock.Object + }; + } + + + [Test] + public async Task SendPayloadAsync_SendingSuccess_PayloadSent() { + _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>())) + .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK))); + + await _client.SendPayloadAsync(ExamplePayload); + + _httpClientMock.Verify(x => x.PostAsJsonAsync(It.IsAny<Payload>()), Times.Once); + } + + + [Test] + [TestCase(15, true)] + [TestCase(0, false)] + public async Task SendPayloadAsync_SendingFailure_PayloadSaved2Cache(int itemsInQueueCount, bool isDequeueHappening) { + + _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>())) + .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity))); + _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(itemsInQueueCount); + + await _client.SendPayloadAsync(ExamplePayload); + + _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Once); + _httpClientMock.Verify(x => x.PostAsJsonAsync(It.IsAny<Payload>()), Times.Once); + _cacheSessionMock.Verify(x => x.Flush(), Times.Once); + + _cacheSessionMock.Verify(x => x.Dequeue(), isDequeueHappening ? Times.Once : Times.Never); + } + + + [Test] + [Timeout(1000)] + public void Run_EmptyCache_NothingSent() { + //nothing in cache + _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(0); + _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>())) + .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity))); + + var clientThread = new Thread(_client.Run); + + clientThread.Start(); + Thread.Sleep(400); + _client.ClientRunning = false; + //_processDetection.DetectionRunning = false; + clientThread.Join(); + + _httpClientMock.Verify(p => p.PostAsJsonAsync(It.IsAny<Payload>()), Times.Never); + _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Never); + _cacheSessionMock.Verify(p => p.Flush(), Times.Never); + _cacheMock.Verify(p => p.EstimatedCountOfItemsInQueue, Times.AtLeastOnce); + + } + + /// <summary> + /// Some tests here can fail due to not long enough sleep period. + /// + /// </summary> + /// <param name="itemsInQueueCount"></param> + /// <param name="flushedHappened"></param> + /// <param name="testSleep"></param> + [Test] + [Timeout(5000)] + [TestCase(100, 20, 2000)] + [TestCase(15, 3, 600)] + [TestCase(1, 1, 200)] + [TestCase(6, 2, 400)] + public void Run_CacheContainX_SentX(int itemsInQueueCount, int flushedHappened, int testSleep) { + + var cacheItemCount = itemsInQueueCount; + //nothing in cache + _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(() => { return cacheItemCount; }); + _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>())) + .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK))); + _cacheSessionMock.Setup(x => x.Dequeue()) + .Returns(() => { + --cacheItemCount; + return JsonSerializer.SerializeToUtf8Bytes(ExamplePayload); + }); + + var clientThread = new Thread(_client.Run); + + clientThread.Start(); + Thread.Sleep(testSleep); + _client.ClientRunning = false; + //_processDetection.DetectionRunning = false; + clientThread.Join(); + + _httpClientMock.Verify(p => p.PostAsJsonAsync(It.IsAny<Payload>()), Times.Exactly(itemsInQueueCount)); + _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Never); + _cacheSessionMock.Verify(p => p.Flush(), Times.Exactly(flushedHappened)); + _cacheMock.Verify(p => p.EstimatedCountOfItemsInQueue, Times.AtLeastOnce); + } + + + } +} -- GitLab From 7b6b75a3ce9b740dbca019d788798e2959c05652 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Wed, 27 Apr 2022 11:08:42 +0200 Subject: [PATCH 41/67] re #9573 Added a sequence and UML diagram --- .../ASWI_SequenceDiagram.drawio | 1 + .../ASWI_SequenceDiagram.drawio.pdf | Bin 0 -> 47537 bytes ld_client/doc/uml/ld_uml.pdf | Bin 0 -> 37852 bytes ld_client/doc/uml/ld_uml.txt | 154 ++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio create mode 100644 ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio.pdf create mode 100644 ld_client/doc/uml/ld_uml.pdf create mode 100644 ld_client/doc/uml/ld_uml.txt diff --git a/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio b/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio new file mode 100644 index 0000000..dc3bd8e --- /dev/null +++ b/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio @@ -0,0 +1 @@ +<mxfile host="Electron" modified="2022-04-27T08:58:36.177Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/16.5.1 Chrome/96.0.4664.110 Electron/16.0.7 Safari/537.36" etag="pkxSyWU8jUEetNVYmsDH" version="16.5.1" type="device"><diagram id="kgpKYQtTHZ0yAKxKKP6v" name="Page-1">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</diagram></mxfile> \ No newline at end of file diff --git a/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio.pdf b/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5128acd1bf415de1716ada13e610c8526e0c55c3 GIT binary patch literal 47537 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	GIfTvOi7xE@)c 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 DXrqKP literal 0 HcmV?d00001 diff --git a/ld_client/doc/uml/ld_uml.pdf b/ld_client/doc/uml/ld_uml.pdf new file mode 100644 index 0000000000000000000000000000000000000000..12dce252ae25008aabeceffc8606623a4275cc69 GIT binary patch literal 37852 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 Ipwke413SdetN;K2 literal 0 HcmV?d00001 diff --git a/ld_client/doc/uml/ld_uml.txt b/ld_client/doc/uml/ld_uml.txt new file mode 100644 index 0000000..39a6ec0 --- /dev/null +++ b/ld_client/doc/uml/ld_uml.txt @@ -0,0 +1,154 @@ +@startuml +interface IProcessDection { + + void RunPeriodicDetection() +} + +class ProcessDetection { + ____ + + ProcessProcessDetection(string processName, + uint detectionPeriodMs, + InfoFetcher infoFetcher, + IApiClient apiClient) + + + async void RunPeriodicDetection() +} + +interface IApiClient { + + Task SendPayloadAsync(Payload payload) + + void Run() +} + +class ApiClient { + ____ + + ApiClient(string url, uint port, + string path, uint retryPeriod, + uint maxEntries, uint maxRetries, + string cacheFilename) + + + async Task SendPayloadAsync(Payload payload) + + async void Run() +} + +class InfoFetcher { + ____ + + string HeadSerialNumber + + string BodySerialNumber + + + InfoFetcher(uint maxAttempts, uint waitPeriodMs, + string infoFilePath, string f32RemExecutable, + string[] f32RemArguments, int f32SuccessExitCode, + int f32WaitTimeoutMs) + + + async Task<bool> FetchDataAsync() +} + +class DebuggerInfoParser { + + {static} static (string headSerialNumber, + {static} string bodySerialNumber) Parse(string dataTxt) +} + +abstract class ALogger{ + + ALogger Current + + - LogVerbosity _verbosity + - LogFlow _logFlow + + + void Info(string message) + + void Debug(string message) + + void Error(string message) + + void Error(Exception e) + + # ALogger() + + {abstract} # CreateLog(string message) +} + + +class FileLogger{ + # CreateLog(string message) + - void Rotate(string filePat) + +} + +class ConsoleLogger{ + # CreateLog(string message) + +} + +enum LogVerbosity{ + None + Exceptions + Full +} + +enum LogFlow{ + Console + File +} + + +class Payload{ + + string UserName + + string HostName + + string TimeStamp + + DebuggerInfo HeadDevice + + DebuggerInfo BodyDevice + + ConnectionStatus Status +} + +class DebuggerInfo{ + + string SerialNumber +} + +enum ConnectionStatus{ + Connected + Disconnected +} + +LogVerbosity -[hidden] ALogger +ALogger -left[hidden] LogFlow + +ALogger ---left[hidden] ProcessDetection + +Payload -right[hidden] ApiClient + +ALogger <|.. FileLogger +ALogger <|.. ConsoleLogger +ALogger .. LogVerbosity +ALogger .. LogFlow + +Payload o- DebuggerInfo +Payload o- ConnectionStatus + +IProcessDection <|.. ProcessDetection : implements +IApiClient <|.. ApiClient : implements +DebuggerInfoParser <.. InfoFetcher : calls (uses) +ProcessDetection o-- IApiClient : is held in +note on link: Uses ApiClient to send\ndatato the server +ProcessDetection o-- InfoFetcher : is held in +note on link: Calls FetchDataAsync,\nreads the status\ncode (true/false) + +class DebuggerInfoParser +note left: Parses the content of a .txt file \n(throws an ArgumentException) + +class InfoFetcher +note left: Sends commands to the\ndebugger, periodically attempts\nto parse the .txt file + +class ApiClient +note left: Sends data (payload) to the server,\nmanages a file-based cache. + +class ProcessDetection +note top: Detects a running\nprocess (t32mtc) + +note top of ALogger + Wraps up common logging functions. + Singleton design pattern +end note + +note bottom of FileLogger + Transfers logs into file. Upon reaching + specified size starts logging into new file. + Full block of files are zipped. +end note + +@enduml -- GitLab From 015ea63649eb8219507b643f2c05a7ab71417d84 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Wed, 27 Apr 2022 18:45:14 +0200 Subject: [PATCH 42/67] re #9573 added ld coverage --- .../doc/coverage/2022-04-26 21_33_03.coverage | Bin 0 -> 116240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ld_client/doc/coverage/2022-04-26 21_33_03.coverage diff --git a/ld_client/doc/coverage/2022-04-26 21_33_03.coverage b/ld_client/doc/coverage/2022-04-26 21_33_03.coverage new file mode 100644 index 0000000000000000000000000000000000000000..8c85839f595cac63ae4761a73585d6a4c27a0cc1 GIT binary patch literal 116240 zcmeI52Y^+@_5bg}x(d<-L<C)mNS7`sB1;G9U0tR3Djn=mV~J5?H`b`J8>2DC7Jn(m zXf&1-lbB|V>6)lXOf(w*-_M<y_wKv<4(ww$e;z1sIQM;acJ7%oGiT<`+<V{T;bT53 ziDpMp^wF5%lW)Cc*8Rh-7&Y>oYwvz(z_xwf6wdkcVEm~>|IdhqM@K}J(d1}dv?f}j z|K~-kqVi}|v@BW~EsECbXAAX{4bf_S+MrMCqoqo-PM;R)(*&hk5dZFarCO{MJ)?=y z$Y{FqT@$D38C67U^|vw_pr7@U^waUQXsdGCpj=joaQ0=<Cglt1nfcxEqVx56p=?<x zYpYYXcQa+%<jXcgXIi8)P?ojPM&-0YXR3@Q#bp}d&%H=wvVOKk<)MVw$k7`8U8zqK zC4D3n;<KW$I+~{(H_O64Dpeo-ov*x?L_L)I()ft;t(5I^l+Q|~Tcq>h!ST@uS(YW! z^%HzS`uR$?T6%<-%dgUV-g&Q5>0D|o<F^X)&aD~mOz_^>wKYFgp2923)DEcmLTb7v z4LIVzOZUi{&eyj>TcM@WTNbMotc&|l=x;M(Z_>K(Ds81OuilVpA>(#Y3vrQ#wmna6 zW1;?Er~eBp#p9V$9J`B3ksIMgs4nIyI;{4+mZ(Y1Ojp_F>6l)>q`)!`&b0q)K574P z>`wNG3dK*_kn=BnVU2uTXm5Bl(~f2rMLSBz%aPF*m64HU{Z5wf;Y<l<6-5cHo{}9A z3yTEzWXd<CD9T5iW;U}(y?$p~WuHvXzx<P)FAp$xU9Z1kR2&&cQ(|hNbBduE&tCh9 zXXSx4np>=j=V**r#8($bYdXsqk@55O9~(c<l<(Hdm-E#7r^%BWHLJm!%mUn;KD6KL ztZtG<vE@EiOi<c|I$l}eJmH9pudn{Z*W2-RXzk1s3L9feGaf#5kM!_FwYtq}v2F$x zuJgyKH5cxymoww>V(+Wsx&oc1va%XMFI^UGOT@gePO(ayIJikE3!P7XIaB&+MN#_E zD&-o*n0%!z<XZfWOt~f%MY*PH4Td$Ud2x&_{MzctOnFWyit<>q;&A=ANF&M`jVS9h zN*6lk`E#bMYm1_+>1&*^ipN~zFw0x3a&oju{g0B;|8molI*gy$`AT8&{N{{D#utT0 zCa9#VRQh#VH7%?pyURL=8v|U878+BZ&eYbNqNpu5k65ev;`)QOo1D41weFgXAx~t= zdt6bJH(#txvdQuU*Sx!1%gwj`I!ke9b<|g@{k1V0D7H~1H<I?$F30vGZy_^;2Qsae zy`f#d=fs?r-IJR4$6{My3MFGkupn9ym$T5AT5M%<wUpf<oT0IBS%DE{cZi#l;;V{v zik9=@T~l^h3yYhd&-Ak~MbXd3YM-^R5)|9+^a#zmR;xZ3vlpl==_px96nrRCJ2Q)- zcE-o!*-0uDI|*ymtC&;o>|VlMnbJ)ziqcJ0X%?$5CD+;uYm48=l<4>(E>X>Qfp-0_ zZ|;6+wp|v|yNYeps*Tm#Vp}nqtvJYBezxvWVSceupWRhXVLhwZB4K)l5z4t|v_z|P zh4ijsyINt_gxzmO<VCuBf;+poSEM#Zvgb2#e|}NNeYcLlmD>1dbleYF9oyM;ujewQ zp0`_+n!dS2E4>@EJFzHpTv#01Jw|xfe`~U8RBYGZ=~?u6jV7$t(|!x9!TOoqw=;aJ z-LvlaoT$5WSF3ez(7IE0ued_K;u_Jdj2GsyVp}mKezTVt_AlJ3elDA!(sC8HWG7lk zS*C@Ywnw&*)$*KcAwA_CcDq=mWFLqYQs_EKvCYiFOpI0%BE&3333^1~(W2Pq({6nv z+;5+I6;#OVY)^0F6V=9<;V|DD70+?F?%1rTu}*88g|2V@H#5`O_A!eHg|w-CGI8_t zkC~Si#O<oko%A*tf1STa`ipqWJ=N^fvNJ>sW<@l2%%NX$?>_Srbne{b%*K<t)?0eU zh;yHBxcQK!FSx-b?v3uh$5)`6M-QCa`l*r!I!?TG%fDWDzqISSxHipB-XpziKOdCw z<f~Ei{L<HcRwuf&Tu;A9_KKpiz2%`s+H0N{kN%zGnxcl74;&wz5OtAPD-=b!k1O|D zkzEF^FtSg8MNw(|WX-zW(8J7pxFU2T15a!*2g?7%RZq3w^-*1Ut~`2w!6Og;=kf`y zdfnJ@{51#M@Qr%MmHwvm=t0-sbNCPLsJB;($4a7`<Y`2nF4M0>gC%>%ccgGP=h~>V zeB5Ze=WDT@r@wl}bGEGIM{$a{7WzxKm7ouj@Q40zxTK-i<2-{8^c)SZBY__wAw8OB z1t~ZDNC_OhK~gHo$JNU6a-5MbJuNaH-^bwf3|`;h`x?A~=hP47LLcLgu_w(NiRI&s z4c^4yO%2}6;QJZ8xxrf)yrseS_nel5AJ8XAT1hBxnjc{B)&@V&;B5@v*5I`1eD)k{ z@N$E<GkAN0cQANI&xc6kH}qJ^ArkCN^G*go)Zm>B-o@Zu4c^V*-3{Ku;5`j~nCC;K z@dJ9Mq?ZIg43#8#Z-e(Scwd9}GdS@t-+2cZocNe8J#i5}OoII*B=q$`l6;(anU51M z;Ugu)F0_kPr4`cy`=LE8A8<2g#VDqgwSs!@rj|CVaRnxiL-dCq#NAF;X5kvUfF zjwwT8OR#yVgnB_!4_F9aF2N`0i4tN&K29IV$B#DnP=i+(oVv-E|8UQlCSvDG$$ANO zNcuFVPV(_l1|MzkF$O0t<ja4Y!5N40r5|tb2?nQb^5rwh^VQP$2TgmQEFpcGPw{-M zH0japB~vA&KS=^d6OX4!;OiuCG;t_!<_~amJIQnj={HH>=o2L~B>6b;B_E$<aON@j z(jRN^;|zYh!7B~UIGXRglnuUFLV3~HK1Y&|&o%fwgU>hk0)sC!_#%TZHuw^Q6F(@| z7767=(?^#{@^RuyK2E>Q$LZhs_$q_bzVoGDV{qC#>9<O-A5DGH-t%$Vdp=GK%E##k z`S?bI(?9a1ryaphmN3?!>q|<awVHk)`)aJg`$Vu#nXx82!f;<QBZ|8|oUIla#+ca} zWw=h<5Ot5rs~pwlHO<)Azm($w32g^WTfy(}3nkP8x}PNQi#$hD_uC|-Pjmc|kDp@j zQw@Ha!B02%83sSo^NXb^*Ci7A@TVl$ndWC1{A`1tWAINK{9J>dXYlh4PQB%`|1$=s zKJ%sjtmmJT#y?j`noFox(x*B8%E$3*KF;sw<ChxzGJ{`kaO};O|COF!B~7`|1HC4F znqMsjzeYlOG~+ND{&@);eTdiaYb9_r<1jymUoU~9+e!F2{6+~JP0YGZl8^Iy`S=Y6 zC%=5@Z!-8741Tl0Z!!3-2LGbxH%U`o^eoA3670N5lH|7={0@WPY4E!Yez(EzG5Ea( z|B}J)^BliYE;MtgFH0zIn%{5m2MqodgFk5SuNwRzgMZC)>L2^j)Yroj>`(JY4F0IW zA2ayl2LHOjpYWXa$T*CyAG0&ML=htE%l=QKfuzZHR|9MJ+OBEDS@G4u5^U=#(X1f) zh9n>Vroq2u@NXOZNrQjK;7=L+y9R&S;LjNRd!Bcf#t-P>lE8a-j-Hy}Jv~P=_Xz0^ z^Bg@W!Fzd*Cboz4y*)=CE-8&yV0Xu7!?_=aU7zf`N|Ns;bN6EKln_r`PS(tlx2&-z zKVAQ`Q^dY(c7^@D50{;DK)X$Ak0`(8loKlN`^}$5oqBfn#&=vaq_XQ3KYrw+t|d|D zu2C$F)Q6spJ%`7$IrD@c>-y`wO*3`Qm0Ek}Y;#nXSj$}`tK+#XyC3{~z2>*>T|jO( zgjw$PK6i=sPrQMxI;GryyX*Q@y|`CI>FP)hku3Lmg>>MZbWGbtGoyb_Li)}UIJ&Ro z`x1B;2^<Z7UILdx*&T{?nRH21DTFkZk6#cem2}VXF*WLTK=b?AJ>9oP*S6ei$!;L` zA-Ok$<a+vl@5$2WMcGeDkCM>K(IX^*579B6K~I*vBq4p8|G@L3rSTZrdF)bo3u!9w zLs4Ss0R^@YV*UTRRn?8Kj<Qi+%FskYGz+|$=jf3MzMto4cxk*hv^%~*v1(tdjGtp9 zLXC>!gIjO4V${s9bsX^d4fnRZYEkKrpV`uI{?^}~`S{a+yzR27BmUdx`8&@1VM+9$ zS^^>;mi<V+!q@3tz$QC9XQ2_Je#E)zN?J+|@Vd2h;QQ+sThQYqKbDZ5v~V>2;$;cE zjRamU*;n!tNk0Blga6F)4$|avsDyl8k&sWC|J>le@SKQ7n?<{Rw^9Q)q7s$;Qk0h6 zY=@qur`5jy>qJ;UxfC~JJJE|JzmnwRrEz549q&=d*N5Ew0pSV#5phpS&I|I7_!S?X zH-7$@Z{Pi^2TuA!^PeB_ezy&eetPty4O_OF`@Q~q9sSkUOQP#kzep?9@vr5{c9L{& zYN5Ez-3iq>d!hZReZ*NA17$(nN6_@Ez|;NbRsD?gq@mrTmr8yk$;V$a_-_sVy1{>E z@ZTH!4+j6E!T)6NKO6inp0}0859l$HHzfGsAPF2jOY){9AOEYt|7P&F4F0yk-!b^# zJwI3)JJHzr4+(ar`9BT*uEGCh@P8ZpJ%hjRIXweA(Zu)vNU*b`1djfU<O4}Q{-MGD zYw(XeKSY|ijCOIkxuz6|dPW(OA!uvOxLI3Xr~fN7e_R-U=8Y{?V?|hP?h^ekd-gu@ zL=8`Lmh|^}fHXG4yGZaHda9(v;B`Fj=F_9wN$Pr@yq=`h@IEl|KTJaY=zfyGdwGs7 zm+a-!bG?YC(azJA@-m_rQ^p;>jIkAdZGW<2FjqLd6^{Gxs``0ODsE<LC_57xr8;x( z`sPj5y%Te!Uhy@-R$V{2Co{rs0psicvfesJlobC_XVbi%E*&^^h+omiO7`~Y)13QP z$tTV08Js6c@}=L`;0+Ak(BO>>-q`cQWh>=ES4x@~ys5#P8GJv3H#c|-gSRyJ{swPl z@B=(Q!j~7_QPSG;!Jea!lN@Mp?zg4B(&^h8{2+rLZ18e}w=;NqgLg1^N6(M)<wcK@ z9AfZJ20zr`oekc_;97u*{h79>o58z#K14PXx6m$bl`6C$2MY91D&p3#T8&%Nw9d02 zGb7B6T)lT$<f5#!$YBy97J7yx@Zmb9hofgpc!xdd)BG@l_cC~IgY%}~eEIh^ct3;p zH~0Y0N2m;x3r*xY+~5NZKFHv_yA=D=`5$R;-ie+s{ZR%VV(_C4KGgHkvWfDdJ4z}% zAL}`qk!hI0hZ}r^!ABZ=l)*<Ee2l@z8ho6=kMW#&D1JZ_xyBoOg25*me3HQ@8+?kv zry6{k=f}uqA{W|4u6s23LfQySS1RTXLu(;&<<5!MYVMYvZ}r(lQEOmCIq5Z1B+P@+ z%)0`IQOjte)(oFM&1V{XmceHm{8)n@XYk_<UTN?XJg1D53r*BI(cp6oKG)#$3_joB z3k<%{;EN2t*x*Y%XC$J$XzFgM!Iyc?)iCMN?Ig=RC$hoO8sVcAo-<d2qfd~mH25lm zuQvD^gReFCNd{kM@bw1YVDOEe(`G0y8b56E{6x>uT=xY&$8&VKWV25{&vP_C+hXvo z2H$4zlMQ}~!A~{#X$C*t;Aa^8OwZ^0@}e0vK4tK;41Tu3&oTI?4Sue{&olV>o-dHi zj2dV+YW%xz6d`Q|E>NoR`bi=4-9Fk!%U$ElUaRLHIr=27)cftCkz-;+Ss6K&Nto}V zi7tUJ*D*Z=&B*Z?pFYhmH27x?ev!d1Huxn5|D3@uHTY$oukhtU)B7(s_!S1f(%@Ga z{Az<=WAM)#{91!wXYlJiU**e-X5_fR;5T}{#-~TOlicL_NuHyLm|yUGo#$vqj++gB zi@|R-_!kX+o5624_#Fnn)8Ka*{BF-T`0}Fh!#$pF^c+pQy4T=eGWdN4|FXgFH~0ev z|BAsMH27By{*dQee0kCM;cK36^&Cxmc-Y{N82nL#KW6a94gPh5KVk6yGx#?Q{!P!f z`SPOi!?!#?#d9<>iNH_w99=H?woiY$=V)dUPa6C?27k)n-!=Ht27kuj-!u5L27k`r z-}n3sUtTn0?(+tJ!Qd|%{3V0`z~DbL_>T<!W6#f&&CDdwZYFV<7Jre01YTCEI{L}} zskuSbmHzDR>;HOnzD|TyjQPza*p6oX>L&)*_mZkSNIRA3r%I)N+Myq;>n?Y{)>^F` z&R2V76|cAc@1q@?F52ne{*&8-^;-+H6S2ML<#V3}uM>r{50(YYJkhM-BsqJS@UfDT z=y=(Uw3qEatA_3U{%5v_vmYh9m`kC#0!wnPyx_-6N}>~GH_}12zfuj`2mH@$4`*kE zc!UH!Qj+A<2b}sSiB`&P<Ph2ZbJ<QmI9T=K-W$e!fZ@r>?LF6$ZCA9Yj@4>Wv_rmc zW4-n+d7~gtX`*>AZg1^L&C&C(g|xc55%%j}{7eIDD;G(aMI||F5O8MDzeuEKrVMAM zSrVNsk071om0v1VUD2KQifgO8#w&Y8*pF8(m6UtkPCD?*blgIMR(Ui0a?jC|CBO3d zr1`Hszd~u6O3=+DCDG&ZAfkQYvR9Rgk)wY6Ee(99&qN9Dm88Xt*<p)uyP~{5gO(EZ zN-NY>cx&_mwU&^=-Fq7LTe(Y>r+#yPZ<=z!hJ}iO*%m$|UMnOz_ARL84UJy+KA5Qz zo+d#vHwc_K(ojMiSugpWPoL($H~1e6{zrrV$>4uB_+JeEhQZ%7_+JhFH-o?BIq?+# zpih*%ZSZ#t{&$1_!{Glk_`3%Gm*<t<PBdfJzYYGL!9VhxGE!bNZH2I_AH|=Oyu{#j z3|`mZr3T;2;AIBi+u-{cyq@RGktrAY1WA2^?`!Y|25)HaMh0(e@FoUtYVc+T-_P^8 zDkJ4Z50f-EcngEKH2D4oZ)NZU4Bpz{2YNnVHe)|}iKLCe+Zy~JgCA`0a)Y-sczc6) zFnC9UA7b!M2Jhne0{MjXHgtVSNi^_CJ)0uwrm?QOQgJU-{;{s2*2lW^9({VOb8ooF zj&6Ml8r|ANy?m*esRtRS<G?wlwHzavFX`>mr+FWP_ceGwgZDT10D~WH@PP&&Wbh*l zex$(%dp^PY2hFH)l);A>e1zwdd_HKR=tzT)GWckNk1_aIgO4-#F$N!R@CgQ=Xz(eX zGaIG%p<VCWUl(JDZs9ANu2lM`XKe<@vp)B%)SUQ!_MLs&CS2e2if60cb=|T^Eq$Y6 zV|AWd>M2XOhTh&4Pe1*%msTLQca^<RXU%;|tWFe4J47YcjX?30-9+gb-V1475{;0b zkUsL&Or_#FJb$DbzQbn#C|UL%#}S%Ub8l*LR?d@4+`rEI@D}MOd?z<==1J0p;@rua z&54<Lh*yUf?3KaMaVi(rY>LM5`U9Hl-N1Y3m=>h=5_{};pFYhi4Ss^bPc--(gU>bi zJcG|S_yU73H25NeFE;oRgD*AsGJ`KS_zHusH25md5A*d%%O|?7HuxHYuQm8d2483J z^#<Qy@QnuFWbn-f-{N^+?+3KHcC^*t+YEk&=ly*?=z}F^dd}TB^cP*s$Jel*GWb~r zKilBv82r-)KiA;r8T@>MUtsXh82mzmf7aj^8T?{{Ut;jj8T?X%UuN*jJs;%j5xq!q zg~6}%{0N^OP5P@0ezn1`^_*GHUJ`VfM9(7))$>RawY0Jul!`Gc|0p!3)<>c6B(-}J z-0*mXh>^?PE0!IF!WvR?H0r$*qx7)oX77iEDkZaGG_&Qv@h$ypv4j!(7N0)NZ#DQA z4St)!Z#VcI2EWtbcNzR{gWqHDdky|2gWqTHFB|-RgFj&KuNeG6gMZa?u9c}rG<)(7 z8T@Mof7sxU82nL#KW6a94gPh5KVk6yGx#?=U*`RQW<2_)!M|njr#)Zp^FfzOp7DI8 z=c}YyQ~jR7pEdY%2LHanpEvjm27l4uFB$v?2LGYKe`N3<8~kO1|HR-wHTcgA{))kW zZt!1tzS`F#dV}Pb2LF}8e{Jwr4gMR0zh>~?8vJ#G|IXmQH~61CU#qe+KBC?D*iqYe z$UuQNl#1DH{_$~At&fk4i>u>nG<N407kOu0?wiYVui@M~De{e%0}H--tBBt6Ua3%- z*}p?ilLS6o$3$7VCw_ax+dh4ozhm&f8~h&z|EIy<HTb^_{%?c7XYlt8{vU&XVDJwO z{$GQCWN<F2xvEb4xy0ag3|`msk-i>BNw<@f8hkH<ml=F-gYRSTdIqm=@O=&5z~Bu% zAM4ADW>jos@Wuvj;W_)Lw10HDq^0M?2sm@;VUqm~-pb$y7`(N?4>WiigSR#KK?XnA z;N=EyXYlq0?_ltb20z5$oeX}c!8;qgi|4HGQjch6H(d?h&EVY)-oxNM4Stxxdl|g9 z!TT7zufYd+K3QdFR7AT`@ylAoL$uLSHb|-LQE^<YkBYN&&j{}g=ljzb4S5EiZ>x4| zvaB+PcZ;W2H^WNipq&^CkMh1?{G+sJ`gh>dbxd2CAvszy#HUa5qYXaP;1vcRX7J$# zA7Sv31|Mbc(FPx5@UaFTXYgYTKHlIH3_j7|lMFuDbM6A59%o59NTwKks==oje7eDB z7<{I|XBm99!H+fgah?;`C@-4%-SGymH28eaxdV@U(B+Z^o>%G^eu9LtcA>!+8GNz9 zml%Ah!Iv3)xxrT$e5Jux8GN<D*BE@Q!A~;yI)kq__y&V-H25aZPxSSOrmbu?_!fh2 zHTX7zpKS0`41TJ?Pc!)G20z2#XL&wXWoIlzGZua{X87b=Z<%%fuq#H5Jm=cGUmCD& zpEreb{*;#Rk^gqbcVf=hc)MCpXJq$UEA^Stc7XQndg&+0@8evY8I8j?Qf0oyt6IK# zDE1t_ni&n(H#b$Lu6N6|kLcdtvR*%1s9C@UZ%w5}{-yD3fOX<Zjncd&hWBXkU8{?g zuBS%qk$P^+y;GBKyW@`QwMy$s(o@eIRBB}3>aVs}DTRCYqx&XKcSmC`E39<4W=c1q zC`#w<CB{E1RilNK<*7_rPArPDOjilq_oI(gi{K6e-V?;P!S#&SP~7^-dNEd23jGGn zZ)HkbSrnzE=GenezLSnJxf*4k-@P@K6{EuH_4!Omi{rcCDG}cvM6J0Mun9Wm9*mVL z*>v?*-Y($E&Ar6Dk*n(W<nHKu80&wPVmFVvkGZ|?v5mep=B|cqo}T#Ox%G)eX|_AQ zCv?YAJblMYw$+qG7xn(q-`qDOhQ40x-#MNhH<IsV-tV8k>~QTre>?lJb>C|<r0Io! zZ9jE>_qnfKb?c#RA6W2Qw`a;qqVw8Eu{3mpd^~nHi0?7lpsP#Q))p(0EQ#+!+B-Ey z?NjCMp?Cri=h8&&sfz^NLsAl5taBlabS}~%`(@6>sJmFB+D5hZ4a%4AtaSG}ald|b z&K&aOnE>v;L36)GNpz*oiZs@l>%@e&t&%&X%sq3}XOpUX{*W`zB5+>>n)??@qU&{T zM804NF)n#;Mds?BziNxkeg3JZ)*h<bT|KV_d$3k(|FPBVnwLa($YMl(EGrf1B`MQv zBYY2Ob@J~UKT$@_9F!35^dLt#$6Pm|S4fz1=HqTXrfT}Vjr98%oO9*N-`&?&HUE7R z>DdLu&Q+4Y%XO^Y6QQ{#Y#<^3a!HbN3~%Q-x}`+DA?6*Wv5l5X-fF9PIsJ)z(&=gK z`8f5OkMC#j<_2$JaLSM`|NRZ#%HRhWytTm(G<X|>w>3EJGN1j_GrWg{dZ9;CFXfVa zyq&?-f%2yBU~uX+U;c*}yp!j;uO+sVh=ZMn8l3yY$v>UGi^02kPHeyrXv#`EC7*D| z4l#rCb~iYF%$L5W=d78KKN{b=$n8ESIZ=pwj+W5&(6qI{hw7NVhQ`L;64F;l$Olbd z?;{EMz{!U;PCdhiNr**g7kge*l_Ba;W&K3yS@lvQV)e#~X7MxMoQ2+uC1`4nT7lD> zIR|>UWPk)t@5CxvIgyXw$;YXse0-3>sl|Nhk2JU&A*$L#?d8j7h{5rCzVt&4USV)* zDPKPLE*~FZ@R0_0-}J$^O>?DQ{BuHf3|Kv2?I1aeV_wBKxV!6y>^FEkcEj2QS3lA5 zqYn>ie8ZxD|L*Vwr#<=h8|@a&{>iTg&c1QMb$a~1LV*d<xKTFBd#PDw4&~-+!?iB4 zQCBZ3w6?HJ-{iI^o;5ZwEof9_{@63#>u{Er#CKBH(Yfda>Ugnsac!(DLDV10Mtf^o zWM)*hHC!ie(0p>|ZQ^XfCSqymsU^`=*@GyGlyQ$c?JhgZOxwgfYD?@HJm#KC-Fd4x zA65~Q@DSQX=;LG&qF7lrRuroaFg;b(s+xO@vj*E39k9*Crv<VLQT#3&CyH&YQf;b2 z*SUPN!?O7K*{b%{q%JupmN6IV;<X#6R>&%(l`K0(Kf$sCQ(oJVWi|I4XAbr;PGYBv z)Ei_QqFGbfc+vcAja8F*YF&JXee$i+j8Z$_);J$lF&5F*(5|hWB8w2s*~%t}=5K4Z zRW<h*XAQQ|*09aBwR2<_qIqN4L~mQVcg~FC;(WzOR?jwQ#U-q|)XZa?53878Fi%1E zlaxfCl|_ig^Rh`X;d_z7m7$9n+q0_bm0>pW_f-7PUPZHJX609t)_~QaY|LILTSZ)w zD^)H;Gw-s=F(F!pt8Qn@sMyBMwd7~cf-TGonHQto{PhOefoQg0Hbs<{d05KNRc+ZB z?}l7z;!`XP<)CL#4mZ=gU1dNHRyn4MQjX>spSm@GVe0d=pbCxi3l%;24lTYZt0oq4 zE-Yf+$*6~>f0ab{$r_|w7EOx@{Xewe?OVjXe!S_Pwd<N#$9aQw#BZ!~Gu?+}8PZPH zP50KN{l#o<zE;jx%UhGxV_X!fnZGy}7OCyW{z5x{eM8nD?PbvnQED*lFUz9Z@)zd~ z*5NO#bN+fpmLZyLmCY2zx`wItg^yT!u9=6(9UHj*R%?zmbG(x1C7mD9zp_~|A#UWh zsH_beeSOuW{cx6Gi_RL`LYyv%UeQNHSKno`y)D@_%j}yx!d~4(^*!#;shMv$6ZT*W zBP`mDu&?P5QFJRiR+Re5&gQmfPi?gw&Khi^MPr*AVgI5-L>8AFCyH%NGHu7r+}t<$ z(dUUuHS-eZz!KFBy(!j2{gUYKvI0@0Dq~F!OPXg|P<~5lqaAUsU=j6(Wql<j(Fd{y z(JZs9GA31hLj-d1u;#wu99V)s@D1Aerc_2D8W+n>5Y6YCv?aCS8_pFh!Z%pseA7_Y zAZp=dCwhyr^Muf1w$|bdma||Bb`W#WNJ-Q}b|7lmWpiS}j3&e$%a+>k4`&NDF~VYx zn<E}1dk{tHvbmzJ#=<;my1d96#*^QpRXb6Lb72v^9E;FMNz_T!Ai5?gn-`Ph7`A<j zYAX(L-e4VL7?!y)>@Zmti>#aPt!t5qL+tjjZ<_t))7rZ-;%wN2J=7oC#qGmo6QWV2 zY=J0sn2p;zvZ*%O7iSH&;VW!&aeJujLVC-#g`(J&^_Q#7v5HN6(;~C>1sdbB-wIlj zahJ1U6W6v}f1|OhBpM@okUp|$QB0E8-#fCYw%QnH4)$Ri;;z4^$Tma~tZcEjFMBmP zD(;g+i&gO*8R2~d^EA)o>bGX&9_Pa<R>--!L1S4-bgV2w6gSG2#DuwUh+aFks<!;b zxr2pRhq#sG`LYhtm15aaZ(-|9-^@M<8`_&2t1Hyr=(F4%!FLbW%zvC0>zLuu6VPt9 zw_KJX17zJYQF_8b3I7o}Sc}?`b+yr7Ie)NHJu|lOsMx0UvJlY~VcGJSP|IOFsOrO9 z@6}$k<J?$?b+kXU`m4NlvaCZCU&>a*B#QWEX1Cv6n1!|BOKb?1GUve3qhq_ymX(M` zj<S_8Nyffpk72cMiB{5>-7`<CX)EMx*o4OzBhd7dlITL&gDBFJt%?a(Xj$(u-n-b6 z&!%J_K3;bt*Cal3_FyAD1RDp(7F{9x5cTS^)iEJHhc@Wqv$HYxT~R!#z{(nX66`|M ztS573?4wTU$!OP;ua|9ztSwt3n%k2LvCpjr)WnONKUhi2!%EkaZ<B?HK9#NYRvwVo zi?cN5;<xGgpBCtz37JsiR>)bgjhQB63EGV%Uy@zO5ZQK;C?3p?B}or%&$gO-k8=kL z=^t3=#*&9+9ipCGwobIZq>;JTRFjt0Tz%hJ!RqEH37S=dz*(WAXP}Qs@HRS@2jdl~ z;R)W>b99pH5;1NY=wXtOKdqa5(8=`F6_E@*LK4#Bsi6||NJ-#*bX*}pQ;xuy3D%RK z50b2x;B`J9>~*<x;LNleN~np}k_{5lr};*MZ}OaeKt5>7uvtPrlogI9I&P7`DJvY^ zL$Xx@A1Z;Pi2&Oq@L>`-8b6#Yf#XBUi>BR_MB_W@`9{f5wWd=<DAkBK&az+XR;!6` z>$JC-yn5)I_x@|*T-Ez<lRL58x0;<ta|f6G)18k#Z6nG;i77objvg&JRRV`K^}3mK z;G}`0$4E|-ke*{W8t<Jh$;Zzy_?e!Ml_noFJ?2vq@=5cv41Tuf<D|(4JxOwognZKc z(*{4+b8H|VG;*GVeA4`UgJ0nJcxm!MW5Z`8<dfzX8vL`KPmm@b^s$nQB;=Fk7aRN% z&nHSZl%N|)J|`g`J~#Hdy>yay@SG?VIKIUmbWh2p67os&%RHYfO?q^1$>kE#Pmy2` z8hfsgz^6*;d0k(+Bx-Z0;-*CLs_aS;tmQj$-7^YqXJL2hi_IcRL0P9u=sRel_Ei%2 z3<*9%(-#Au={cHyceRA{j6kGEGx}U3$;UtM`D|&@qlw(tN=TpP*LhC6BR%>E$@LP_ zr}+&AztQvKq^WZ>b$*kCeE3YQqT5Suk_1j0gwqCZlE9CbU=Nx$_ytKmezWJ5(xgZC zmfRvC{RtB6L1WLY68MP{+92As!JE|nkYQ?rUliR>GCb1;v+M1<Q#))KQ4-2KS2EIT z#(~=;@OcvahNc|`KHqaR?e=yF=@&>yj~*(yLz0i*Y4E!|UnosJ=pmB3CFGOl_Za+M z&lgFP51M?wBq5(Pzt7-b_I$B4`Je|%?w62Hnm^$A5^35Mns)US3F-MvJ4d&dBzXtV zJ0|#29dlkZ?fgLr`K0+*JzpkGdUS8eLlV+2mtYSXd%h-tuaMBr(XO2j?HonOaJBP? zMX_d7rk%4snSA@`?$p{3jVKSLUL_gh^;qdgB=FS|yoaW>2foI0^a#nL64I}gkRE-M z<S|J;{<!BSNs}JUy!Go6(x>?op0AT8J^C2Q|4B%n=HD>*H$7i3O+M%f$+slrljh&{ ze1kOU(TqS(N=TpP-!b@8o^O;UA2cJycO~SL=1&{^8P7LKlMkAa?|TyRN%Ln7{+#EV zrO5|9Rq}la`K0;t27kfxEz;zJ{;cFh3HhY?O9uae!GCD*9~u0|27lS$Kk<C4G|>P} zH2A3m`}s_CLbsPBInfDDJP3T7j`0J!ljLU-@;O-oNB5SzB7vVG;k;<h`*R8WR0&ZC zO%y7P>gxZ+ib1>IJ+@*0e};OCyL&bH9M**&bbR%$rK?Aez4-Lrf37p<{SV&ic*7gZ z$_L-v?~)D=*LiECz7?m7z7<EJI8*iuc>zzf%EaH0yL+4Qc%6age^`M`uJ(12H$%#- z9oxUhwloT7qb3fQpa)6<r)H=<ba%-wC0Li{zw&%vY4Sk3S}oPl%H6V7S8AOtJcY)c z)D=1F0LdCYrD?Ou1JC;Tz4!g}gm)(V_a6gW)csMPH!H9F+Q3UYl|8z;e6H^FQ|%(7 zRl~oQN9Y0BJ8On3I%c0^Wvy!O)Y)3<+#}@0m8yNW0-d~9I(@HSorrVb`L>d-UQ@rX zO7d~NAyw8P8Y9boqg3?OdMPVvZdv1qys?1RQO|2EdrbmQwxE&v{9Df(NRu8tT=Kev z^t4VmnsM%T68OOqIJ%AG_maTz3jCl1FV``7ppTIJK|=a+Ns|B3^LC!2`%3;~@IQOr zUYdN+lO%tUkbj!LVemIS?;uS+=#G-VO2~&}%8SOgB~dq3JTg`_`Ztj}k_P(Z_HxtF zqh>9xZp0a|gE2uTjdeHazz@|icB4B>-ja}>W9&vdyARi|BjaTE+oIUrP^~}ALTlS{ z&VeO5WxU#mCe{T`DX<*fMe>e>^rXRZbbU!lG+e)m93#vBF5)a78TW1OnyYQgIR}>X zlwchiYXUz^$5@WW@_$H3-%En!XlMCkS&fXB<^L4jOR~SN4v9+6^4#}Du)?`OHNuXp zd(%KoW7ggg=f%1{5?TWqs{^N(Q5rNejCUoZ=QC;1NZ|c++*E=dD*2a$^lAQY&-+W0 zKbq+Go`m!RBzOz$ymg8^g-npQ-uJY=)^pZqbvS!ZYt5r&{fOMLfiaodMKdG&k0c-e zz~CPm{J#eO$lz+^dCyy7@Hz&sYw(ijHTe~pB;WEz8T!!Pn%S(>7|EMYYVOrK5&7c1 z!IE;XX+e7#yd-){79o>m6_2miRqA?*N$&dud1AorX4Wi<md209W7!Z1BNVz^!a3nb zOK78LMz6g+AF5+Gnvr22&nt9H+eO!xltc{_D3B@2w4PEm5bduKHN1U-lDPejsbZT` zF{^u2UeHV=JarJBq^N0>Xb@pDo){sa#OQ4jUSW}s?`!Y|25)HaMh0(e@FoUtYVc+T z-_PL94X$sKRP7>DRl_ZmiW=^sYx>oyO?I8uDz2xa_XO2C&k4-ajMrUT{IBDEg9zKG zvC$H061`T^(%}0Wyp_QZFnDW&A87D425)QdgA9JK!OIO^61}ckM5d`G+bI=2zESFK z&nb$Fi(;vHWIQn9EY!(3$st}dqigT^F*<H7K_8glnm5E_ExKIN!Ka_#Ir?}>N6#mE zj%Id#NP;svhj)~8@?4`qoIe_S4)t8|IOgc~lFpvXV=+hLwJrwln&8A+(w9pDpRVH; z67-RhZa)1C&(YY~-Se3`X3l|bCh6_@Y|qiHQXD_S8Q=RP(kFSp1jqlRZzt)W;JrL& zZWQ>jI>vr9^)<k!KTgNkiN?;u6Zzmr@~2z_4L-==gFUCN>C@;&lA}DQ-N4ZYNQQV` zsbj_|v>T^h?XIg;i9BC+v{LP-pLFvhQ|>%^SC2_eqM^PNC(1@z37WY@;B$0LsnN{E zD}4GiALjX7rJ;7vw3gwX&(|^eppTG@@O**i=z$U~DaE~bk>_Yy#i#^lz60-@;EQ$4 zdC~Nm(LQ~ekMVqo($KolM@hySe4N22dA>})%X!hXy2+j|*D>Wq(~72ezCy>e7PM<E z=k?H@y+r-7Y^qY#jZ@^V*wj2e){V%!RCzav^LKq}UmZ^~_;iDp##dPD_K0;ccjroY zyI%5MndBPTtUq3~dB(&)JiXVI$8I=o(4_Ca{QIBwe0I^dU+?zhxT||U`i!P;x2paS z#m=%B@>?DGwW&O`PVJO?Wx~8PxA%8Z3$ZOIY~8GG#CiA9d1*iNWHdcFaO%FH1kE+- zOrM_Lp+%x;k($Zt|22C={f1R#t7h-J=iEmQTlU_je-FBT*nPJ?e97k~-ShN!oBX(2 z%XeQ{Huk=EjxUKGR;?l$Rmx_`WAydv)NK9Cigxnch1F@(h%-_f@i^x-Q8Mu6I;QT> zZ6vdOdOkB3K@$xFC*sit&_umsefpN3qst}7C3ri1hBLMXzQ2y~1e$0rN5ys$@!{xB z3C?)QdC^3}N}s;9j<Fw2+dIK?$^u7^keui_Wr3q9-yF}&bqq)Mm&`TzJkQ%H4e8O$ zo#uN^8R-XT{JzBCy6a9;9z?T~vZYFerHypm!rM+=k5BjY+Gr8w5$D3Pj*_lkcaskM z5FJx8G-;Ok^l834!TA|NjRnpzHHM}Yt?=o)=$QP`%m-F_jxBJsx=Xam;Hwi{?u*lt zPvDe=^P)NL8lRp#$savdvew`yc~0J>N7I7V8GOCx*g$$TW!T_(Z_m;6n2nw@2O&M0 zxyvSlZ#MWAgKzb`pU<DxJW;aE;3pgW6oa4YIr|pakEU#=8T|AFr>vxB-W52}i26cP zUuXFAj6md%9xOT2bB^I?>he<tKg)A`zLx||yDy0btBR201kP5fa#6lXHTkxc&bk`f zsx<-k?2UWpYQA@|j@HP`jwH|ZE>K$;tMvumI>MdmtT(u)o(89K8><z*o|*WbJX6@A z7^1c8^7#DWEde|F+(q#(-)L3Xh;dMaNAT0plFeRkkq*2<$M_$8z2qF9KFvRE@N*4* zp25#I_ywL1_x7NfnI<`r8BT2aOd@@fe>TAxB}spv<e~&W)N^J%ffEyGx9I7Ti+%bu zzr^65^L(Vw2R%q~slhMve3a7Qe{_Ax<(^|VV+fkj?FxfmY4B@3AEVzTfAqzY>kNLq z!EZ45jRwET;9u~3thWbEpTF7Qw|G8IY3T20*Wcr<9xV_YFL0|;F<0oJdgJZF?upn* zI^vs=lM#S>43a&QzP+Pf>z+EQjeb}jVJY^rs>JFbnmP%bm`**RPm_Gnr%&_S41T-8 z?=bkCo=^7YMKi|S<@ppH(;v{p@w+`|RS7%M$4Krm_`L@IlELpY_?JDWPjX%~Hr;RV z2RxtQ)1!w-zGCnP4gS>xCw7w0P)XprvWxwL#y?5UY!S}*_>j+s&n-QtKPP!V&l%eT zpQYob5;XDcYd)XZI;LLGjU*2z@+TeVX(xHabInI%zoCgQk0v<r70!7A*C-n2kM1pb z%%@ND$30gsjPpm6|JOaQ)G_@Q?fUKO>a&PQ*%L~I_4#)iYoo_CiZ};nK2g%u>sO@z z&*0xM_%{vyErWmC;7=O-I|hHs;NLa)(*}RW;NLU&vj*4moN5rr33BXnN=1D)$U946 zeX2HUv3|sPs73ld?Fl_f@_mCp?>V-S9!(5=!Qd}?zOPS@o+^3C;6L!ZflrSn{~sFs zM+X0~!ArG6%>B{3%e{lS@9*Z$vbCB!=ic3weLLqVXEc2A)InDaUH5pCXAhh6a>Ge) z&p-ImI#0K)``3qOy*GEQX7jJAeIe?#WiQJ|)c1rux#nI?Gn)?2S96@an=t*eWV+<B z+W}vp(IxCcF-LGune!GsclE#%)7cc<saUndP4et3=lZEpMA@im#stcUK40>a1i!%Z z&m{Q%Iwt<3dq{rj)2I2*4E~D2e{S$!82p!>xAOL&nNJ6PfamB=3EtXsbdtC69NkUw zE1!Q`&(ZuWaK=#lhNh3}E$<p`k-2I)zt(Rz6Fp8XF}vo<6IUn2wM$*Pb-2zutSi1% zffby2y2j(X>$Ylk>E1m{%gUWoPK;-uJvFoAJr8U38{vp^uNQIOWU@$YI=M?tPUPy| zAGdRDYQKn5)21}YDkrDcNC&QN6}O!M(v2mr`t)i38-u@Q@ZTEzb<YR-^By5RRPsB6 z|K8w#F!&!0{wIU~+2DUM_!|a))8KzK_}>ivmgh&xC$wd>Ys;5tNd=j&w*0nI(Yv~- zEzi@c#8S1K+;&)#HoUVDtYw5<v^Hj_%wW;XU<046<1kZYgnY-RPxHSU{2vDYr@`Mf z_`eMPZ_k+lV<#Fr-}C%9&(ZXl_YM9Z&zS*}5BhM)2MJCOfDcM=&4c5aH@bu5L!Vx= zt2iHYBgua~XC6!b=nBb4p3m_dJxs!86ZMkjB?hnK`CR=D`J;)pbv>V_V_GMg*13<t zOQU`C)7|II;<+PoWhPQvbC<G{8*RB_`ui8$d}8N2-x~Af4_@y)x$mrT%YWBoLX-0* z-ZMr)>U?zrWTAR(J$b3F{Lw6LzPYm(=E`B5NS=Mi^N777&V%2ZN~k3?<7)i`Kh$%^ z=fL;VF|~~zEZNtmZ|*sos1tY#9g{!WkGCr69g;;VZ3F+?jF8+xxIry+z1D2lNnITu zZ<Su48A8>2|8wiX9&LBtOZB2)AG4%mBxqJ(0;i;SgBb=_#SMLV(!7zu8ymcd!J8Vq znZft-JU#0vjq7CXZhN&5W>(4XDs=Cr2rK8wefKGAhu`zUmh-p$;Np9qdhfiK4;y{q zn*LYy>3(gWe!qC(+wVnMntfaC5m}}-*<3zTh*S?GN4_74r#)GJpQpLj#CTPIeoVMp zZ4j>@CZ7!r7PKg!&6Y%*m3~45rr)8N&z3~*$u4BMY-{0dYo#8tBioYKGPP$X76d!H zdpnsomd3q%#U9Y2a_30Nc67p_-A@0{=g#c&r@uV9sm{Vz4!P*cOP8Ja&XzILzB%^v zzkOzLr;=!2O=OUjs;id1t{P?95pOl7B_-cZ$@h9CuMG-oHJpQ}%4!000W__rB-&3_ zAgg4_{@#-88(^zilG|EpW)<fPRxx&9RrlDcHnIrORYqB>D*hSc$AH@N59h!Vu3GR9 z+WDuWtUz>~Q+7ZV|5UZ4HvPl-f>rnjtDJv&$RcE|tZMD8YMg05;oVo$6qR_(@>-3H z?mNhKz6Eg>Y~iZ6qu1C}67`oI$Vsy0KyOR-O|bcFsZAeo#$Z<$Zlt|77sStq;N zc)PN1SstSv#`}uc*V&|)%@aB`_Y&v9nidkGGWsxyzM(~yAnRpKTW?LDOmxm~O(Aoc z>@#1v<6BMZ9a}?*h~Jb*gN#ZvNu@zHs6+=<@$WG8n1x!)s9pbZ9;{*2hn|4Os*-4y zEI~HPnuDwOH@`K-;9qPFC1Ra~5~&y}(OfBHlS)+XOO*Y_N!PbGsJ!m|iZzSG<c}51 zPrG{EGqz%>EI>BPigs1}nrlTN{&e>tGB?k@UpSdtP1`NDh7!>ODVY{L<kt-<4YEZg zYOhpWMdjZos)<iaBl5-qcFl+dXxePx<vQk?0L>Lu2cMqLN#4=(cH+#a(B!NA5|skk zs*)VyOVTi&C#;Jj3s2dFYowaSw$g|*a9+m8L%hcBz!?>=8%^8k<kP45p`Mcm<w3jh z+^Vu5+f<&;O0|!E($y?aA+0TU?o_k3RWHIeEM|tlni`sG+`t(Z@dUNanBB#vPxGz@ z?`H7s2JhiHUgx~%qtOOG%yaq$HGrl(rSTKx>vx;E`9ehx?zqZE5c@ih7T|itI{7EN zV>IZhH}8Gv-7Bwq>X{cGI{#;<+&knKBd=)v@;A42YtXyX{PX(j_PE#8B9T+nDtpOu z?4%@nS$eIdnR%s`w4qs^tG=q`X%%tCeRW1;uGjOV18<;X>Kr{p(%YwR<T;vk@jeFc zo8Yu%($kg$r~R_#gT7MI&!<oG{stdl@WTy0(BOj%euTk~H27eHALTjoTl|ThA{k=v zqYXaP;1vcRX7J$#A7Sv3p0nOYpGLc=da)LlkyF)vM=6#5>5dX>zL;#Ij2X4rn(IWI zpO%b;L0GpQZSc~#UGF~cM5)??E49b#-Xf8Gn>W|?$ryCt(=ShL`h{5?$DTg7;fN>B zT6xIu`w#j<>0|%6{?02)-o5bG+5oso^@p6LIvgWkmB?q=x9EqfhwZID?Q7Uky*Q-r z8PHjYF)bxsy=I)zzNqX%&X#Rsy=~d|AMe<<+^fNw+KC0hPR2Ftb@RUaWg~Kq>>O9c zhv5q0f9XTcifyb8<3qIb;UlsO`Lt|1riu@DY+LR65DS8x_z*jt51*8c$hop}yi%3w zCr27BtFx|6mZ|M;&^&1ScTXg(CvEaG_ejFBIk}@QiX-`ZR`pu6-uC26*-~W~C_zt< z1Wu{p=p=8g&%~|+CDZwt&xg-5JfE51TzN2}pqT-N^z4Db(X@uZS%Zh8lbq`ZIJ%D{ zq%YSo9L=?G;O%q_N2|&*yuIh>WIoL6Nsp%1C;D<F=kHy_Cwb1?A3vb$OG=_M4%hwo zlJnI%CMy+VXq))mT;bcAHfgqIjXddjRL$zQMT7;kVrDhWXwXMVrg#oxW`mALd(TM& zN1ra4YVc_WpKkCO2A}CUvp3F*o-di@IWu`UTGP;Iw&z223`fI{^}IsIa5PsY$9X<X z$J8&HS>Evp&TI}&drNYzTjAXke7KIuAAPr^(&v-rCm8%hgU|7NgwG#MADHX;C>>)z znpKi{o{!cs?GWwSVLx?S<N~$B`AS94u8enQ_~t_Hlu5S75JlX3Jyz*DfmG>t#u0;Z z@5Lc~^`7zIjI1?IQqC)Nwa$C#h;f5+BAt7NqqgH*%Lot955`I^@%nSpfsfNMenr#w z7x?sirthP<Mi2ZL9aI146_SNMeVQ*a_+rn;`+U&U^AgV|>KJ>_%~PCM11CN$O{7oq z<q1yBlfJ!VMS}PCocI^`Bpp*O^cu-ZpFYi3CHPvO{v_$ZC+oO{1kHI@`}9+FOu5jF zBx^j!KKzcx&ua~SlEF85K25(%{%HEgX3rU;=pX3%lF~TUNxSt`e(txpF{0$I10-kH z1CIIT)L)&u@4!W;_HX&rK4X60;FsV0;O(Bzbi4agFSb3c^ARVPL{BSLAQvfKY?0UW zPtQo~=p4D@ReFw7b#<!hwE_2khUk-fbwF-ab4cIGFjg@>eK&0W-^_pR+!AKrgxN*+ zDCGXEs)wsL%c>vYPg*5Cf>wy`DG8j}6&!uFWUEil=W9Iwe1f;qG5MjHO@;KdcsROW zf-_r#qm${Gt-;YmxsVUDG&s6jf-_5lqq`<Jkqi6Lu6H%k(W*VDcV*i}vR5@by#KTH zuN!;I6P=p9*lz2pktZD5@hhwEY*n&s()@aRpEJI#-qd=8VyNVD^{Q>E)w=RaE4BCa zskSv$*9oijmyvIY>L@w;=YE9TmYB7sdM&Ut;@s59z7not(6o@i85^lt^iavkK7E>> z;yG!laWpkv5}l_~B3G!Srz#cgqg(vusPKJuixk}#X%8j0EV*T+=O)X}=c==Tn);(x zgoXH{iDZS>E2RTxE=<|bhe=NJ>G$&-JxFr8!O!r#xlfOlbD}d1{waf><v9_9aT$$G zfit$l(adwt_UVZna5Q$FWAINWIQEgAYlOgwFq{*8n&e!cKF!ZF`1uCEz~G-T_=N`l ztmi~L>_oShT;w^C4L_i{cDUH!mn8U5pT0sma3Uf3qqj;v=hLV8r3Syu;FlZx3WHy1 z@T)v0GGiyYz2s`o57sg58BM#tCcztfPLEA;B0uT7CwRGz@h5t@<nulsJ}3FL2EWeW z*Bkr>gWqWIn+*O1gWqiMTMT}y=k0uX(TsXu^qf%?Kci`jw|UN-mUxMF@v_cf&9Nlc zC|=&KRQjjq3J1qmX5pTU<ehS?$z}I=hD7squiYH=?ScBgmqv^Uijxbprple6YxG8@ z4Vq!p?)OUNTEP6s?O!j}nU`p$=APGZ>$-z=1;0Qot?K-3qbzgpJg*ala&J-DgPf`3 zJG?&vL&Hm=a(N87PF}lHsTjwa%4>|uc!zh-2H*72NauXRI$7?!oqFnbu&}Tv{p&@X zvot=Z8#`$8NZ`a~KBF05@AB!>{BDEa=Q-mA?FZdk@@0eH?>TXs^k~lefWg1wd26Mi zouY{cCDB}Y6}ds4eNd_NPhJ}w*XxpuPibjg6kYOrlNK4?ak^4h`&-pQ(7Y+KkN#2{ zg?YSAge`b{iG&D+W`z2x!F7kYN`ZVqC3#4xm~(YjNs{l032kJMZy~v>8asY!y^Fk- z@68cA*RJYD*jXk!`%9=7^mxhF4F0geOQIW9a^z-Z_=r+b`hF@sS1;Rtc0c%}w_2R* zH@n&^*pF8x#$|ANosJ(h_+thyi5`$gkXw}D<4UD}JLQ$$YDv4+D|I65$1ALHFqcPH zNWO0HlITg59QmSt@d>3Gr_}W|Vyw}9Rc=<!_YcyuJLI{VrcJvi>v(U=Le1ZkcTld^ zZ>(2OU#)05L_c+-(vF|1I3oI%EZJL@93|=FHRTC>h>qzCXnOs(efl(i(sSl_q(}FX ze8=;lI)<ZrN}ft^=Js&X2aYd^;b`W>-}UL!{AtgJDGl>)H1nlr5`2W`BNKeMj+vvO z2S~o>(~}mCo+5eH;LmwZo}@?jkbFPEDJPur1wKm0j1g$~^FIA(9g`25a=hUA7#-sW zG~-v`!*q;~(a4KFJ;&`lqfTG)e5{Vi2hGoaVDO)MPV1z;(2Pw#^PG4HM|YIGV(_0Q z_#r-hC+WZ^=oov@OC`VX>C^m|2LF}8e{Jwr4gMR0zh>~?dQLRNel+#`y62NTN4HAx zF8U1bE%{v{eUkqn!I>A39{>F@!ReoH<`{vq#!LG_Q^$Yu>C^nr2LFq}-!S-_2LG$U z|K|A=Zzr05{g%Ps_I#?+;Ab@L{~gaMKkW(4YTDlo{ttt{=Q(kk{Lx%%y>IaU7`#M7 zJMnY6gnoghzwG7t3?0{#pzBLYqRvBQvE&Yo1N$fytt9_A(A*pcSf>hco|(dqBYlIY zfwyRZ&PN15x0eLIP{))2O$%!1)2DeO&lmahX!2?7`C=V+kf4bWfirsGX><=s6Q4fK zn;Lw7&xsb~gYF|~<@qulV?UZ2IKXr4fTOXqt>?>iOwFL{OG=`F8eEXORWs#E)g}H( zz7e|Is2Q%#s*cW8$L7PUQDd#6j^5I8*+DEvGwycroLa;aX!=IrloF1{(_MY~4xXct zZk`igNRJ*Z>2B~I2Jh>6C!Y_RbNBQ7P|wlykNyT9;5mNB9yBrTaL>Eyn3_aW!vhn% zvFDsO$vb#XOAMTTPX6dsl0iP7G(W=NM;d&v!H+Wd5Q86W@Sz5;@SHUw%7w<)!#t-A z;5RgW8|8UV9n%BQt_SoTuGy^QKJ|dHN>xWc>EUOd$(?GhW0LD4Vecqhz4Xys&RxBv z*O8N-yXaod@SC~2PT>l!dMoR7B5Z9STj?dsygpTWoWb=LQ<W0AUnM<8sc38Yqj0<J z*qF6?gy!Qs<5ab;_tyGQ^~%vMn&j<eL?gDL<I&!8tfVH<%)llae2VAE9&@JBPxYLZ zPCjU68PgJ+Ra$tP1W&fC+2YfE`ZS;6IW3Krh(1U%)APf0Or%0{o>>V_PlxwUaIOf* z2h9jN+ow<SV-0?s!H+k1rNK||ytlUpJxFq*!RI76vmDa1UJ^KU+d_h_l+5+%(|n%i zv;oqiiT3k7$5;3V%~i|-gD*7ra?kl)+5?&h5jgb`1lv~l^su)6XVmdZ&kxrz`Jm~C zs|>!{^MO7+ns#`S=lHgs1nnZz+>!E<<U#e<4N7Itn!2a<wyN$J6J62~%&nL$(A79Q zfNqs{k>*0#SyrEF_Tq-o7TJdvLhnV>x&u%4Vrq1&PY)*@ni>t9UQ8{cCrY;Y^vUt+ zSn-n$eu}|Q^*q^&$0?uF41T)7&+(j=fSqW@l)yR0ALvGs^L=_+5w(nVwS3(uttv~t zrdqyGsp#kVqcTt9u+GlYlB{gnwH)rp$W5OwPWP>54VOok`4Z5tgU~+$=a>?sCrU2& z>8V{f8o9#YR~q~(gI}HCv>fuLF9)8C6O+ZS@#)k2^9H}xbMmBy(X^WD5}aCxQ_F!9 z2U<wblO)&s^l5&B!Eg1P_`rG5%_Lv+ocMr0(X_1F61=(R#NFEseuu&DH27T!uBE*A zyv#WQC)Q&p8b9Cd)2I182EW&HY$hKxy(4hW2}k4SFZuLoexJd=>Nz&!H#B~G$n)f? z9{E4wIV(-{RJ7}<ua1c#<Wcq1$CZjvDSuDxRjr<yz85mgr$)uSd{vcrosG-AtJ!NC zMc?+NDVMF398HM>rwn)nO-Y~h>C^l>27lIbu0hBLeSqY-1aIy6feGG0$J8qNGRgOS z`ZRyu;4c{bMT5WWIoCwkiKZ3&#B;6#;pjG!S3Kvsj#hy7@mj;hb&{{E75q}EYC0;r zJ8;~a2>FJ}g_=by$P?SMwco#*wcjB6jW5MiSx;O>Gx`QTO~;fPJw@`GPoL($^?bTd zkH%B4dp<+QcnHl^Sl}~tOf92{oxk(x)BN`af5Y=xJ|8r3^i9ua>lpjd)aGA3#|}6e zJKyn~83VP6cC~rWF?!3f<QuBZe<~I2K7XI?QLR25RzpHxcHgzh-ZVQN>+)VJ^{Zxm zwus*I<*1OAXG_rMNCF?GW6C{2(pd7oPoL)hG57}t|Ipz7HTXvcXG0bH()N@XypF-^ z8obotdl|gU;CmZ<AI~SM43q=S_*~E6^$p&{bLI!+gC^?i=Q-mj?G#Nr{b<ba$+zAz z>;7R^j2d~)wRgWXVB0=#3g`TJIsR0l|HF6FyV>6owL0EIQl8m2<~za{D$;C-XZ;)W ziSH}r30-FYm3i;zn5bQy>DoEsK8Hmbhq?E4t<nzAaW6?f9p~;(y1O>`zVKx_(^jS7 zZJk^7Tih+-tXiw{@)ImwCL2k)Ebb}mMHj|*`0x3puTVLc#Ga-6OXY_`OaDfu?su0v z%csZJFdJ0TO0BAKr)Bc#@k-w^UF)JnuF)HA3TqJ`WPHNiAV(<w@IEEZxmNeRu9Uau z>6j-&cruDMNR+Nrd*pqsyp5BePm7P%h^*A7iIP5&3h`N5C#zJN^}4%snP@LbAHPc2 zBd*Jhs#(s*cNWZ1J}Z@u^>TV$`W~gie8T%eSy|-X3iq8Su4fj~Yo5;dXpZ;Mu8kSY zh!@8t%HDC-Q*no=u}Be!y9MwbZ)|4OqR@WwV5Yn?inzQZeIzWby^kRDYe$D~df5}( zd+pq3SfSqO*5i5GE~CxPw4<&WUtjWxuhkFTotTXE><BoY7S?+EWjuPtCmuCD8r~;V zm~TIc455#QJ15;J$D8LCYCPf1G|XsgBQlK1wBs8;X~$+e4)sv;5q)sR-`9N1{T+Oo zuWe6`ud|pnEl`ABS>Q~%W5&my{h0f>=GUorWM-g~yf1g{jGJo?X4O4)*Q0x%cVT18 zLz(i-EQ<2DH$M~8Y3s!GnJQs;LZi^@g&$=~x2Pye=hljuVey@n?y8SB%<^0dWoFHV zl}5_W9$`;i^Kz9mPct;q7jkX*?@ZY@?~%Pe-!}pk;vek-=?|fCc2TsAY)>AkI%ij( zodllhr5(&t{m(D31r%Ee)2*NTsN5Y|ZbiWL_d@FMwoDyPEQ&hhIb~vT_`Zn3dhGL= z(#$W4($K@^sr{{1TjZKMMC5#Yn$mFnNZcx{)L+V!dTLRWI@Dp+_3uJj=4+W!h4=66 z+Id3N(%7r{vvns=FWo0FTy?oFu6Nc4n0c~#SLhi0_*h&)oE_}zcUBzN*umJW+_tx0 zQK>x-xBJ2K|Lk3?(2fOr6`S<G+qvi~Tl?ycmO-Mdyc0QDNnNC~WLu)Mpg2|y-7IvI z_h)wPmp2<FW4yC@<SyzJtaY!`o#yOmr2V+b+q7q`$h+3f4vvd==~7SFMKzJTFP9!g zLsW9D<<dQ}X7a5aGhbp<Vy}nDv^ehftJGG*E@yb#iQARTja<%K<91PvvR}pC8T(hO zHP2)3c43uXcI+;)F1Nkq8|@hbrpsp5;N2WG-B%9uwzI=FQG0WfG=rU{2t7^rZcNkf zj?|uD-*_L6k!53*vVVM5gY0&kZrM9t;dHIKIId^XaccW(h0gL>Mcv}F_g|-5`;?-v zo4A+nor<|5#O2=BJ!|YPbcAs4JK=3wZuH=qdr2J2lGiV;RbKmv$K-)Enq9Ao-!>Mm z1>8R2jz`&#&wlnywV?I#5o`3*G`eq$*KpRvqop-lnWQ=Ya?J-=<K#XWcC?Z!{H_gN z{jq6-JLAL9I@u>o$L3S_NYAlKu~{v~?Tm)^HdWmNaIL2}?kG&p2;6G7`^Lv*`rex4 zy$9Rhsd1&6=4*D>uB?n!Z(XB4OrKAeB6s91mK~#|@%jkw3d=utKcOi6x})okMT)Tb z)*M~i2;aK8YuiS;#k&=6R@K&M*Qe@kPi}frhpXCT-^guM<BOuUCMX`QQmME@I30nD z`#RROknl`i+V<kOuhNZgYvo^74%jtG&J?N>D~~IRRx({{Ypl&CV^5Ot{nT8;q-$YU zwV-@g6>jyKwTm6y_wFK5aYWPH$ilm`X+?G<%8fBRIlvv*yEdAJotf&i_u{xB4;C|0 zEzsVDTlGt~?t{H|(`#kC9gQ_YBCA^~V}FA^6PMf0=R+P#{k7bdD!r{ZeCKL8yGt@d zk)!I4&OwInl53dGcf*u2Jin6mT=7Q7N%0d6>l72`X~w`^^i|i1#}q~Hbnm{*jT^<W z-!?-1Xtn&eO6_NXT6;Pc=Gt5w_d&52xH^7jhIP}m@u<l=1FGKd?nar(MbQTGKmU>I z-{Xte((0^H@2WkcWJK$!XOBYr$n|b<#O~^?X%)xy`)tJpW}LINOU1alQJ>u$J3UGi zM`TEki^2ZlZV{H%xvjT2=F05IxqE7fXG_!~7=72p&#&z`5*Nq4Tlph#_Q|xdiXfxo zcFr|`y}B^3sG~I_I(Mhg_LpczyFs&K?)!1a>Hb^HBaiDJt~^zrpmt+?aa@I^XHU8B z@6YYeXZY5$XYDmkjPJ^(<@HtD3;XvKnwc|4cURTvwpSeMNJIs$9>blQ+{ck-6I2Rj z%S)7&Z`#eR(bM+G8eQ$Lg^4AM{n?#hYP9NAXK~B~!pKhzvZ6+P&63bE^VMB(%(v|C zNcecPHJ)%`<fW}uy}LDecdd*1+dgJJE;rts{xK{40!8O_Y8~mmaH#h~dX2E^{dBy^ zVzr`yySuul;=TKJ8yC^j`L;3hO|L!9(kytPqG39R>aV~}({mBSbtm9d&7{-0oWDob zGjSOIv%3_Ybzuc6cZ}hBlRH6~KcLgT*)#88NRGLS)#h2B%iiUm_CaxsxXHaLdf5`y zRg$HxE{;3K**)Y5D|XhZMwSzO&*KUtyw~af|J$aRMZ0V6k+PL2n7uopI;(P(MNtYo zo$n4zR|Bjqt&5{Ou^`=6ieudXOL-zS|4wswlaDKpdm~={xu&(JRdu{tubOwBaeJz{ z<A3$@nWp<GCTm}FxK;zk%DW?^$7i0xDvmp#3V8~vIx7OZU#YhLt~58}J!y}e3#8wH z=E}Ntk1Xqs-fiZ}UOa0eJNwQuSB~P?<zyA0YB{nizPWMr`aQDU<-1=e|LnnyU_95# z`hM;Tcy*t%`Q+VU%o6hZFt@dR@=h?@Q`SA(ANL-*z4swiw};;NNt82tXz*|T_?X*& zKR!=m=J!VMmAgjHeeaz8ZZ0=F_~e~i>_}{XXR}zIj96s8OUu<|ajZgB{~cM*>OJe- zSFTJSzjs=>au>(5-S%o7`&a3ARTY!v>AM%kYJ9ZcLFFtj_IFD;D~n_O(0XbsALp+4 za3?}~HFS4*7nJk;p8k%fu~#g8cF4;!#y$Lg*LI^1d1254=eB;T<bjS8Z{6~*7v3-J z`tAk#z7YPDeDY^c_kdN$h17m%C{^-GW#ZD2s!GbLZchDfZh~;eT)MNLLT)>@YP&|c z)7O4xeA`UA$95lcd*5RleQV5J4ck0D@xycLx7Ih+@JFsK_)k^0>Gf{$Uw#sfv$|^f z?GR^FCPC^WJP*nw&m1Tb2{WH_4#*+>Cz&AmGq{nB`$66xCUe*Y$H~G}|2P<0<u~+$ zDy+sJoUK|qK3kkJd*rODiDf<qpGC;YQQDa+W30k)fXU+LW67T<jziLLuDCVp=Yc1W i;$I8KWb(+hIiyb{%S{kY6cU6J1)j+_HbOK`@c#hW->kI& literal 0 HcmV?d00001 -- GitLab From b78da0228175d682f1ab9a7e59f0c6fdb04228c5 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Wed, 27 Apr 2022 19:50:09 +0200 Subject: [PATCH 43/67] re #9573 Added generated html of code coverage --- .../doc/coverage/coveragereport/class.js | 218 ++++++ .../doc/coverage/coveragereport/icon_cube.svg | 2 + .../coveragereport/icon_cube_dark.svg | 1 + .../coveragereport/icon_down-dir_active.svg | 2 + .../icon_down-dir_active_dark.svg | 1 + .../doc/coverage/coveragereport/icon_fork.svg | 2 + .../coveragereport/icon_fork_dark.svg | 1 + .../coveragereport/icon_info-circled.svg | 2 + .../coveragereport/icon_info-circled_dark.svg | 2 + .../coverage/coveragereport/icon_minus.svg | 2 + .../coveragereport/icon_minus_dark.svg | 1 + .../doc/coverage/coveragereport/icon_plus.svg | 2 + .../coveragereport/icon_plus_dark.svg | 1 + .../coveragereport/icon_search-minus.svg | 2 + .../coveragereport/icon_search-minus_dark.svg | 1 + .../coveragereport/icon_search-plus.svg | 2 + .../coveragereport/icon_search-plus_dark.svg | 1 + .../coverage/coveragereport/icon_sponsor.svg | 2 + .../doc/coverage/coveragereport/icon_star.svg | 2 + .../coveragereport/icon_star_dark.svg | 2 + .../coverage/coveragereport/icon_up-dir.svg | 2 + .../coveragereport/icon_up-dir_active.svg | 2 + .../coverage/coveragereport/icon_wrench.svg | 2 + .../coveragereport/icon_wrench_dark.svg | 1 + .../doc/coverage/coveragereport/index.htm | 197 +++++ .../doc/coverage/coveragereport/index.html | 197 +++++ .../coveragereport/ldclient.dll_ALogger.html | 301 +++++++ .../ldclient.dll_ApiClient.html | 285 +++++++ .../ldclient.dll_ConfigLoader.html | 346 ++++++++ .../ldclient.dll_ConsoleLogger.html | 174 +++++ .../ldclient.dll_DebuggerInfo.html | 168 ++++ .../ldclient.dll_DebuggerInfoParser.html | 190 +++++ .../ldclient.dll_FileLogger.html | 272 +++++++ .../ldclient.dll_FileUtils.html | 180 +++++ .../ldclient.dll_HttpClient.html | 201 +++++ .../ldclient.dll_InfoFetcher.html | 263 +++++++ .../coveragereport/ldclient.dll_Payload.html | 232 ++++++ .../ldclient.dll_ProcessDetection.html | 268 +++++++ .../ldclient.dll_ProcessUtils.html | 209 +++++ .../coveragereport/ldclient.dll_Program.html | 240 ++++++ .../ldclienttests.dll_ApiClientTests.html | 344 ++++++++ ...ienttests.dll_DebuggerInfoParserTests.html | 237 ++++++ .../ldclienttests.dll_InfoFetcherTests.html | 294 +++++++ ...clienttests.dll_ProcessDetectionTests.html | 311 ++++++++ ld_client/doc/coverage/coveragereport/main.js | 301 +++++++ .../doc/coverage/coveragereport/report.css | 736 ++++++++++++++++++ 46 files changed, 6202 insertions(+) create mode 100644 ld_client/doc/coverage/coveragereport/class.js create mode 100644 ld_client/doc/coverage/coveragereport/icon_cube.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_cube_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_fork.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_fork_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_info-circled.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_minus.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_minus_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_plus.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_plus_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-minus.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-plus.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_sponsor.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_star.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_star_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_up-dir.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_wrench.svg create mode 100644 ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg create mode 100644 ld_client/doc/coverage/coveragereport/index.htm create mode 100644 ld_client/doc/coverage/coveragereport/index.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html create mode 100644 ld_client/doc/coverage/coveragereport/main.js create mode 100644 ld_client/doc/coverage/coveragereport/report.css diff --git a/ld_client/doc/coverage/coveragereport/class.js b/ld_client/doc/coverage/coveragereport/class.js new file mode 100644 index 0000000..b7a43b2 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/class.js @@ -0,0 +1,218 @@ +/* Chartist.js 0.11.4 + * Copyright © 2019 Gion Kunz + * Free to use under either the WTFPL license or the MIT license. + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT + */ + +!function (a, b) { "function" == typeof define && define.amd ? define("Chartist", [], function () { return a.Chartist = b() }) : "object" == typeof module && module.exports ? module.exports = b() : a.Chartist = b() }(this, function () { + var a = { version: "0.11.4" }; return function (a, b) { "use strict"; var c = a.window, d = a.document; b.namespaces = { svg: "http://www.w3.org/2000/svg", xmlns: "http://www.w3.org/2000/xmlns/", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", ct: "http://gionkunz.github.com/chartist-js/ct" }, b.noop = function (a) { return a }, b.alphaNumerate = function (a) { return String.fromCharCode(97 + a % 26) }, b.extend = function (a) { var c, d, e; for (a = a || {}, c = 1; c < arguments.length; c++) { d = arguments[c]; for (var f in d) e = d[f], "object" != typeof e || null === e || e instanceof Array ? a[f] = e : a[f] = b.extend(a[f], e) } return a }, b.replaceAll = function (a, b, c) { return a.replace(new RegExp(b, "g"), c) }, b.ensureUnit = function (a, b) { return "number" == typeof a && (a += b), a }, b.quantity = function (a) { if ("string" == typeof a) { var b = /^(\d+)\s*(.*)$/g.exec(a); return { value: +b[1], unit: b[2] || void 0 } } return { value: a } }, b.querySelector = function (a) { return a instanceof Node ? a : d.querySelector(a) }, b.times = function (a) { return Array.apply(null, new Array(a)) }, b.sum = function (a, b) { return a + (b ? b : 0) }, b.mapMultiply = function (a) { return function (b) { return b * a } }, b.mapAdd = function (a) { return function (b) { return b + a } }, b.serialMap = function (a, c) { var d = [], e = Math.max.apply(null, a.map(function (a) { return a.length })); return b.times(e).forEach(function (b, e) { var f = a.map(function (a) { return a[e] }); d[e] = c.apply(null, f) }), d }, b.roundWithPrecision = function (a, c) { var d = Math.pow(10, c || b.precision); return Math.round(a * d) / d }, b.precision = 8, b.escapingMap = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, b.serialize = function (a) { return null === a || void 0 === a ? a : ("number" == typeof a ? a = "" + a : "object" == typeof a && (a = JSON.stringify({ data: a })), Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, c, b.escapingMap[c]) }, a)) }, b.deserialize = function (a) { if ("string" != typeof a) return a; a = Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, b.escapingMap[c], c) }, a); try { a = JSON.parse(a), a = void 0 !== a.data ? a.data : a } catch (c) { } return a }, b.createSvg = function (a, c, d, e) { var f; return c = c || "100%", d = d || "100%", Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function (a) { return a.getAttributeNS(b.namespaces.xmlns, "ct") }).forEach(function (b) { a.removeChild(b) }), f = new b.Svg("svg").attr({ width: c, height: d }).addClass(e), f._node.style.width = c, f._node.style.height = d, a.appendChild(f._node), f }, b.normalizeData = function (a, c, d) { var e, f = { raw: a, normalized: {} }; return f.normalized.series = b.getDataArray({ series: a.series || [] }, c, d), e = f.normalized.series.every(function (a) { return a instanceof Array }) ? Math.max.apply(null, f.normalized.series.map(function (a) { return a.length })) : f.normalized.series.length, f.normalized.labels = (a.labels || []).slice(), Array.prototype.push.apply(f.normalized.labels, b.times(Math.max(0, e - f.normalized.labels.length)).map(function () { return "" })), c && b.reverseData(f.normalized), f }, b.safeHasProperty = function (a, b) { return null !== a && "object" == typeof a && a.hasOwnProperty(b) }, b.isDataHoleValue = function (a) { return null === a || void 0 === a || "number" == typeof a && isNaN(a) }, b.reverseData = function (a) { a.labels.reverse(), a.series.reverse(); for (var b = 0; b < a.series.length; b++)"object" == typeof a.series[b] && void 0 !== a.series[b].data ? a.series[b].data.reverse() : a.series[b] instanceof Array && a.series[b].reverse() }, b.getDataArray = function (a, c, d) { function e(a) { if (b.safeHasProperty(a, "value")) return e(a.value); if (b.safeHasProperty(a, "data")) return e(a.data); if (a instanceof Array) return a.map(e); if (!b.isDataHoleValue(a)) { if (d) { var c = {}; return "string" == typeof d ? c[d] = b.getNumberOrUndefined(a) : c.y = b.getNumberOrUndefined(a), c.x = a.hasOwnProperty("x") ? b.getNumberOrUndefined(a.x) : c.x, c.y = a.hasOwnProperty("y") ? b.getNumberOrUndefined(a.y) : c.y, c } return b.getNumberOrUndefined(a) } } return a.series.map(e) }, b.normalizePadding = function (a, b) { return b = b || 0, "number" == typeof a ? { top: a, right: a, bottom: a, left: a } : { top: "number" == typeof a.top ? a.top : b, right: "number" == typeof a.right ? a.right : b, bottom: "number" == typeof a.bottom ? a.bottom : b, left: "number" == typeof a.left ? a.left : b } }, b.getMetaData = function (a, b) { var c = a.data ? a.data[b] : a[b]; return c ? c.meta : void 0 }, b.orderOfMagnitude = function (a) { return Math.floor(Math.log(Math.abs(a)) / Math.LN10) }, b.projectLength = function (a, b, c) { return b / c.range * a }, b.getAvailableHeight = function (a, c) { return Math.max((b.quantity(c.height).value || a.height()) - (c.chartPadding.top + c.chartPadding.bottom) - c.axisX.offset, 0) }, b.getHighLow = function (a, c, d) { function e(a) { if (void 0 !== a) if (a instanceof Array) for (var b = 0; b < a.length; b++)e(a[b]); else { var c = d ? +a[d] : +a; g && c > f.high && (f.high = c), h && c < f.low && (f.low = c) } } c = b.extend({}, c, d ? c["axis" + d.toUpperCase()] : {}); var f = { high: void 0 === c.high ? -Number.MAX_VALUE : +c.high, low: void 0 === c.low ? Number.MAX_VALUE : +c.low }, g = void 0 === c.high, h = void 0 === c.low; return (g || h) && e(a), (c.referenceValue || 0 === c.referenceValue) && (f.high = Math.max(c.referenceValue, f.high), f.low = Math.min(c.referenceValue, f.low)), f.high <= f.low && (0 === f.low ? f.high = 1 : f.low < 0 ? f.high = 0 : f.high > 0 ? f.low = 0 : (f.high = 1, f.low = 0)), f }, b.isNumeric = function (a) { return null !== a && isFinite(a) }, b.isFalseyButZero = function (a) { return !a && 0 !== a }, b.getNumberOrUndefined = function (a) { return b.isNumeric(a) ? +a : void 0 }, b.isMultiValue = function (a) { return "object" == typeof a && ("x" in a || "y" in a) }, b.getMultiValue = function (a, c) { return b.isMultiValue(a) ? b.getNumberOrUndefined(a[c || "y"]) : b.getNumberOrUndefined(a) }, b.rho = function (a) { function b(a, c) { return a % c === 0 ? c : b(c, a % c) } function c(a) { return a * a + 1 } if (1 === a) return a; var d, e = 2, f = 2; if (a % 2 === 0) return 2; do e = c(e) % a, f = c(c(f)) % a, d = b(Math.abs(e - f), a); while (1 === d); return d }, b.getBounds = function (a, c, d, e) { function f(a, b) { return a === (a += b) && (a *= 1 + (b > 0 ? o : -o)), a } var g, h, i, j = 0, k = { high: c.high, low: c.low }; k.valueRange = k.high - k.low, k.oom = b.orderOfMagnitude(k.valueRange), k.step = Math.pow(10, k.oom), k.min = Math.floor(k.low / k.step) * k.step, k.max = Math.ceil(k.high / k.step) * k.step, k.range = k.max - k.min, k.numberOfSteps = Math.round(k.range / k.step); var l = b.projectLength(a, k.step, k), m = l < d, n = e ? b.rho(k.range) : 0; if (e && b.projectLength(a, 1, k) >= d) k.step = 1; else if (e && n < k.step && b.projectLength(a, n, k) >= d) k.step = n; else for (; ;) { if (m && b.projectLength(a, k.step, k) <= d) k.step *= 2; else { if (m || !(b.projectLength(a, k.step / 2, k) >= d)) break; if (k.step /= 2, e && k.step % 1 !== 0) { k.step *= 2; break } } if (j++ > 1e3) throw new Error("Exceeded maximum number of iterations while optimizing scale step!") } var o = 2.221e-16; for (k.step = Math.max(k.step, o), h = k.min, i = k.max; h + k.step <= k.low;)h = f(h, k.step); for (; i - k.step >= k.high;)i = f(i, -k.step); k.min = h, k.max = i, k.range = k.max - k.min; var p = []; for (g = k.min; g <= k.max; g = f(g, k.step)) { var q = b.roundWithPrecision(g); q !== p[p.length - 1] && p.push(q) } return k.values = p, k }, b.polarToCartesian = function (a, b, c, d) { var e = (d - 90) * Math.PI / 180; return { x: a + c * Math.cos(e), y: b + c * Math.sin(e) } }, b.createChartRect = function (a, c, d) { var e = !(!c.axisX && !c.axisY), f = e ? c.axisY.offset : 0, g = e ? c.axisX.offset : 0, h = a.width() || b.quantity(c.width).value || 0, i = a.height() || b.quantity(c.height).value || 0, j = b.normalizePadding(c.chartPadding, d); h = Math.max(h, f + j.left + j.right), i = Math.max(i, g + j.top + j.bottom); var k = { padding: j, width: function () { return this.x2 - this.x1 }, height: function () { return this.y1 - this.y2 } }; return e ? ("start" === c.axisX.position ? (k.y2 = j.top + g, k.y1 = Math.max(i - j.bottom, k.y2 + 1)) : (k.y2 = j.top, k.y1 = Math.max(i - j.bottom - g, k.y2 + 1)), "start" === c.axisY.position ? (k.x1 = j.left + f, k.x2 = Math.max(h - j.right, k.x1 + 1)) : (k.x1 = j.left, k.x2 = Math.max(h - j.right - f, k.x1 + 1))) : (k.x1 = j.left, k.x2 = Math.max(h - j.right, k.x1 + 1), k.y2 = j.top, k.y1 = Math.max(i - j.bottom, k.y2 + 1)), k }, b.createGrid = function (a, c, d, e, f, g, h, i) { var j = {}; j[d.units.pos + "1"] = a, j[d.units.pos + "2"] = a, j[d.counterUnits.pos + "1"] = e, j[d.counterUnits.pos + "2"] = e + f; var k = g.elem("line", j, h.join(" ")); i.emit("draw", b.extend({ type: "grid", axis: d, index: c, group: g, element: k }, j)) }, b.createGridBackground = function (a, b, c, d) { var e = a.elem("rect", { x: b.x1, y: b.y2, width: b.width(), height: b.height() }, c, !0); d.emit("draw", { type: "gridBackground", group: a, element: e }) }, b.createLabel = function (a, c, e, f, g, h, i, j, k, l, m) { var n, o = {}; if (o[g.units.pos] = a + i[g.units.pos], o[g.counterUnits.pos] = i[g.counterUnits.pos], o[g.units.len] = c, o[g.counterUnits.len] = Math.max(0, h - 10), l) { var p = d.createElement("span"); p.className = k.join(" "), p.setAttribute("xmlns", b.namespaces.xhtml), p.innerText = f[e], p.style[g.units.len] = Math.round(o[g.units.len]) + "px", p.style[g.counterUnits.len] = Math.round(o[g.counterUnits.len]) + "px", n = j.foreignObject(p, b.extend({ style: "overflow: visible;" }, o)) } else n = j.elem("text", o, k.join(" ")).text(f[e]); m.emit("draw", b.extend({ type: "label", axis: g, index: e, group: j, element: n, text: f[e] }, o)) }, b.getSeriesOption = function (a, b, c) { if (a.name && b.series && b.series[a.name]) { var d = b.series[a.name]; return d.hasOwnProperty(c) ? d[c] : b[c] } return b[c] }, b.optionsProvider = function (a, d, e) { function f(a) { var f = h; if (h = b.extend({}, j), d) for (i = 0; i < d.length; i++) { var g = c.matchMedia(d[i][0]); g.matches && (h = b.extend(h, d[i][1])) } e && a && e.emit("optionsChanged", { previousOptions: f, currentOptions: h }) } function g() { k.forEach(function (a) { a.removeListener(f) }) } var h, i, j = b.extend({}, a), k = []; if (!c.matchMedia) throw "window.matchMedia not found! Make sure you're using a polyfill."; if (d) for (i = 0; i < d.length; i++) { var l = c.matchMedia(d[i][0]); l.addListener(f), k.push(l) } return f(), { removeMediaQueryListeners: g, getCurrentOptions: function () { return b.extend({}, h) } } }, b.splitIntoSegments = function (a, c, d) { var e = { increasingX: !1, fillHoles: !1 }; d = b.extend({}, e, d); for (var f = [], g = !0, h = 0; h < a.length; h += 2)void 0 === b.getMultiValue(c[h / 2].value) ? d.fillHoles || (g = !0) : (d.increasingX && h >= 2 && a[h] <= a[h - 2] && (g = !0), g && (f.push({ pathCoordinates: [], valueData: [] }), g = !1), f[f.length - 1].pathCoordinates.push(a[h], a[h + 1]), f[f.length - 1].valueData.push(c[h / 2])); return f } }(this || global, a), function (a, b) { "use strict"; b.Interpolation = {}, b.Interpolation.none = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e = new b.Svg.Path, f = !0, g = 0; g < c.length; g += 2) { var h = c[g], i = c[g + 1], j = d[g / 2]; void 0 !== b.getMultiValue(j.value) ? (f ? e.move(h, i, !1, j) : e.line(h, i, !1, j), f = !1) : a.fillHoles || (f = !0) } return e } }, b.Interpolation.simple = function (a) { var c = { divisor: 2, fillHoles: !1 }; a = b.extend({}, c, a); var d = 1 / Math.max(1, a.divisor); return function (c, e) { for (var f, g, h, i = new b.Svg.Path, j = 0; j < c.length; j += 2) { var k = c[j], l = c[j + 1], m = (k - f) * d, n = e[j / 2]; void 0 !== n.value ? (void 0 === h ? i.move(k, l, !1, n) : i.curve(f + m, g, k - m, l, k, l, !1, n), f = k, g = l, h = n) : a.fillHoles || (f = k = h = void 0) } return i } }, b.Interpolation.cardinal = function (a) { var c = { tension: 1, fillHoles: !1 }; a = b.extend({}, c, a); var d = Math.min(1, Math.max(0, a.tension)), e = 1 - d; return function f(c, g) { var h = b.splitIntoSegments(c, g, { fillHoles: a.fillHoles }); if (h.length) { if (h.length > 1) { var i = []; return h.forEach(function (a) { i.push(f(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(i) } if (c = h[0].pathCoordinates, g = h[0].valueData, c.length <= 4) return b.Interpolation.none()(c, g); for (var j, k = (new b.Svg.Path).move(c[0], c[1], !1, g[0]), l = 0, m = c.length; m - 2 * !j > l; l += 2) { var n = [{ x: +c[l - 2], y: +c[l - 1] }, { x: +c[l], y: +c[l + 1] }, { x: +c[l + 2], y: +c[l + 3] }, { x: +c[l + 4], y: +c[l + 5] }]; j ? l ? m - 4 === l ? n[3] = { x: +c[0], y: +c[1] } : m - 2 === l && (n[2] = { x: +c[0], y: +c[1] }, n[3] = { x: +c[2], y: +c[3] }) : n[0] = { x: +c[m - 2], y: +c[m - 1] } : m - 4 === l ? n[3] = n[2] : l || (n[0] = { x: +c[l], y: +c[l + 1] }), k.curve(d * (-n[0].x + 6 * n[1].x + n[2].x) / 6 + e * n[2].x, d * (-n[0].y + 6 * n[1].y + n[2].y) / 6 + e * n[2].y, d * (n[1].x + 6 * n[2].x - n[3].x) / 6 + e * n[2].x, d * (n[1].y + 6 * n[2].y - n[3].y) / 6 + e * n[2].y, n[2].x, n[2].y, !1, g[(l + 2) / 2]) } return k } return b.Interpolation.none()([]) } }, b.Interpolation.monotoneCubic = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function d(c, e) { var f = b.splitIntoSegments(c, e, { fillHoles: a.fillHoles, increasingX: !0 }); if (f.length) { if (f.length > 1) { var g = []; return f.forEach(function (a) { g.push(d(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(g) } if (c = f[0].pathCoordinates, e = f[0].valueData, c.length <= 4) return b.Interpolation.none()(c, e); var h, i, j = [], k = [], l = c.length / 2, m = [], n = [], o = [], p = []; for (h = 0; h < l; h++)j[h] = c[2 * h], k[h] = c[2 * h + 1]; for (h = 0; h < l - 1; h++)o[h] = k[h + 1] - k[h], p[h] = j[h + 1] - j[h], n[h] = o[h] / p[h]; for (m[0] = n[0], m[l - 1] = n[l - 2], h = 1; h < l - 1; h++)0 === n[h] || 0 === n[h - 1] || n[h - 1] > 0 != n[h] > 0 ? m[h] = 0 : (m[h] = 3 * (p[h - 1] + p[h]) / ((2 * p[h] + p[h - 1]) / n[h - 1] + (p[h] + 2 * p[h - 1]) / n[h]), isFinite(m[h]) || (m[h] = 0)); for (i = (new b.Svg.Path).move(j[0], k[0], !1, e[0]), h = 0; h < l - 1; h++)i.curve(j[h] + p[h] / 3, k[h] + m[h] * p[h] / 3, j[h + 1] - p[h] / 3, k[h + 1] - m[h + 1] * p[h] / 3, j[h + 1], k[h + 1], !1, e[h + 1]); return i } return b.Interpolation.none()([]) } }, b.Interpolation.step = function (a) { var c = { postpone: !0, fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e, f, g, h = new b.Svg.Path, i = 0; i < c.length; i += 2) { var j = c[i], k = c[i + 1], l = d[i / 2]; void 0 !== l.value ? (void 0 === g ? h.move(j, k, !1, l) : (a.postpone ? h.line(j, f, !1, g) : h.line(e, k, !1, l), h.line(j, k, !1, l)), e = j, f = k, g = l) : a.fillHoles || (e = f = g = void 0) } return h } } }(this || global, a), function (a, b) { "use strict"; b.EventEmitter = function () { function a(a, b) { d[a] = d[a] || [], d[a].push(b) } function b(a, b) { d[a] && (b ? (d[a].splice(d[a].indexOf(b), 1), 0 === d[a].length && delete d[a]) : delete d[a]) } function c(a, b) { d[a] && d[a].forEach(function (a) { a(b) }), d["*"] && d["*"].forEach(function (c) { c(a, b) }) } var d = []; return { addEventHandler: a, removeEventHandler: b, emit: c } } }(this || global, a), function (a, b) { "use strict"; function c(a) { var b = []; if (a.length) for (var c = 0; c < a.length; c++)b.push(a[c]); return b } function d(a, c) { var d = c || this.prototype || b.Class, e = Object.create(d); b.Class.cloneDefinitions(e, a); var f = function () { var a, c = e.constructor || function () { }; return a = this === b ? Object.create(e) : this, c.apply(a, Array.prototype.slice.call(arguments, 0)), a }; return f.prototype = e, f["super"] = d, f.extend = this.extend, f } function e() { var a = c(arguments), b = a[0]; return a.splice(1, a.length - 1).forEach(function (a) { Object.getOwnPropertyNames(a).forEach(function (c) { delete b[c], Object.defineProperty(b, c, Object.getOwnPropertyDescriptor(a, c)) }) }), b } b.Class = { extend: d, cloneDefinitions: e } }(this || global, a), function (a, b) { "use strict"; function c(a, c, d) { return a && (this.data = a || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.eventEmitter.emit("data", { type: "update", data: this.data })), c && (this.options = b.extend({}, d ? this.options : this.defaultOptions, c), this.initializeTimeoutId || (this.optionsProvider.removeMediaQueryListeners(), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter))), this.initializeTimeoutId || this.createChart(this.optionsProvider.getCurrentOptions()), this } function d() { return this.initializeTimeoutId ? i.clearTimeout(this.initializeTimeoutId) : (i.removeEventListener("resize", this.resizeListener), this.optionsProvider.removeMediaQueryListeners()), this } function e(a, b) { return this.eventEmitter.addEventHandler(a, b), this } function f(a, b) { return this.eventEmitter.removeEventHandler(a, b), this } function g() { i.addEventListener("resize", this.resizeListener), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter), this.eventEmitter.addEventHandler("optionsChanged", function () { this.update() }.bind(this)), this.options.plugins && this.options.plugins.forEach(function (a) { a instanceof Array ? a[0](this, a[1]) : a(this) }.bind(this)), this.eventEmitter.emit("data", { type: "initial", data: this.data }), this.createChart(this.optionsProvider.getCurrentOptions()), this.initializeTimeoutId = void 0 } function h(a, c, d, e, f) { this.container = b.querySelector(a), this.data = c || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.defaultOptions = d, this.options = e, this.responsiveOptions = f, this.eventEmitter = b.EventEmitter(), this.supportsForeignObject = b.Svg.isSupported("Extensibility"), this.supportsAnimations = b.Svg.isSupported("AnimationEventsAttribute"), this.resizeListener = function () { this.update() }.bind(this), this.container && (this.container.__chartist__ && this.container.__chartist__.detach(), this.container.__chartist__ = this), this.initializeTimeoutId = setTimeout(g.bind(this), 0) } var i = a.window; b.Base = b.Class.extend({ constructor: h, optionsProvider: void 0, container: void 0, svg: void 0, eventEmitter: void 0, createChart: function () { throw new Error("Base chart type can't be instantiated!") }, update: c, detach: d, on: e, off: f, version: b.version, supportsForeignObject: !1 }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f) { a instanceof Element ? this._node = a : (this._node = y.createElementNS(b.namespaces.svg, a), "svg" === a && this.attr({ "xmlns:ct": b.namespaces.ct })), c && this.attr(c), d && this.addClass(d), e && (f && e._node.firstChild ? e._node.insertBefore(this._node, e._node.firstChild) : e._node.appendChild(this._node)) } function d(a, c) { return "string" == typeof a ? c ? this._node.getAttributeNS(c, a) : this._node.getAttribute(a) : (Object.keys(a).forEach(function (c) { if (void 0 !== a[c]) if (c.indexOf(":") !== -1) { var d = c.split(":"); this._node.setAttributeNS(b.namespaces[d[0]], c, a[c]) } else this._node.setAttribute(c, a[c]) }.bind(this)), this) } function e(a, c, d, e) { return new b.Svg(a, c, d, this, e) } function f() { return this._node.parentNode instanceof SVGElement ? new b.Svg(this._node.parentNode) : null } function g() { for (var a = this._node; "svg" !== a.nodeName;)a = a.parentNode; return new b.Svg(a) } function h(a) { var c = this._node.querySelector(a); return c ? new b.Svg(c) : null } function i(a) { var c = this._node.querySelectorAll(a); return c.length ? new b.Svg.List(c) : null } function j() { return this._node } function k(a, c, d, e) { if ("string" == typeof a) { var f = y.createElement("div"); f.innerHTML = a, a = f.firstChild } a.setAttribute("xmlns", b.namespaces.xmlns); var g = this.elem("foreignObject", c, d, e); return g._node.appendChild(a), g } function l(a) { return this._node.appendChild(y.createTextNode(a)), this } function m() { for (; this._node.firstChild;)this._node.removeChild(this._node.firstChild); return this } function n() { return this._node.parentNode.removeChild(this._node), this.parent() } function o(a) { return this._node.parentNode.replaceChild(a._node, this._node), a } function p(a, b) { return b && this._node.firstChild ? this._node.insertBefore(a._node, this._node.firstChild) : this._node.appendChild(a._node), this } function q() { return this._node.getAttribute("class") ? this._node.getAttribute("class").trim().split(/\s+/) : [] } function r(a) { return this._node.setAttribute("class", this.classes(this._node).concat(a.trim().split(/\s+/)).filter(function (a, b, c) { return c.indexOf(a) === b }).join(" ")), this } function s(a) { var b = a.trim().split(/\s+/); return this._node.setAttribute("class", this.classes(this._node).filter(function (a) { return b.indexOf(a) === -1 }).join(" ")), this } function t() { return this._node.setAttribute("class", ""), this } function u() { return this._node.getBoundingClientRect().height } function v() { return this._node.getBoundingClientRect().width } function w(a, c, d) { return void 0 === c && (c = !0), Object.keys(a).forEach(function (e) { function f(a, c) { var f, g, h, i = {}; a.easing && (h = a.easing instanceof Array ? a.easing : b.Svg.Easing[a.easing], delete a.easing), a.begin = b.ensureUnit(a.begin, "ms"), a.dur = b.ensureUnit(a.dur, "ms"), h && (a.calcMode = "spline", a.keySplines = h.join(" "), a.keyTimes = "0;1"), c && (a.fill = "freeze", i[e] = a.from, this.attr(i), g = b.quantity(a.begin || 0).value, a.begin = "indefinite"), f = this.elem("animate", b.extend({ attributeName: e }, a)), c && setTimeout(function () { try { f._node.beginElement() } catch (b) { i[e] = a.to, this.attr(i), f.remove() } }.bind(this), g), d && f._node.addEventListener("beginEvent", function () { d.emit("animationBegin", { element: this, animate: f._node, params: a }) }.bind(this)), f._node.addEventListener("endEvent", function () { d && d.emit("animationEnd", { element: this, animate: f._node, params: a }), c && (i[e] = a.to, this.attr(i), f.remove()) }.bind(this)) } a[e] instanceof Array ? a[e].forEach(function (a) { f.bind(this)(a, !1) }.bind(this)) : f.bind(this)(a[e], c) }.bind(this)), this } function x(a) { var c = this; this.svgElements = []; for (var d = 0; d < a.length; d++)this.svgElements.push(new b.Svg(a[d])); Object.keys(b.Svg.prototype).filter(function (a) { return ["constructor", "parent", "querySelector", "querySelectorAll", "replace", "append", "classes", "height", "width"].indexOf(a) === -1 }).forEach(function (a) { c[a] = function () { var d = Array.prototype.slice.call(arguments, 0); return c.svgElements.forEach(function (c) { b.Svg.prototype[a].apply(c, d) }), c } }) } var y = a.document; b.Svg = b.Class.extend({ constructor: c, attr: d, elem: e, parent: f, root: g, querySelector: h, querySelectorAll: i, getNode: j, foreignObject: k, text: l, empty: m, remove: n, replace: o, append: p, classes: q, addClass: r, removeClass: s, removeAllClasses: t, height: u, width: v, animate: w }), b.Svg.isSupported = function (a) { return y.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#" + a, "1.1") }; var z = { easeInSine: [.47, 0, .745, .715], easeOutSine: [.39, .575, .565, 1], easeInOutSine: [.445, .05, .55, .95], easeInQuad: [.55, .085, .68, .53], easeOutQuad: [.25, .46, .45, .94], easeInOutQuad: [.455, .03, .515, .955], easeInCubic: [.55, .055, .675, .19], easeOutCubic: [.215, .61, .355, 1], easeInOutCubic: [.645, .045, .355, 1], easeInQuart: [.895, .03, .685, .22], easeOutQuart: [.165, .84, .44, 1], easeInOutQuart: [.77, 0, .175, 1], easeInQuint: [.755, .05, .855, .06], easeOutQuint: [.23, 1, .32, 1], easeInOutQuint: [.86, 0, .07, 1], easeInExpo: [.95, .05, .795, .035], easeOutExpo: [.19, 1, .22, 1], easeInOutExpo: [1, 0, 0, 1], easeInCirc: [.6, .04, .98, .335], easeOutCirc: [.075, .82, .165, 1], easeInOutCirc: [.785, .135, .15, .86], easeInBack: [.6, -.28, .735, .045], easeOutBack: [.175, .885, .32, 1.275], easeInOutBack: [.68, -.55, .265, 1.55] }; b.Svg.Easing = z, b.Svg.List = b.Class.extend({ constructor: x }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f, g) { var h = b.extend({ command: f ? a.toLowerCase() : a.toUpperCase() }, c, g ? { data: g } : {}); d.splice(e, 0, h) } function d(a, b) { a.forEach(function (c, d) { t[c.command.toLowerCase()].forEach(function (e, f) { b(c, e, d, f, a) }) }) } function e(a, c) { this.pathElements = [], this.pos = 0, this.close = a, this.options = b.extend({}, u, c) } function f(a) { return void 0 !== a ? (this.pos = Math.max(0, Math.min(this.pathElements.length, a)), this) : this.pos } function g(a) { return this.pathElements.splice(this.pos, a), this } function h(a, b, d, e) { return c("M", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function i(a, b, d, e) { return c("L", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function j(a, b, d, e, f, g, h, i) { return c("C", { x1: +a, y1: +b, x2: +d, y2: +e, x: +f, y: +g }, this.pathElements, this.pos++, h, i), this } function k(a, b, d, e, f, g, h, i, j) { return c("A", { rx: +a, ry: +b, xAr: +d, lAf: +e, sf: +f, x: +g, y: +h }, this.pathElements, this.pos++, i, j), this } function l(a) { var c = a.replace(/([A-Za-z])([0-9])/g, "$1 $2").replace(/([0-9])([A-Za-z])/g, "$1 $2").split(/[\s,]+/).reduce(function (a, b) { return b.match(/[A-Za-z]/) && a.push([]), a[a.length - 1].push(b), a }, []); "Z" === c[c.length - 1][0].toUpperCase() && c.pop(); var d = c.map(function (a) { var c = a.shift(), d = t[c.toLowerCase()]; return b.extend({ command: c }, d.reduce(function (b, c, d) { return b[c] = +a[d], b }, {})) }), e = [this.pos, 0]; return Array.prototype.push.apply(e, d), Array.prototype.splice.apply(this.pathElements, e), this.pos += d.length, this } function m() { var a = Math.pow(10, this.options.accuracy); return this.pathElements.reduce(function (b, c) { var d = t[c.command.toLowerCase()].map(function (b) { return this.options.accuracy ? Math.round(c[b] * a) / a : c[b] }.bind(this)); return b + c.command + d.join(",") }.bind(this), "") + (this.close ? "Z" : "") } function n(a, b) { return d(this.pathElements, function (c, d) { c[d] *= "x" === d[0] ? a : b }), this } function o(a, b) { return d(this.pathElements, function (c, d) { c[d] += "x" === d[0] ? a : b }), this } function p(a) { return d(this.pathElements, function (b, c, d, e, f) { var g = a(b, c, d, e, f); (g || 0 === g) && (b[c] = g) }), this } function q(a) { var c = new b.Svg.Path(a || this.close); return c.pos = this.pos, c.pathElements = this.pathElements.slice().map(function (a) { return b.extend({}, a) }), c.options = b.extend({}, this.options), c } function r(a) { var c = [new b.Svg.Path]; return this.pathElements.forEach(function (d) { d.command === a.toUpperCase() && 0 !== c[c.length - 1].pathElements.length && c.push(new b.Svg.Path), c[c.length - 1].pathElements.push(d) }), c } function s(a, c, d) { for (var e = new b.Svg.Path(c, d), f = 0; f < a.length; f++)for (var g = a[f], h = 0; h < g.pathElements.length; h++)e.pathElements.push(g.pathElements[h]); return e } var t = { m: ["x", "y"], l: ["x", "y"], c: ["x1", "y1", "x2", "y2", "x", "y"], a: ["rx", "ry", "xAr", "lAf", "sf", "x", "y"] }, u = { accuracy: 3 }; b.Svg.Path = b.Class.extend({ constructor: e, position: f, remove: g, move: h, line: i, curve: j, arc: k, scale: n, translate: o, transform: p, parse: l, stringify: m, clone: q, splitByCommand: r }), b.Svg.Path.elementDescriptions = t, b.Svg.Path.join = s }(this || global, a), function (a, b) { "use strict"; function c(a, b, c, d) { this.units = a, this.counterUnits = a === e.x ? e.y : e.x, this.chartRect = b, this.axisLength = b[a.rectEnd] - b[a.rectStart], this.gridOffset = b[a.rectOffset], this.ticks = c, this.options = d } function d(a, c, d, e, f) { var g = e["axis" + this.units.pos.toUpperCase()], h = this.ticks.map(this.projectValue.bind(this)), i = this.ticks.map(g.labelInterpolationFnc); h.forEach(function (j, k) { var l, m = { x: 0, y: 0 }; l = h[k + 1] ? h[k + 1] - j : Math.max(this.axisLength - j, 30), b.isFalseyButZero(i[k]) && "" !== i[k] || ("x" === this.units.pos ? (j = this.chartRect.x1 + j, m.x = e.axisX.labelOffset.x, "start" === e.axisX.position ? m.y = this.chartRect.padding.top + e.axisX.labelOffset.y + (d ? 5 : 20) : m.y = this.chartRect.y1 + e.axisX.labelOffset.y + (d ? 5 : 20)) : (j = this.chartRect.y1 - j, m.y = e.axisY.labelOffset.y - (d ? l : 0), "start" === e.axisY.position ? m.x = d ? this.chartRect.padding.left + e.axisY.labelOffset.x : this.chartRect.x1 - 10 : m.x = this.chartRect.x2 + e.axisY.labelOffset.x + 10), g.showGrid && b.createGrid(j, k, this, this.gridOffset, this.chartRect[this.counterUnits.len](), a, [e.classNames.grid, e.classNames[this.units.dir]], f), g.showLabel && b.createLabel(j, l, k, i, this, g.offset, m, c, [e.classNames.label, e.classNames[this.units.dir], "start" === g.position ? e.classNames[g.position] : e.classNames.end], d, f)) }.bind(this)) } var e = (a.window, a.document, { x: { pos: "x", len: "width", dir: "horizontal", rectStart: "x1", rectEnd: "x2", rectOffset: "y2" }, y: { pos: "y", len: "height", dir: "vertical", rectStart: "y2", rectEnd: "y1", rectOffset: "x1" } }); b.Axis = b.Class.extend({ constructor: c, createGridAndLabels: d, projectValue: function (a, b, c) { throw new Error("Base axis can't be instantiated!") } }), b.Axis.units = e }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.bounds = b.getBounds(d[a.rectEnd] - d[a.rectStart], f, e.scaleMinSpace || 20, e.onlyInteger), this.range = { min: this.bounds.min, max: this.bounds.max }, b.AutoScaleAxis["super"].constructor.call(this, a, d, this.bounds.values, e) } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.bounds.min) / this.bounds.range } a.window, a.document; b.AutoScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.divisor = e.divisor || 1, this.ticks = e.ticks || b.times(this.divisor).map(function (a, b) { return f.low + (f.high - f.low) / this.divisor * b }.bind(this)), this.ticks.sort(function (a, b) { return a - b }), this.range = { min: f.low, max: f.high }, b.FixedScaleAxis["super"].constructor.call(this, a, d, this.ticks, e), this.stepLength = this.axisLength / this.divisor } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.range.min) / (this.range.max - this.range.min) } a.window, a.document; b.FixedScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { b.StepAxis["super"].constructor.call(this, a, d, e.ticks, e); var f = Math.max(1, e.ticks.length - (e.stretch ? 1 : 0)); this.stepLength = this.axisLength / f } function d(a, b) { return this.stepLength * b } a.window, a.document; b.StepAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a) { var c = b.normalizeData(this.data, a.reverseData, !0); this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart); var d, f, g = this.svg.elem("g").addClass(a.classNames.gridGroup), h = this.svg.elem("g"), i = this.svg.elem("g").addClass(a.classNames.labelGroup), j = b.createChartRect(this.svg, a, e.padding); d = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, j, b.extend({}, a.axisX, { ticks: c.normalized.labels, stretch: a.fullWidth })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, j, a.axisX), f = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, j, b.extend({}, a.axisY, { high: b.isNumeric(a.high) ? a.high : a.axisY.high, low: b.isNumeric(a.low) ? a.low : a.axisY.low })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, j, a.axisY), d.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), f.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(g, j, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (e, g) { var i = h.elem("g"); i.attr({ "ct:series-name": e.name, "ct:meta": b.serialize(e.meta) }), i.addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(g)].join(" ")); var k = [], l = []; c.normalized.series[g].forEach(function (a, h) { var i = { x: j.x1 + d.projectValue(a, h, c.normalized.series[g]), y: j.y1 - f.projectValue(a, h, c.normalized.series[g]) }; k.push(i.x, i.y), l.push({ value: a, valueIndex: h, meta: b.getMetaData(e, h) }) }.bind(this)); var m = { lineSmooth: b.getSeriesOption(e, a, "lineSmooth"), showPoint: b.getSeriesOption(e, a, "showPoint"), showLine: b.getSeriesOption(e, a, "showLine"), showArea: b.getSeriesOption(e, a, "showArea"), areaBase: b.getSeriesOption(e, a, "areaBase") }, n = "function" == typeof m.lineSmooth ? m.lineSmooth : m.lineSmooth ? b.Interpolation.monotoneCubic() : b.Interpolation.none(), o = n(k, l); if (m.showPoint && o.pathElements.forEach(function (c) { var h = i.elem("line", { x1: c.x, y1: c.y, x2: c.x + .01, y2: c.y }, a.classNames.point).attr({ "ct:value": [c.data.value.x, c.data.value.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(c.data.meta) }); this.eventEmitter.emit("draw", { type: "point", value: c.data.value, index: c.data.valueIndex, meta: c.data.meta, series: e, seriesIndex: g, axisX: d, axisY: f, group: i, element: h, x: c.x, y: c.y }) }.bind(this)), m.showLine) { var p = i.elem("path", { d: o.stringify() }, a.classNames.line, !0); this.eventEmitter.emit("draw", { type: "line", values: c.normalized.series[g], path: o.clone(), chartRect: j, index: g, series: e, seriesIndex: g, seriesMeta: e.meta, axisX: d, axisY: f, group: i, element: p }) } if (m.showArea && f.range) { var q = Math.max(Math.min(m.areaBase, f.range.max), f.range.min), r = j.y1 - f.projectValue(q); o.splitByCommand("M").filter(function (a) { return a.pathElements.length > 1 }).map(function (a) { var b = a.pathElements[0], c = a.pathElements[a.pathElements.length - 1]; return a.clone(!0).position(0).remove(1).move(b.x, r).line(b.x, b.y).position(a.pathElements.length + 1).line(c.x, r) }).forEach(function (b) { var h = i.elem("path", { d: b.stringify() }, a.classNames.area, !0); this.eventEmitter.emit("draw", { type: "area", values: c.normalized.series[g], path: b.clone(), series: e, seriesIndex: g, axisX: d, axisY: f, chartRect: j, index: g, group: i, element: h }) }.bind(this)) } }.bind(this)), this.eventEmitter.emit("created", { bounds: f.bounds, chartRect: j, axisX: d, axisY: f, svg: this.svg, options: a }) } function d(a, c, d, f) { b.Line["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, showLine: !0, showPoint: !0, showArea: !1, areaBase: 0, lineSmooth: !0, showGridBackground: !1, low: void 0, high: void 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, fullWidth: !1, reverseData: !1, classNames: { chart: "ct-chart-line", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", line: "ct-line", point: "ct-point", area: "ct-area", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Line = b.Base.extend({ constructor: d, createChart: c }) }(this || global, a), function (a, b) { + "use strict"; function c(a) { + var c, d; a.distributeSeries ? (c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), c.normalized.series = c.normalized.series.map(function (a) { return [a] })) : c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart + (a.horizontalBars ? " " + a.classNames.horizontalBars : "")); var f = this.svg.elem("g").addClass(a.classNames.gridGroup), g = this.svg.elem("g"), h = this.svg.elem("g").addClass(a.classNames.labelGroup); + if (a.stackBars && 0 !== c.normalized.series.length) { var i = b.serialMap(c.normalized.series, function () { return Array.prototype.slice.call(arguments).map(function (a) { return a }).reduce(function (a, b) { return { x: a.x + (b && b.x) || 0, y: a.y + (b && b.y) || 0 } }, { x: 0, y: 0 }) }); d = b.getHighLow([i], a, a.horizontalBars ? "x" : "y") } else d = b.getHighLow(c.normalized.series, a, a.horizontalBars ? "x" : "y"); d.high = +a.high || (0 === a.high ? 0 : d.high), d.low = +a.low || (0 === a.low ? 0 : d.low); var j, k, l, m, n, o = b.createChartRect(this.svg, a, e.padding); k = a.distributeSeries && a.stackBars ? c.normalized.labels.slice(0, 1) : c.normalized.labels, a.horizontalBars ? (j = m = void 0 === a.axisX.type ? new b.AutoScaleAxis(b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })), l = n = void 0 === a.axisY.type ? new b.StepAxis(b.Axis.units.y, c.normalized.series, o, { ticks: k }) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, a.axisY)) : (l = m = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, o, { ticks: k }) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, a.axisX), j = n = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 }))); var p = a.horizontalBars ? o.x1 + j.projectValue(0) : o.y1 - j.projectValue(0), q = []; l.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), j.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(f, o, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (d, e) { var f, h, i = e - (c.raw.series.length - 1) / 2; f = a.distributeSeries && !a.stackBars ? l.axisLength / c.normalized.series.length / 2 : a.distributeSeries && a.stackBars ? l.axisLength / 2 : l.axisLength / c.normalized.series[e].length / 2, h = g.elem("g"), h.attr({ "ct:series-name": d.name, "ct:meta": b.serialize(d.meta) }), h.addClass([a.classNames.series, d.className || a.classNames.series + "-" + b.alphaNumerate(e)].join(" ")), c.normalized.series[e].forEach(function (g, k) { var r, s, t, u; if (u = a.distributeSeries && !a.stackBars ? e : a.distributeSeries && a.stackBars ? 0 : k, r = a.horizontalBars ? { x: o.x1 + j.projectValue(g && g.x ? g.x : 0, k, c.normalized.series[e]), y: o.y1 - l.projectValue(g && g.y ? g.y : 0, u, c.normalized.series[e]) } : { x: o.x1 + l.projectValue(g && g.x ? g.x : 0, u, c.normalized.series[e]), y: o.y1 - j.projectValue(g && g.y ? g.y : 0, k, c.normalized.series[e]) }, l instanceof b.StepAxis && (l.options.stretch || (r[l.units.pos] += f * (a.horizontalBars ? -1 : 1)), r[l.units.pos] += a.stackBars || a.distributeSeries ? 0 : i * a.seriesBarDistance * (a.horizontalBars ? -1 : 1)), t = q[k] || p, q[k] = t - (p - r[l.counterUnits.pos]), void 0 !== g) { var v = {}; v[l.units.pos + "1"] = r[l.units.pos], v[l.units.pos + "2"] = r[l.units.pos], !a.stackBars || "accumulate" !== a.stackMode && a.stackMode ? (v[l.counterUnits.pos + "1"] = p, v[l.counterUnits.pos + "2"] = r[l.counterUnits.pos]) : (v[l.counterUnits.pos + "1"] = t, v[l.counterUnits.pos + "2"] = q[k]), v.x1 = Math.min(Math.max(v.x1, o.x1), o.x2), v.x2 = Math.min(Math.max(v.x2, o.x1), o.x2), v.y1 = Math.min(Math.max(v.y1, o.y2), o.y1), v.y2 = Math.min(Math.max(v.y2, o.y2), o.y1); var w = b.getMetaData(d, k); s = h.elem("line", v, a.classNames.bar).attr({ "ct:value": [g.x, g.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(w) }), this.eventEmitter.emit("draw", b.extend({ type: "bar", value: g, index: k, meta: w, series: d, seriesIndex: e, axisX: m, axisY: n, chartRect: o, group: h, element: s }, v)) } }.bind(this)) }.bind(this)), this.eventEmitter.emit("created", { bounds: j.bounds, chartRect: o, axisX: m, axisY: n, svg: this.svg, options: a }) + } function d(a, c, d, f) { b.Bar["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 30, onlyInteger: !1 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, high: void 0, low: void 0, referenceValue: 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, seriesBarDistance: 15, stackBars: !1, stackMode: "accumulate", horizontalBars: !1, distributeSeries: !1, reverseData: !1, showGridBackground: !1, classNames: { chart: "ct-chart-bar", horizontalBars: "ct-horizontal-bars", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", bar: "ct-bar", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Bar = b.Base.extend({ constructor: d, createChart: c }) + }(this || global, a), function (a, b) { "use strict"; function c(a, b, c) { var d = b.x > a.x; return d && "explode" === c || !d && "implode" === c ? "start" : d && "implode" === c || !d && "explode" === c ? "end" : "middle" } function d(a) { var d, e, g, h, i, j = b.normalizeData(this.data), k = [], l = a.startAngle; this.svg = b.createSvg(this.container, a.width, a.height, a.donut ? a.classNames.chartDonut : a.classNames.chartPie), e = b.createChartRect(this.svg, a, f.padding), g = Math.min(e.width() / 2, e.height() / 2), i = a.total || j.normalized.series.reduce(function (a, b) { return a + b }, 0); var m = b.quantity(a.donutWidth); "%" === m.unit && (m.value *= g / 100), g -= a.donut && !a.donutSolid ? m.value / 2 : 0, h = "outside" === a.labelPosition || a.donut && !a.donutSolid ? g : "center" === a.labelPosition ? 0 : a.donutSolid ? g - m.value / 2 : g / 2, h += a.labelOffset; var n = { x: e.x1 + e.width() / 2, y: e.y2 + e.height() / 2 }, o = 1 === j.raw.series.filter(function (a) { return a.hasOwnProperty("value") ? 0 !== a.value : 0 !== a }).length; j.raw.series.forEach(function (a, b) { k[b] = this.svg.elem("g", null, null) }.bind(this)), a.showLabel && (d = this.svg.elem("g", null, null)), j.raw.series.forEach(function (e, f) { if (0 !== j.normalized.series[f] || !a.ignoreEmptyValues) { k[f].attr({ "ct:series-name": e.name }), k[f].addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(f)].join(" ")); var p = i > 0 ? l + j.normalized.series[f] / i * 360 : 0, q = Math.max(0, l - (0 === f || o ? 0 : .2)); p - q >= 359.99 && (p = q + 359.99); var r, s, t, u = b.polarToCartesian(n.x, n.y, g, q), v = b.polarToCartesian(n.x, n.y, g, p), w = new b.Svg.Path(!a.donut || a.donutSolid).move(v.x, v.y).arc(g, g, 0, p - l > 180, 0, u.x, u.y); a.donut ? a.donutSolid && (t = g - m.value, r = b.polarToCartesian(n.x, n.y, t, l - (0 === f || o ? 0 : .2)), s = b.polarToCartesian(n.x, n.y, t, p), w.line(r.x, r.y), w.arc(t, t, 0, p - l > 180, 1, s.x, s.y)) : w.line(n.x, n.y); var x = a.classNames.slicePie; a.donut && (x = a.classNames.sliceDonut, a.donutSolid && (x = a.classNames.sliceDonutSolid)); var y = k[f].elem("path", { d: w.stringify() }, x); if (y.attr({ "ct:value": j.normalized.series[f], "ct:meta": b.serialize(e.meta) }), a.donut && !a.donutSolid && (y._node.style.strokeWidth = m.value + "px"), this.eventEmitter.emit("draw", { type: "slice", value: j.normalized.series[f], totalDataSum: i, index: f, meta: e.meta, series: e, group: k[f], element: y, path: w.clone(), center: n, radius: g, startAngle: l, endAngle: p }), a.showLabel) { var z; z = 1 === j.raw.series.length ? { x: n.x, y: n.y } : b.polarToCartesian(n.x, n.y, h, l + (p - l) / 2); var A; A = j.normalized.labels && !b.isFalseyButZero(j.normalized.labels[f]) ? j.normalized.labels[f] : j.normalized.series[f]; var B = a.labelInterpolationFnc(A, f); if (B || 0 === B) { var C = d.elem("text", { dx: z.x, dy: z.y, "text-anchor": c(n, z, a.labelDirection) }, a.classNames.label).text("" + B); this.eventEmitter.emit("draw", { type: "label", index: f, group: d, element: C, text: "" + B, x: z.x, y: z.y }) } } l = p } }.bind(this)), this.eventEmitter.emit("created", { chartRect: e, svg: this.svg, options: a }) } function e(a, c, d, e) { b.Pie["super"].constructor.call(this, a, c, f, b.extend({}, f, d), e) } var f = (a.window, a.document, { width: void 0, height: void 0, chartPadding: 5, classNames: { chartPie: "ct-chart-pie", chartDonut: "ct-chart-donut", series: "ct-series", slicePie: "ct-slice-pie", sliceDonut: "ct-slice-donut", sliceDonutSolid: "ct-slice-donut-solid", label: "ct-label" }, startAngle: 0, total: void 0, donut: !1, donutSolid: !1, donutWidth: 60, showLabel: !0, labelOffset: 0, labelPosition: "inside", labelInterpolationFnc: b.noop, labelDirection: "neutral", reverseData: !1, ignoreEmptyValues: !1 }); b.Pie = b.Base.extend({ constructor: e, createChart: d, determineAnchorPosition: c }) }(this || global, a), a +}); +//# sourceMappingURL=chartist.min.js.map + +var i, l, selectedLine = null; + +/* Navigate to hash without browser history entry */ +var navigateToHash = function () { + if (window.history !== undefined && window.history.replaceState !== undefined) { + window.history.replaceState(undefined, undefined, this.getAttribute("href")); + } +}; + +var hashLinks = document.getElementsByClassName('navigatetohash'); +for (i = 0, l = hashLinks.length; i < l; i++) { + hashLinks[i].addEventListener('click', navigateToHash); +} + +/* Switch test method */ +var switchTestMethod = function () { + var method = this.getAttribute("value"); + console.log("Selected test method: " + method); + + var lines, i, l, coverageData, lineAnalysis, cells; + + lines = document.querySelectorAll('.lineAnalysis tr'); + + for (i = 1, l = lines.length; i < l; i++) { + coverageData = JSON.parse(lines[i].getAttribute('data-coverage').replace(/'/g, '"')); + lineAnalysis = coverageData[method]; + cells = lines[i].querySelectorAll('td'); + if (lineAnalysis === undefined) { + lineAnalysis = coverageData.AllTestMethods; + if (lineAnalysis.LVS !== 'gray') { + cells[0].setAttribute('class', 'red'); + cells[1].innerText = cells[1].textContent = '0'; + cells[4].setAttribute('class', 'lightred'); + } + } else { + cells[0].setAttribute('class', lineAnalysis.LVS); + cells[1].innerText = cells[1].textContent = lineAnalysis.VC; + cells[4].setAttribute('class', 'light' + lineAnalysis.LVS); + } + } +}; + +var testMethods = document.getElementsByClassName('switchtestmethod'); +for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].addEventListener('change', switchTestMethod); +} + +/* Highlight test method by line */ +var toggleLine = function () { + if (selectedLine === this) { + selectedLine = null; + } else { + selectedLine = null; + unhighlightTestMethods(); + highlightTestMethods.call(this); + selectedLine = this; + } + +}; +var highlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var lineAnalysis; + var coverageData = JSON.parse(this.getAttribute('data-coverage').replace(/'/g, '"')); + var testMethods = document.getElementsByClassName('testmethod'); + + for (i = 0, l = testMethods.length; i < l; i++) { + lineAnalysis = coverageData[testMethods[i].id]; + if (lineAnalysis === undefined) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } else { + testMethods[i].className += ' light' + lineAnalysis.LVS; + } + } +}; +var unhighlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var testMethods = document.getElementsByClassName('testmethod'); + for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } +}; +var coverableLines = document.getElementsByClassName('coverableline'); +for (i = 0, l = coverableLines.length; i < l; i++) { + coverableLines[i].addEventListener('click', toggleLine); + coverableLines[i].addEventListener('mouseenter', highlightTestMethods); + coverableLines[i].addEventListener('mouseleave', unhighlightTestMethods); +} + +/* History charts */ +var renderChart = function (chart) { + // Remove current children (e.g. PNG placeholder) + while (chart.firstChild) { + chart.firstChild.remove(); + } + + var chartData = window[chart.getAttribute('data-data')]; + var options = { + axisY: { + type: undefined, + onlyInteger: true + }, + lineSmooth: false, + low: 0, + high: 100, + scaleMinSpace: 20, + onlyInteger: true, + fullWidth: true + }; + var lineChart = new Chartist.Line(chart, { + labels: [], + series: chartData.series + }, options); + + /* Zoom */ + var zoomButtonDiv = document.createElement("div"); + zoomButtonDiv.className = "toggleZoom"; + var zoomButtonLink = document.createElement("a"); + zoomButtonLink.setAttribute("href", ""); + var zoomButtonText = document.createElement("i"); + zoomButtonText.className = "icon-search-plus"; + + zoomButtonLink.appendChild(zoomButtonText); + zoomButtonDiv.appendChild(zoomButtonLink); + + chart.appendChild(zoomButtonDiv); + + zoomButtonDiv.addEventListener('click', function (event) { + event.preventDefault(); + + if (options.axisY.type === undefined) { + options.axisY.type = Chartist.AutoScaleAxis; + zoomButtonText.className = "icon-search-minus"; + } else { + options.axisY.type = undefined; + zoomButtonText.className = "icon-search-plus"; + } + + lineChart.update(null, options); + }); + + var tooltip = document.createElement("div"); + tooltip.className = "tooltip"; + + chart.appendChild(tooltip); + + /* Tooltips */ + var showToolTip = function () { + var index = this.getAttribute('ct:meta'); + + tooltip.innerHTML = chartData.tooltips[index]; + tooltip.style.display = 'block'; + }; + + var moveToolTip = function (event) { + var box = chart.getBoundingClientRect(); + var left = event.pageX - box.left - window.pageXOffset; + var top = event.pageY - box.top - window.pageYOffset; + + left = left + 20; + top = top - tooltip.offsetHeight / 2; + + if (left + tooltip.offsetWidth > box.width) { + left -= tooltip.offsetWidth + 40; + } + + if (top < 0) { + top = 0; + } + + if (top + tooltip.offsetHeight > box.height) { + top = box.height - tooltip.offsetHeight; + } + + tooltip.style.left = left + 'px'; + tooltip.style.top = top + 'px'; + }; + + var hideToolTip = function () { + tooltip.style.display = 'none'; + }; + chart.addEventListener('mousemove', moveToolTip); + + lineChart.on('created', function () { + var chartPoints = chart.getElementsByClassName('ct-point'); + for (i = 0, l = chartPoints.length; i < l; i++) { + chartPoints[i].addEventListener('mousemove', showToolTip); + chartPoints[i].addEventListener('mouseout', hideToolTip); + } + }); +}; + +var charts = document.getElementsByClassName('historychart'); +for (i = 0, l = charts.length; i < l; i++) { + renderChart(charts[i]); +} \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_cube.svg b/ld_client/doc/coverage/coveragereport/icon_cube.svg new file mode 100644 index 0000000..3302443 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_cube.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M896 1629l640-349v-636l-640 233v752zm-64-865l698-254-698-254-698 254zm832-252v768q0 35-18 65t-49 47l-704 384q-28 16-61 16t-61-16l-704-384q-31-17-49-47t-18-65v-768q0-40 23-73t61-47l704-256q22-8 44-8t44 8l704 256q38 14 61 47t23 73z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_cube_dark.svg b/ld_client/doc/coverage/coveragereport/icon_cube_dark.svg new file mode 100644 index 0000000..3e7f0fa --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_cube_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M896 1629l640-349v-636l-640 233v752zm-64-865l698-254-698-254-698 254zm832-252v768q0 35-18 65t-49 47l-704 384q-28 16-61 16t-61-16l-704-384q-31-17-49-47t-18-65v-768q0-40 23-73t61-47l704-256q22-8 44-8t44 8l704 256q38 14 61 47t23 73z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg b/ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg new file mode 100644 index 0000000..d11cf04 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg b/ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg new file mode 100644 index 0000000..fa34aeb --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_fork.svg b/ld_client/doc/coverage/coveragereport/icon_fork.svg new file mode 100644 index 0000000..f0148b3 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_fork.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><rect width="1792" height="1792" style="fill:#fff" /><path d="M672 1472q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm0-1152q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm640 128q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm96 0q0 52-26 96.5t-70 69.5q-2 287-226 414-67 38-203 81-128 40-169.5 71t-41.5 100v26q44 25 70 69.5t26 96.5q0 80-56 136t-136 56-136-56-56-136q0-52 26-96.5t70-69.5v-820q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136q0 52-26 96.5t-70 69.5v497q54-26 154-57 55-17 87.5-29.5t70.5-31 59-39.5 40.5-51 28-69.5 8.5-91.5q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_fork_dark.svg b/ld_client/doc/coverage/coveragereport/icon_fork_dark.svg new file mode 100644 index 0000000..11930c9 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_fork_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M672 1472q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm0-1152q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm640 128q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm96 0q0 52-26 96.5t-70 69.5q-2 287-226 414-67 38-203 81-128 40-169.5 71t-41.5 100v26q44 25 70 69.5t26 96.5q0 80-56 136t-136 56-136-56-56-136q0-52 26-96.5t70-69.5v-820q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136q0 52-26 96.5t-70 69.5v497q54-26 154-57 55-17 87.5-29.5t70.5-31 59-39.5 40.5-51 28-69.5 8.5-91.5q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_info-circled.svg b/ld_client/doc/coverage/coveragereport/icon_info-circled.svg new file mode 100644 index 0000000..252166b --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_info-circled.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><circle cx="896" cy="896" r="750" fill="#fff" /><path fill="#28A5FF" d="M1152 1376v-160q0-14-9-23t-23-9h-96v-512q0-14-9-23t-23-9h-320q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23zm-128-896v-160q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23zm640 416q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg b/ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg new file mode 100644 index 0000000..252166b --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><circle cx="896" cy="896" r="750" fill="#fff" /><path fill="#28A5FF" d="M1152 1376v-160q0-14-9-23t-23-9h-96v-512q0-14-9-23t-23-9h-320q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23zm-128-896v-160q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23zm640 416q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_minus.svg b/ld_client/doc/coverage/coveragereport/icon_minus.svg new file mode 100644 index 0000000..3c30c36 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_minus.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#c00" d="M1600 736v192q0 40-28 68t-68 28h-1216q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h1216q40 0 68 28t28 68z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_minus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_minus_dark.svg new file mode 100644 index 0000000..2516b6f --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_minus_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1600 736v192q0 40-28 68t-68 28h-1216q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h1216q40 0 68 28t28 68z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_plus.svg b/ld_client/doc/coverage/coveragereport/icon_plus.svg new file mode 100644 index 0000000..7932723 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_plus.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1600 736v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_plus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_plus_dark.svg new file mode 100644 index 0000000..6ed4edd --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_plus_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1600 736v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_search-minus.svg b/ld_client/doc/coverage/coveragereport/icon_search-minus.svg new file mode 100644 index 0000000..c174eb5 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_search-minus.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#6f6f6f" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-576q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h576q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg new file mode 100644 index 0000000..9caaffb --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-576q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h576q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_search-plus.svg b/ld_client/doc/coverage/coveragereport/icon_search-plus.svg new file mode 100644 index 0000000..04b24ec --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_search-plus.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#6f6f6f" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-224v224q0 13-9.5 22.5t-22.5 9.5h-64q-13 0-22.5-9.5t-9.5-22.5v-224h-224q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h224v-224q0-13 9.5-22.5t22.5-9.5h64q13 0 22.5 9.5t9.5 22.5v224h224q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg new file mode 100644 index 0000000..5324194 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-224v224q0 13-9.5 22.5t-22.5 9.5h-64q-13 0-22.5-9.5t-9.5-22.5v-224h-224q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h224v-224q0-13 9.5-22.5t22.5-9.5h64q13 0 22.5 9.5t9.5 22.5v224h224q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_sponsor.svg b/ld_client/doc/coverage/coveragereport/icon_sponsor.svg new file mode 100644 index 0000000..bf6d959 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_sponsor.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M896 1664q-26 0-44-18l-624-602q-10-8-27.5-26t-55.5-65.5-68-97.5-53.5-121-23.5-138q0-220 127-344t351-124q62 0 126.5 21.5t120 58 95.5 68.5 76 68q36-36 76-68t95.5-68.5 120-58 126.5-21.5q224 0 351 124t127 344q0 221-229 450l-623 600q-18 18-44 18z" fill="#ea4aaa"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_star.svg b/ld_client/doc/coverage/coveragereport/icon_star.svg new file mode 100644 index 0000000..b23c54e --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_star.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="#000"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_star_dark.svg b/ld_client/doc/coverage/coveragereport/icon_star_dark.svg new file mode 100644 index 0000000..49c0d03 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_star_dark.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="#fff"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_up-dir.svg b/ld_client/doc/coverage/coveragereport/icon_up-dir.svg new file mode 100644 index 0000000..567c11f --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_up-dir.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#c00" d="M1408 1216q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg b/ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg new file mode 100644 index 0000000..bb22554 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#c00" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_wrench.svg b/ld_client/doc/coverage/coveragereport/icon_wrench.svg new file mode 100644 index 0000000..b6aa318 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_wrench.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M448 1472q0-26-19-45t-45-19-45 19-19 45 19 45 45 19 45-19 19-45zm644-420l-682 682q-37 37-90 37-52 0-91-37l-106-108q-38-36-38-90 0-53 38-91l681-681q39 98 114.5 173.5t173.5 114.5zm634-435q0 39-23 106-47 134-164.5 217.5t-258.5 83.5q-185 0-316.5-131.5t-131.5-316.5 131.5-316.5 316.5-131.5q58 0 121.5 16.5t107.5 46.5q16 11 16 28t-16 28l-293 169v224l193 107q5-3 79-48.5t135.5-81 70.5-35.5q15 0 23.5 10t8.5 25z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg b/ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg new file mode 100644 index 0000000..5c77a9c --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BDBDBF" d="M448 1472q0-26-19-45t-45-19-45 19-19 45 19 45 45 19 45-19 19-45zm644-420l-682 682q-37 37-90 37-52 0-91-37l-106-108q-38-36-38-90 0-53 38-91l681-681q39 98 114.5 173.5t173.5 114.5zm634-435q0 39-23 106-47 134-164.5 217.5t-258.5 83.5q-185 0-316.5-131.5t-131.5-316.5 131.5-316.5 316.5-131.5q58 0 121.5 16.5t107.5 46.5q16 11 16 28t-16 28l-293 169v224l193 107q5-3 79-48.5t135.5-81 70.5-35.5q15 0 23.5 10t8.5 25z"/></svg> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/index.htm b/ld_client/doc/coverage/coveragereport/index.htm new file mode 100644 index 0000000..96bf9a8 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/index.htm @@ -0,0 +1,197 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>Summary - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1>Summary<a class="button" href="https://github.com/danielpalme/ReportGenerator" title="Star on GitHub"><i class="icon-star"></i>Star</a><a class="button" href="https://github.com/sponsors/danielpalme" title="Become a sponsor"><i class="icon-sponsor"></i>Sponsor</a></h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Parser:</th> +<td class="limit-width " title="VisualStudio">VisualStudio</td> +</tr> +<tr> +<th>Assemblies:</th> +<td class="limit-width right" title="2">2</td> +</tr> +<tr> +<th>Classes:</th> +<td class="limit-width right" title="18">18</td> +</tr> +<tr> +<th>Files:</th> +<td class="limit-width right" title="18">18</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar20">79%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="583">583</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="150">150</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="733">733</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="1336">1336</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="583 of 733">79.5%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="Total">Total</td><td>1308</td><td>275</td></tr> +</tbody> +</table> +</div> +<risk-hotspots> +</risk-hotspots> +<h1>Coverage</h1> +<coverage-info> +<div class="table-responsive"> +<table class="overview table-fixed stripped"> +<colgroup> +<col class="column-min-200" /> +<col class="column90" /> +<col class="column105" /> +<col class="column100" /> +<col class="column70" /> +<col class="column60" /> +<col class="column112" /> +</colgroup> +<thead> +<tr class="header"><th></th><th colspan="6" class="center">Line coverage</th></tr> +<tr><th>Name</th><th class="right">Covered</th><th class="right">Uncovered</th><th class="right">Coverable</th><th class="right">Total</th><th class="center" colspan="2">Percentage</th></tr></thead> +<tbody> +<tr><th>ldclient.dll</th><th class="right">364</th><th class="right">150</th><th class="right">514</th><th class="right">854</th><th title="LineCoverage: 364/514" class="right">70.8%</th><th><table class="coverage"><tr><td class="green covered71"> </td><td class="red covered29"> </td></tr></table></th></tr> +<tr><td><a href="ldclient.dll_DebuggerInfoParser.html">LDClient.detection.DebuggerInfoParser</a></td><td class="right">7</td><td class="right">0</td><td class="right">7</td><td class="right">21</td><td title="LineCoverage: 7/7" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_InfoFetcher.html">LDClient.detection.InfoFetcher</a></td><td class="right">52</td><td class="right">0</td><td class="right">52</td><td class="right">86</td><td title="LineCoverage: 52/52" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ProcessDetection.html">LDClient.detection.ProcessDetection</a></td><td class="right">62</td><td class="right">0</td><td class="right">62</td><td class="right">91</td><td title="LineCoverage: 62/62" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ProcessUtils.html">LDClient.detection.ProcessUtils</a></td><td class="right">0</td><td class="right">20</td><td class="right">20</td><td class="right">40</td><td title="LineCoverage: 0/20" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ApiClient.html">LDClient.network.ApiClient</a></td><td class="right">75</td><td class="right">0</td><td class="right">75</td><td class="right">108</td><td title="LineCoverage: 75/75" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_DebuggerInfo.html">LDClient.network.data.DebuggerInfo</a></td><td class="right">1</td><td class="right">0</td><td class="right">1</td><td class="right">9</td><td title="LineCoverage: 1/1" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_Payload.html">LDClient.network.data.Payload</a></td><td class="right">17</td><td class="right">3</td><td class="right">20</td><td class="right">49</td><td title="LineCoverage: 17/20" class="right">85%</td><td><table class="coverage"><tr><td class="green covered85"> </td><td class="red covered15"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_HttpClient.html">LDClient.network.HttpClient</a></td><td class="right">4</td><td class="right">7</td><td class="right">11</td><td class="right">32</td><td title="LineCoverage: 4/11" class="right">36.3%</td><td><table class="coverage"><tr><td class="green covered36"> </td><td class="red covered64"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_Program.html">LDClient.Program</a></td><td class="right">11</td><td class="right">32</td><td class="right">43</td><td class="right">67</td><td title="LineCoverage: 11/43" class="right">25.5%</td><td><table class="coverage"><tr><td class="green covered26"> </td><td class="red covered74"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ConfigLoader.html">LDClient.utils.ConfigLoader</a></td><td class="right">74</td><td class="right">12</td><td class="right">86</td><td class="right">127</td><td title="LineCoverage: 74/86" class="right">86%</td><td><table class="coverage"><tr><td class="green covered86"> </td><td class="red covered14"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_FileUtils.html">LDClient.utils.FileUtils</a></td><td class="right">0</td><td class="right">3</td><td class="right">3</td><td class="right">13</td><td title="LineCoverage: 0/3" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ALogger.html">LDClient.utils.loggers.ALogger</a></td><td class="right">58</td><td class="right">14</td><td class="right">72</td><td class="right">109</td><td title="LineCoverage: 58/72" class="right">80.5%</td><td><table class="coverage"><tr><td class="green covered80"> </td><td class="red covered20"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ConsoleLogger.html">LDClient.utils.loggers.ConsoleLogger</a></td><td class="right">3</td><td class="right">0</td><td class="right">3</td><td class="right">7</td><td title="LineCoverage: 3/3" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_FileLogger.html">LDClient.utils.loggers.FileLogger</a></td><td class="right">0</td><td class="right">59</td><td class="right">59</td><td class="right">95</td><td title="LineCoverage: 0/59" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100"> </td></tr></table></td></tr> +<tr><th>ldclienttests.dll</th><th class="right">219</th><th class="right">0</th><th class="right">219</th><th class="right">482</th><th title="LineCoverage: 219/219" class="right">100%</th><th><table class="coverage"><tr><td class="green covered100"> </td></tr></table></th></tr> +<tr><td><a href="ldclienttests.dll_DebuggerInfoParserTests.html">LDClientTests.detection.DebuggerInfoParserTests</a></td><td class="right">18</td><td class="right">0</td><td class="right">18</td><td class="right">66</td><td title="LineCoverage: 18/18" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclienttests.dll_InfoFetcherTests.html">LDClientTests.detection.InfoFetcherTests</a></td><td class="right">59</td><td class="right">0</td><td class="right">59</td><td class="right">117</td><td title="LineCoverage: 59/59" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclienttests.dll_ProcessDetectionTests.html">LDClientTests.detection.ProcessDetectionTests</a></td><td class="right">61</td><td class="right">0</td><td class="right">61</td><td class="right">132</td><td title="LineCoverage: 61/61" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclienttests.dll_ApiClientTests.html">LDClientTests.network.ApiClientTests</a></td><td class="right">81</td><td class="right">0</td><td class="right">81</td><td class="right">167</td><td title="LineCoverage: 81/81" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +</tbody> +</table> +</div> +</coverage-info> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'main.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/index.html b/ld_client/doc/coverage/coveragereport/index.html new file mode 100644 index 0000000..96bf9a8 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/index.html @@ -0,0 +1,197 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFwklEQVR4AcWXA3Qk2RrH/7e6qtPbaQ6TdKyXsbm2bdv22N7R2raRs9JYyhszk0FvOkYnzfJLnTc3p3rv9GY9X+m7hfv/fagGwRG2PwywdetWUl5e7hNF0QeAv/LKK1f+4wDffPONIXiZqqpntG3DdV13tW3gOC5wt3XM22ElfAZHLPWEkD084cu62br+XH7WBv9fBvjhhx9KAExRFOXCNkHeEDWMHtsEA9fhvkWtaujaQxdgXCEgusAJ63gL/8Jgb//3F4/8SvxDAP6TT7ZEN268d2mfPjf7Hn20t9PphCF6OIAL5BsXRfXYtYa0Yf8/tI/AE/6gXbA/0nxSxSe/C8BfUJAmNzV9pEnSsQqAj08+GaeMGgVBEBgAAIEz41ctCpHItdBNsqZs0GOKJeWDDFvarRVDN4STAlTl5haoweAiXVGyqUjYYsFXV16Jc++914j41xCB4yMXLgpxiQDUp0N6RSDCJq/Vc2rNwO0NDEBDfn53tbl5bZt4DqU2RAy/ymbD2ocfxllXXcUADGk9c1HIEr42QYxymIDomCf8xiyb7/iKknWhdoDI8cdz8vbtP2qSdBIVNZ4xg2x3OlHzxBM49qSTzP0Q+E/o2G9UXrn1kAYT/eF6w8pZ34+X+K9qB4j5fDdp4fCremLkCdEa3pLu3eF86SX06t0bhmmaFsiLDiuFgDv0X9c+UZQph52znxfOqygl2qmnCurGjXtp3ak4BaHiFOjjkhIMfP11+Hw+YxzIjA0qhRV3UA26MyUhAYL6PCzbBtn69SV6Xt4FCAY/Z1JPN4CBevmYY3Deyy/D5XIF0uX+pbpA7oBxlRjX2VfRDGT23ZzzJKKnp78GUbzReLJ9A6jPQBnHOMfhpYsuwnULFwayLUNLZat6R3Ihtjmpn0KszxA9LW0bJKmXWZSFYM81CgLeuvHGwPgZX5cqNpXpAVaU9QXwZUYGQpBlBytqHrPXNKMU2Wl1j+4Q/ApRBptFk/sMQJDo2dkqJInrQJAZr4tGMeGVNKy5zmFMx4owIxaABy8TPSenCarq7TBy07ajTXzh/S58OTPNmMo8eQcwTAZaiF5UtB6yPDi5YCKYPxbDq6dY8MZHBdA4nU7MHH8T5tBcAoSNRO/ZcwEk6QFDoCOIBlHE+7lxvLCkN0Q7Z4qewaB7BolObfhWCM8SedCgY/lIZBkrmAgTliR8ITTj2VUD0JpupbLmErBHamZE084ZTz2L7L7lFi571aqDNiAzGYSkqvi+pQbP/zwQNf0drDiT7OQZaAdo1RqK1mRmEGO8s6BgZondPupw0WuahmWBSrz6Xm/sPbebWZwFoHu2+kwDSj+Hntl16rp7DQB8k5ubUczz5QUOhx2altAD6ysr8e6EHGx6sBB68sUsxpaDzkdgGCJlLQr5WOy5Y/Z/ywnl+iQzc9xwp3Oqz2ZrB9hVU4OPz3di+QuDaKx/MAPsWdEfQ8PzlQv8s3Y/lPCDpHTECEvzgQOLjvV6j8u12/FLYyO+KBTx4zcnQ+Vh2G9Ez+4B1osfjKD6hQNb236QjFg5aVGE+Un2Tu/enVrq6xf3stn6HrA047uyCyB6BCbNGjTzGbNHfaYIwbUNqPnA/4uDSz125/xNB5P+KH2lTx9vpLb2U9Uled6b2X+A7+RcpHhTOqp/UgSxPo7AJ/sR2tKyw53qOnvbvLIDHf4sf/+ii3hJCx41e3DwFSkqXdapZxd0G5YBZ4EHIDq0DtKv6zpC5S1oWFGNpg31Gk8sr3V1d3tw7cxl4T/8z2jgpBEnhVvDk6WIdIzVZYW7uBMcOU7YutphcfDgBA6arEEKiYjXxxD2h9C6qwlySNZ5C/+DwPOTdj29Zc1f/m846JERfSOxyGWqpp2qaWp/TdetSDAdhHAxjuM2coR87zzK+UHZvNV7/tY/p9Tue+UhoWzvxtyIGO0ajUcET6pbsQop1T2zSvwv3fWcgj9gBEfY/gcDB4tklLmGUgAAAABJRU5ErkJggg==" rel="icon" type="image/x-icon" /> +<title>Summary - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1>Summary<a class="button" href="https://github.com/danielpalme/ReportGenerator" title="Star on GitHub"><i class="icon-star"></i>Star</a><a class="button" href="https://github.com/sponsors/danielpalme" title="Become a sponsor"><i class="icon-sponsor"></i>Sponsor</a></h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Parser:</th> +<td class="limit-width " title="VisualStudio">VisualStudio</td> +</tr> +<tr> +<th>Assemblies:</th> +<td class="limit-width right" title="2">2</td> +</tr> +<tr> +<th>Classes:</th> +<td class="limit-width right" title="18">18</td> +</tr> +<tr> +<th>Files:</th> +<td class="limit-width right" title="18">18</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar20">79%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="583">583</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="150">150</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="733">733</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="1336">1336</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="583 of 733">79.5%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="Total">Total</td><td>1308</td><td>275</td></tr> +</tbody> +</table> +</div> +<risk-hotspots> +</risk-hotspots> +<h1>Coverage</h1> +<coverage-info> +<div class="table-responsive"> +<table class="overview table-fixed stripped"> +<colgroup> +<col class="column-min-200" /> +<col class="column90" /> +<col class="column105" /> +<col class="column100" /> +<col class="column70" /> +<col class="column60" /> +<col class="column112" /> +</colgroup> +<thead> +<tr class="header"><th></th><th colspan="6" class="center">Line coverage</th></tr> +<tr><th>Name</th><th class="right">Covered</th><th class="right">Uncovered</th><th class="right">Coverable</th><th class="right">Total</th><th class="center" colspan="2">Percentage</th></tr></thead> +<tbody> +<tr><th>ldclient.dll</th><th class="right">364</th><th class="right">150</th><th class="right">514</th><th class="right">854</th><th title="LineCoverage: 364/514" class="right">70.8%</th><th><table class="coverage"><tr><td class="green covered71"> </td><td class="red covered29"> </td></tr></table></th></tr> +<tr><td><a href="ldclient.dll_DebuggerInfoParser.html">LDClient.detection.DebuggerInfoParser</a></td><td class="right">7</td><td class="right">0</td><td class="right">7</td><td class="right">21</td><td title="LineCoverage: 7/7" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_InfoFetcher.html">LDClient.detection.InfoFetcher</a></td><td class="right">52</td><td class="right">0</td><td class="right">52</td><td class="right">86</td><td title="LineCoverage: 52/52" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ProcessDetection.html">LDClient.detection.ProcessDetection</a></td><td class="right">62</td><td class="right">0</td><td class="right">62</td><td class="right">91</td><td title="LineCoverage: 62/62" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ProcessUtils.html">LDClient.detection.ProcessUtils</a></td><td class="right">0</td><td class="right">20</td><td class="right">20</td><td class="right">40</td><td title="LineCoverage: 0/20" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ApiClient.html">LDClient.network.ApiClient</a></td><td class="right">75</td><td class="right">0</td><td class="right">75</td><td class="right">108</td><td title="LineCoverage: 75/75" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_DebuggerInfo.html">LDClient.network.data.DebuggerInfo</a></td><td class="right">1</td><td class="right">0</td><td class="right">1</td><td class="right">9</td><td title="LineCoverage: 1/1" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_Payload.html">LDClient.network.data.Payload</a></td><td class="right">17</td><td class="right">3</td><td class="right">20</td><td class="right">49</td><td title="LineCoverage: 17/20" class="right">85%</td><td><table class="coverage"><tr><td class="green covered85"> </td><td class="red covered15"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_HttpClient.html">LDClient.network.HttpClient</a></td><td class="right">4</td><td class="right">7</td><td class="right">11</td><td class="right">32</td><td title="LineCoverage: 4/11" class="right">36.3%</td><td><table class="coverage"><tr><td class="green covered36"> </td><td class="red covered64"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_Program.html">LDClient.Program</a></td><td class="right">11</td><td class="right">32</td><td class="right">43</td><td class="right">67</td><td title="LineCoverage: 11/43" class="right">25.5%</td><td><table class="coverage"><tr><td class="green covered26"> </td><td class="red covered74"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ConfigLoader.html">LDClient.utils.ConfigLoader</a></td><td class="right">74</td><td class="right">12</td><td class="right">86</td><td class="right">127</td><td title="LineCoverage: 74/86" class="right">86%</td><td><table class="coverage"><tr><td class="green covered86"> </td><td class="red covered14"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_FileUtils.html">LDClient.utils.FileUtils</a></td><td class="right">0</td><td class="right">3</td><td class="right">3</td><td class="right">13</td><td title="LineCoverage: 0/3" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ALogger.html">LDClient.utils.loggers.ALogger</a></td><td class="right">58</td><td class="right">14</td><td class="right">72</td><td class="right">109</td><td title="LineCoverage: 58/72" class="right">80.5%</td><td><table class="coverage"><tr><td class="green covered80"> </td><td class="red covered20"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_ConsoleLogger.html">LDClient.utils.loggers.ConsoleLogger</a></td><td class="right">3</td><td class="right">0</td><td class="right">3</td><td class="right">7</td><td title="LineCoverage: 3/3" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclient.dll_FileLogger.html">LDClient.utils.loggers.FileLogger</a></td><td class="right">0</td><td class="right">59</td><td class="right">59</td><td class="right">95</td><td title="LineCoverage: 0/59" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100"> </td></tr></table></td></tr> +<tr><th>ldclienttests.dll</th><th class="right">219</th><th class="right">0</th><th class="right">219</th><th class="right">482</th><th title="LineCoverage: 219/219" class="right">100%</th><th><table class="coverage"><tr><td class="green covered100"> </td></tr></table></th></tr> +<tr><td><a href="ldclienttests.dll_DebuggerInfoParserTests.html">LDClientTests.detection.DebuggerInfoParserTests</a></td><td class="right">18</td><td class="right">0</td><td class="right">18</td><td class="right">66</td><td title="LineCoverage: 18/18" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclienttests.dll_InfoFetcherTests.html">LDClientTests.detection.InfoFetcherTests</a></td><td class="right">59</td><td class="right">0</td><td class="right">59</td><td class="right">117</td><td title="LineCoverage: 59/59" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclienttests.dll_ProcessDetectionTests.html">LDClientTests.detection.ProcessDetectionTests</a></td><td class="right">61</td><td class="right">0</td><td class="right">61</td><td class="right">132</td><td title="LineCoverage: 61/61" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +<tr><td><a href="ldclienttests.dll_ApiClientTests.html">LDClientTests.network.ApiClientTests</a></td><td class="right">81</td><td class="right">0</td><td class="right">81</td><td class="right">167</td><td title="LineCoverage: 81/81" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100"> </td></tr></table></td></tr> +</tbody> +</table> +</div> +</coverage-info> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'main.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html new file mode 100644 index 0000000..433ba04 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html @@ -0,0 +1,301 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.utils.loggers.ALogger - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.utils.loggers.ALogger">LDClient.utils.loggers.ALogger</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersALoggercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ALogger.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar20">80%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="58">58</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="14">14</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="72">72</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="109">109</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="58 of 72">80.5%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ALogger()"><a href="#file0_line10" class="navigatetohash">ALogger()</a></td><td>14</td><td>0</td></tr> +<tr><td title="ALogger()"><a href="#file0_line16" class="navigatetohash">ALogger()</a></td><td>3</td><td>0</td></tr> +<tr><td title="Info(string)"><a href="#file0_line38" class="navigatetohash">Info(...)</a></td><td>2</td><td>0</td></tr> +<tr><td title="Debug(string)"><a href="#file0_line42" class="navigatetohash">Debug(...)</a></td><td>2</td><td>0</td></tr> +<tr><td title="Error(string)"><a href="#file0_line46" class="navigatetohash">Error(...)</a></td><td>2</td><td>0</td></tr> +<tr><td title="Error(System.Exception)"><a href="#file0_line50" class="navigatetohash">Error(...)</a></td><td>0</td><td>5</td></tr> +<tr><td title="ToString()"><a href="#file0_line56" class="navigatetohash">ToString()</a></td><td>0</td><td>10</td></tr> +<tr><td title="Flush()"><a href="#file0_line60" class="navigatetohash">Flush()</a></td><td>0</td><td>2</td></tr> +<tr><td title="Dispose()"><a href="#file0_line62" class="navigatetohash">Dispose()</a></td><td>0</td><td>3</td></tr> +<tr><td title="ComposeLogRow(string, LDClient.utils.loggers.LogType)"><a href="#file0_line68" class="navigatetohash">ComposeLogRow(...)</a></td><td>12</td><td>0</td></tr> +<tr><td title="UnwrapExceptionMessages(System.Exception)"><a href="#file0_line71" class="navigatetohash">UnwrapExceptionMessages(...)</a></td><td>0</td><td>12</td></tr> +<tr><td title="ProcessQueue()"><a href="#file0_line74" class="navigatetohash">ProcessQueue()</a></td><td>21</td><td>2</td></tr> +<tr><td title="Log(string, LDClient.utils.loggers.LogType)"><a href="#file0_line94" class="navigatetohash">Log(...)</a></td><td>13</td><td>1</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersALoggercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ALogger.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Globalization;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace LDClient.utils.loggers {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code> public abstract class ALogger : IDisposable {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code> private readonly LogVerbosity _verbosity;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code> private readonly LogFlow _logFlow;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgreen"><code> private readonly Queue<Action> _queue = new();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgreen"><code> private readonly ManualResetEvent _hasNewItems = new(false);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code> private readonly ManualResetEvent _terminate = new(false);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgreen"><code> private readonly ManualResetEvent _waiting = new(false);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code> private readonly Thread _loggingThread;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgreen"><code> private static readonly Lazy<ALogger> LazyLog = new(()</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code> => {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code> switch (Program.Config.LogFlowType) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code> case LogFlow.File:</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code> return new FileLogger();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code> case LogFlow.Console:</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code> default:</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code> return new ConsoleLogger();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code> );</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code> public static ALogger Current => LazyLog.Value;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code> protected ALogger() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code> _verbosity = Program.Config.LogVerbosityType;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code> _logFlow = Program.Config.LogFlowType;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code> _loggingThread = new Thread(ProcessQueue) { IsBackground = true };</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code> _loggingThread.Start();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> public void Info(string message) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code> Log(message, LogType.Info);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code> public void Debug(string message) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code> Log(message, LogType.Debug);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code> public void Error(string message) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> Log(message, LogType.Error);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightred"><code> public void Error(Exception e) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightred"><code> if (_verbosity != LogVerbosity.None) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightred"><code> Log(UnwrapExceptionMessages(e), LogType.Error);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightred"><code> public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, "</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code> protected abstract void CreateLog(string message);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightred"><code> public void Flush() => _waiting.WaitOne();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightred"><code> public void Dispose() {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightred"><code> _terminate.Set();</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightred"><code> _loggingThread.Join();</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgray"><code> protected virtual string ComposeLogRow(string message, LogType logType) =></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code> $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgray"><code> protected virtual string UnwrapExceptionMessages(Exception? ex) =></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightred"><code> ex == null ? string.Empty : $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} ";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code> private void ProcessQueue() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code> while (true) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code> _waiting.Set();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code> var i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate });</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code> if (i == 1) return;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code> _hasNewItems.Reset();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code> _waiting.Reset();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code> Queue<Action> queueCopy;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code> lock (_queue) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code> queueCopy = new Queue<Action>(_queue);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code> _queue.Clear();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code> foreach (var log in queueCopy) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code> log();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code> private void Log(string message, LogType logType) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code> if (string.IsNullOrEmpty(message))</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightred"><code> return;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code> var logRow = ComposeLogRow(message, logType);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code> System.Diagnostics.Debug.WriteLine(logRow);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code> if (_verbosity == LogVerbosity.Full) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code> lock (_queue)</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code> _queue.Enqueue(() => CreateLog(logRow));</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code> _hasNewItems.Set();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line10" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ALogger()"><i class="icon-cube"></i>ALogger()</a><br /> +<a href="#file0_line16" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ALogger()"><i class="icon-cube"></i>ALogger()</a><br /> +<a href="#file0_line29" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Current()"><i class="icon-wrench"></i>Current()</a><br /> +<a href="#file0_line38" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Info(string)"><i class="icon-cube"></i>Info(string)</a><br /> +<a href="#file0_line42" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Debug(string)"><i class="icon-cube"></i>Debug(string)</a><br /> +<a href="#file0_line46" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Error(string)"><i class="icon-cube"></i>Error(string)</a><br /> +<a href="#file0_line50" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Error(System.Exception)"><i class="icon-cube"></i>Error(System.Exception)</a><br /> +<a href="#file0_line56" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ToString()"><i class="icon-cube"></i>ToString()</a><br /> +<a href="#file0_line60" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Flush()"><i class="icon-cube"></i>Flush()</a><br /> +<a href="#file0_line62" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Dispose()"><i class="icon-cube"></i>Dispose()</a><br /> +<a href="#file0_line68" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ComposeLogRow(string, LDClient.utils.loggers.LogType)"><i class="icon-cube"></i>ComposeLogRow(string, LDClient.utils.loggers.LogType)</a><br /> +<a href="#file0_line71" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - UnwrapExceptionMessages(System.Exception)"><i class="icon-cube"></i>UnwrapExceptionMessages(System.Exception)</a><br /> +<a href="#file0_line74" class="navigatetohash percentagebar percentagebar90" title="Line coverage: 93.7% - ProcessQueue()"><i class="icon-cube"></i>ProcessQueue()</a><br /> +<a href="#file0_line94" class="navigatetohash percentagebar percentagebar90" title="Line coverage: 90.9% - Log(string, LDClient.utils.loggers.LogType)"><i class="icon-cube"></i>Log(string, LDClient.utils.loggers.LogType)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html new file mode 100644 index 0000000..31cd516 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html @@ -0,0 +1,285 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.network.ApiClient - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.network.ApiClient">LDClient.network.ApiClient</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkApiClientcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\ApiClient.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="75">75</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="75">75</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="108">108</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="75 of 75">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ApiClient(string, uint, string, uint, uint, uint, DiskQueue.IPersistentQueue)"><a href="#file0_line22" class="navigatetohash">ApiClient(...)</a></td><td>9</td><td>0</td></tr> +<tr><td title="SendPayloadAsync()"><a href="#file0_line32" class="navigatetohash">SendPayloadAsync()</a></td><td>23</td><td>0</td></tr> +<tr><td title="CreateRequestLog(LDClient.network.data.Payload, System.Net.Http.HttpResponseMessage, long)"><a href="#file0_line48" class="navigatetohash">CreateRequestLog(...)</a></td><td>18</td><td>0</td></tr> +<tr><td title="ResendPayloadsAsync()"><a href="#file0_line61" class="navigatetohash">ResendPayloadsAsync()</a></td><td>50</td><td>0</td></tr> +<tr><td title="CachePayload(LDClient.network.data.Payload)"><a href="#file0_line87" class="navigatetohash">CachePayload(...)</a></td><td>20</td><td>0</td></tr> +<tr><td title="Run()"><a href="#file0_line99" class="navigatetohash">Run()</a></td><td>10</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkApiClientcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\ApiClient.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Diagnostics;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Net.Http.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using System.Text;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using System.Text.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using System.Text.Json.Serialization;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using DiskQueue;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using LDClient.network.data;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>namespace LDClient.network {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code> public sealed class ApiClient : IApiClient {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code> public IHttpClient _client;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code> public bool ClientRunning;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code> private readonly uint _retryPeriod;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code> private readonly uint _maxEntries;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code> private readonly uint _maxRetries;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code> private readonly IPersistentQueue _cache;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code> public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersis</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code> var uri = $"{url}:{port}{path}";</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code> _retryPeriod = retryPeriod;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code> _maxEntries = maxEntries;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code> _maxRetries = maxRetries;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code> _client = new HttpClient(uri);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code> _cache = cache;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code> public async Task SendPayloadAsync(Payload payload) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code> try {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code> Stopwatch stopWatch = new();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code> stopWatch.Start();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code> var response = await _client.PostAsJsonAsync(payload);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> stopWatch.Stop();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code> CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code> response.EnsureSuccessStatusCode();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code> } catch (Exception e) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Error($"Failed to send {payload} to the server. Due to: {e.Message}");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code> CachePayload(payload);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code> private static void CreateRequestLog(Payload payload, HttpResponseMessage response, long durationMs) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code> var responseToLog = new {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code> statusCode = response.StatusCode,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code> content = response.Content,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgreen"><code> headers = response.Headers,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code> errorMessage = response.RequestMessage,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code> };</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code> $"Request body: {payload},\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code> $"Response: {responseToLog}");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code> private async Task ResendPayloadsAsync() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code> var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code> var payloads = new List<Payload>();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code> if (numberOfPayloadsToResend > 0) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code> using var session = _cache.OpenSession();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code> for (var i = 0; i < numberOfPayloadsToResend; i++) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code> var rawBytes = session.Dequeue();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code> var payload = JsonSerializer.Deserialize<Payload>(rawBytes);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code> if (payload is not null) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code> payloads.Add(payload);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code> session.Flush();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code> if (payloads.Count > 0) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Debug($"ResendPayloadAsync -> {payloads.Count} unsent payloads");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code> var tasks = new List<Task>();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code> foreach (var payload in payloads) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info($"Resending {payload}.");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgreen"><code> tasks.Add(SendPayloadAsync(payload));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code> await Task.WhenAll(tasks);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code> private void CachePayload(Payload payload) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info($"Storing {payload} into the cache.");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code> var numberOfCachedPayloads = _cache.EstimatedCountOfItemsInQueue;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code> using var session = _cache.OpenSession();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgreen"><code> if (numberOfCachedPayloads >= _maxEntries) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code> session.Dequeue();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code> var payloadJson = JsonSerializer.Serialize(payload);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code> session.Enqueue(Encoding.UTF8.GetBytes(payloadJson));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code> session.Flush();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code> public async void Run() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info("Api Client thread has started");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code> ClientRunning = true;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code> while (ClientRunning) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code> await ResendPayloadsAsync();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgreen"><code> Thread.Sleep((int) _retryPeriod);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiClient(string, uint, string, uint, uint, uint, DiskQueue.IPersistentQueue)"><i class="icon-cube"></i>ApiClient(string, uint, string, uint, uint, uint, DiskQueue.IPersistentQueue)</a><br /> +<a href="#file0_line32" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendPayloadAsync()"><i class="icon-cube"></i>SendPayloadAsync()</a><br /> +<a href="#file0_line48" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CreateRequestLog(LDClient.network.data.Payload, System.Net.Http.HttpResponseMessage, long)"><i class="icon-cube"></i>CreateRequestLog(LDClient.network.data.Payload, System.Net.Http.HttpResponseMessage, long)</a><br /> +<a href="#file0_line61" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ResendPayloadsAsync()"><i class="icon-cube"></i>ResendPayloadsAsync()</a><br /> +<a href="#file0_line87" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CachePayload(LDClient.network.data.Payload)"><i class="icon-cube"></i>CachePayload(LDClient.network.data.Payload)</a><br /> +<a href="#file0_line99" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Run()"><i class="icon-cube"></i>Run()</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html new file mode 100644 index 0000000..e7713f7 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html @@ -0,0 +1,346 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.utils.ConfigLoader - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.utils.ConfigLoader">LDClient.utils.ConfigLoader</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsConfigLoadercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\ConfigLoader.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar14">86%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="74">74</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="12">12</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="86">86</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="127">127</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="74 of 86">86%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ConfigLoader()"><a href="#file0_line21" class="navigatetohash">ConfigLoader()</a></td><td>10</td><td>0</td></tr> +<tr><td title="ReadLoggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line69" class="navigatetohash">ReadLoggerSection(...)</a></td><td>22</td><td>4</td></tr> +<tr><td title="ReadApiSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line84" class="navigatetohash">ReadApiSection(...)</a></td><td>11</td><td>4</td></tr> +<tr><td title="ReadCacheSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line96" class="navigatetohash">ReadCacheSection(...)</a></td><td>15</td><td>4</td></tr> +<tr><td title="ReadDebuggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line109" class="navigatetohash">ReadDebuggerSection(...)</a></td><td>33</td><td>3</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsConfigLoadercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\ConfigLoader.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using LDClient.utils.loggers;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using Microsoft.Extensions.Configuration;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>namespace LDClient.utils {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code> internal class ConfigLoader {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code> private const int ErrorExitCode = 1;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code> private const string ConfigFile = "appsettings.json";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code> private const string LoggingSection = "Logging";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code> private const string NetworkSection = "Network";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code> private const string CacheSection = "Cache";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code> private const string DdSection = "DebuggerDetection";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code> #region Logger</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code> public int LogChunkSize { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code> public int LogChunkMaxCount { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code> public int LogArchiveMaxCount { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code> public int LogCleanupPeriod { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code> public LogVerbosity LogVerbosityType { get; private set; } = LogVerbosity.Full;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code> public LogFlow LogFlowType { get; private set; } = LogFlow.Console;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code> #endregion</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code> #region Api</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code> public string ApiBaseAddress { get; private set; } = null!;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code> public string ApiUsbEndPoint { get; private set; } = null!;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code> public uint ApiPort { get; private set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code> #endregion</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code> #region Cache</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code> public string CacheFileName { get; private set; } = null!;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code> public uint MaxRetries { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> public uint MaxEntries { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code> public uint RetryPeriod { get; private set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgray"><code> #endregion</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgray"><code> #region Detection</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code> public string T32ProcessName { get; private set; } = null!;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code> public uint DetectionPeriod { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code> public string T32InfoLocation { get; private set; } = null!;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> public string F32RemExecutable { get; private set; } = null!;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code> public uint FetchInfoMaxAttempts { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code> public uint FetchInfoAttemptPeriod { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code> public string[] F32RemArguments { get; private set; } = null!;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code> public int T32RemSuccessExitCode { get; private set; }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgreen"><code> public int T32RemWaitTimeoutMs { get; private set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code> #endregion</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code> public ConfigLoader() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code> var configuration = new ConfigurationBuilder()</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code> .AddJsonFile(ConfigFile)</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code> .Build();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code> ReadLoggerSection(configuration);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code> ReadApiSection(configuration);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code> ReadCacheSection(configuration);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code> ReadDebuggerSection(configuration);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code> Console.WriteLine("Configuration successfully loaded!");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code> private void ReadLoggerSection(IConfiguration configuration) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code> try {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code> var logging = configuration.GetSection(LoggingSection);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgreen"><code> LogChunkSize = int.Parse(logging["LogChunkSize"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code> LogChunkMaxCount = int.Parse(logging["LogChunkMaxCount"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code> LogArchiveMaxCount = int.Parse(logging["LogArchiveMaxCount"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code> LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code> LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code> LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code> } catch (Exception e) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightred"><code> Console.WriteLine(e.Message);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightred"><code> Environment.Exit(ErrorExitCode);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code> private void ReadApiSection(IConfiguration configuration) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code> try {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code> var network = configuration.GetSection(NetworkSection);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code> ApiBaseAddress = network["ApiBaseAddress"];</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code> ApiUsbEndPoint = network["ApiLDEndPoint"];</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code> ApiPort = uint.Parse(network["ApiPort"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code> } catch (Exception e) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightred"><code> Console.WriteLine(e.Message);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightred"><code> Environment.Exit(ErrorExitCode);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code> private void ReadCacheSection(IConfiguration configuration) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgreen"><code> try {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code> var cache = configuration.GetSection(CacheSection);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code> RetryPeriod = uint.Parse(cache["RetryPeriod"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgreen"><code> MaxEntries = uint.Parse(cache["MaxEntries"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code> MaxRetries = uint.Parse(cache["MaxRetries"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code> CacheFileName = cache["CacheFileName"];</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code> } catch (Exception e) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightred"><code> Console.WriteLine(e.Message);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightred"><code> Environment.Exit(ErrorExitCode);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgreen"><code> private void ReadDebuggerSection(IConfiguration configuration) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgreen"><code> try {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgreen"><code> var debugger = configuration.GetSection(DdSection);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgreen"><code> T32ProcessName = debugger["T32ProcessName"];</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgreen"><code> T32InfoLocation = debugger["T32InfoLocation"];</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgreen"><code> DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgreen"><code> F32RemExecutable = debugger["F32RemExecutable"];</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgreen"><code> FetchInfoMaxAttempts = uint.Parse(debugger["FetchInfoMaxAttempts"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgreen"><code> FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line118"></a><code>118</code></td><td></td><td class="lightgreen"><code> T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line119"></a><code>119</code></td><td></td><td class="lightgreen"><code> T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line120"></a><code>120</code></td><td></td><td class="lightgreen"><code> F32RemArguments = configuration.GetSection($"{DdSection}:F32RemArguments").GetChildren().Select(key => k</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line121"></a><code>121</code></td><td></td><td class="lightgreen"><code> } catch (Exception e) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line122"></a><code>122</code></td><td></td><td class="lightred"><code> Console.WriteLine(e);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line123"></a><code>123</code></td><td></td><td class="lightred"><code> Environment.Exit(ErrorExitCode);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line124"></a><code>124</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line125"></a><code>125</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line126"></a><code>126</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line127"></a><code>127</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkSize()"><i class="icon-wrench"></i>LogChunkSize()</a><br /> +<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkSize(int)"><i class="icon-wrench"></i>LogChunkSize(int)</a><br /> +<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkMaxCount()"><i class="icon-wrench"></i>LogChunkMaxCount()</a><br /> +<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkMaxCount(int)"><i class="icon-wrench"></i>LogChunkMaxCount(int)</a><br /> +<a href="#file0_line19" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogArchiveMaxCount()"><i class="icon-wrench"></i>LogArchiveMaxCount()</a><br /> +<a href="#file0_line19" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogArchiveMaxCount(int)"><i class="icon-wrench"></i>LogArchiveMaxCount(int)</a><br /> +<a href="#file0_line20" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogCleanupPeriod()"><i class="icon-wrench"></i>LogCleanupPeriod()</a><br /> +<a href="#file0_line20" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogCleanupPeriod(int)"><i class="icon-wrench"></i>LogCleanupPeriod(int)</a><br /> +<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogVerbosityType()"><i class="icon-wrench"></i>LogVerbosityType()</a><br /> +<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogVerbosityType(LDClient.utils.loggers.LogVerbosity)"><i class="icon-wrench"></i>LogVerbosityType(LDClient.utils.loggers.LogVerbosity)</a><br /> +<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ConfigLoader()"><i class="icon-cube"></i>ConfigLoader()</a><br /> +<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogFlowType()"><i class="icon-wrench"></i>LogFlowType()</a><br /> +<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogFlowType(LDClient.utils.loggers.LogFlow)"><i class="icon-wrench"></i>LogFlowType(LDClient.utils.loggers.LogFlow)</a><br /> +<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiBaseAddress()"><i class="icon-wrench"></i>ApiBaseAddress()</a><br /> +<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiBaseAddress(string)"><i class="icon-wrench"></i>ApiBaseAddress(string)</a><br /> +<a href="#file0_line29" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiUsbEndPoint()"><i class="icon-wrench"></i>ApiUsbEndPoint()</a><br /> +<a href="#file0_line29" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiUsbEndPoint(string)"><i class="icon-wrench"></i>ApiUsbEndPoint(string)</a><br /> +<a href="#file0_line30" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiPort()"><i class="icon-wrench"></i>ApiPort()</a><br /> +<a href="#file0_line30" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiPort(uint)"><i class="icon-wrench"></i>ApiPort(uint)</a><br /> +<a href="#file0_line36" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CacheFileName()"><i class="icon-wrench"></i>CacheFileName()</a><br /> +<a href="#file0_line36" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CacheFileName(string)"><i class="icon-wrench"></i>CacheFileName(string)</a><br /> +<a href="#file0_line37" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxRetries()"><i class="icon-wrench"></i>MaxRetries()</a><br /> +<a href="#file0_line37" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxRetries(uint)"><i class="icon-wrench"></i>MaxRetries(uint)</a><br /> +<a href="#file0_line38" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxEntries()"><i class="icon-wrench"></i>MaxEntries()</a><br /> +<a href="#file0_line38" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxEntries(uint)"><i class="icon-wrench"></i>MaxEntries(uint)</a><br /> +<a href="#file0_line39" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetryPeriod()"><i class="icon-wrench"></i>RetryPeriod()</a><br /> +<a href="#file0_line39" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetryPeriod(uint)"><i class="icon-wrench"></i>RetryPeriod(uint)</a><br /> +<a href="#file0_line44" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32ProcessName()"><i class="icon-wrench"></i>T32ProcessName()</a><br /> +<a href="#file0_line44" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32ProcessName(string)"><i class="icon-wrench"></i>T32ProcessName(string)</a><br /> +<a href="#file0_line45" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DetectionPeriod()"><i class="icon-wrench"></i>DetectionPeriod()</a><br /> +<a href="#file0_line45" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DetectionPeriod(uint)"><i class="icon-wrench"></i>DetectionPeriod(uint)</a><br /> +<a href="#file0_line46" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32InfoLocation()"><i class="icon-wrench"></i>T32InfoLocation()</a><br /> +<a href="#file0_line46" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32InfoLocation(string)"><i class="icon-wrench"></i>T32InfoLocation(string)</a><br /> +<a href="#file0_line47" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemExecutable()"><i class="icon-wrench"></i>F32RemExecutable()</a><br /> +<a href="#file0_line47" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemExecutable(string)"><i class="icon-wrench"></i>F32RemExecutable(string)</a><br /> +<a href="#file0_line48" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoMaxAttempts()"><i class="icon-wrench"></i>FetchInfoMaxAttempts()</a><br /> +<a href="#file0_line48" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoMaxAttempts(uint)"><i class="icon-wrench"></i>FetchInfoMaxAttempts(uint)</a><br /> +<a href="#file0_line49" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoAttemptPeriod()"><i class="icon-wrench"></i>FetchInfoAttemptPeriod()</a><br /> +<a href="#file0_line49" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoAttemptPeriod(uint)"><i class="icon-wrench"></i>FetchInfoAttemptPeriod(uint)</a><br /> +<a href="#file0_line50" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemArguments()"><i class="icon-wrench"></i>F32RemArguments()</a><br /> +<a href="#file0_line50" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemArguments(string[])"><i class="icon-wrench"></i>F32RemArguments(string[])</a><br /> +<a href="#file0_line51" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemSuccessExitCode()"><i class="icon-wrench"></i>T32RemSuccessExitCode()</a><br /> +<a href="#file0_line51" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemSuccessExitCode(int)"><i class="icon-wrench"></i>T32RemSuccessExitCode(int)</a><br /> +<a href="#file0_line52" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemWaitTimeoutMs()"><i class="icon-wrench"></i>T32RemWaitTimeoutMs()</a><br /> +<a href="#file0_line52" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemWaitTimeoutMs(int)"><i class="icon-wrench"></i>T32RemWaitTimeoutMs(int)</a><br /> +<a href="#file0_line69" class="navigatetohash percentagebar percentagebar70" title="Line coverage: 78.5% - ReadLoggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadLoggerSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br /> +<a href="#file0_line84" class="navigatetohash percentagebar percentagebar70" title="Line coverage: 72.7% - ReadApiSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadApiSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br /> +<a href="#file0_line96" class="navigatetohash percentagebar percentagebar70" title="Line coverage: 75% - ReadCacheSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadCacheSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br /> +<a href="#file0_line109" class="navigatetohash percentagebar percentagebar80" title="Line coverage: 82.3% - ReadDebuggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadDebuggerSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html new file mode 100644 index 0000000..c41aaa5 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html @@ -0,0 +1,174 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.utils.loggers.ConsoleLogger - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.utils.loggers.ConsoleLogger">LDClient.utils.loggers.ConsoleLogger</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersConsoleLoggercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ConsoleLogger.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="3">3</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="3">3</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="7">7</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="3 of 3">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="CreateLog(string)"><a href="#file0_line3" class="navigatetohash">CreateLog(...)</a></td><td>2</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersConsoleLoggercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ConsoleLogger.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>namespace LDClient.utils.loggers {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code> public class ConsoleLogger : ALogger {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgreen"><code> protected override void CreateLog(string message) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgreen"><code> Console.WriteLine(message);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line3" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CreateLog(string)"><i class="icon-cube"></i>CreateLog(string)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html new file mode 100644 index 0000000..63eece6 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html @@ -0,0 +1,168 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.network.data.DebuggerInfo - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.network.data.DebuggerInfo">LDClient.network.data.DebuggerInfo</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataDebuggerInfocs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\DebuggerInfo.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="1">1</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="1">1</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="9">9</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="1 of 1">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataDebuggerInfocs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\DebuggerInfo.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Text.Json.Serialization;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace LDClient.network.data {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code> public class DebuggerInfo {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code> [JsonPropertyName("serial_number")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgreen"><code> public string? SerialNumber { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line7" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SerialNumber()"><i class="icon-wrench"></i>SerialNumber()</a><br /> +<a href="#file0_line7" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SerialNumber(string)"><i class="icon-wrench"></i>SerialNumber(string)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html new file mode 100644 index 0000000..f4fd26d --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html @@ -0,0 +1,190 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.detection.DebuggerInfoParser - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.detection.DebuggerInfoParser">LDClient.detection.DebuggerInfoParser</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionDebuggerInfoParsercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\DebuggerInfoParser.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="7">7</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="7">7</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="21">21</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="7 of 7">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="DebuggerInfoParser()"><a href="#file0_line9" class="navigatetohash">DebuggerInfoParser()</a></td><td>2</td><td>0</td></tr> +<tr><td title="Parse(string)"><a href="#file0_line11" class="navigatetohash">Parse(...)</a></td><td>22</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionDebuggerInfoParsercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\DebuggerInfoParser.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Text.RegularExpressions;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace LDClient.detection {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code> public static class DebuggerInfoParser {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code> private const int ExpectedNumberOfMatches = 2;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgreen"><code> private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)");</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgreen"><code> public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code> var matches = SerialNumberRegex.Matches(dataTxt);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgreen"><code> if (matches.Count != ExpectedNumberOfMatches) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code> throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actual</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code> return (matches[1].ToString().Trim(), matches[0].ToString().Trim());</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line9" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DebuggerInfoParser()"><i class="icon-cube"></i>DebuggerInfoParser()</a><br /> +<a href="#file0_line11" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Parse(string)"><i class="icon-cube"></i>Parse(string)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html new file mode 100644 index 0000000..ba2bc04 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html @@ -0,0 +1,272 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.utils.loggers.FileLogger - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.utils.loggers.FileLogger">LDClient.utils.loggers.FileLogger</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersFileLoggercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\FileLogger.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar100">0%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="59">59</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="59">59</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="95">95</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="0 of 59">0%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="FileLogger()"><a href="#file0_line9" class="navigatetohash">FileLogger()</a></td><td>0</td><td>10</td></tr> +<tr><td title="CreateLog(string)"><a href="#file0_line18" class="navigatetohash">CreateLog(...)</a></td><td>0</td><td>13</td></tr> +<tr><td title="Rotate(string)"><a href="#file0_line36" class="navigatetohash">Rotate(...)</a></td><td>0</td><td>28</td></tr> +<tr><td title="Archive(System.Collections.Generic.IEnumerable<System.IO.FileSystemInfo>, string, string, string)"><a href="#file0_line63" class="navigatetohash">Archive(...)</a></td><td>0</td><td>27</td></tr> +<tr><td title="DeleteOldArchives(System.IO.FileSystemInfo[])"><a href="#file0_line76" class="navigatetohash">DeleteOldArchives(...)</a></td><td>0</td><td>26</td></tr> +<tr><td title="ToString()"><a href="#file0_line94" class="navigatetohash">ToString()</a></td><td>0</td><td>14</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersFileLoggercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\FileLogger.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.IO.Compression;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace LDClient.utils.loggers;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>public class FileLogger : ALogger {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code> private const string LogFolderName = "logs";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code> private const string LogFileName = "app_info.log";</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightred"><code> private readonly int _logChunkSize = Program.Config.LogChunkSize;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightred"><code> private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightred"><code> private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightred"><code> private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code> private const string LogFolderPath = $"ldClient\\{LogFolderName}";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code> private bool _logDirExists;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightred"><code> protected override void CreateLog(string message) {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightred"><code> if (!_logDirExists) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightred"><code> _logDirExists = Directory.Exists(LogFolderPath);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightred"><code> if (!_logDirExists) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightred"><code> Directory.CreateDirectory(LogFolderPath);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightred"><code> _logDirExists = true;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightred"><code> var logFilePath = Path.Combine(LogFolderPath, LogFileName);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightred"><code> Rotate(logFilePath);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightred"><code> using var sw = File.AppendText(logFilePath);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightred"><code> sw.WriteLine(message);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code> private void Rotate(string filePath) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code> if (!File.Exists(filePath)) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightred"><code> return;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightred"><code> var fileInfo = new FileInfo(filePath);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightred"><code> if (fileInfo.Length < _logChunkSize) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightred"><code> return;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightred"><code> var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff");</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightred"><code> var rotatedPath = filePath.Replace(".log", $".{fileTime}");</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightred"><code> File.Move(filePath, rotatedPath);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightred"><code> var folderPath = Path.GetDirectoryName(rotatedPath);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightred"><code> var logFolderContent = new DirectoryInfo(folderPath ?? string.Empty).GetFileSystemInfos();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightred"><code> var chunks = logFolderContent.Where(x =></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightred"><code> !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase));</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightred"><code> if (chunks.Count() <= _logChunkMaxCount) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightred"><code> return;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightred"><code> Archive(chunks, rotatedPath, fileTime, folderPath);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightred"><code> DeleteOldArchives(logFolderContent);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightred"><code> private void Archive(IEnumerable<FileSystemInfo> chunks, string rotatedPath, string fileTime, string? folderPath) {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightred"><code> var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath) ?? LogFolderPa</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightred"><code> foreach (var chunk in chunks) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightred"><code> var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightred"><code> Directory.Move(chunk.FullName, destination);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightred"><code> ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath ?? LogFolderPath, $"{LogFolderNa</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightred"><code> Directory.Delete(archiveFolderInfo.FullName, true);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightred"><code> private void DeleteOldArchives(FileSystemInfo[] logFolderContent) {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightred"><code> var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArr</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightred"><code> if (archives.Length <= _logArchiveMaxCount)</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightred"><code> return;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightred"><code> var oldestArchive = archives.OrderBy(x => x.CreationTime).First();</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightred"><code> var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightred"><code> if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightred"><code> foreach (var file in logFolderContent) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightred"><code> file.Delete();</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightred"><code> } else {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightred"><code> File.Delete(oldestArchive.FullName);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightred"><code> public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMa</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line9" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - FileLogger()"><i class="icon-cube"></i>FileLogger()</a><br /> +<a href="#file0_line18" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - CreateLog(string)"><i class="icon-cube"></i>CreateLog(string)</a><br /> +<a href="#file0_line36" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Rotate(string)"><i class="icon-cube"></i>Rotate(string)</a><br /> +<a href="#file0_line63" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Archive(System.Collections.Generic.IEnumerable<System.IO.FileSystemInfo>, string, string, string)"><i class="icon-cube"></i>Archive(System.Collections.Generic.IEnumerable<System.IO.FileSystemInfo>, string, string, string)</a><br /> +<a href="#file0_line76" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - DeleteOldArchives(System.IO.FileSystemInfo[])"><i class="icon-cube"></i>DeleteOldArchives(System.IO.FileSystemInfo[])</a><br /> +<a href="#file0_line94" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ToString()"><i class="icon-cube"></i>ToString()</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html new file mode 100644 index 0000000..9eb1fd6 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html @@ -0,0 +1,180 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFwklEQVR4AcWXA3Qk2RrH/7e6qtPbaQ6TdKyXsbm2bdv22N7R2raRs9JYyhszk0FvOkYnzfJLnTc3p3rv9GY9X+m7hfv/fagGwRG2PwywdetWUl5e7hNF0QeAv/LKK1f+4wDffPONIXiZqqpntG3DdV13tW3gOC5wt3XM22ElfAZHLPWEkD084cu62br+XH7WBv9fBvjhhx9KAExRFOXCNkHeEDWMHtsEA9fhvkWtaujaQxdgXCEgusAJ63gL/8Jgb//3F4/8SvxDAP6TT7ZEN268d2mfPjf7Hn20t9PphCF6OIAL5BsXRfXYtYa0Yf8/tI/AE/6gXbA/0nxSxSe/C8BfUJAmNzV9pEnSsQqAj08+GaeMGgVBEBgAAIEz41ctCpHItdBNsqZs0GOKJeWDDFvarRVDN4STAlTl5haoweAiXVGyqUjYYsFXV16Jc++914j41xCB4yMXLgpxiQDUp0N6RSDCJq/Vc2rNwO0NDEBDfn53tbl5bZt4DqU2RAy/ymbD2ocfxllXXcUADGk9c1HIEr42QYxymIDomCf8xiyb7/iKknWhdoDI8cdz8vbtP2qSdBIVNZ4xg2x3OlHzxBM49qSTzP0Q+E/o2G9UXrn1kAYT/eF6w8pZ34+X+K9qB4j5fDdp4fCremLkCdEa3pLu3eF86SX06t0bhmmaFsiLDiuFgDv0X9c+UZQph52znxfOqygl2qmnCurGjXtp3ak4BaHiFOjjkhIMfP11+Hw+YxzIjA0qhRV3UA26MyUhAYL6PCzbBtn69SV6Xt4FCAY/Z1JPN4CBevmYY3Deyy/D5XIF0uX+pbpA7oBxlRjX2VfRDGT23ZzzJKKnp78GUbzReLJ9A6jPQBnHOMfhpYsuwnULFwayLUNLZat6R3Ihtjmpn0KszxA9LW0bJKmXWZSFYM81CgLeuvHGwPgZX5cqNpXpAVaU9QXwZUYGQpBlBytqHrPXNKMU2Wl1j+4Q/ApRBptFk/sMQJDo2dkqJInrQJAZr4tGMeGVNKy5zmFMx4owIxaABy8TPSenCarq7TBy07ajTXzh/S58OTPNmMo8eQcwTAZaiF5UtB6yPDi5YCKYPxbDq6dY8MZHBdA4nU7MHH8T5tBcAoSNRO/ZcwEk6QFDoCOIBlHE+7lxvLCkN0Q7Z4qewaB7BolObfhWCM8SedCgY/lIZBkrmAgTliR8ITTj2VUD0JpupbLmErBHamZE084ZTz2L7L7lFi571aqDNiAzGYSkqvi+pQbP/zwQNf0drDiT7OQZaAdo1RqK1mRmEGO8s6BgZondPupw0WuahmWBSrz6Xm/sPbebWZwFoHu2+kwDSj+Hntl16rp7DQB8k5ubUczz5QUOhx2altAD6ysr8e6EHGx6sBB68sUsxpaDzkdgGCJlLQr5WOy5Y/Z/ywnl+iQzc9xwp3Oqz2ZrB9hVU4OPz3di+QuDaKx/MAPsWdEfQ8PzlQv8s3Y/lPCDpHTECEvzgQOLjvV6j8u12/FLYyO+KBTx4zcnQ+Vh2G9Ez+4B1osfjKD6hQNb236QjFg5aVGE+Un2Tu/enVrq6xf3stn6HrA047uyCyB6BCbNGjTzGbNHfaYIwbUNqPnA/4uDSz125/xNB5P+KH2lTx9vpLb2U9Uled6b2X+A7+RcpHhTOqp/UgSxPo7AJ/sR2tKyw53qOnvbvLIDHf4sf/+ii3hJCx41e3DwFSkqXdapZxd0G5YBZ4EHIDq0DtKv6zpC5S1oWFGNpg31Gk8sr3V1d3tw7cxl4T/8z2jgpBEnhVvDk6WIdIzVZYW7uBMcOU7YutphcfDgBA6arEEKiYjXxxD2h9C6qwlySNZ5C/+DwPOTdj29Zc1f/m846JERfSOxyGWqpp2qaWp/TdetSDAdhHAxjuM2coR87zzK+UHZvNV7/tY/p9Tue+UhoWzvxtyIGO0ajUcET6pbsQop1T2zSvwv3fWcgj9gBEfY/gcDB4tklLmGUgAAAABJRU5ErkJggg==" rel="icon" type="image/x-icon" /> +<title>LDClient.utils.FileUtils - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.utils.FileUtils">LDClient.utils.FileUtils</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsFileUtilscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\FileUtils.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar100">0%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="3">3</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="3">3</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="13">13</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="0 of 3">0%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ReadFileAllLines(string)"><a href="#file0_line9" class="navigatetohash">ReadFileAllLines(...)</a></td><td>0</td><td>3</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsFileUtilscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\FileUtils.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Collections.Generic;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using System.Linq;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using System.Text;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using System.Threading.Tasks;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>namespace LDClient.utils {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code> public class FileUtils : IFileUtils {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightred"><code> public string[] ReadFileAllLines(string file) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightred"><code> return File.ReadAllLines(file);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line9" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ReadFileAllLines(string)"><i class="icon-cube"></i>ReadFileAllLines(string)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html new file mode 100644 index 0000000..d975c30 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html @@ -0,0 +1,201 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.network.HttpClient - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.network.HttpClient">LDClient.network.HttpClient</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkHttpClientcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\HttpClient.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar64">36%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="4">4</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="7">7</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="11">11</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="32">32</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="4 of 11">36.3%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="HttpClient(string)"><a href="#file0_line17" class="navigatetohash">HttpClient(...)</a></td><td>3</td><td>0</td></tr> +<tr><td title="PostAsJsonAsync(LDClient.network.data.Payload)"><a href="#file0_line23" class="navigatetohash">PostAsJsonAsync(...)</a></td><td>0</td><td>8</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkHttpClientcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\HttpClient.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Collections.Generic;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using System.Linq;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using System.Net.Http.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using System.Text;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using System.Text.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using System.Text.Json.Serialization;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>using System.Threading.Tasks;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>using LDClient.network.data;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>namespace LDClient.network {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code> public class HttpClient : IHttpClient{</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code> private readonly System.Net.Http.HttpClient _httpClient;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code> private readonly string _uri;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code> public HttpClient(string uri) {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code> _httpClient = new System.Net.Http.HttpClient();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code> _uri = uri;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightred"><code> public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightred"><code> return _httpClient.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightred"><code> Converters = {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightred"><code> new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightred"><code> });</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HttpClient(string)"><i class="icon-cube"></i>HttpClient(string)</a><br /> +<a href="#file0_line23" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - PostAsJsonAsync(LDClient.network.data.Payload)"><i class="icon-cube"></i>PostAsJsonAsync(LDClient.network.data.Payload)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html new file mode 100644 index 0000000..77c4c2a --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html @@ -0,0 +1,263 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFwklEQVR4AcWXA3Qk2RrH/7e6qtPbaQ6TdKyXsbm2bdv22N7R2raRs9JYyhszk0FvOkYnzfJLnTc3p3rv9GY9X+m7hfv/fagGwRG2PwywdetWUl5e7hNF0QeAv/LKK1f+4wDffPONIXiZqqpntG3DdV13tW3gOC5wt3XM22ElfAZHLPWEkD084cu62br+XH7WBv9fBvjhhx9KAExRFOXCNkHeEDWMHtsEA9fhvkWtaujaQxdgXCEgusAJ63gL/8Jgb//3F4/8SvxDAP6TT7ZEN268d2mfPjf7Hn20t9PphCF6OIAL5BsXRfXYtYa0Yf8/tI/AE/6gXbA/0nxSxSe/C8BfUJAmNzV9pEnSsQqAj08+GaeMGgVBEBgAAIEz41ctCpHItdBNsqZs0GOKJeWDDFvarRVDN4STAlTl5haoweAiXVGyqUjYYsFXV16Jc++914j41xCB4yMXLgpxiQDUp0N6RSDCJq/Vc2rNwO0NDEBDfn53tbl5bZt4DqU2RAy/ymbD2ocfxllXXcUADGk9c1HIEr42QYxymIDomCf8xiyb7/iKknWhdoDI8cdz8vbtP2qSdBIVNZ4xg2x3OlHzxBM49qSTzP0Q+E/o2G9UXrn1kAYT/eF6w8pZ34+X+K9qB4j5fDdp4fCremLkCdEa3pLu3eF86SX06t0bhmmaFsiLDiuFgDv0X9c+UZQph52znxfOqygl2qmnCurGjXtp3ak4BaHiFOjjkhIMfP11+Hw+YxzIjA0qhRV3UA26MyUhAYL6PCzbBtn69SV6Xt4FCAY/Z1JPN4CBevmYY3Deyy/D5XIF0uX+pbpA7oBxlRjX2VfRDGT23ZzzJKKnp78GUbzReLJ9A6jPQBnHOMfhpYsuwnULFwayLUNLZat6R3Ihtjmpn0KszxA9LW0bJKmXWZSFYM81CgLeuvHGwPgZX5cqNpXpAVaU9QXwZUYGQpBlBytqHrPXNKMU2Wl1j+4Q/ApRBptFk/sMQJDo2dkqJInrQJAZr4tGMeGVNKy5zmFMx4owIxaABy8TPSenCarq7TBy07ajTXzh/S58OTPNmMo8eQcwTAZaiF5UtB6yPDi5YCKYPxbDq6dY8MZHBdA4nU7MHH8T5tBcAoSNRO/ZcwEk6QFDoCOIBlHE+7lxvLCkN0Q7Z4qewaB7BolObfhWCM8SedCgY/lIZBkrmAgTliR8ITTj2VUD0JpupbLmErBHamZE084ZTz2L7L7lFi571aqDNiAzGYSkqvi+pQbP/zwQNf0drDiT7OQZaAdo1RqK1mRmEGO8s6BgZondPupw0WuahmWBSrz6Xm/sPbebWZwFoHu2+kwDSj+Hntl16rp7DQB8k5ubUczz5QUOhx2altAD6ysr8e6EHGx6sBB68sUsxpaDzkdgGCJlLQr5WOy5Y/Z/ywnl+iQzc9xwp3Oqz2ZrB9hVU4OPz3di+QuDaKx/MAPsWdEfQ8PzlQv8s3Y/lPCDpHTECEvzgQOLjvV6j8u12/FLYyO+KBTx4zcnQ+Vh2G9Ez+4B1osfjKD6hQNb236QjFg5aVGE+Un2Tu/enVrq6xf3stn6HrA047uyCyB6BCbNGjTzGbNHfaYIwbUNqPnA/4uDSz125/xNB5P+KH2lTx9vpLb2U9Uled6b2X+A7+RcpHhTOqp/UgSxPo7AJ/sR2tKyw53qOnvbvLIDHf4sf/+ii3hJCx41e3DwFSkqXdapZxd0G5YBZ4EHIDq0DtKv6zpC5S1oWFGNpg31Gk8sr3V1d3tw7cxl4T/8z2jgpBEnhVvDk6WIdIzVZYW7uBMcOU7YutphcfDgBA6arEEKiYjXxxD2h9C6qwlySNZ5C/+DwPOTdj29Zc1f/m846JERfSOxyGWqpp2qaWp/TdetSDAdhHAxjuM2coR87zzK+UHZvNV7/tY/p9Tue+UhoWzvxtyIGO0ajUcET6pbsQop1T2zSvwv3fWcgj9gBEfY/gcDB4tklLmGUgAAAABJRU5ErkJggg==" rel="icon" type="image/x-icon" /> +<title>LDClient.detection.InfoFetcher - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.detection.InfoFetcher">LDClient.detection.InfoFetcher</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionInfoFetchercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\InfoFetcher.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="52">52</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="52">52</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="86">86</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="52 of 52">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="InfoFetcher(uint, uint, string, string, string[], int, int)"><a href="#file0_line22" class="navigatetohash">InfoFetcher(...)</a></td><td>4</td><td>0</td></tr> +<tr><td title="FetchDataAsync()"><a href="#file0_line40" class="navigatetohash">FetchDataAsync()</a></td><td>28</td><td>0</td></tr> +<tr><td title="RetrieveDebuggerInfo(string)"><a href="#file0_line59" class="navigatetohash">RetrieveDebuggerInfo(...)</a></td><td>18</td><td>0</td></tr> +<tr><td title="SendRetrieveInfoCommands(string, System.Collections.Generic.IReadOnlyList<string>, int, int)"><a href="#file0_line73" class="navigatetohash">SendRetrieveInfoCommands(...)</a></td><td>17</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionInfoFetchercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\InfoFetcher.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Diagnostics;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using LDClient.utils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using LDClient.utils.loggers;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>namespace LDClient.detection {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code> public class InfoFetcher : IInfoFetcher {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code> private const string UndefinedSerialNumber = "number";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code> private readonly string _f32RemExecutable;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code> private readonly string[] _f32RemArguments;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code> private readonly int _f32SuccessExitCode;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code> private readonly int _f32WaitTimeoutMs;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code> private readonly uint _maxAttempts;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code> private readonly uint _waitPeriodMs;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code> private readonly string _infoFilePath;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code> public IProcessUtils ProcessUtils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code> public IFileUtils FileUtils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code> public string HeadSerialNumber { get; set; } = UndefinedSerialNumber;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code> public string BodySerialNumber { get; set; } = UndefinedSerialNumber;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code> public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code> string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code> _maxAttempts = maxAttempts;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code> _waitPeriodMs = waitPeriodMs;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code> _infoFilePath = infoFilePath;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code> _f32RemExecutable = f32RemExecutable;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code> _f32RemArguments = f32RemArguments;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code> _f32SuccessExitCode = f32SuccessExitCode;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code> _f32WaitTimeoutMs = f32WaitTimeoutMs;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code> ProcessUtils = new ProcessUtils();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code> FileUtils = new FileUtils();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> public async Task<bool> FetchDataAsync() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info("Fetching data from the debugger.");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code> var success = SendRetrieveInfoCommands(_f32RemExecutable, _f32RemArguments, _f32SuccessExitCode, _f32WaitTim</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code> if (!success) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Error("Failed to fetch data from the debugger.");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code> return false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> for (var i = 0; i < _maxAttempts; i++) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info($"{i}. attempt to parse the info file.");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code> if (RetrieveDebuggerInfo(_infoFilePath)) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info($"Info file has been parsed successfully.");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code> return true;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code> await Task.Delay((int)_waitPeriodMs);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created.");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code> return false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code> private bool RetrieveDebuggerInfo(string filePath) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code> try {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code> var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code> var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code> HeadSerialNumber = headSerialNumber;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code> BodySerialNumber = bodySerialNumber;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code> File.Delete(filePath);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code> } catch (Exception exception) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code> return false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code> return true;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code> private bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int desiredExitCo</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code> if (arguments == null) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code> return false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code> foreach (var argument in arguments) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code> if (!ProcessUtils.ExecuteNewProcess(executableFile, argument, waitTimeoutMs, desiredExitCode)) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code> return false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code> return true;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadSerialNumber()"><i class="icon-wrench"></i>HeadSerialNumber()</a><br /> +<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadSerialNumber(string)"><i class="icon-wrench"></i>HeadSerialNumber(string)</a><br /> +<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - InfoFetcher(uint, uint, string, string, string[], int, int)"><i class="icon-cube"></i>InfoFetcher(uint, uint, string, string, string[], int, int)</a><br /> +<a href="#file0_line23" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodySerialNumber()"><i class="icon-wrench"></i>BodySerialNumber()</a><br /> +<a href="#file0_line23" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodySerialNumber(string)"><i class="icon-wrench"></i>BodySerialNumber(string)</a><br /> +<a href="#file0_line40" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync()"><i class="icon-cube"></i>FetchDataAsync()</a><br /> +<a href="#file0_line59" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetrieveDebuggerInfo(string)"><i class="icon-cube"></i>RetrieveDebuggerInfo(string)</a><br /> +<a href="#file0_line73" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendRetrieveInfoCommands(string, System.Collections.Generic.IReadOnlyList<string>, int, int)"><i class="icon-cube"></i>SendRetrieveInfoCommands(string, System.Collections.Generic.IReadOnlyList<string>, int, int)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html new file mode 100644 index 0000000..9c252eb --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html @@ -0,0 +1,232 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.network.data.Payload - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.network.data.Payload">LDClient.network.data.Payload</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataPayloadcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\Payload.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar15">85%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="17">17</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="3">3</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="20">20</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="49">49</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="17 of 20">85%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ToString()"><a href="#file0_line31" class="navigatetohash">ToString()</a></td><td>3</td><td>0</td></tr> +<tr><td title="ParseToJson()"><a href="#file0_line35" class="navigatetohash">ParseToJson()</a></td><td>0</td><td>3</td></tr> +<tr><td title="ParseToJson(LDClient.network.data.Payload)"><a href="#file0_line39" class="navigatetohash">ParseToJson(...)</a></td><td>8</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataPayloadcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\Payload.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Text.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Text.Json.Serialization;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using Newtonsoft.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using JsonSerializer = System.Text.Json.JsonSerializer;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>namespace LDClient.network.data {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code> [JsonObject(MemberSerialization.OptIn)]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code> public class Payload {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code> [JsonPropertyName("username")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code> public string? UserName { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code> [JsonPropertyName("hostname")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code> public string? HostName { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code> [JsonPropertyName("timestamp")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code> public string? TimeStamp { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code> [JsonPropertyName("head_device")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code> public DebuggerInfo? HeadDevice { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code> [JsonPropertyName("body_device")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code> public DebuggerInfo? BodyDevice { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code> [JsonPropertyName("status")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code> public ConnectionStatus Status { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code> public override string ToString() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code> return ParseToJson(this);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightred"><code> public string ParseToJson() {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code> return Payload.ParseToJson(this);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code> public static string ParseToJson(Payload payload) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> var options = new JsonSerializerOptions {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code> Converters = {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code> new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code> };</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code> return JsonSerializer.Serialize(payload, options);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line12" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - UserName()"><i class="icon-wrench"></i>UserName()</a><br /> +<a href="#file0_line12" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - UserName(string)"><i class="icon-wrench"></i>UserName(string)</a><br /> +<a href="#file0_line15" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HostName()"><i class="icon-wrench"></i>HostName()</a><br /> +<a href="#file0_line15" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HostName(string)"><i class="icon-wrench"></i>HostName(string)</a><br /> +<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - TimeStamp()"><i class="icon-wrench"></i>TimeStamp()</a><br /> +<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - TimeStamp(string)"><i class="icon-wrench"></i>TimeStamp(string)</a><br /> +<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadDevice()"><i class="icon-wrench"></i>HeadDevice()</a><br /> +<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadDevice(LDClient.network.data.DebuggerInfo)"><i class="icon-wrench"></i>HeadDevice(LDClient.network.data.DebuggerInfo)</a><br /> +<a href="#file0_line25" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodyDevice()"><i class="icon-wrench"></i>BodyDevice()</a><br /> +<a href="#file0_line25" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodyDevice(LDClient.network.data.DebuggerInfo)"><i class="icon-wrench"></i>BodyDevice(LDClient.network.data.DebuggerInfo)</a><br /> +<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Status()"><i class="icon-wrench"></i>Status()</a><br /> +<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Status(LDClient.network.data.ConnectionStatus)"><i class="icon-wrench"></i>Status(LDClient.network.data.ConnectionStatus)</a><br /> +<a href="#file0_line31" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ToString()"><i class="icon-cube"></i>ToString()</a><br /> +<a href="#file0_line35" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ParseToJson()"><i class="icon-cube"></i>ParseToJson()</a><br /> +<a href="#file0_line39" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ParseToJson(LDClient.network.data.Payload)"><i class="icon-cube"></i>ParseToJson(LDClient.network.data.Payload)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html new file mode 100644 index 0000000..367b986 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html @@ -0,0 +1,268 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.detection.ProcessDetection - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.detection.ProcessDetection">LDClient.detection.ProcessDetection</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessDetectioncs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessDetection.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="62">62</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="62">62</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="91">91</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="62 of 62">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ProcessDetection(string, uint, LDClient.detection.IInfoFetcher, LDClient.network.IApiClient, LDClient.detection.IProcessUtils)"><a href="#file0_line21" class="navigatetohash">ProcessDetection(...)</a></td><td>2</td><td>0</td></tr> +<tr><td title="RetrieveDataFromDebugger()"><a href="#file0_line32" class="navigatetohash">RetrieveDataFromDebugger()</a></td><td>12</td><td>0</td></tr> +<tr><td title="DebuggerDisconnected()"><a href="#file0_line40" class="navigatetohash">DebuggerDisconnected()</a></td><td>10</td><td>0</td></tr> +<tr><td title="DetectProcessAsync()"><a href="#file0_line49" class="navigatetohash">DetectProcessAsync()</a></td><td>27</td><td>0</td></tr> +<tr><td title="SendDataToServerAsync()"><a href="#file0_line65" class="navigatetohash">SendDataToServerAsync()</a></td><td>20</td><td>0</td></tr> +<tr><td title="RunPeriodicDetection()"><a href="#file0_line82" class="navigatetohash">RunPeriodicDetection()</a></td><td>10</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessDetectioncs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessDetection.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Diagnostics;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using LDClient.network;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using LDClient.network.data;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>namespace LDClient.detection {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code> public sealed class ProcessDetection : IProcessDetection {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code> private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code> private readonly string _processName;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code> private readonly uint _detectionPeriodMs;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code> private readonly IInfoFetcher _infoFetcher;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code> private readonly IApiClient _apiClient;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code> private readonly IProcessUtils _processUtils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code> private bool _processIsActive;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code> private bool _failedToRetrieveData;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code> private Payload? _lastConnectedPayload;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code> public bool DetectionRunning = false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code> public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, IApiClient apiClie</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code> _processName = processName;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code> _detectionPeriodMs = detectionPeriodMs;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code> _infoFetcher = infoFetcher;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code> _apiClient = apiClient;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code> _failedToRetrieveData = false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code> _processUtils = processUtils;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code> private async Task<bool> RetrieveDataFromDebugger() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code> var success = await _infoFetcher.FetchDataAsync();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code> if (success) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code> _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySeri</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code> return success;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> private async Task DebuggerDisconnected() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code> if (_lastConnectedPayload is not null) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code> _lastConnectedPayload.Status = ConnectionStatus.Disconnected;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code> _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code> await _apiClient.SendPayloadAsync(_lastConnectedPayload);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code> _lastConnectedPayload = null;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code> private async Task DetectProcessAsync() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code> var processExists = _processUtils.IsProcessRunning(_processName);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgreen"><code> if (processExists && !_processIsActive) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info($"Process started: {_processName}");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code> if (!_failedToRetrieveData) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code> _failedToRetrieveData = !await RetrieveDataFromDebugger();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code> } else if (!processExists && _processIsActive) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info($"Process stopped: {_processName}");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code> _failedToRetrieveData = false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code> await DebuggerDisconnected();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code> _processIsActive = processExists;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code> private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datet</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code> Payload payload = new() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code> UserName = Environment.UserName,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code> HostName = Environment.MachineName,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code> TimeStamp = DateTime.Now.ToString(datetimeFormat),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code> HeadDevice = new DebuggerInfo {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code> SerialNumber = headSerialNumber</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgreen"><code> },</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code> BodyDevice = new DebuggerInfo {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code> SerialNumber = bodySerialNumber</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code> },</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code> Status = ConnectionStatus.Connected</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code> };</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code> await _apiClient.SendPayloadAsync(payload);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code> return payload;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code> public async void RunPeriodicDetection() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code> Program.DefaultLogger.Info("Process periodic detector has started");</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code> DetectionRunning = true;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code> while (DetectionRunning) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code> await DetectProcessAsync();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code> Thread.Sleep((int)_detectionPeriodMs);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ProcessDetection(string, uint, LDClient.detection.IInfoFetcher, LDClient.network.IApiClient, LDClient.detection.IProcessUtils)"><i class="icon-cube"></i>ProcessDetection(string, uint, LDClient.detection.IInfoFetcher, LDClient.network.IApiClient, LDClient.detection.IProcessUtils)</a><br /> +<a href="#file0_line32" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetrieveDataFromDebugger()"><i class="icon-cube"></i>RetrieveDataFromDebugger()</a><br /> +<a href="#file0_line40" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DebuggerDisconnected()"><i class="icon-cube"></i>DebuggerDisconnected()</a><br /> +<a href="#file0_line49" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DetectProcessAsync()"><i class="icon-cube"></i>DetectProcessAsync()</a><br /> +<a href="#file0_line65" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendDataToServerAsync()"><i class="icon-cube"></i>SendDataToServerAsync()</a><br /> +<a href="#file0_line82" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection()"><i class="icon-cube"></i>RunPeriodicDetection()</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html new file mode 100644 index 0000000..d90cd9e --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html @@ -0,0 +1,209 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.detection.ProcessUtils - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.detection.ProcessUtils">LDClient.detection.ProcessUtils</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessUtilscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessUtils.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar100">0%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="20">20</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="20">20</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="40">40</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="0 of 20">0%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="IsProcessRunning(string)"><a href="#file0_line11" class="navigatetohash">IsProcessRunning(...)</a></td><td>0</td><td>3</td></tr> +<tr><td title="ExecuteNewProcess(string, string, int, int)"><a href="#file0_line16" class="navigatetohash">ExecuteNewProcess(...)</a></td><td>0</td><td>42</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessUtilscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessUtils.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Collections.Generic;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using System.Diagnostics;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using System.Linq;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using System.Text;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using System.Threading.Tasks;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>namespace LDClient.detection {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code> public class ProcessUtils : IProcessUtils{</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightred"><code> public bool IsProcessRunning(string name) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightred"><code> return Process.GetProcessesByName(name).Length > 0;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightred"><code> public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightred"><code> var t32RemProcess = new Process();</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightred"><code> t32RemProcess.StartInfo.FileName = fileName;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightred"><code> t32RemProcess.StartInfo.Arguments = argument;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightred"><code> try {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightred"><code> t32RemProcess.Start();</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightred"><code> if (!t32RemProcess.WaitForExit(timeout)) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightred"><code> Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} </code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightred"><code> return false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightred"><code> if (t32RemProcess.ExitCode != desiredExitCode) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightred"><code> Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}");</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightred"><code> return false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightred"><code> } catch (Exception exception) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightred"><code> Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}");</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightred"><code> return false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code> return true;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line11" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - IsProcessRunning(string)"><i class="icon-cube"></i>IsProcessRunning(string)</a><br /> +<a href="#file0_line16" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ExecuteNewProcess(string, string, int, int)"><i class="icon-cube"></i>ExecuteNewProcess(string, string, int, int)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html new file mode 100644 index 0000000..96ce423 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html @@ -0,0 +1,240 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClient.Program - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClient.Program">LDClient.Program</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclient.dll">ldclient.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientProgramcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\Program.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar74">25%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="11">11</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="32">32</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="43">43</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="67">67</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="11 of 43">25.5%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="Program()"><a href="#file0_line16" class="navigatetohash">Program()</a></td><td>18</td><td>0</td></tr> +<tr><td title="Main()"><a href="#file0_line30" class="navigatetohash">Main()</a></td><td>0</td><td>48</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientProgramcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\Program.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using DiskQueue;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using LDClient.detection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using LDClient.network;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using LDClient.utils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using LDClient.utils.loggers;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using static System.Diagnostics.Process;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>using static System.Reflection.Assembly;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code>namespace LDClient;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>internal static class Program {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code> private const int MainLoopDelayMs = 30000;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgreen"><code> public static ConfigLoader Config { get; } = new();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code> public static ALogger DefaultLogger { get; } = ALogger.Current;</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightred"><code> private static IApiClient? DefaultApiClient { get; set; }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code> private static readonly InfoFetcher InfoFetcher = new(</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code> Config.FetchInfoMaxAttempts,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code> Config.FetchInfoAttemptPeriod,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code> Config.T32InfoLocation,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code> Config.F32RemExecutable,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code> Config.F32RemArguments,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code> Config.T32RemSuccessExitCode,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code> Config.T32RemWaitTimeoutMs</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code> );</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightred"><code> public static int Main() {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightred"><code> if (GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightred"><code> DefaultLogger.Error("Another instance of the application is already running");</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightred"><code> return 1;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code> DefaultApiClient = new ApiClient(</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code> Config.ApiBaseAddress,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightred"><code> Config.ApiPort,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightred"><code> Config.ApiUsbEndPoint,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightred"><code> Config.RetryPeriod, Config.MaxEntries,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightred"><code> Config.MaxRetries,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightred"><code> new PersistentQueue(Config.CacheFileName)</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightred"><code> );</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightred"><code> IProcessDetection processProcessDetection = new ProcessDetection(</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightred"><code> Config.T32ProcessName,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightred"><code> Config.DetectionPeriod,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightred"><code> InfoFetcher,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightred"><code> DefaultApiClient,</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightred"><code> new ProcessUtils()</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightred"><code> );</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightred"><code> var apiClientThread = new Thread(DefaultApiClient.Run) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightred"><code> IsBackground = true</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightred"><code> };</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightred"><code> apiClientThread.Start();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightred"><code> var processThread = new Thread(processProcessDetection.RunPeriodicDetection) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightred"><code> IsBackground = true</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightred"><code> };</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightred"><code> processThread.Start();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightred"><code> while (true) {</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightred"><code> Thread.Sleep(MainLoopDelayMs);</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red"> </td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightred"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line16" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Config()"><i class="icon-wrench"></i>Config()</a><br /> +<a href="#file0_line16" class="navigatetohash percentagebar percentagebar90" title="Line coverage: 91.6% - Program()"><i class="icon-cube"></i>Program()</a><br /> +<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DefaultLogger()"><i class="icon-wrench"></i>DefaultLogger()</a><br /> +<a href="#file0_line18" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - DefaultApiClient()"><i class="icon-wrench"></i>DefaultApiClient()</a><br /> +<a href="#file0_line18" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - DefaultApiClient(LDClient.network.IApiClient)"><i class="icon-wrench"></i>DefaultApiClient(LDClient.network.IApiClient)</a><br /> +<a href="#file0_line30" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Main()"><i class="icon-cube"></i>Main()</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html new file mode 100644 index 0000000..be4d31b --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html @@ -0,0 +1,344 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClientTests.network.ApiClientTests - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClientTests.network.ApiClientTests">LDClientTests.network.ApiClientTests</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsnetworkApiClientTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\network\ApiClientTests.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="81">81</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="81">81</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="167">167</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="81 of 81">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ApiClientTests()"><a href="#file0_line31" class="navigatetohash">ApiClientTests()</a></td><td>12</td><td>0</td></tr> +<tr><td title="Setup()"><a href="#file0_line53" class="navigatetohash">Setup()</a></td><td>60</td><td>0</td></tr> +<tr><td title="SendPayloadAsync_SendingSuccess_PayloadSent()"><a href="#file0_line73" class="navigatetohash">SendPayloadAsync_SendingSuccess_PayloadSent()</a></td><td>27</td><td>0</td></tr> +<tr><td title="SendPayloadAsync_SendingFailure_PayloadSaved2Cache()"><a href="#file0_line86" class="navigatetohash">SendPayloadAsync_SendingFailure_PayloadSaved2Cache()</a></td><td>63</td><td>0</td></tr> +<tr><td title="Run_EmptyCache_NothingSent()"><a href="#file0_line104" class="navigatetohash">Run_EmptyCache_NothingSent()</a></td><td>60</td><td>0</td></tr> +<tr><td title="Run_CacheContainX_SentX(int, int, int)"><a href="#file0_line138" class="navigatetohash">Run_CacheContainX_SentX(...)</a></td><td>70</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsnetworkApiClientTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\network\ApiClientTests.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Collections.Generic;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using System.Linq;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using System.Net.Http;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using System.Net.Http.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using System.Runtime.CompilerServices;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using System.Text;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>using System.Text.Json;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>using System.Threading;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code>using System.Threading.Tasks;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>using DiskQueue;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>using LDClient.network;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>using LDClient.network.data;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>using Moq;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code>using Newtonsoft.Json.Serialization;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>using NUnit.Framework;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code>using NUnit.Framework.Internal;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code>namespace LDClientTests.network {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code> internal class ApiClientTests {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code> private ApiClient _client;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code> private Mock<IHttpClient> _httpClientMock;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code> private Mock<IPersistentQueue> _cacheMock;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code> private Mock<IPersistentQueueSession> _cacheSessionMock;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code> public static readonly Payload ExamplePayload = new() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code> UserName = "honikCz",</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code> HostName = "Bramborak",</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code> TimeStamp = "2022-03-21 18:05:00",</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code> HeadDevice = new DebuggerInfo {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code> SerialNumber = "C12345678912"</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code> },</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> BodyDevice = new DebuggerInfo {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code> SerialNumber = "C98765432198"</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> },</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code> Status = ConnectionStatus.Connected</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code> };</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code> public static readonly string ApiUrl = "http://127.0.0.1";</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code> public static readonly string ApiEndPoint = "/lauterbach-debugger-logs/";</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code> public static readonly uint ApiPort = 8000;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> public static readonly uint ApiRetryPeriod = 50;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code> public static readonly uint ApiMaxEntries = 10;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code> public static readonly uint ApiMaxRetries = 5;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code> [SetUp]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code> public void Setup() {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code> _httpClientMock = new Mock<IHttpClient>(MockBehavior.Strict);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code> _cacheMock = new Mock<IPersistentQueue>(MockBehavior.Strict);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock = new Mock<IPersistentQueueSession>(MockBehavior.Strict);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Setup(x => x.Dequeue()).Returns(JsonSerializer.SerializeToUtf8Bytes(ExamplePayload));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Setup(x => x.Dispose()).Callback(() => { });</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Setup(p => p.Enqueue(It.IsAny<byte[]>())).Callback(() => { });</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Setup(p => p.Flush()).Callback(() => { });</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code> _cacheMock.Setup(p => p.OpenSession()).Returns(_cacheSessionMock.Object);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code> _client = new ApiClient(ApiUrl, ApiPort, ApiEndPoint, ApiRetryPeriod, ApiMaxEntries, ApiMaxRetries, _cacheMo</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code> _client = _httpClientMock.Object</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code> };</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code> public async Task SendPayloadAsync_SendingSuccess_PayloadSent() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code> .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code> await _client.SendPayloadAsync(ExamplePayload);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Verify(x => x.PostAsJsonAsync(It.IsAny<Payload>()), Times.Once);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgray"><code> [TestCase(15, true)]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgray"><code> [TestCase(0, false)]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code> public async Task SendPayloadAsync_SendingFailure_PayloadSaved2Cache(int itemsInQueueCount, bool isDequeueHappen</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code> .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity)));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code> _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(itemsInQueueCount);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code> await _client.SendPayloadAsync(ExamplePayload);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Once);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Verify(x => x.PostAsJsonAsync(It.IsAny<Payload>()), Times.Once);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Verify(x => x.Flush(), Times.Once);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Verify(x => x.Dequeue(), isDequeueHappening ? Times.Once : Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgray"><code> [Timeout(1000)]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgreen"><code> public void Run_EmptyCache_NothingSent() {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgray"><code> //nothing in cache</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code> _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(0);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgreen"><code> .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity)));</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgreen"><code> var clientThread = new Thread(_client.Run);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgreen"><code> clientThread.Start();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(400);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgreen"><code> _client.ClientRunning = false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgray"><code> //_processDetection.DetectionRunning = false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgreen"><code> clientThread.Join();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line118"></a><code>118</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Verify(p => p.PostAsJsonAsync(It.IsAny<Payload>()), Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line119"></a><code>119</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line120"></a><code>120</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Verify(p => p.Flush(), Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line121"></a><code>121</code></td><td></td><td class="lightgreen"><code> _cacheMock.Verify(p => p.EstimatedCountOfItemsInQueue, Times.AtLeastOnce);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line122"></a><code>122</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line123"></a><code>123</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line124"></a><code>124</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line125"></a><code>125</code></td><td></td><td class="lightgray"><code> /// <summary></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line126"></a><code>126</code></td><td></td><td class="lightgray"><code> /// Some tests here can fail due to not long enough sleep period.</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line127"></a><code>127</code></td><td></td><td class="lightgray"><code> ///</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line128"></a><code>128</code></td><td></td><td class="lightgray"><code> /// </summary></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line129"></a><code>129</code></td><td></td><td class="lightgray"><code> /// <param name="itemsInQueueCount"></param></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line130"></a><code>130</code></td><td></td><td class="lightgray"><code> /// <param name="flushedHappened"></param></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line131"></a><code>131</code></td><td></td><td class="lightgray"><code> /// <param name="testSleep"></param></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line132"></a><code>132</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line133"></a><code>133</code></td><td></td><td class="lightgray"><code> [Timeout(5000)]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line134"></a><code>134</code></td><td></td><td class="lightgray"><code> [TestCase(100, 20, 2000)]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line135"></a><code>135</code></td><td></td><td class="lightgray"><code> [TestCase(15, 3, 600)]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line136"></a><code>136</code></td><td></td><td class="lightgray"><code> [TestCase(1, 1, 200)]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line137"></a><code>137</code></td><td></td><td class="lightgray"><code> [TestCase(6, 2, 400)]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line138"></a><code>138</code></td><td></td><td class="lightgreen"><code> public void Run_CacheContainX_SentX(int itemsInQueueCount, int flushedHappened, int testSleep) {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line139"></a><code>139</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line140"></a><code>140</code></td><td></td><td class="lightgreen"><code> var cacheItemCount = itemsInQueueCount;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line141"></a><code>141</code></td><td></td><td class="lightgray"><code> //nothing in cache</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line142"></a><code>142</code></td><td></td><td class="lightgreen"><code> _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(() => { return cacheItemCount; });</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line143"></a><code>143</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line144"></a><code>144</code></td><td></td><td class="lightgreen"><code> .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line145"></a><code>145</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Setup(x => x.Dequeue())</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line146"></a><code>146</code></td><td></td><td class="lightgreen"><code> .Returns(() => {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line147"></a><code>147</code></td><td></td><td class="lightgreen"><code> --cacheItemCount;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line148"></a><code>148</code></td><td></td><td class="lightgreen"><code> return JsonSerializer.SerializeToUtf8Bytes(ExamplePayload);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line149"></a><code>149</code></td><td></td><td class="lightgreen"><code> });</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line150"></a><code>150</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line151"></a><code>151</code></td><td></td><td class="lightgreen"><code> var clientThread = new Thread(_client.Run);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line152"></a><code>152</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line153"></a><code>153</code></td><td></td><td class="lightgreen"><code> clientThread.Start();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line154"></a><code>154</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(testSleep);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line155"></a><code>155</code></td><td></td><td class="lightgreen"><code> _client.ClientRunning = false;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line156"></a><code>156</code></td><td></td><td class="lightgray"><code> //_processDetection.DetectionRunning = false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line157"></a><code>157</code></td><td></td><td class="lightgreen"><code> clientThread.Join();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line158"></a><code>158</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line159"></a><code>159</code></td><td></td><td class="lightgreen"><code> _httpClientMock.Verify(p => p.PostAsJsonAsync(It.IsAny<Payload>()), Times.Exactly(itemsInQueueCount));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line160"></a><code>160</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line161"></a><code>161</code></td><td></td><td class="lightgreen"><code> _cacheSessionMock.Verify(p => p.Flush(), Times.Exactly(flushedHappened));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line162"></a><code>162</code></td><td></td><td class="lightgreen"><code> _cacheMock.Verify(p => p.EstimatedCountOfItemsInQueue, Times.AtLeastOnce);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line163"></a><code>163</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line164"></a><code>164</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line165"></a><code>165</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line166"></a><code>166</code></td><td></td><td class="lightgray"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line167"></a><code>167</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line31" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiClientTests()"><i class="icon-cube"></i>ApiClientTests()</a><br /> +<a href="#file0_line53" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Setup()"><i class="icon-cube"></i>Setup()</a><br /> +<a href="#file0_line73" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendPayloadAsync_SendingSuccess_PayloadSent()"><i class="icon-cube"></i>SendPayloadAsync_SendingSuccess_PayloadSent()</a><br /> +<a href="#file0_line86" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendPayloadAsync_SendingFailure_PayloadSaved2Cache()"><i class="icon-cube"></i>SendPayloadAsync_SendingFailure_PayloadSaved2Cache()</a><br /> +<a href="#file0_line104" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Run_EmptyCache_NothingSent()"><i class="icon-cube"></i>Run_EmptyCache_NothingSent()</a><br /> +<a href="#file0_line138" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Run_CacheContainX_SentX(int, int, int)"><i class="icon-cube"></i>Run_CacheContainX_SentX(int, int, int)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html new file mode 100644 index 0000000..3830ab5 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html @@ -0,0 +1,237 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClientTests.detection.DebuggerInfoParserTests - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClientTests.detection.DebuggerInfoParserTests">LDClientTests.detection.DebuggerInfoParserTests</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionDebuggerInfoParserTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\DebuggerInfoParserTests.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="18">18</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="18">18</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="66">66</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="18 of 18">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="DebuggerInfoParserTests()"><a href="#file0_line9" class="navigatetohash">DebuggerInfoParserTests()</a></td><td>1</td><td>0</td></tr> +<tr><td title="Parse_CorrectValues_ReturnSerials(string, string, string)"><a href="#file0_line37" class="navigatetohash">Parse_CorrectValues_ReturnSerials(...)</a></td><td>4</td><td>0</td></tr> +<tr><td title="Parse_IncorrectValues_ThrowException(string)"><a href="#file0_line61" class="navigatetohash">Parse_IncorrectValues_ThrowException(...)</a></td><td>3</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionDebuggerInfoParserTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\DebuggerInfoParserTests.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using LDClient.detection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using NUnit.Framework;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>namespace LDClientTests.detection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>public class DebuggerInfoParserTests {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgreen"><code> public static readonly string CorrectFileContent =</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgreen"><code> "B::version.hardware \r\n\r\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgreen"><code> "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code> " Serial Number: C12345678912 \r\n\r\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgreen"><code> " Firmware R.2021.02 (136263) \r\n\r\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgreen"><code> " Instance: 1. \r\n\r\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code> " Automotive Debug Cable \r\n\r\n" +</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgreen"><code> " Serial Number: C98765432198 ";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code> public static readonly string HeadSerialNumber = "C98765432198";</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code> public static readonly string BodySerialNumber = "C12345678912";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code> [TestCase("B::version.hardware \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code> "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code> " Serial Number: C12345678912 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code> " Firmware R.2021.02 (136263) \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code> " Instance: 1. \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code> " Automotive Debug Cable \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code> " Serial Number: C12345678912 ", "C12345678912", "C12345678912")]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code> [TestCase("B::version.hardware \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code> "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code> " Serial Number: C1awfaw484 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgray"><code> " Firmware R.2021.02 (136263) \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code> " Instance: 1. \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code> " Automotive Debug Cable \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgray"><code> " Serial Number: C16468551", "C16468551", "C1awfaw484")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code> public void Parse_CorrectValues_ReturnSerials(string file, string expectedHead, string expectedBody) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> var (headResult, bodyResult) = DebuggerInfoParser.Parse(file);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> Assert.AreEqual(expectedHead, headResult);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code> Assert.AreEqual(expectedBody, bodyResult);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgray"><code> [TestCase("B::version.hardware \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgray"><code> "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code> " Serial Number: C12345678912 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code> " Firmware R.2021.02 (136263) \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code> " Instance: 1. \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code> " Automotive Debug Cable \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code> " Serial Number: C12345678912 \n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgray"><code> " Serial Number: C12345678912 ")]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code> [TestCase("B::version.hardware \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code> "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgray"><code> " Serial Number: C1awfaw484 \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code> " Firmware R.2021.02 (136263) \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code> " Instance: 1. \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code> " Automotive Debug Cable \r\n\r\n" +</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgray"><code> " Serial Numbeeeer: C16468551")]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code> public void Parse_IncorrectValues_ThrowException(string file) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code> Assert.Throws<ArgumentException>(() => DebuggerInfoParser.Parse(file));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line9" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DebuggerInfoParserTests()"><i class="icon-cube"></i>DebuggerInfoParserTests()</a><br /> +<a href="#file0_line37" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Parse_CorrectValues_ReturnSerials(string, string, string)"><i class="icon-cube"></i>Parse_CorrectValues_ReturnSerials(string, string, string)</a><br /> +<a href="#file0_line61" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Parse_IncorrectValues_ThrowException(string)"><i class="icon-cube"></i>Parse_IncorrectValues_ThrowException(string)</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html new file mode 100644 index 0000000..686512c --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html @@ -0,0 +1,294 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClientTests.detection.InfoFetcherTests - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClientTests.detection.InfoFetcherTests">LDClientTests.detection.InfoFetcherTests</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionInfoFetcherTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\InfoFetcherTests.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="59">59</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="59">59</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="117">117</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="59 of 59">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="InfoFetcherTests()"><a href="#file0_line15" class="navigatetohash">InfoFetcherTests()</a></td><td>2</td><td>0</td></tr> +<tr><td title="Setup()"><a href="#file0_line22" class="navigatetohash">Setup()</a></td><td>9</td><td>0</td></tr> +<tr><td title="FetchDataAsync_ExecuteAll_ExecutedAndFetched()"><a href="#file0_line43" class="navigatetohash">FetchDataAsync_ExecuteAll_ExecutedAndFetched()</a></td><td>59</td><td>0</td></tr> +<tr><td title="FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()"><a href="#file0_line65" class="navigatetohash">FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()</a></td><td>64</td><td>0</td></tr> +<tr><td title="FetchDataAsync_ExecuteWithoutParameters_NotExecuted()"><a href="#file0_line83" class="navigatetohash">FetchDataAsync_ExecuteWithoutParameters_NotExecuted()</a></td><td>64</td><td>0</td></tr> +<tr><td title="FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()"><a href="#file0_line100" class="navigatetohash">FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()</a></td><td>65</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionInfoFetcherTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\InfoFetcherTests.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.IO;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Threading.Tasks;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using LDClient.detection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using LDClient.utils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using Moq;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using NUnit.Framework;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>namespace LDClientTests.detection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code>internal class InfoFetcherTests {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code> private InfoFetcher _defaultFetcher;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code> private InfoFetcher _fetcherWithoutPars;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code> private readonly string[] _defaultArguments = new[] { "argument 1", "argument 2" , "argument 3"};</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code> private const uint DefaultMaxAttempts = 5;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code> private Mock<IProcessUtils> _mockProcessUtils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code> private Mock<IFileUtils> _mockFileUtils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code> [SetUp]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code> public void Setup() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code> _mockFileUtils = new Mock<IFileUtils>(MockBehavior.Strict);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code> _defaultFetcher = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code> _defaultArguments, 0, 50) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code> FileUtils = _mockFileUtils.Object,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code> ProcessUtils = _mockProcessUtils.Object</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code> };</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code> _fetcherWithoutPars = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code> null, 0, 50) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code> FileUtils = _mockFileUtils.Object,</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code> ProcessUtils = _mockProcessUtils.Object</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code> };</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code> public async Task FetchDataAsync_ExecuteAll_ExecutedAndFetched() {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>())).Returns(true);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code> Returns(DebuggerInfoParserTests.CorrectFileContent.Split("\n"));</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code> var result = await _defaultFetcher.FetchDataAsync();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code> Assert.IsTrue(result);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(_defaultArguments.Length));</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code> Assert.AreEqual(DebuggerInfoParserTests.BodySerialNumber, _defaultFetcher.BodySerialNumber);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code> Assert.AreEqual(DebuggerInfoParserTests.HeadSerialNumber, _defaultFetcher.HeadSerialNumber);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code> public async Task FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed() {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>())).Returns(false);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code> _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code> Returns(new []{""});</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code> var result = await _defaultFetcher.FetchDataAsync();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code> Assert.IsFalse(result);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(1));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code> _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code> public async Task FetchDataAsync_ExecuteWithoutParameters_NotExecuted() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>())).Returns(false);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code> _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code> Returns(new[] { "" });</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code> var result = await _fetcherWithoutPars.FetchDataAsync();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgreen"><code> Assert.IsFalse(result);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>()), Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code> _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Never);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgreen"><code> public async Task FetchDataAsync_ExecuteInfoNotCreated_FetchFailed() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>())).Returns(true);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code> _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).Throws(new FileNotFoundException());</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code> var result = await _defaultFetcher.FetchDataAsync();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code> Assert.IsFalse(result);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgreen"><code> It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(_defaultArguments.Length));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgreen"><code> _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Exactly((int)DefaultMaxAttempts));</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line15" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - InfoFetcherTests()"><i class="icon-cube"></i>InfoFetcherTests()</a><br /> +<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Setup()"><i class="icon-cube"></i>Setup()</a><br /> +<a href="#file0_line43" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteAll_ExecutedAndFetched()"><i class="icon-cube"></i>FetchDataAsync_ExecuteAll_ExecutedAndFetched()</a><br /> +<a href="#file0_line65" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()"><i class="icon-cube"></i>FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()</a><br /> +<a href="#file0_line83" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteWithoutParameters_NotExecuted()"><i class="icon-cube"></i>FetchDataAsync_ExecuteWithoutParameters_NotExecuted()</a><br /> +<a href="#file0_line100" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()"><i class="icon-cube"></i>FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html new file mode 100644 index 0000000..b46a892 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html @@ -0,0 +1,311 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> +<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" /> +<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" /> +<title>LDClientTests.detection.ProcessDetectionTests - Coverage Report</title> +<link rel="stylesheet" type="text/css" href="report.css" /> +</head><body><div class="container"><div class="containerleft"> +<h1><a href="index.html" class="back"><</a> Summary</h1> +<div class="card-group"> +<div class="card"> +<div class="card-header">Information</div> +<div class="card-body"> +<div class="table"> +<table> +<tr> +<th>Class:</th> +<td class="limit-width " title="LDClientTests.detection.ProcessDetectionTests">LDClientTests.detection.ProcessDetectionTests</td> +</tr> +<tr> +<th>Assembly:</th> +<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td> +</tr> +<tr> +<th>File(s):</th> +<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionProcessDetectionTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\ProcessDetectionTests.cs</a></td> +</tr> +</table> +</div> +</div> +</div> +</div> +<div class="card-group"> +<div class="card"> +<div class="card-header">Line coverage</div> +<div class="card-body"> +<div class="large cardpercentagebar cardpercentagebar0">100%</div> +<div class="table"> +<table> +<tr> +<th>Covered lines:</th> +<td class="limit-width right" title="61">61</td> +</tr> +<tr> +<th>Uncovered lines:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Coverable lines:</th> +<td class="limit-width right" title="61">61</td> +</tr> +<tr> +<th>Total lines:</th> +<td class="limit-width right" title="132">132</td> +</tr> +<tr> +<th>Line coverage:</th> +<td class="limit-width right" title="61 of 61">100%</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Branch coverage</div> +<div class="card-body"> +<div class="large">N/A</div> +<div class="table"> +<table> +<tr> +<th>Covered branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Total branches:</th> +<td class="limit-width right" title="0">0</td> +</tr> +<tr> +<th>Branch coverage:</th> +<td class="limit-width right" title="N/A">N/A</td> +</tr> +</table> +</div> +</div> +</div> +<div class="card"> +<div class="card-header">Method coverage</div> +<div class="card-body"> +<div class="center"> +<p>Method coverage is only available for sponsors.</p> +<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a> +</div> +</div> +</div> +</div> +<h1>Metrics</h1> +<div class="table-responsive"> +<table class="overview table-fixed"> +<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead> +<tbody> +<tr><td title="ProcessDetectionTests()"><a href="#file0_line20" class="navigatetohash">ProcessDetectionTests()</a></td><td>2</td><td>0</td></tr> +<tr><td title="Setup()"><a href="#file0_line24" class="navigatetohash">Setup()</a></td><td>33</td><td>0</td></tr> +<tr><td title="StartAndStopDetection(int)"><a href="#file0_line40" class="navigatetohash">StartAndStopDetection(...)</a></td><td>6</td><td>0</td></tr> +<tr><td title="RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()"><a href="#file0_line53" class="navigatetohash">RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()</a></td><td>39</td><td>0</td></tr> +<tr><td title="RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()"><a href="#file0_line66" class="navigatetohash">RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()</a></td><td>39</td><td>0</td></tr> +<tr><td title="RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()"><a href="#file0_line81" class="navigatetohash">RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()</a></td><td>54</td><td>0</td></tr> +<tr><td title="RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()"><a href="#file0_line105" class="navigatetohash">RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()</a></td><td>76</td><td>0</td></tr> +</tbody> +</table> +</div> +<h1>File(s)</h1> +<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionProcessDetectionTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\ProcessDetectionTests.cs</h2> +<div class="table-responsive"> +<table class="lineAnalysis"> +<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead> +<tbody> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using System.Threading;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using System.Threading.Tasks;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using LDClient.detection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using LDClient.network;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using LDClient.network.data;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using Moq;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using NUnit.Framework;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>namespace LDClientTests.detection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>public class ProcessDetectionTests {</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code> private ProcessDetection _processDetection;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code> private Mock<IApiClient> _mockApiClient;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code> private Mock<IInfoFetcher> _mockInfoFetcher;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code> private Mock<IProcessUtils> _mockProcessUtils;</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code> private readonly string _defaultSerialNumber = "C12345678912";</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code> [SetUp]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code> public void Setup() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code> _mockApiClient = new Mock<IApiClient>(MockBehavior.Strict);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code> _mockApiClient.Setup(x => x.SendPayloadAsync(It.IsAny<Payload>())).Returns(Task.CompletedTask);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher = new Mock<IInfoFetcher>(MockBehavior.Strict);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Setup(x => x.BodySerialNumber).Returns(_defaultSerialNumber);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Setup(x => x.HeadSerialNumber).Returns(_defaultSerialNumber);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code> _processDetection = new ProcessDetection("process", 50, _mockInfoFetcher.Object, _mockApiClient.Object, _mockPro</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code> private void StartAndStopDetection(int timeout) {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code> var detectionThread = new Thread(_processDetection.RunPeriodicDetection);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code> detectionThread.Start();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(timeout);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code> _processDetection.DetectionRunning = false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code> detectionThread.Join();</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code> [Timeout(1000)]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code> public void RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(false));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code> StartAndStopDetection(500);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code> _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Never);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code> [Timeout(1000)]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code> public void RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code> StartAndStopDetection(500);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code> _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Once);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgray"><code> [Timeout(1000)]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgreen"><code> public void RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code> var detectionThread = new Thread(_processDetection.RunPeriodicDetection);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code> detectionThread.Start();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(250);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(250);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code> _processDetection.DetectionRunning = false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code> detectionThread.Join();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgreen"><code> _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Exactly(2));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgray"><code> [Test]</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgray"><code> [Timeout(2000)]</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code> public void RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent() {</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgreen"><code> var detectionThread = new Thread(_processDetection.RunPeriodicDetection);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgreen"><code> detectionThread.Start();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(200);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(200);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line118"></a><code>118</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line119"></a><code>119</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line120"></a><code>120</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(200);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line121"></a><code>121</code></td><td></td><td class="lightgreen"><code> _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false);</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line122"></a><code>122</code></td><td></td><td class="lightgreen"><code> Thread.Sleep(200);</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line123"></a><code>123</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line124"></a><code>124</code></td><td></td><td class="lightgreen"><code> _processDetection.DetectionRunning = false;</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line125"></a><code>125</code></td><td></td><td class="lightgreen"><code> detectionThread.Join();</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line126"></a><code>126</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line127"></a><code>127</code></td><td></td><td class="lightgreen"><code> _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Exactly(4));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line128"></a><code>128</code></td><td></td><td class="lightgreen"><code> _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Exactly(2));</code></td></tr> +<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green"> </td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line129"></a><code>129</code></td><td></td><td class="lightgreen"><code> }</code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line130"></a><code>130</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line131"></a><code>131</code></td><td></td><td class="lightgray"><code></code></td></tr> +<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray"> </td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line132"></a><code>132</code></td><td></td><td class="lightgray"><code>}</code></td></tr> +</tbody> +</table> +</div> +<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div> +<div class="containerright"> +<div class="containerrightfixed"> +<h1>Methods/Properties</h1> +<a href="#file0_line20" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ProcessDetectionTests()"><i class="icon-cube"></i>ProcessDetectionTests()</a><br /> +<a href="#file0_line24" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Setup()"><i class="icon-cube"></i>Setup()</a><br /> +<a href="#file0_line40" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - StartAndStopDetection(int)"><i class="icon-cube"></i>StartAndStopDetection(int)</a><br /> +<a href="#file0_line53" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()</a><br /> +<a href="#file0_line66" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()</a><br /> +<a href="#file0_line81" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()</a><br /> +<a href="#file0_line105" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()</a><br /> +<br/></div> +</div></div> +<script type="text/javascript"> +/* <![CDATA[ */ +(function() { + var url = window.location.href; + var startOfQueryString = url.indexOf('?'); + var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : ''; + + if (startOfQueryString > -1) { + var i = 0, href= null; + var css = document.getElementsByTagName('link'); + + for (i = 0; i < css.length; i++) { + if (css[i].getAttribute('rel') !== 'stylesheet') { + continue; + } + + href = css[i].getAttribute('href'); + + if (href) { + css[i].setAttribute('href', href + queryString); + } + } + + var links = document.getElementsByTagName('a'); + + for (i = 0; i < links.length; i++) { + href = links[i].getAttribute('href'); + + if (href + && !href.startsWith('http://') + && !href.startsWith('https://') + && !href.startsWith('#') + && href.indexOf('?') === -1) { + links[i].setAttribute('href', href + queryString); + } + } + } + + var newScript = document.createElement('script'); + newScript.src = 'class.js' + queryString; + document.getElementsByTagName('body')[0].appendChild(newScript); +})(); +/* ]]> */ +</script> +</body></html> \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/main.js b/ld_client/doc/coverage/coveragereport/main.js new file mode 100644 index 0000000..51d2896 --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/main.js @@ -0,0 +1,301 @@ +/* Chartist.js 0.11.4 + * Copyright © 2019 Gion Kunz + * Free to use under either the WTFPL license or the MIT license. + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT + */ + +!function (a, b) { "function" == typeof define && define.amd ? define("Chartist", [], function () { return a.Chartist = b() }) : "object" == typeof module && module.exports ? module.exports = b() : a.Chartist = b() }(this, function () { + var a = { version: "0.11.4" }; return function (a, b) { "use strict"; var c = a.window, d = a.document; b.namespaces = { svg: "http://www.w3.org/2000/svg", xmlns: "http://www.w3.org/2000/xmlns/", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", ct: "http://gionkunz.github.com/chartist-js/ct" }, b.noop = function (a) { return a }, b.alphaNumerate = function (a) { return String.fromCharCode(97 + a % 26) }, b.extend = function (a) { var c, d, e; for (a = a || {}, c = 1; c < arguments.length; c++) { d = arguments[c]; for (var f in d) e = d[f], "object" != typeof e || null === e || e instanceof Array ? a[f] = e : a[f] = b.extend(a[f], e) } return a }, b.replaceAll = function (a, b, c) { return a.replace(new RegExp(b, "g"), c) }, b.ensureUnit = function (a, b) { return "number" == typeof a && (a += b), a }, b.quantity = function (a) { if ("string" == typeof a) { var b = /^(\d+)\s*(.*)$/g.exec(a); return { value: +b[1], unit: b[2] || void 0 } } return { value: a } }, b.querySelector = function (a) { return a instanceof Node ? a : d.querySelector(a) }, b.times = function (a) { return Array.apply(null, new Array(a)) }, b.sum = function (a, b) { return a + (b ? b : 0) }, b.mapMultiply = function (a) { return function (b) { return b * a } }, b.mapAdd = function (a) { return function (b) { return b + a } }, b.serialMap = function (a, c) { var d = [], e = Math.max.apply(null, a.map(function (a) { return a.length })); return b.times(e).forEach(function (b, e) { var f = a.map(function (a) { return a[e] }); d[e] = c.apply(null, f) }), d }, b.roundWithPrecision = function (a, c) { var d = Math.pow(10, c || b.precision); return Math.round(a * d) / d }, b.precision = 8, b.escapingMap = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, b.serialize = function (a) { return null === a || void 0 === a ? a : ("number" == typeof a ? a = "" + a : "object" == typeof a && (a = JSON.stringify({ data: a })), Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, c, b.escapingMap[c]) }, a)) }, b.deserialize = function (a) { if ("string" != typeof a) return a; a = Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, b.escapingMap[c], c) }, a); try { a = JSON.parse(a), a = void 0 !== a.data ? a.data : a } catch (c) { } return a }, b.createSvg = function (a, c, d, e) { var f; return c = c || "100%", d = d || "100%", Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function (a) { return a.getAttributeNS(b.namespaces.xmlns, "ct") }).forEach(function (b) { a.removeChild(b) }), f = new b.Svg("svg").attr({ width: c, height: d }).addClass(e), f._node.style.width = c, f._node.style.height = d, a.appendChild(f._node), f }, b.normalizeData = function (a, c, d) { var e, f = { raw: a, normalized: {} }; return f.normalized.series = b.getDataArray({ series: a.series || [] }, c, d), e = f.normalized.series.every(function (a) { return a instanceof Array }) ? Math.max.apply(null, f.normalized.series.map(function (a) { return a.length })) : f.normalized.series.length, f.normalized.labels = (a.labels || []).slice(), Array.prototype.push.apply(f.normalized.labels, b.times(Math.max(0, e - f.normalized.labels.length)).map(function () { return "" })), c && b.reverseData(f.normalized), f }, b.safeHasProperty = function (a, b) { return null !== a && "object" == typeof a && a.hasOwnProperty(b) }, b.isDataHoleValue = function (a) { return null === a || void 0 === a || "number" == typeof a && isNaN(a) }, b.reverseData = function (a) { a.labels.reverse(), a.series.reverse(); for (var b = 0; b < a.series.length; b++)"object" == typeof a.series[b] && void 0 !== a.series[b].data ? a.series[b].data.reverse() : a.series[b] instanceof Array && a.series[b].reverse() }, b.getDataArray = function (a, c, d) { function e(a) { if (b.safeHasProperty(a, "value")) return e(a.value); if (b.safeHasProperty(a, "data")) return e(a.data); if (a instanceof Array) return a.map(e); if (!b.isDataHoleValue(a)) { if (d) { var c = {}; return "string" == typeof d ? c[d] = b.getNumberOrUndefined(a) : c.y = b.getNumberOrUndefined(a), c.x = a.hasOwnProperty("x") ? b.getNumberOrUndefined(a.x) : c.x, c.y = a.hasOwnProperty("y") ? b.getNumberOrUndefined(a.y) : c.y, c } return b.getNumberOrUndefined(a) } } return a.series.map(e) }, b.normalizePadding = function (a, b) { return b = b || 0, "number" == typeof a ? { top: a, right: a, bottom: a, left: a } : { top: "number" == typeof a.top ? a.top : b, right: "number" == typeof a.right ? a.right : b, bottom: "number" == typeof a.bottom ? a.bottom : b, left: "number" == typeof a.left ? a.left : b } }, b.getMetaData = function (a, b) { var c = a.data ? a.data[b] : a[b]; return c ? c.meta : void 0 }, b.orderOfMagnitude = function (a) { return Math.floor(Math.log(Math.abs(a)) / Math.LN10) }, b.projectLength = function (a, b, c) { return b / c.range * a }, b.getAvailableHeight = function (a, c) { return Math.max((b.quantity(c.height).value || a.height()) - (c.chartPadding.top + c.chartPadding.bottom) - c.axisX.offset, 0) }, b.getHighLow = function (a, c, d) { function e(a) { if (void 0 !== a) if (a instanceof Array) for (var b = 0; b < a.length; b++)e(a[b]); else { var c = d ? +a[d] : +a; g && c > f.high && (f.high = c), h && c < f.low && (f.low = c) } } c = b.extend({}, c, d ? c["axis" + d.toUpperCase()] : {}); var f = { high: void 0 === c.high ? -Number.MAX_VALUE : +c.high, low: void 0 === c.low ? Number.MAX_VALUE : +c.low }, g = void 0 === c.high, h = void 0 === c.low; return (g || h) && e(a), (c.referenceValue || 0 === c.referenceValue) && (f.high = Math.max(c.referenceValue, f.high), f.low = Math.min(c.referenceValue, f.low)), f.high <= f.low && (0 === f.low ? f.high = 1 : f.low < 0 ? f.high = 0 : f.high > 0 ? f.low = 0 : (f.high = 1, f.low = 0)), f }, b.isNumeric = function (a) { return null !== a && isFinite(a) }, b.isFalseyButZero = function (a) { return !a && 0 !== a }, b.getNumberOrUndefined = function (a) { return b.isNumeric(a) ? +a : void 0 }, b.isMultiValue = function (a) { return "object" == typeof a && ("x" in a || "y" in a) }, b.getMultiValue = function (a, c) { return b.isMultiValue(a) ? b.getNumberOrUndefined(a[c || "y"]) : b.getNumberOrUndefined(a) }, b.rho = function (a) { function b(a, c) { return a % c === 0 ? c : b(c, a % c) } function c(a) { return a * a + 1 } if (1 === a) return a; var d, e = 2, f = 2; if (a % 2 === 0) return 2; do e = c(e) % a, f = c(c(f)) % a, d = b(Math.abs(e - f), a); while (1 === d); return d }, b.getBounds = function (a, c, d, e) { function f(a, b) { return a === (a += b) && (a *= 1 + (b > 0 ? o : -o)), a } var g, h, i, j = 0, k = { high: c.high, low: c.low }; k.valueRange = k.high - k.low, k.oom = b.orderOfMagnitude(k.valueRange), k.step = Math.pow(10, k.oom), k.min = Math.floor(k.low / k.step) * k.step, k.max = Math.ceil(k.high / k.step) * k.step, k.range = k.max - k.min, k.numberOfSteps = Math.round(k.range / k.step); var l = b.projectLength(a, k.step, k), m = l < d, n = e ? b.rho(k.range) : 0; if (e && b.projectLength(a, 1, k) >= d) k.step = 1; else if (e && n < k.step && b.projectLength(a, n, k) >= d) k.step = n; else for (; ;) { if (m && b.projectLength(a, k.step, k) <= d) k.step *= 2; else { if (m || !(b.projectLength(a, k.step / 2, k) >= d)) break; if (k.step /= 2, e && k.step % 1 !== 0) { k.step *= 2; break } } if (j++ > 1e3) throw new Error("Exceeded maximum number of iterations while optimizing scale step!") } var o = 2.221e-16; for (k.step = Math.max(k.step, o), h = k.min, i = k.max; h + k.step <= k.low;)h = f(h, k.step); for (; i - k.step >= k.high;)i = f(i, -k.step); k.min = h, k.max = i, k.range = k.max - k.min; var p = []; for (g = k.min; g <= k.max; g = f(g, k.step)) { var q = b.roundWithPrecision(g); q !== p[p.length - 1] && p.push(q) } return k.values = p, k }, b.polarToCartesian = function (a, b, c, d) { var e = (d - 90) * Math.PI / 180; return { x: a + c * Math.cos(e), y: b + c * Math.sin(e) } }, b.createChartRect = function (a, c, d) { var e = !(!c.axisX && !c.axisY), f = e ? c.axisY.offset : 0, g = e ? c.axisX.offset : 0, h = a.width() || b.quantity(c.width).value || 0, i = a.height() || b.quantity(c.height).value || 0, j = b.normalizePadding(c.chartPadding, d); h = Math.max(h, f + j.left + j.right), i = Math.max(i, g + j.top + j.bottom); var k = { padding: j, width: function () { return this.x2 - this.x1 }, height: function () { return this.y1 - this.y2 } }; return e ? ("start" === c.axisX.position ? (k.y2 = j.top + g, k.y1 = Math.max(i - j.bottom, k.y2 + 1)) : (k.y2 = j.top, k.y1 = Math.max(i - j.bottom - g, k.y2 + 1)), "start" === c.axisY.position ? (k.x1 = j.left + f, k.x2 = Math.max(h - j.right, k.x1 + 1)) : (k.x1 = j.left, k.x2 = Math.max(h - j.right - f, k.x1 + 1))) : (k.x1 = j.left, k.x2 = Math.max(h - j.right, k.x1 + 1), k.y2 = j.top, k.y1 = Math.max(i - j.bottom, k.y2 + 1)), k }, b.createGrid = function (a, c, d, e, f, g, h, i) { var j = {}; j[d.units.pos + "1"] = a, j[d.units.pos + "2"] = a, j[d.counterUnits.pos + "1"] = e, j[d.counterUnits.pos + "2"] = e + f; var k = g.elem("line", j, h.join(" ")); i.emit("draw", b.extend({ type: "grid", axis: d, index: c, group: g, element: k }, j)) }, b.createGridBackground = function (a, b, c, d) { var e = a.elem("rect", { x: b.x1, y: b.y2, width: b.width(), height: b.height() }, c, !0); d.emit("draw", { type: "gridBackground", group: a, element: e }) }, b.createLabel = function (a, c, e, f, g, h, i, j, k, l, m) { var n, o = {}; if (o[g.units.pos] = a + i[g.units.pos], o[g.counterUnits.pos] = i[g.counterUnits.pos], o[g.units.len] = c, o[g.counterUnits.len] = Math.max(0, h - 10), l) { var p = d.createElement("span"); p.className = k.join(" "), p.setAttribute("xmlns", b.namespaces.xhtml), p.innerText = f[e], p.style[g.units.len] = Math.round(o[g.units.len]) + "px", p.style[g.counterUnits.len] = Math.round(o[g.counterUnits.len]) + "px", n = j.foreignObject(p, b.extend({ style: "overflow: visible;" }, o)) } else n = j.elem("text", o, k.join(" ")).text(f[e]); m.emit("draw", b.extend({ type: "label", axis: g, index: e, group: j, element: n, text: f[e] }, o)) }, b.getSeriesOption = function (a, b, c) { if (a.name && b.series && b.series[a.name]) { var d = b.series[a.name]; return d.hasOwnProperty(c) ? d[c] : b[c] } return b[c] }, b.optionsProvider = function (a, d, e) { function f(a) { var f = h; if (h = b.extend({}, j), d) for (i = 0; i < d.length; i++) { var g = c.matchMedia(d[i][0]); g.matches && (h = b.extend(h, d[i][1])) } e && a && e.emit("optionsChanged", { previousOptions: f, currentOptions: h }) } function g() { k.forEach(function (a) { a.removeListener(f) }) } var h, i, j = b.extend({}, a), k = []; if (!c.matchMedia) throw "window.matchMedia not found! Make sure you're using a polyfill."; if (d) for (i = 0; i < d.length; i++) { var l = c.matchMedia(d[i][0]); l.addListener(f), k.push(l) } return f(), { removeMediaQueryListeners: g, getCurrentOptions: function () { return b.extend({}, h) } } }, b.splitIntoSegments = function (a, c, d) { var e = { increasingX: !1, fillHoles: !1 }; d = b.extend({}, e, d); for (var f = [], g = !0, h = 0; h < a.length; h += 2)void 0 === b.getMultiValue(c[h / 2].value) ? d.fillHoles || (g = !0) : (d.increasingX && h >= 2 && a[h] <= a[h - 2] && (g = !0), g && (f.push({ pathCoordinates: [], valueData: [] }), g = !1), f[f.length - 1].pathCoordinates.push(a[h], a[h + 1]), f[f.length - 1].valueData.push(c[h / 2])); return f } }(this || global, a), function (a, b) { "use strict"; b.Interpolation = {}, b.Interpolation.none = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e = new b.Svg.Path, f = !0, g = 0; g < c.length; g += 2) { var h = c[g], i = c[g + 1], j = d[g / 2]; void 0 !== b.getMultiValue(j.value) ? (f ? e.move(h, i, !1, j) : e.line(h, i, !1, j), f = !1) : a.fillHoles || (f = !0) } return e } }, b.Interpolation.simple = function (a) { var c = { divisor: 2, fillHoles: !1 }; a = b.extend({}, c, a); var d = 1 / Math.max(1, a.divisor); return function (c, e) { for (var f, g, h, i = new b.Svg.Path, j = 0; j < c.length; j += 2) { var k = c[j], l = c[j + 1], m = (k - f) * d, n = e[j / 2]; void 0 !== n.value ? (void 0 === h ? i.move(k, l, !1, n) : i.curve(f + m, g, k - m, l, k, l, !1, n), f = k, g = l, h = n) : a.fillHoles || (f = k = h = void 0) } return i } }, b.Interpolation.cardinal = function (a) { var c = { tension: 1, fillHoles: !1 }; a = b.extend({}, c, a); var d = Math.min(1, Math.max(0, a.tension)), e = 1 - d; return function f(c, g) { var h = b.splitIntoSegments(c, g, { fillHoles: a.fillHoles }); if (h.length) { if (h.length > 1) { var i = []; return h.forEach(function (a) { i.push(f(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(i) } if (c = h[0].pathCoordinates, g = h[0].valueData, c.length <= 4) return b.Interpolation.none()(c, g); for (var j, k = (new b.Svg.Path).move(c[0], c[1], !1, g[0]), l = 0, m = c.length; m - 2 * !j > l; l += 2) { var n = [{ x: +c[l - 2], y: +c[l - 1] }, { x: +c[l], y: +c[l + 1] }, { x: +c[l + 2], y: +c[l + 3] }, { x: +c[l + 4], y: +c[l + 5] }]; j ? l ? m - 4 === l ? n[3] = { x: +c[0], y: +c[1] } : m - 2 === l && (n[2] = { x: +c[0], y: +c[1] }, n[3] = { x: +c[2], y: +c[3] }) : n[0] = { x: +c[m - 2], y: +c[m - 1] } : m - 4 === l ? n[3] = n[2] : l || (n[0] = { x: +c[l], y: +c[l + 1] }), k.curve(d * (-n[0].x + 6 * n[1].x + n[2].x) / 6 + e * n[2].x, d * (-n[0].y + 6 * n[1].y + n[2].y) / 6 + e * n[2].y, d * (n[1].x + 6 * n[2].x - n[3].x) / 6 + e * n[2].x, d * (n[1].y + 6 * n[2].y - n[3].y) / 6 + e * n[2].y, n[2].x, n[2].y, !1, g[(l + 2) / 2]) } return k } return b.Interpolation.none()([]) } }, b.Interpolation.monotoneCubic = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function d(c, e) { var f = b.splitIntoSegments(c, e, { fillHoles: a.fillHoles, increasingX: !0 }); if (f.length) { if (f.length > 1) { var g = []; return f.forEach(function (a) { g.push(d(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(g) } if (c = f[0].pathCoordinates, e = f[0].valueData, c.length <= 4) return b.Interpolation.none()(c, e); var h, i, j = [], k = [], l = c.length / 2, m = [], n = [], o = [], p = []; for (h = 0; h < l; h++)j[h] = c[2 * h], k[h] = c[2 * h + 1]; for (h = 0; h < l - 1; h++)o[h] = k[h + 1] - k[h], p[h] = j[h + 1] - j[h], n[h] = o[h] / p[h]; for (m[0] = n[0], m[l - 1] = n[l - 2], h = 1; h < l - 1; h++)0 === n[h] || 0 === n[h - 1] || n[h - 1] > 0 != n[h] > 0 ? m[h] = 0 : (m[h] = 3 * (p[h - 1] + p[h]) / ((2 * p[h] + p[h - 1]) / n[h - 1] + (p[h] + 2 * p[h - 1]) / n[h]), isFinite(m[h]) || (m[h] = 0)); for (i = (new b.Svg.Path).move(j[0], k[0], !1, e[0]), h = 0; h < l - 1; h++)i.curve(j[h] + p[h] / 3, k[h] + m[h] * p[h] / 3, j[h + 1] - p[h] / 3, k[h + 1] - m[h + 1] * p[h] / 3, j[h + 1], k[h + 1], !1, e[h + 1]); return i } return b.Interpolation.none()([]) } }, b.Interpolation.step = function (a) { var c = { postpone: !0, fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e, f, g, h = new b.Svg.Path, i = 0; i < c.length; i += 2) { var j = c[i], k = c[i + 1], l = d[i / 2]; void 0 !== l.value ? (void 0 === g ? h.move(j, k, !1, l) : (a.postpone ? h.line(j, f, !1, g) : h.line(e, k, !1, l), h.line(j, k, !1, l)), e = j, f = k, g = l) : a.fillHoles || (e = f = g = void 0) } return h } } }(this || global, a), function (a, b) { "use strict"; b.EventEmitter = function () { function a(a, b) { d[a] = d[a] || [], d[a].push(b) } function b(a, b) { d[a] && (b ? (d[a].splice(d[a].indexOf(b), 1), 0 === d[a].length && delete d[a]) : delete d[a]) } function c(a, b) { d[a] && d[a].forEach(function (a) { a(b) }), d["*"] && d["*"].forEach(function (c) { c(a, b) }) } var d = []; return { addEventHandler: a, removeEventHandler: b, emit: c } } }(this || global, a), function (a, b) { "use strict"; function c(a) { var b = []; if (a.length) for (var c = 0; c < a.length; c++)b.push(a[c]); return b } function d(a, c) { var d = c || this.prototype || b.Class, e = Object.create(d); b.Class.cloneDefinitions(e, a); var f = function () { var a, c = e.constructor || function () { }; return a = this === b ? Object.create(e) : this, c.apply(a, Array.prototype.slice.call(arguments, 0)), a }; return f.prototype = e, f["super"] = d, f.extend = this.extend, f } function e() { var a = c(arguments), b = a[0]; return a.splice(1, a.length - 1).forEach(function (a) { Object.getOwnPropertyNames(a).forEach(function (c) { delete b[c], Object.defineProperty(b, c, Object.getOwnPropertyDescriptor(a, c)) }) }), b } b.Class = { extend: d, cloneDefinitions: e } }(this || global, a), function (a, b) { "use strict"; function c(a, c, d) { return a && (this.data = a || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.eventEmitter.emit("data", { type: "update", data: this.data })), c && (this.options = b.extend({}, d ? this.options : this.defaultOptions, c), this.initializeTimeoutId || (this.optionsProvider.removeMediaQueryListeners(), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter))), this.initializeTimeoutId || this.createChart(this.optionsProvider.getCurrentOptions()), this } function d() { return this.initializeTimeoutId ? i.clearTimeout(this.initializeTimeoutId) : (i.removeEventListener("resize", this.resizeListener), this.optionsProvider.removeMediaQueryListeners()), this } function e(a, b) { return this.eventEmitter.addEventHandler(a, b), this } function f(a, b) { return this.eventEmitter.removeEventHandler(a, b), this } function g() { i.addEventListener("resize", this.resizeListener), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter), this.eventEmitter.addEventHandler("optionsChanged", function () { this.update() }.bind(this)), this.options.plugins && this.options.plugins.forEach(function (a) { a instanceof Array ? a[0](this, a[1]) : a(this) }.bind(this)), this.eventEmitter.emit("data", { type: "initial", data: this.data }), this.createChart(this.optionsProvider.getCurrentOptions()), this.initializeTimeoutId = void 0 } function h(a, c, d, e, f) { this.container = b.querySelector(a), this.data = c || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.defaultOptions = d, this.options = e, this.responsiveOptions = f, this.eventEmitter = b.EventEmitter(), this.supportsForeignObject = b.Svg.isSupported("Extensibility"), this.supportsAnimations = b.Svg.isSupported("AnimationEventsAttribute"), this.resizeListener = function () { this.update() }.bind(this), this.container && (this.container.__chartist__ && this.container.__chartist__.detach(), this.container.__chartist__ = this), this.initializeTimeoutId = setTimeout(g.bind(this), 0) } var i = a.window; b.Base = b.Class.extend({ constructor: h, optionsProvider: void 0, container: void 0, svg: void 0, eventEmitter: void 0, createChart: function () { throw new Error("Base chart type can't be instantiated!") }, update: c, detach: d, on: e, off: f, version: b.version, supportsForeignObject: !1 }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f) { a instanceof Element ? this._node = a : (this._node = y.createElementNS(b.namespaces.svg, a), "svg" === a && this.attr({ "xmlns:ct": b.namespaces.ct })), c && this.attr(c), d && this.addClass(d), e && (f && e._node.firstChild ? e._node.insertBefore(this._node, e._node.firstChild) : e._node.appendChild(this._node)) } function d(a, c) { return "string" == typeof a ? c ? this._node.getAttributeNS(c, a) : this._node.getAttribute(a) : (Object.keys(a).forEach(function (c) { if (void 0 !== a[c]) if (c.indexOf(":") !== -1) { var d = c.split(":"); this._node.setAttributeNS(b.namespaces[d[0]], c, a[c]) } else this._node.setAttribute(c, a[c]) }.bind(this)), this) } function e(a, c, d, e) { return new b.Svg(a, c, d, this, e) } function f() { return this._node.parentNode instanceof SVGElement ? new b.Svg(this._node.parentNode) : null } function g() { for (var a = this._node; "svg" !== a.nodeName;)a = a.parentNode; return new b.Svg(a) } function h(a) { var c = this._node.querySelector(a); return c ? new b.Svg(c) : null } function i(a) { var c = this._node.querySelectorAll(a); return c.length ? new b.Svg.List(c) : null } function j() { return this._node } function k(a, c, d, e) { if ("string" == typeof a) { var f = y.createElement("div"); f.innerHTML = a, a = f.firstChild } a.setAttribute("xmlns", b.namespaces.xmlns); var g = this.elem("foreignObject", c, d, e); return g._node.appendChild(a), g } function l(a) { return this._node.appendChild(y.createTextNode(a)), this } function m() { for (; this._node.firstChild;)this._node.removeChild(this._node.firstChild); return this } function n() { return this._node.parentNode.removeChild(this._node), this.parent() } function o(a) { return this._node.parentNode.replaceChild(a._node, this._node), a } function p(a, b) { return b && this._node.firstChild ? this._node.insertBefore(a._node, this._node.firstChild) : this._node.appendChild(a._node), this } function q() { return this._node.getAttribute("class") ? this._node.getAttribute("class").trim().split(/\s+/) : [] } function r(a) { return this._node.setAttribute("class", this.classes(this._node).concat(a.trim().split(/\s+/)).filter(function (a, b, c) { return c.indexOf(a) === b }).join(" ")), this } function s(a) { var b = a.trim().split(/\s+/); return this._node.setAttribute("class", this.classes(this._node).filter(function (a) { return b.indexOf(a) === -1 }).join(" ")), this } function t() { return this._node.setAttribute("class", ""), this } function u() { return this._node.getBoundingClientRect().height } function v() { return this._node.getBoundingClientRect().width } function w(a, c, d) { return void 0 === c && (c = !0), Object.keys(a).forEach(function (e) { function f(a, c) { var f, g, h, i = {}; a.easing && (h = a.easing instanceof Array ? a.easing : b.Svg.Easing[a.easing], delete a.easing), a.begin = b.ensureUnit(a.begin, "ms"), a.dur = b.ensureUnit(a.dur, "ms"), h && (a.calcMode = "spline", a.keySplines = h.join(" "), a.keyTimes = "0;1"), c && (a.fill = "freeze", i[e] = a.from, this.attr(i), g = b.quantity(a.begin || 0).value, a.begin = "indefinite"), f = this.elem("animate", b.extend({ attributeName: e }, a)), c && setTimeout(function () { try { f._node.beginElement() } catch (b) { i[e] = a.to, this.attr(i), f.remove() } }.bind(this), g), d && f._node.addEventListener("beginEvent", function () { d.emit("animationBegin", { element: this, animate: f._node, params: a }) }.bind(this)), f._node.addEventListener("endEvent", function () { d && d.emit("animationEnd", { element: this, animate: f._node, params: a }), c && (i[e] = a.to, this.attr(i), f.remove()) }.bind(this)) } a[e] instanceof Array ? a[e].forEach(function (a) { f.bind(this)(a, !1) }.bind(this)) : f.bind(this)(a[e], c) }.bind(this)), this } function x(a) { var c = this; this.svgElements = []; for (var d = 0; d < a.length; d++)this.svgElements.push(new b.Svg(a[d])); Object.keys(b.Svg.prototype).filter(function (a) { return ["constructor", "parent", "querySelector", "querySelectorAll", "replace", "append", "classes", "height", "width"].indexOf(a) === -1 }).forEach(function (a) { c[a] = function () { var d = Array.prototype.slice.call(arguments, 0); return c.svgElements.forEach(function (c) { b.Svg.prototype[a].apply(c, d) }), c } }) } var y = a.document; b.Svg = b.Class.extend({ constructor: c, attr: d, elem: e, parent: f, root: g, querySelector: h, querySelectorAll: i, getNode: j, foreignObject: k, text: l, empty: m, remove: n, replace: o, append: p, classes: q, addClass: r, removeClass: s, removeAllClasses: t, height: u, width: v, animate: w }), b.Svg.isSupported = function (a) { return y.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#" + a, "1.1") }; var z = { easeInSine: [.47, 0, .745, .715], easeOutSine: [.39, .575, .565, 1], easeInOutSine: [.445, .05, .55, .95], easeInQuad: [.55, .085, .68, .53], easeOutQuad: [.25, .46, .45, .94], easeInOutQuad: [.455, .03, .515, .955], easeInCubic: [.55, .055, .675, .19], easeOutCubic: [.215, .61, .355, 1], easeInOutCubic: [.645, .045, .355, 1], easeInQuart: [.895, .03, .685, .22], easeOutQuart: [.165, .84, .44, 1], easeInOutQuart: [.77, 0, .175, 1], easeInQuint: [.755, .05, .855, .06], easeOutQuint: [.23, 1, .32, 1], easeInOutQuint: [.86, 0, .07, 1], easeInExpo: [.95, .05, .795, .035], easeOutExpo: [.19, 1, .22, 1], easeInOutExpo: [1, 0, 0, 1], easeInCirc: [.6, .04, .98, .335], easeOutCirc: [.075, .82, .165, 1], easeInOutCirc: [.785, .135, .15, .86], easeInBack: [.6, -.28, .735, .045], easeOutBack: [.175, .885, .32, 1.275], easeInOutBack: [.68, -.55, .265, 1.55] }; b.Svg.Easing = z, b.Svg.List = b.Class.extend({ constructor: x }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f, g) { var h = b.extend({ command: f ? a.toLowerCase() : a.toUpperCase() }, c, g ? { data: g } : {}); d.splice(e, 0, h) } function d(a, b) { a.forEach(function (c, d) { t[c.command.toLowerCase()].forEach(function (e, f) { b(c, e, d, f, a) }) }) } function e(a, c) { this.pathElements = [], this.pos = 0, this.close = a, this.options = b.extend({}, u, c) } function f(a) { return void 0 !== a ? (this.pos = Math.max(0, Math.min(this.pathElements.length, a)), this) : this.pos } function g(a) { return this.pathElements.splice(this.pos, a), this } function h(a, b, d, e) { return c("M", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function i(a, b, d, e) { return c("L", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function j(a, b, d, e, f, g, h, i) { return c("C", { x1: +a, y1: +b, x2: +d, y2: +e, x: +f, y: +g }, this.pathElements, this.pos++, h, i), this } function k(a, b, d, e, f, g, h, i, j) { return c("A", { rx: +a, ry: +b, xAr: +d, lAf: +e, sf: +f, x: +g, y: +h }, this.pathElements, this.pos++, i, j), this } function l(a) { var c = a.replace(/([A-Za-z])([0-9])/g, "$1 $2").replace(/([0-9])([A-Za-z])/g, "$1 $2").split(/[\s,]+/).reduce(function (a, b) { return b.match(/[A-Za-z]/) && a.push([]), a[a.length - 1].push(b), a }, []); "Z" === c[c.length - 1][0].toUpperCase() && c.pop(); var d = c.map(function (a) { var c = a.shift(), d = t[c.toLowerCase()]; return b.extend({ command: c }, d.reduce(function (b, c, d) { return b[c] = +a[d], b }, {})) }), e = [this.pos, 0]; return Array.prototype.push.apply(e, d), Array.prototype.splice.apply(this.pathElements, e), this.pos += d.length, this } function m() { var a = Math.pow(10, this.options.accuracy); return this.pathElements.reduce(function (b, c) { var d = t[c.command.toLowerCase()].map(function (b) { return this.options.accuracy ? Math.round(c[b] * a) / a : c[b] }.bind(this)); return b + c.command + d.join(",") }.bind(this), "") + (this.close ? "Z" : "") } function n(a, b) { return d(this.pathElements, function (c, d) { c[d] *= "x" === d[0] ? a : b }), this } function o(a, b) { return d(this.pathElements, function (c, d) { c[d] += "x" === d[0] ? a : b }), this } function p(a) { return d(this.pathElements, function (b, c, d, e, f) { var g = a(b, c, d, e, f); (g || 0 === g) && (b[c] = g) }), this } function q(a) { var c = new b.Svg.Path(a || this.close); return c.pos = this.pos, c.pathElements = this.pathElements.slice().map(function (a) { return b.extend({}, a) }), c.options = b.extend({}, this.options), c } function r(a) { var c = [new b.Svg.Path]; return this.pathElements.forEach(function (d) { d.command === a.toUpperCase() && 0 !== c[c.length - 1].pathElements.length && c.push(new b.Svg.Path), c[c.length - 1].pathElements.push(d) }), c } function s(a, c, d) { for (var e = new b.Svg.Path(c, d), f = 0; f < a.length; f++)for (var g = a[f], h = 0; h < g.pathElements.length; h++)e.pathElements.push(g.pathElements[h]); return e } var t = { m: ["x", "y"], l: ["x", "y"], c: ["x1", "y1", "x2", "y2", "x", "y"], a: ["rx", "ry", "xAr", "lAf", "sf", "x", "y"] }, u = { accuracy: 3 }; b.Svg.Path = b.Class.extend({ constructor: e, position: f, remove: g, move: h, line: i, curve: j, arc: k, scale: n, translate: o, transform: p, parse: l, stringify: m, clone: q, splitByCommand: r }), b.Svg.Path.elementDescriptions = t, b.Svg.Path.join = s }(this || global, a), function (a, b) { "use strict"; function c(a, b, c, d) { this.units = a, this.counterUnits = a === e.x ? e.y : e.x, this.chartRect = b, this.axisLength = b[a.rectEnd] - b[a.rectStart], this.gridOffset = b[a.rectOffset], this.ticks = c, this.options = d } function d(a, c, d, e, f) { var g = e["axis" + this.units.pos.toUpperCase()], h = this.ticks.map(this.projectValue.bind(this)), i = this.ticks.map(g.labelInterpolationFnc); h.forEach(function (j, k) { var l, m = { x: 0, y: 0 }; l = h[k + 1] ? h[k + 1] - j : Math.max(this.axisLength - j, 30), b.isFalseyButZero(i[k]) && "" !== i[k] || ("x" === this.units.pos ? (j = this.chartRect.x1 + j, m.x = e.axisX.labelOffset.x, "start" === e.axisX.position ? m.y = this.chartRect.padding.top + e.axisX.labelOffset.y + (d ? 5 : 20) : m.y = this.chartRect.y1 + e.axisX.labelOffset.y + (d ? 5 : 20)) : (j = this.chartRect.y1 - j, m.y = e.axisY.labelOffset.y - (d ? l : 0), "start" === e.axisY.position ? m.x = d ? this.chartRect.padding.left + e.axisY.labelOffset.x : this.chartRect.x1 - 10 : m.x = this.chartRect.x2 + e.axisY.labelOffset.x + 10), g.showGrid && b.createGrid(j, k, this, this.gridOffset, this.chartRect[this.counterUnits.len](), a, [e.classNames.grid, e.classNames[this.units.dir]], f), g.showLabel && b.createLabel(j, l, k, i, this, g.offset, m, c, [e.classNames.label, e.classNames[this.units.dir], "start" === g.position ? e.classNames[g.position] : e.classNames.end], d, f)) }.bind(this)) } var e = (a.window, a.document, { x: { pos: "x", len: "width", dir: "horizontal", rectStart: "x1", rectEnd: "x2", rectOffset: "y2" }, y: { pos: "y", len: "height", dir: "vertical", rectStart: "y2", rectEnd: "y1", rectOffset: "x1" } }); b.Axis = b.Class.extend({ constructor: c, createGridAndLabels: d, projectValue: function (a, b, c) { throw new Error("Base axis can't be instantiated!") } }), b.Axis.units = e }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.bounds = b.getBounds(d[a.rectEnd] - d[a.rectStart], f, e.scaleMinSpace || 20, e.onlyInteger), this.range = { min: this.bounds.min, max: this.bounds.max }, b.AutoScaleAxis["super"].constructor.call(this, a, d, this.bounds.values, e) } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.bounds.min) / this.bounds.range } a.window, a.document; b.AutoScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.divisor = e.divisor || 1, this.ticks = e.ticks || b.times(this.divisor).map(function (a, b) { return f.low + (f.high - f.low) / this.divisor * b }.bind(this)), this.ticks.sort(function (a, b) { return a - b }), this.range = { min: f.low, max: f.high }, b.FixedScaleAxis["super"].constructor.call(this, a, d, this.ticks, e), this.stepLength = this.axisLength / this.divisor } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.range.min) / (this.range.max - this.range.min) } a.window, a.document; b.FixedScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { b.StepAxis["super"].constructor.call(this, a, d, e.ticks, e); var f = Math.max(1, e.ticks.length - (e.stretch ? 1 : 0)); this.stepLength = this.axisLength / f } function d(a, b) { return this.stepLength * b } a.window, a.document; b.StepAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a) { var c = b.normalizeData(this.data, a.reverseData, !0); this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart); var d, f, g = this.svg.elem("g").addClass(a.classNames.gridGroup), h = this.svg.elem("g"), i = this.svg.elem("g").addClass(a.classNames.labelGroup), j = b.createChartRect(this.svg, a, e.padding); d = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, j, b.extend({}, a.axisX, { ticks: c.normalized.labels, stretch: a.fullWidth })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, j, a.axisX), f = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, j, b.extend({}, a.axisY, { high: b.isNumeric(a.high) ? a.high : a.axisY.high, low: b.isNumeric(a.low) ? a.low : a.axisY.low })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, j, a.axisY), d.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), f.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(g, j, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (e, g) { var i = h.elem("g"); i.attr({ "ct:series-name": e.name, "ct:meta": b.serialize(e.meta) }), i.addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(g)].join(" ")); var k = [], l = []; c.normalized.series[g].forEach(function (a, h) { var i = { x: j.x1 + d.projectValue(a, h, c.normalized.series[g]), y: j.y1 - f.projectValue(a, h, c.normalized.series[g]) }; k.push(i.x, i.y), l.push({ value: a, valueIndex: h, meta: b.getMetaData(e, h) }) }.bind(this)); var m = { lineSmooth: b.getSeriesOption(e, a, "lineSmooth"), showPoint: b.getSeriesOption(e, a, "showPoint"), showLine: b.getSeriesOption(e, a, "showLine"), showArea: b.getSeriesOption(e, a, "showArea"), areaBase: b.getSeriesOption(e, a, "areaBase") }, n = "function" == typeof m.lineSmooth ? m.lineSmooth : m.lineSmooth ? b.Interpolation.monotoneCubic() : b.Interpolation.none(), o = n(k, l); if (m.showPoint && o.pathElements.forEach(function (c) { var h = i.elem("line", { x1: c.x, y1: c.y, x2: c.x + .01, y2: c.y }, a.classNames.point).attr({ "ct:value": [c.data.value.x, c.data.value.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(c.data.meta) }); this.eventEmitter.emit("draw", { type: "point", value: c.data.value, index: c.data.valueIndex, meta: c.data.meta, series: e, seriesIndex: g, axisX: d, axisY: f, group: i, element: h, x: c.x, y: c.y }) }.bind(this)), m.showLine) { var p = i.elem("path", { d: o.stringify() }, a.classNames.line, !0); this.eventEmitter.emit("draw", { type: "line", values: c.normalized.series[g], path: o.clone(), chartRect: j, index: g, series: e, seriesIndex: g, seriesMeta: e.meta, axisX: d, axisY: f, group: i, element: p }) } if (m.showArea && f.range) { var q = Math.max(Math.min(m.areaBase, f.range.max), f.range.min), r = j.y1 - f.projectValue(q); o.splitByCommand("M").filter(function (a) { return a.pathElements.length > 1 }).map(function (a) { var b = a.pathElements[0], c = a.pathElements[a.pathElements.length - 1]; return a.clone(!0).position(0).remove(1).move(b.x, r).line(b.x, b.y).position(a.pathElements.length + 1).line(c.x, r) }).forEach(function (b) { var h = i.elem("path", { d: b.stringify() }, a.classNames.area, !0); this.eventEmitter.emit("draw", { type: "area", values: c.normalized.series[g], path: b.clone(), series: e, seriesIndex: g, axisX: d, axisY: f, chartRect: j, index: g, group: i, element: h }) }.bind(this)) } }.bind(this)), this.eventEmitter.emit("created", { bounds: f.bounds, chartRect: j, axisX: d, axisY: f, svg: this.svg, options: a }) } function d(a, c, d, f) { b.Line["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, showLine: !0, showPoint: !0, showArea: !1, areaBase: 0, lineSmooth: !0, showGridBackground: !1, low: void 0, high: void 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, fullWidth: !1, reverseData: !1, classNames: { chart: "ct-chart-line", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", line: "ct-line", point: "ct-point", area: "ct-area", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Line = b.Base.extend({ constructor: d, createChart: c }) }(this || global, a), function (a, b) { + "use strict"; function c(a) { + var c, d; a.distributeSeries ? (c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), c.normalized.series = c.normalized.series.map(function (a) { return [a] })) : c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart + (a.horizontalBars ? " " + a.classNames.horizontalBars : "")); var f = this.svg.elem("g").addClass(a.classNames.gridGroup), g = this.svg.elem("g"), h = this.svg.elem("g").addClass(a.classNames.labelGroup); + if (a.stackBars && 0 !== c.normalized.series.length) { var i = b.serialMap(c.normalized.series, function () { return Array.prototype.slice.call(arguments).map(function (a) { return a }).reduce(function (a, b) { return { x: a.x + (b && b.x) || 0, y: a.y + (b && b.y) || 0 } }, { x: 0, y: 0 }) }); d = b.getHighLow([i], a, a.horizontalBars ? "x" : "y") } else d = b.getHighLow(c.normalized.series, a, a.horizontalBars ? "x" : "y"); d.high = +a.high || (0 === a.high ? 0 : d.high), d.low = +a.low || (0 === a.low ? 0 : d.low); var j, k, l, m, n, o = b.createChartRect(this.svg, a, e.padding); k = a.distributeSeries && a.stackBars ? c.normalized.labels.slice(0, 1) : c.normalized.labels, a.horizontalBars ? (j = m = void 0 === a.axisX.type ? new b.AutoScaleAxis(b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })), l = n = void 0 === a.axisY.type ? new b.StepAxis(b.Axis.units.y, c.normalized.series, o, { ticks: k }) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, a.axisY)) : (l = m = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, o, { ticks: k }) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, a.axisX), j = n = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 }))); var p = a.horizontalBars ? o.x1 + j.projectValue(0) : o.y1 - j.projectValue(0), q = []; l.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), j.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(f, o, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (d, e) { var f, h, i = e - (c.raw.series.length - 1) / 2; f = a.distributeSeries && !a.stackBars ? l.axisLength / c.normalized.series.length / 2 : a.distributeSeries && a.stackBars ? l.axisLength / 2 : l.axisLength / c.normalized.series[e].length / 2, h = g.elem("g"), h.attr({ "ct:series-name": d.name, "ct:meta": b.serialize(d.meta) }), h.addClass([a.classNames.series, d.className || a.classNames.series + "-" + b.alphaNumerate(e)].join(" ")), c.normalized.series[e].forEach(function (g, k) { var r, s, t, u; if (u = a.distributeSeries && !a.stackBars ? e : a.distributeSeries && a.stackBars ? 0 : k, r = a.horizontalBars ? { x: o.x1 + j.projectValue(g && g.x ? g.x : 0, k, c.normalized.series[e]), y: o.y1 - l.projectValue(g && g.y ? g.y : 0, u, c.normalized.series[e]) } : { x: o.x1 + l.projectValue(g && g.x ? g.x : 0, u, c.normalized.series[e]), y: o.y1 - j.projectValue(g && g.y ? g.y : 0, k, c.normalized.series[e]) }, l instanceof b.StepAxis && (l.options.stretch || (r[l.units.pos] += f * (a.horizontalBars ? -1 : 1)), r[l.units.pos] += a.stackBars || a.distributeSeries ? 0 : i * a.seriesBarDistance * (a.horizontalBars ? -1 : 1)), t = q[k] || p, q[k] = t - (p - r[l.counterUnits.pos]), void 0 !== g) { var v = {}; v[l.units.pos + "1"] = r[l.units.pos], v[l.units.pos + "2"] = r[l.units.pos], !a.stackBars || "accumulate" !== a.stackMode && a.stackMode ? (v[l.counterUnits.pos + "1"] = p, v[l.counterUnits.pos + "2"] = r[l.counterUnits.pos]) : (v[l.counterUnits.pos + "1"] = t, v[l.counterUnits.pos + "2"] = q[k]), v.x1 = Math.min(Math.max(v.x1, o.x1), o.x2), v.x2 = Math.min(Math.max(v.x2, o.x1), o.x2), v.y1 = Math.min(Math.max(v.y1, o.y2), o.y1), v.y2 = Math.min(Math.max(v.y2, o.y2), o.y1); var w = b.getMetaData(d, k); s = h.elem("line", v, a.classNames.bar).attr({ "ct:value": [g.x, g.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(w) }), this.eventEmitter.emit("draw", b.extend({ type: "bar", value: g, index: k, meta: w, series: d, seriesIndex: e, axisX: m, axisY: n, chartRect: o, group: h, element: s }, v)) } }.bind(this)) }.bind(this)), this.eventEmitter.emit("created", { bounds: j.bounds, chartRect: o, axisX: m, axisY: n, svg: this.svg, options: a }) + } function d(a, c, d, f) { b.Bar["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 30, onlyInteger: !1 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, high: void 0, low: void 0, referenceValue: 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, seriesBarDistance: 15, stackBars: !1, stackMode: "accumulate", horizontalBars: !1, distributeSeries: !1, reverseData: !1, showGridBackground: !1, classNames: { chart: "ct-chart-bar", horizontalBars: "ct-horizontal-bars", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", bar: "ct-bar", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Bar = b.Base.extend({ constructor: d, createChart: c }) + }(this || global, a), function (a, b) { "use strict"; function c(a, b, c) { var d = b.x > a.x; return d && "explode" === c || !d && "implode" === c ? "start" : d && "implode" === c || !d && "explode" === c ? "end" : "middle" } function d(a) { var d, e, g, h, i, j = b.normalizeData(this.data), k = [], l = a.startAngle; this.svg = b.createSvg(this.container, a.width, a.height, a.donut ? a.classNames.chartDonut : a.classNames.chartPie), e = b.createChartRect(this.svg, a, f.padding), g = Math.min(e.width() / 2, e.height() / 2), i = a.total || j.normalized.series.reduce(function (a, b) { return a + b }, 0); var m = b.quantity(a.donutWidth); "%" === m.unit && (m.value *= g / 100), g -= a.donut && !a.donutSolid ? m.value / 2 : 0, h = "outside" === a.labelPosition || a.donut && !a.donutSolid ? g : "center" === a.labelPosition ? 0 : a.donutSolid ? g - m.value / 2 : g / 2, h += a.labelOffset; var n = { x: e.x1 + e.width() / 2, y: e.y2 + e.height() / 2 }, o = 1 === j.raw.series.filter(function (a) { return a.hasOwnProperty("value") ? 0 !== a.value : 0 !== a }).length; j.raw.series.forEach(function (a, b) { k[b] = this.svg.elem("g", null, null) }.bind(this)), a.showLabel && (d = this.svg.elem("g", null, null)), j.raw.series.forEach(function (e, f) { if (0 !== j.normalized.series[f] || !a.ignoreEmptyValues) { k[f].attr({ "ct:series-name": e.name }), k[f].addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(f)].join(" ")); var p = i > 0 ? l + j.normalized.series[f] / i * 360 : 0, q = Math.max(0, l - (0 === f || o ? 0 : .2)); p - q >= 359.99 && (p = q + 359.99); var r, s, t, u = b.polarToCartesian(n.x, n.y, g, q), v = b.polarToCartesian(n.x, n.y, g, p), w = new b.Svg.Path(!a.donut || a.donutSolid).move(v.x, v.y).arc(g, g, 0, p - l > 180, 0, u.x, u.y); a.donut ? a.donutSolid && (t = g - m.value, r = b.polarToCartesian(n.x, n.y, t, l - (0 === f || o ? 0 : .2)), s = b.polarToCartesian(n.x, n.y, t, p), w.line(r.x, r.y), w.arc(t, t, 0, p - l > 180, 1, s.x, s.y)) : w.line(n.x, n.y); var x = a.classNames.slicePie; a.donut && (x = a.classNames.sliceDonut, a.donutSolid && (x = a.classNames.sliceDonutSolid)); var y = k[f].elem("path", { d: w.stringify() }, x); if (y.attr({ "ct:value": j.normalized.series[f], "ct:meta": b.serialize(e.meta) }), a.donut && !a.donutSolid && (y._node.style.strokeWidth = m.value + "px"), this.eventEmitter.emit("draw", { type: "slice", value: j.normalized.series[f], totalDataSum: i, index: f, meta: e.meta, series: e, group: k[f], element: y, path: w.clone(), center: n, radius: g, startAngle: l, endAngle: p }), a.showLabel) { var z; z = 1 === j.raw.series.length ? { x: n.x, y: n.y } : b.polarToCartesian(n.x, n.y, h, l + (p - l) / 2); var A; A = j.normalized.labels && !b.isFalseyButZero(j.normalized.labels[f]) ? j.normalized.labels[f] : j.normalized.series[f]; var B = a.labelInterpolationFnc(A, f); if (B || 0 === B) { var C = d.elem("text", { dx: z.x, dy: z.y, "text-anchor": c(n, z, a.labelDirection) }, a.classNames.label).text("" + B); this.eventEmitter.emit("draw", { type: "label", index: f, group: d, element: C, text: "" + B, x: z.x, y: z.y }) } } l = p } }.bind(this)), this.eventEmitter.emit("created", { chartRect: e, svg: this.svg, options: a }) } function e(a, c, d, e) { b.Pie["super"].constructor.call(this, a, c, f, b.extend({}, f, d), e) } var f = (a.window, a.document, { width: void 0, height: void 0, chartPadding: 5, classNames: { chartPie: "ct-chart-pie", chartDonut: "ct-chart-donut", series: "ct-series", slicePie: "ct-slice-pie", sliceDonut: "ct-slice-donut", sliceDonutSolid: "ct-slice-donut-solid", label: "ct-label" }, startAngle: 0, total: void 0, donut: !1, donutSolid: !1, donutWidth: 60, showLabel: !0, labelOffset: 0, labelPosition: "inside", labelInterpolationFnc: b.noop, labelDirection: "neutral", reverseData: !1, ignoreEmptyValues: !1 }); b.Pie = b.Base.extend({ constructor: e, createChart: d, determineAnchorPosition: c }) }(this || global, a), a +}); +//# sourceMappingURL=chartist.min.js.map + +var i, l, selectedLine = null; + +/* Navigate to hash without browser history entry */ +var navigateToHash = function () { + if (window.history !== undefined && window.history.replaceState !== undefined) { + window.history.replaceState(undefined, undefined, this.getAttribute("href")); + } +}; + +var hashLinks = document.getElementsByClassName('navigatetohash'); +for (i = 0, l = hashLinks.length; i < l; i++) { + hashLinks[i].addEventListener('click', navigateToHash); +} + +/* Switch test method */ +var switchTestMethod = function () { + var method = this.getAttribute("value"); + console.log("Selected test method: " + method); + + var lines, i, l, coverageData, lineAnalysis, cells; + + lines = document.querySelectorAll('.lineAnalysis tr'); + + for (i = 1, l = lines.length; i < l; i++) { + coverageData = JSON.parse(lines[i].getAttribute('data-coverage').replace(/'/g, '"')); + lineAnalysis = coverageData[method]; + cells = lines[i].querySelectorAll('td'); + if (lineAnalysis === undefined) { + lineAnalysis = coverageData.AllTestMethods; + if (lineAnalysis.LVS !== 'gray') { + cells[0].setAttribute('class', 'red'); + cells[1].innerText = cells[1].textContent = '0'; + cells[4].setAttribute('class', 'lightred'); + } + } else { + cells[0].setAttribute('class', lineAnalysis.LVS); + cells[1].innerText = cells[1].textContent = lineAnalysis.VC; + cells[4].setAttribute('class', 'light' + lineAnalysis.LVS); + } + } +}; + +var testMethods = document.getElementsByClassName('switchtestmethod'); +for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].addEventListener('change', switchTestMethod); +} + +/* Highlight test method by line */ +var toggleLine = function () { + if (selectedLine === this) { + selectedLine = null; + } else { + selectedLine = null; + unhighlightTestMethods(); + highlightTestMethods.call(this); + selectedLine = this; + } + +}; +var highlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var lineAnalysis; + var coverageData = JSON.parse(this.getAttribute('data-coverage').replace(/'/g, '"')); + var testMethods = document.getElementsByClassName('testmethod'); + + for (i = 0, l = testMethods.length; i < l; i++) { + lineAnalysis = coverageData[testMethods[i].id]; + if (lineAnalysis === undefined) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } else { + testMethods[i].className += ' light' + lineAnalysis.LVS; + } + } +}; +var unhighlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var testMethods = document.getElementsByClassName('testmethod'); + for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } +}; +var coverableLines = document.getElementsByClassName('coverableline'); +for (i = 0, l = coverableLines.length; i < l; i++) { + coverableLines[i].addEventListener('click', toggleLine); + coverableLines[i].addEventListener('mouseenter', highlightTestMethods); + coverableLines[i].addEventListener('mouseleave', unhighlightTestMethods); +} + +/* History charts */ +var renderChart = function (chart) { + // Remove current children (e.g. PNG placeholder) + while (chart.firstChild) { + chart.firstChild.remove(); + } + + var chartData = window[chart.getAttribute('data-data')]; + var options = { + axisY: { + type: undefined, + onlyInteger: true + }, + lineSmooth: false, + low: 0, + high: 100, + scaleMinSpace: 20, + onlyInteger: true, + fullWidth: true + }; + var lineChart = new Chartist.Line(chart, { + labels: [], + series: chartData.series + }, options); + + /* Zoom */ + var zoomButtonDiv = document.createElement("div"); + zoomButtonDiv.className = "toggleZoom"; + var zoomButtonLink = document.createElement("a"); + zoomButtonLink.setAttribute("href", ""); + var zoomButtonText = document.createElement("i"); + zoomButtonText.className = "icon-search-plus"; + + zoomButtonLink.appendChild(zoomButtonText); + zoomButtonDiv.appendChild(zoomButtonLink); + + chart.appendChild(zoomButtonDiv); + + zoomButtonDiv.addEventListener('click', function (event) { + event.preventDefault(); + + if (options.axisY.type === undefined) { + options.axisY.type = Chartist.AutoScaleAxis; + zoomButtonText.className = "icon-search-minus"; + } else { + options.axisY.type = undefined; + zoomButtonText.className = "icon-search-plus"; + } + + lineChart.update(null, options); + }); + + var tooltip = document.createElement("div"); + tooltip.className = "tooltip"; + + chart.appendChild(tooltip); + + /* Tooltips */ + var showToolTip = function () { + var index = this.getAttribute('ct:meta'); + + tooltip.innerHTML = chartData.tooltips[index]; + tooltip.style.display = 'block'; + }; + + var moveToolTip = function (event) { + var box = chart.getBoundingClientRect(); + var left = event.pageX - box.left - window.pageXOffset; + var top = event.pageY - box.top - window.pageYOffset; + + left = left + 20; + top = top - tooltip.offsetHeight / 2; + + if (left + tooltip.offsetWidth > box.width) { + left -= tooltip.offsetWidth + 40; + } + + if (top < 0) { + top = 0; + } + + if (top + tooltip.offsetHeight > box.height) { + top = box.height - tooltip.offsetHeight; + } + + tooltip.style.left = left + 'px'; + tooltip.style.top = top + 'px'; + }; + + var hideToolTip = function () { + tooltip.style.display = 'none'; + }; + chart.addEventListener('mousemove', moveToolTip); + + lineChart.on('created', function () { + var chartPoints = chart.getElementsByClassName('ct-point'); + for (i = 0, l = chartPoints.length; i < l; i++) { + chartPoints[i].addEventListener('mousemove', showToolTip); + chartPoints[i].addEventListener('mouseout', hideToolTip); + } + }); +}; + +var charts = document.getElementsByClassName('historychart'); +for (i = 0, l = charts.length; i < l; i++) { + renderChart(charts[i]); +} + +var assemblies = [ + { + "name": "ldclient.dll", + "classes": [ + { "name": "LDClient.detection.DebuggerInfoParser", "rp": "ldclient.dll_DebuggerInfoParser.html", "cl": 7, "ucl": 0, "cal": 7, "tl": 21, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.detection.InfoFetcher", "rp": "ldclient.dll_InfoFetcher.html", "cl": 52, "ucl": 0, "cal": 52, "tl": 86, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.detection.ProcessDetection", "rp": "ldclient.dll_ProcessDetection.html", "cl": 62, "ucl": 0, "cal": 62, "tl": 91, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.detection.ProcessUtils", "rp": "ldclient.dll_ProcessUtils.html", "cl": 0, "ucl": 20, "cal": 20, "tl": 40, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.network.ApiClient", "rp": "ldclient.dll_ApiClient.html", "cl": 75, "ucl": 0, "cal": 75, "tl": 108, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.network.data.DebuggerInfo", "rp": "ldclient.dll_DebuggerInfo.html", "cl": 1, "ucl": 0, "cal": 1, "tl": 9, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.network.data.Payload", "rp": "ldclient.dll_Payload.html", "cl": 17, "ucl": 3, "cal": 20, "tl": 49, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.network.HttpClient", "rp": "ldclient.dll_HttpClient.html", "cl": 4, "ucl": 7, "cal": 11, "tl": 32, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.Program", "rp": "ldclient.dll_Program.html", "cl": 11, "ucl": 32, "cal": 43, "tl": 67, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.utils.ConfigLoader", "rp": "ldclient.dll_ConfigLoader.html", "cl": 74, "ucl": 12, "cal": 86, "tl": 127, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.utils.FileUtils", "rp": "ldclient.dll_FileUtils.html", "cl": 0, "ucl": 3, "cal": 3, "tl": 13, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.utils.loggers.ALogger", "rp": "ldclient.dll_ALogger.html", "cl": 58, "ucl": 14, "cal": 72, "tl": 109, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.utils.loggers.ConsoleLogger", "rp": "ldclient.dll_ConsoleLogger.html", "cl": 3, "ucl": 0, "cal": 3, "tl": 7, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClient.utils.loggers.FileLogger", "rp": "ldclient.dll_FileLogger.html", "cl": 0, "ucl": 59, "cal": 59, "tl": 95, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + ]}, + { + "name": "ldclienttests.dll", + "classes": [ + { "name": "LDClientTests.detection.DebuggerInfoParserTests", "rp": "ldclienttests.dll_DebuggerInfoParserTests.html", "cl": 18, "ucl": 0, "cal": 18, "tl": 66, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClientTests.detection.InfoFetcherTests", "rp": "ldclienttests.dll_InfoFetcherTests.html", "cl": 59, "ucl": 0, "cal": 59, "tl": 117, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClientTests.detection.ProcessDetectionTests", "rp": "ldclienttests.dll_ProcessDetectionTests.html", "cl": 61, "ucl": 0, "cal": 61, "tl": 132, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + { "name": "LDClientTests.network.ApiClientTests", "rp": "ldclienttests.dll_ApiClientTests.html", "cl": 81, "ucl": 0, "cal": 81, "tl": 167, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] }, + ]}, +]; + +var historicCoverageExecutionTimes = []; + +var riskHotspotMetrics = [ +]; + +var riskHotspots = [ +]; + +var branchCoverageAvailable = false; +var methodCoverageAvailable = false; + + +var translations = { +'top': 'Top:', +'all': 'All', +'assembly': 'Assembly', +'class': 'Class', +'method': 'Method', +'lineCoverage': 'LineCoverage', +'noGrouping': 'No grouping', +'byAssembly': 'By assembly', +'byNamespace': 'By namespace, Level:', +'all': 'All', +'collapseAll': 'Collapse all', +'expandAll': 'Expand all', +'grouping': 'Grouping:', +'filter': 'Filter:', +'name': 'Name', +'covered': 'Covered', +'uncovered': 'Uncovered', +'coverable': 'Coverable', +'total': 'Total', +'coverage': 'Line coverage', +'branchCoverage': 'Branch coverage', +'methodCoverage': 'Method coverage', +'percentage': 'Percentage', +'history': 'Coverage History', +'compareHistory': 'Compare with:', +'date': 'Date', +'allChanges': 'All changes', +'lineCoverageIncreaseOnly': 'Line coverage: Increase only', +'lineCoverageDecreaseOnly': 'Line coverage: Decrease only', +'branchCoverageIncreaseOnly': 'Branch coverage: Increase only', +'branchCoverageDecreaseOnly': 'Branch coverage: Decrease only', +'methodCoverageIncreaseOnly': 'Method coverage: Increase only', +'methodCoverageDecreaseOnly': 'Method coverage: Decrease only' +}; + + +(()=>{"use strict";var e,_={},p={};function n(e){var a=p[e];if(void 0!==a)return a.exports;var r=p[e]={exports:{}};return _[e](r,r.exports,n),r.exports}n.m=_,e=[],n.O=(a,r,u,l)=>{if(!r){var o=1/0;for(f=0;f<e.length;f++){for(var[r,u,l]=e[f],v=!0,t=0;t<r.length;t++)(!1&l||o>=l)&&Object.keys(n.O).every(h=>n.O[h](r[t]))?r.splice(t--,1):(v=!1,l<o&&(o=l));if(v){e.splice(f--,1);var c=u();void 0!==c&&(a=c)}}return a}l=l||0;for(var f=e.length;f>0&&e[f-1][2]>l;f--)e[f]=e[f-1];e[f]=[r,u,l]},n.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return n.d(a,{a}),a},n.d=(e,a)=>{for(var r in a)n.o(a,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:a[r]})},n.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),(()=>{var e={666:0};n.O.j=u=>0===e[u];var a=(u,l)=>{var t,c,[f,o,v]=l,s=0;if(f.some(d=>0!==e[d])){for(t in o)n.o(o,t)&&(n.m[t]=o[t]);if(v)var b=v(n)}for(u&&u(l);s<f.length;s++)n.o(e,c=f[s])&&e[c]&&e[c][0](),e[c]=0;return n.O(b)},r=self.webpackChunkcoverage_app=self.webpackChunkcoverage_app||[];r.forEach(a.bind(null,0)),r.push=a.bind(null,r.push.bind(r))})()})(); +"use strict";(self.webpackChunkcoverage_app=self.webpackChunkcoverage_app||[]).push([[429],{435:(we,ue,he)=>{he(583)},583:()=>{!function(e){const n=e.performance;function i(I){n&&n.mark&&n.mark(I)}function r(I,p){n&&n.measure&&n.measure(I,p)}i("Zone");const c=e.__Zone_symbol_prefix||"__zone_symbol__";function u(I){return c+I}const f=!0===e[u("forceDuplicateZoneCheck")];if(e.Zone){if(f||"function"!=typeof e.Zone.__symbol__)throw new Error("Zone already loaded.");return e.Zone}let _=(()=>{class I{constructor(t,o){this._parent=t,this._name=o?o.name||"unnamed":"<root>",this._properties=o&&o.properties||{},this._zoneDelegate=new T(this,this._parent&&this._parent._zoneDelegate,o)}static assertZonePatched(){if(e.Promise!==J.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")}static get root(){let t=I.current;for(;t.parent;)t=t.parent;return t}static get current(){return G.zone}static get currentTask(){return te}static __load_patch(t,o,g=!1){if(J.hasOwnProperty(t)){if(!g&&f)throw Error("Already loaded patch: "+t)}else if(!e["__Zone_disable_"+t]){const P="Zone:"+t;i(P),J[t]=o(e,I,le),r(P,P)}}get parent(){return this._parent}get name(){return this._name}get(t){const o=this.getZoneWith(t);if(o)return o._properties[t]}getZoneWith(t){let o=this;for(;o;){if(o._properties.hasOwnProperty(t))return o;o=o._parent}return null}fork(t){if(!t)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,t)}wrap(t,o){if("function"!=typeof t)throw new Error("Expecting function got: "+t);const g=this._zoneDelegate.intercept(this,t,o),P=this;return function(){return P.runGuarded(g,this,arguments,o)}}run(t,o,g,P){G={parent:G,zone:this};try{return this._zoneDelegate.invoke(this,t,o,g,P)}finally{G=G.parent}}runGuarded(t,o=null,g,P){G={parent:G,zone:this};try{try{return this._zoneDelegate.invoke(this,t,o,g,P)}catch(K){if(this._zoneDelegate.handleError(this,K))throw K}}finally{G=G.parent}}runTask(t,o,g){if(t.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(t.zone||z).name+"; Execution: "+this.name+")");if(t.state===j&&(t.type===R||t.type===M))return;const P=t.state!=X;P&&t._transitionTo(X,O),t.runCount++;const K=te;te=t,G={parent:G,zone:this};try{t.type==M&&t.data&&!t.data.isPeriodic&&(t.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,t,o,g)}catch(l){if(this._zoneDelegate.handleError(this,l))throw l}}finally{t.state!==j&&t.state!==Y&&(t.type==R||t.data&&t.data.isPeriodic?P&&t._transitionTo(O,X):(t.runCount=0,this._updateTaskCount(t,-1),P&&t._transitionTo(j,X,j))),G=G.parent,te=K}}scheduleTask(t){if(t.zone&&t.zone!==this){let g=this;for(;g;){if(g===t.zone)throw Error(`can not reschedule task to ${this.name} which is descendants of the original zone ${t.zone.name}`);g=g.parent}}t._transitionTo(q,j);const o=[];t._zoneDelegates=o,t._zone=this;try{t=this._zoneDelegate.scheduleTask(this,t)}catch(g){throw t._transitionTo(Y,q,j),this._zoneDelegate.handleError(this,g),g}return t._zoneDelegates===o&&this._updateTaskCount(t,1),t.state==q&&t._transitionTo(O,q),t}scheduleMicroTask(t,o,g,P){return this.scheduleTask(new m(v,t,o,g,P,void 0))}scheduleMacroTask(t,o,g,P,K){return this.scheduleTask(new m(M,t,o,g,P,K))}scheduleEventTask(t,o,g,P,K){return this.scheduleTask(new m(R,t,o,g,P,K))}cancelTask(t){if(t.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(t.zone||z).name+"; Execution: "+this.name+")");t._transitionTo(A,O,X);try{this._zoneDelegate.cancelTask(this,t)}catch(o){throw t._transitionTo(Y,A),this._zoneDelegate.handleError(this,o),o}return this._updateTaskCount(t,-1),t._transitionTo(j,A),t.runCount=0,t}_updateTaskCount(t,o){const g=t._zoneDelegates;-1==o&&(t._zoneDelegates=null);for(let P=0;P<g.length;P++)g[P]._updateTaskCount(t.type,o)}}return I.__symbol__=u,I})();const y={name:"",onHasTask:(I,p,t,o)=>I.hasTask(t,o),onScheduleTask:(I,p,t,o)=>I.scheduleTask(t,o),onInvokeTask:(I,p,t,o,g,P)=>I.invokeTask(t,o,g,P),onCancelTask:(I,p,t,o)=>I.cancelTask(t,o)};class T{constructor(p,t,o){this._taskCounts={microTask:0,macroTask:0,eventTask:0},this.zone=p,this._parentDelegate=t,this._forkZS=o&&(o&&o.onFork?o:t._forkZS),this._forkDlgt=o&&(o.onFork?t:t._forkDlgt),this._forkCurrZone=o&&(o.onFork?this.zone:t._forkCurrZone),this._interceptZS=o&&(o.onIntercept?o:t._interceptZS),this._interceptDlgt=o&&(o.onIntercept?t:t._interceptDlgt),this._interceptCurrZone=o&&(o.onIntercept?this.zone:t._interceptCurrZone),this._invokeZS=o&&(o.onInvoke?o:t._invokeZS),this._invokeDlgt=o&&(o.onInvoke?t:t._invokeDlgt),this._invokeCurrZone=o&&(o.onInvoke?this.zone:t._invokeCurrZone),this._handleErrorZS=o&&(o.onHandleError?o:t._handleErrorZS),this._handleErrorDlgt=o&&(o.onHandleError?t:t._handleErrorDlgt),this._handleErrorCurrZone=o&&(o.onHandleError?this.zone:t._handleErrorCurrZone),this._scheduleTaskZS=o&&(o.onScheduleTask?o:t._scheduleTaskZS),this._scheduleTaskDlgt=o&&(o.onScheduleTask?t:t._scheduleTaskDlgt),this._scheduleTaskCurrZone=o&&(o.onScheduleTask?this.zone:t._scheduleTaskCurrZone),this._invokeTaskZS=o&&(o.onInvokeTask?o:t._invokeTaskZS),this._invokeTaskDlgt=o&&(o.onInvokeTask?t:t._invokeTaskDlgt),this._invokeTaskCurrZone=o&&(o.onInvokeTask?this.zone:t._invokeTaskCurrZone),this._cancelTaskZS=o&&(o.onCancelTask?o:t._cancelTaskZS),this._cancelTaskDlgt=o&&(o.onCancelTask?t:t._cancelTaskDlgt),this._cancelTaskCurrZone=o&&(o.onCancelTask?this.zone:t._cancelTaskCurrZone),this._hasTaskZS=null,this._hasTaskDlgt=null,this._hasTaskDlgtOwner=null,this._hasTaskCurrZone=null;const g=o&&o.onHasTask;(g||t&&t._hasTaskZS)&&(this._hasTaskZS=g?o:y,this._hasTaskDlgt=t,this._hasTaskDlgtOwner=this,this._hasTaskCurrZone=p,o.onScheduleTask||(this._scheduleTaskZS=y,this._scheduleTaskDlgt=t,this._scheduleTaskCurrZone=this.zone),o.onInvokeTask||(this._invokeTaskZS=y,this._invokeTaskDlgt=t,this._invokeTaskCurrZone=this.zone),o.onCancelTask||(this._cancelTaskZS=y,this._cancelTaskDlgt=t,this._cancelTaskCurrZone=this.zone))}fork(p,t){return this._forkZS?this._forkZS.onFork(this._forkDlgt,this.zone,p,t):new _(p,t)}intercept(p,t,o){return this._interceptZS?this._interceptZS.onIntercept(this._interceptDlgt,this._interceptCurrZone,p,t,o):t}invoke(p,t,o,g,P){return this._invokeZS?this._invokeZS.onInvoke(this._invokeDlgt,this._invokeCurrZone,p,t,o,g,P):t.apply(o,g)}handleError(p,t){return!this._handleErrorZS||this._handleErrorZS.onHandleError(this._handleErrorDlgt,this._handleErrorCurrZone,p,t)}scheduleTask(p,t){let o=t;if(this._scheduleTaskZS)this._hasTaskZS&&o._zoneDelegates.push(this._hasTaskDlgtOwner),o=this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt,this._scheduleTaskCurrZone,p,t),o||(o=t);else if(t.scheduleFn)t.scheduleFn(t);else{if(t.type!=v)throw new Error("Task is missing scheduleFn.");d(t)}return o}invokeTask(p,t,o,g){return this._invokeTaskZS?this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt,this._invokeTaskCurrZone,p,t,o,g):t.callback.apply(o,g)}cancelTask(p,t){let o;if(this._cancelTaskZS)o=this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt,this._cancelTaskCurrZone,p,t);else{if(!t.cancelFn)throw Error("Task is not cancelable");o=t.cancelFn(t)}return o}hasTask(p,t){try{this._hasTaskZS&&this._hasTaskZS.onHasTask(this._hasTaskDlgt,this._hasTaskCurrZone,p,t)}catch(o){this.handleError(p,o)}}_updateTaskCount(p,t){const o=this._taskCounts,g=o[p],P=o[p]=g+t;if(P<0)throw new Error("More tasks executed then were scheduled.");0!=g&&0!=P||this.hasTask(this.zone,{microTask:o.microTask>0,macroTask:o.macroTask>0,eventTask:o.eventTask>0,change:p})}}class m{constructor(p,t,o,g,P,K){if(this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=p,this.source=t,this.data=g,this.scheduleFn=P,this.cancelFn=K,!o)throw new Error("callback is not defined");this.callback=o;const l=this;this.invoke=p===R&&g&&g.useG?m.invokeTask:function(){return m.invokeTask.call(e,l,this,arguments)}}static invokeTask(p,t,o){p||(p=this),re++;try{return p.runCount++,p.zone.runTask(p,t,o)}finally{1==re&&L(),re--}}get zone(){return this._zone}get state(){return this._state}cancelScheduleRequest(){this._transitionTo(j,q)}_transitionTo(p,t,o){if(this._state!==t&&this._state!==o)throw new Error(`${this.type} '${this.source}': can not transition to '${p}', expecting state '${t}'${o?" or '"+o+"'":""}, was '${this._state}'.`);this._state=p,p==j&&(this._zoneDelegates=null)}toString(){return this.data&&void 0!==this.data.handleId?this.data.handleId.toString():Object.prototype.toString.call(this)}toJSON(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}}}const S=u("setTimeout"),D=u("Promise"),Z=u("then");let E,B=[],V=!1;function d(I){if(0===re&&0===B.length)if(E||e[D]&&(E=e[D].resolve(0)),E){let p=E[Z];p||(p=E.then),p.call(E,L)}else e[S](L,0);I&&B.push(I)}function L(){if(!V){for(V=!0;B.length;){const I=B;B=[];for(let p=0;p<I.length;p++){const t=I[p];try{t.zone.runTask(t,null,null)}catch(o){le.onUnhandledError(o)}}}le.microtaskDrainDone(),V=!1}}const z={name:"NO ZONE"},j="notScheduled",q="scheduling",O="scheduled",X="running",A="canceling",Y="unknown",v="microTask",M="macroTask",R="eventTask",J={},le={symbol:u,currentZoneFrame:()=>G,onUnhandledError:F,microtaskDrainDone:F,scheduleMicroTask:d,showUncaughtError:()=>!_[u("ignoreConsoleErrorUncaughtError")],patchEventTarget:()=>[],patchOnProperties:F,patchMethod:()=>F,bindArguments:()=>[],patchThen:()=>F,patchMacroTask:()=>F,patchEventPrototype:()=>F,isIEOrEdge:()=>!1,getGlobalObjects:()=>{},ObjectDefineProperty:()=>F,ObjectGetOwnPropertyDescriptor:()=>{},ObjectCreate:()=>{},ArraySlice:()=>[],patchClass:()=>F,wrapWithCurrentZone:()=>F,filterProperties:()=>[],attachOriginToPatched:()=>F,_redefineProperty:()=>F,patchCallbacks:()=>F};let G={parent:null,zone:new _(null,null)},te=null,re=0;function F(){}r("Zone","Zone"),e.Zone=_}("undefined"!=typeof window&&window||"undefined"!=typeof self&&self||global);const ue=Object.getOwnPropertyDescriptor,he=Object.defineProperty,de=Object.getPrototypeOf,Be=Object.create,ut=Array.prototype.slice,Se="addEventListener",Oe="removeEventListener",Ze=Zone.__symbol__(Se),Ie=Zone.__symbol__(Oe),se="true",ie="false",ke=Zone.__symbol__("");function Le(e,n){return Zone.current.wrap(e,n)}function Me(e,n,i,r,c){return Zone.current.scheduleMacroTask(e,n,i,r,c)}const x=Zone.__symbol__,Pe="undefined"!=typeof window,pe=Pe?window:void 0,$=Pe&&pe||"object"==typeof self&&self||global,ht=[null];function Ae(e,n){for(let i=e.length-1;i>=0;i--)"function"==typeof e[i]&&(e[i]=Le(e[i],n+"_"+i));return e}function Fe(e){return!e||!1!==e.writable&&!("function"==typeof e.get&&void 0===e.set)}const Ue="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,Re=!("nw"in $)&&void 0!==$.process&&"[object process]"==={}.toString.call($.process),je=!Re&&!Ue&&!(!Pe||!pe.HTMLElement),We=void 0!==$.process&&"[object process]"==={}.toString.call($.process)&&!Ue&&!(!Pe||!pe.HTMLElement),Ce={},qe=function(e){if(!(e=e||$.event))return;let n=Ce[e.type];n||(n=Ce[e.type]=x("ON_PROPERTY"+e.type));const i=this||e.target||$,r=i[n];let c;if(je&&i===pe&&"error"===e.type){const u=e;c=r&&r.call(this,u.message,u.filename,u.lineno,u.colno,u.error),!0===c&&e.preventDefault()}else c=r&&r.apply(this,arguments),null!=c&&!c&&e.preventDefault();return c};function Xe(e,n,i){let r=ue(e,n);if(!r&&i&&ue(i,n)&&(r={enumerable:!0,configurable:!0}),!r||!r.configurable)return;const c=x("on"+n+"patched");if(e.hasOwnProperty(c)&&e[c])return;delete r.writable,delete r.value;const u=r.get,f=r.set,_=n.substr(2);let y=Ce[_];y||(y=Ce[_]=x("ON_PROPERTY"+_)),r.set=function(T){let m=this;!m&&e===$&&(m=$),m&&(m[y]&&m.removeEventListener(_,qe),f&&f.apply(m,ht),"function"==typeof T?(m[y]=T,m.addEventListener(_,qe,!1)):m[y]=null)},r.get=function(){let T=this;if(!T&&e===$&&(T=$),!T)return null;const m=T[y];if(m)return m;if(u){let S=u&&u.call(this);if(S)return r.set.call(this,S),"function"==typeof T.removeAttribute&&T.removeAttribute(n),S}return null},he(e,n,r),e[c]=!0}function Ye(e,n,i){if(n)for(let r=0;r<n.length;r++)Xe(e,"on"+n[r],i);else{const r=[];for(const c in e)"on"==c.substr(0,2)&&r.push(c);for(let c=0;c<r.length;c++)Xe(e,r[c],i)}}const ne=x("originalInstance");function ve(e){const n=$[e];if(!n)return;$[x(e)]=n,$[e]=function(){const c=Ae(arguments,e);switch(c.length){case 0:this[ne]=new n;break;case 1:this[ne]=new n(c[0]);break;case 2:this[ne]=new n(c[0],c[1]);break;case 3:this[ne]=new n(c[0],c[1],c[2]);break;case 4:this[ne]=new n(c[0],c[1],c[2],c[3]);break;default:throw new Error("Arg list too long.")}},ae($[e],n);const i=new n(function(){});let r;for(r in i)"XMLHttpRequest"===e&&"responseBlob"===r||function(c){"function"==typeof i[c]?$[e].prototype[c]=function(){return this[ne][c].apply(this[ne],arguments)}:he($[e].prototype,c,{set:function(u){"function"==typeof u?(this[ne][c]=Le(u,e+"."+c),ae(this[ne][c],u)):this[ne][c]=u},get:function(){return this[ne][c]}})}(r);for(r in n)"prototype"!==r&&n.hasOwnProperty(r)&&($[e][r]=n[r])}function ce(e,n,i){let r=e;for(;r&&!r.hasOwnProperty(n);)r=de(r);!r&&e[n]&&(r=e);const c=x(n);let u=null;if(r&&(!(u=r[c])||!r.hasOwnProperty(c))&&(u=r[c]=r[n],Fe(r&&ue(r,n)))){const _=i(u,c,n);r[n]=function(){return _(this,arguments)},ae(r[n],u)}return u}function _t(e,n,i){let r=null;function c(u){const f=u.data;return f.args[f.cbIdx]=function(){u.invoke.apply(this,arguments)},r.apply(f.target,f.args),u}r=ce(e,n,u=>function(f,_){const y=i(f,_);return y.cbIdx>=0&&"function"==typeof _[y.cbIdx]?Me(y.name,_[y.cbIdx],y,c):u.apply(f,_)})}function ae(e,n){e[x("OriginalDelegate")]=n}let $e=!1,He=!1;function mt(){if($e)return He;$e=!0;try{const e=pe.navigator.userAgent;(-1!==e.indexOf("MSIE ")||-1!==e.indexOf("Trident/")||-1!==e.indexOf("Edge/"))&&(He=!0)}catch(e){}return He}Zone.__load_patch("ZoneAwarePromise",(e,n,i)=>{const r=Object.getOwnPropertyDescriptor,c=Object.defineProperty,f=i.symbol,_=[],y=!0===e[f("DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION")],T=f("Promise"),m=f("then");i.onUnhandledError=l=>{if(i.showUncaughtError()){const s=l&&l.rejection;s?console.error("Unhandled Promise rejection:",s instanceof Error?s.message:s,"; Zone:",l.zone.name,"; Task:",l.task&&l.task.source,"; Value:",s,s instanceof Error?s.stack:void 0):console.error(l)}},i.microtaskDrainDone=()=>{for(;_.length;){const l=_.shift();try{l.zone.runGuarded(()=>{throw l.throwOriginal?l.rejection:l})}catch(s){Z(s)}}};const D=f("unhandledPromiseRejectionHandler");function Z(l){i.onUnhandledError(l);try{const s=n[D];"function"==typeof s&&s.call(this,l)}catch(s){}}function B(l){return l&&l.then}function V(l){return l}function E(l){return t.reject(l)}const d=f("state"),L=f("value"),z=f("finally"),j=f("parentPromiseValue"),q=f("parentPromiseState"),X=null,A=!0,Y=!1;function M(l,s){return a=>{try{G(l,s,a)}catch(h){G(l,!1,h)}}}const le=f("currentTaskTrace");function G(l,s,a){const h=function(){let l=!1;return function(a){return function(){l||(l=!0,a.apply(null,arguments))}}}();if(l===a)throw new TypeError("Promise resolved with itself");if(l[d]===X){let w=null;try{("object"==typeof a||"function"==typeof a)&&(w=a&&a.then)}catch(C){return h(()=>{G(l,!1,C)})(),l}if(s!==Y&&a instanceof t&&a.hasOwnProperty(d)&&a.hasOwnProperty(L)&&a[d]!==X)re(a),G(l,a[d],a[L]);else if(s!==Y&&"function"==typeof w)try{w.call(a,h(M(l,s)),h(M(l,!1)))}catch(C){h(()=>{G(l,!1,C)})()}else{l[d]=s;const C=l[L];if(l[L]=a,l[z]===z&&s===A&&(l[d]=l[q],l[L]=l[j]),s===Y&&a instanceof Error){const k=n.currentTask&&n.currentTask.data&&n.currentTask.data.__creationTrace__;k&&c(a,le,{configurable:!0,enumerable:!1,writable:!0,value:k})}for(let k=0;k<C.length;)F(l,C[k++],C[k++],C[k++],C[k++]);if(0==C.length&&s==Y){l[d]=0;let k=a;try{throw new Error("Uncaught (in promise): "+function u(l){return l&&l.toString===Object.prototype.toString?(l.constructor&&l.constructor.name||"")+": "+JSON.stringify(l):l?l.toString():Object.prototype.toString.call(l)}(a)+(a&&a.stack?"\n"+a.stack:""))}catch(b){k=b}y&&(k.throwOriginal=!0),k.rejection=a,k.promise=l,k.zone=n.current,k.task=n.currentTask,_.push(k),i.scheduleMicroTask()}}}return l}const te=f("rejectionHandledHandler");function re(l){if(0===l[d]){try{const s=n[te];s&&"function"==typeof s&&s.call(this,{rejection:l[L],promise:l})}catch(s){}l[d]=Y;for(let s=0;s<_.length;s++)l===_[s].promise&&_.splice(s,1)}}function F(l,s,a,h,w){re(l);const C=l[d],k=C?"function"==typeof h?h:V:"function"==typeof w?w:E;s.scheduleMicroTask("Promise.then",()=>{try{const b=l[L],N=!!a&&z===a[z];N&&(a[j]=b,a[q]=C);const H=s.run(k,void 0,N&&k!==E&&k!==V?[]:[b]);G(a,!0,H)}catch(b){G(a,!1,b)}},a)}const p=function(){};class t{static toString(){return"function ZoneAwarePromise() { [native code] }"}static resolve(s){return G(new this(null),A,s)}static reject(s){return G(new this(null),Y,s)}static race(s){let a,h,w=new this((b,N)=>{a=b,h=N});function C(b){a(b)}function k(b){h(b)}for(let b of s)B(b)||(b=this.resolve(b)),b.then(C,k);return w}static all(s){return t.allWithCallback(s)}static allSettled(s){return(this&&this.prototype instanceof t?this:t).allWithCallback(s,{thenCallback:h=>({status:"fulfilled",value:h}),errorCallback:h=>({status:"rejected",reason:h})})}static allWithCallback(s,a){let h,w,C=new this((H,U)=>{h=H,w=U}),k=2,b=0;const N=[];for(let H of s){B(H)||(H=this.resolve(H));const U=b;try{H.then(Q=>{N[U]=a?a.thenCallback(Q):Q,k--,0===k&&h(N)},Q=>{a?(N[U]=a.errorCallback(Q),k--,0===k&&h(N)):w(Q)})}catch(Q){w(Q)}k++,b++}return k-=2,0===k&&h(N),C}constructor(s){const a=this;if(!(a instanceof t))throw new Error("Must be an instanceof Promise.");a[d]=X,a[L]=[];try{s&&s(M(a,A),M(a,Y))}catch(h){G(a,!1,h)}}get[Symbol.toStringTag](){return"Promise"}get[Symbol.species](){return t}then(s,a){let h=this.constructor[Symbol.species];(!h||"function"!=typeof h)&&(h=this.constructor||t);const w=new h(p),C=n.current;return this[d]==X?this[L].push(C,w,s,a):F(this,C,w,s,a),w}catch(s){return this.then(null,s)}finally(s){let a=this.constructor[Symbol.species];(!a||"function"!=typeof a)&&(a=t);const h=new a(p);h[z]=z;const w=n.current;return this[d]==X?this[L].push(w,h,s,s):F(this,w,h,s,s),h}}t.resolve=t.resolve,t.reject=t.reject,t.race=t.race,t.all=t.all;const o=e[T]=e.Promise;e.Promise=t;const g=f("thenPatched");function P(l){const s=l.prototype,a=r(s,"then");if(a&&(!1===a.writable||!a.configurable))return;const h=s.then;s[m]=h,l.prototype.then=function(w,C){return new t((b,N)=>{h.call(this,b,N)}).then(w,C)},l[g]=!0}return i.patchThen=P,o&&(P(o),ce(e,"fetch",l=>function K(l){return function(s,a){let h=l.apply(s,a);if(h instanceof t)return h;let w=h.constructor;return w[g]||P(w),h}}(l))),Promise[n.__symbol__("uncaughtPromiseErrors")]=_,t}),Zone.__load_patch("toString",e=>{const n=Function.prototype.toString,i=x("OriginalDelegate"),r=x("Promise"),c=x("Error"),u=function(){if("function"==typeof this){const T=this[i];if(T)return"function"==typeof T?n.call(T):Object.prototype.toString.call(T);if(this===Promise){const m=e[r];if(m)return n.call(m)}if(this===Error){const m=e[c];if(m)return n.call(m)}}return n.call(this)};u[i]=n,Function.prototype.toString=u;const f=Object.prototype.toString;Object.prototype.toString=function(){return"function"==typeof Promise&&this instanceof Promise?"[object Promise]":f.call(this)}});let me=!1;if("undefined"!=typeof window)try{const e=Object.defineProperty({},"passive",{get:function(){me=!0}});window.addEventListener("test",e,e),window.removeEventListener("test",e,e)}catch(e){me=!1}const Et={useG:!0},ee={},Ke={},Je=new RegExp("^"+ke+"(\\w+)(true|false)$"),xe=x("propagationStopped");function Qe(e,n){const i=(n?n(e):e)+ie,r=(n?n(e):e)+se,c=ke+i,u=ke+r;ee[e]={},ee[e][ie]=c,ee[e][se]=u}function Tt(e,n,i){const r=i&&i.add||Se,c=i&&i.rm||Oe,u=i&&i.listeners||"eventListeners",f=i&&i.rmAll||"removeAllListeners",_=x(r),y="."+r+":",S=function(E,d,L){if(E.isRemoved)return;const z=E.callback;"object"==typeof z&&z.handleEvent&&(E.callback=q=>z.handleEvent(q),E.originalDelegate=z),E.invoke(E,d,[L]);const j=E.options;j&&"object"==typeof j&&j.once&&d[c].call(d,L.type,E.originalDelegate?E.originalDelegate:E.callback,j)},D=function(E){if(!(E=E||e.event))return;const d=this||E.target||e,L=d[ee[E.type][ie]];if(L)if(1===L.length)S(L[0],d,E);else{const z=L.slice();for(let j=0;j<z.length&&(!E||!0!==E[xe]);j++)S(z[j],d,E)}},Z=function(E){if(!(E=E||e.event))return;const d=this||E.target||e,L=d[ee[E.type][se]];if(L)if(1===L.length)S(L[0],d,E);else{const z=L.slice();for(let j=0;j<z.length&&(!E||!0!==E[xe]);j++)S(z[j],d,E)}};function B(E,d){if(!E)return!1;let L=!0;d&&void 0!==d.useG&&(L=d.useG);const z=d&&d.vh;let j=!0;d&&void 0!==d.chkDup&&(j=d.chkDup);let q=!1;d&&void 0!==d.rt&&(q=d.rt);let O=E;for(;O&&!O.hasOwnProperty(r);)O=de(O);if(!O&&E[r]&&(O=E),!O||O[_])return!1;const X=d&&d.eventNameToString,A={},Y=O[_]=O[r],v=O[x(c)]=O[c],M=O[x(u)]=O[u],R=O[x(f)]=O[f];let J;function le(s,a){return!me&&"object"==typeof s&&s?!!s.capture:me&&a?"boolean"==typeof s?{capture:s,passive:!0}:s?"object"==typeof s&&!1!==s.passive?Object.assign(Object.assign({},s),{passive:!0}):s:{passive:!0}:s}d&&d.prepend&&(J=O[x(d.prepend)]=O[d.prepend]);const p=L?function(s){if(!A.isExisting)return Y.call(A.target,A.eventName,A.capture?Z:D,A.options)}:function(s){return Y.call(A.target,A.eventName,s.invoke,A.options)},t=L?function(s){if(!s.isRemoved){const a=ee[s.eventName];let h;a&&(h=a[s.capture?se:ie]);const w=h&&s.target[h];if(w)for(let C=0;C<w.length;C++)if(w[C]===s){w.splice(C,1),s.isRemoved=!0,0===w.length&&(s.allRemoved=!0,s.target[h]=null);break}}if(s.allRemoved)return v.call(s.target,s.eventName,s.capture?Z:D,s.options)}:function(s){return v.call(s.target,s.eventName,s.invoke,s.options)},g=d&&d.diff?d.diff:function(s,a){const h=typeof a;return"function"===h&&s.callback===a||"object"===h&&s.originalDelegate===a},P=Zone[x("UNPATCHED_EVENTS")],K=e[x("PASSIVE_EVENTS")],l=function(s,a,h,w,C=!1,k=!1){return function(){const b=this||e;let N=arguments[0];d&&d.transferEventName&&(N=d.transferEventName(N));let H=arguments[1];if(!H)return s.apply(this,arguments);if(Re&&"uncaughtException"===N)return s.apply(this,arguments);let U=!1;if("function"!=typeof H){if(!H.handleEvent)return s.apply(this,arguments);U=!0}if(z&&!z(s,H,b,arguments))return;const Q=me&&!!K&&-1!==K.indexOf(N),oe=le(arguments[2],Q);if(P)for(let _e=0;_e<P.length;_e++)if(N===P[_e])return Q?s.call(b,N,H,oe):s.apply(this,arguments);const Ge=!!oe&&("boolean"==typeof oe||oe.capture),st=!(!oe||"object"!=typeof oe)&&oe.once,At=Zone.current;let ze=ee[N];ze||(Qe(N,X),ze=ee[N]);const it=ze[Ge?se:ie];let De,ye=b[it],ct=!1;if(ye){if(ct=!0,j)for(let _e=0;_e<ye.length;_e++)if(g(ye[_e],H))return}else ye=b[it]=[];const at=b.constructor.name,lt=Ke[at];lt&&(De=lt[N]),De||(De=at+a+(X?X(N):N)),A.options=oe,st&&(A.options.once=!1),A.target=b,A.capture=Ge,A.eventName=N,A.isExisting=ct;const be=L?Et:void 0;be&&(be.taskData=A);const fe=At.scheduleEventTask(De,H,be,h,w);return A.target=null,be&&(be.taskData=null),st&&(oe.once=!0),!me&&"boolean"==typeof fe.options||(fe.options=oe),fe.target=b,fe.capture=Ge,fe.eventName=N,U&&(fe.originalDelegate=H),k?ye.unshift(fe):ye.push(fe),C?b:void 0}};return O[r]=l(Y,y,p,t,q),J&&(O.prependListener=l(J,".prependListener:",function(s){return J.call(A.target,A.eventName,s.invoke,A.options)},t,q,!0)),O[c]=function(){const s=this||e;let a=arguments[0];d&&d.transferEventName&&(a=d.transferEventName(a));const h=arguments[2],w=!!h&&("boolean"==typeof h||h.capture),C=arguments[1];if(!C)return v.apply(this,arguments);if(z&&!z(v,C,s,arguments))return;const k=ee[a];let b;k&&(b=k[w?se:ie]);const N=b&&s[b];if(N)for(let H=0;H<N.length;H++){const U=N[H];if(g(U,C))return N.splice(H,1),U.isRemoved=!0,0===N.length&&(U.allRemoved=!0,s[b]=null,"string"==typeof a)&&(s[ke+"ON_PROPERTY"+a]=null),U.zone.cancelTask(U),q?s:void 0}return v.apply(this,arguments)},O[u]=function(){const s=this||e;let a=arguments[0];d&&d.transferEventName&&(a=d.transferEventName(a));const h=[],w=et(s,X?X(a):a);for(let C=0;C<w.length;C++){const k=w[C];h.push(k.originalDelegate?k.originalDelegate:k.callback)}return h},O[f]=function(){const s=this||e;let a=arguments[0];if(a){d&&d.transferEventName&&(a=d.transferEventName(a));const h=ee[a];if(h){const k=s[h[ie]],b=s[h[se]];if(k){const N=k.slice();for(let H=0;H<N.length;H++){const U=N[H];this[c].call(this,a,U.originalDelegate?U.originalDelegate:U.callback,U.options)}}if(b){const N=b.slice();for(let H=0;H<N.length;H++){const U=N[H];this[c].call(this,a,U.originalDelegate?U.originalDelegate:U.callback,U.options)}}}}else{const h=Object.keys(s);for(let w=0;w<h.length;w++){const k=Je.exec(h[w]);let b=k&&k[1];b&&"removeListener"!==b&&this[f].call(this,b)}this[f].call(this,"removeListener")}if(q)return this},ae(O[r],Y),ae(O[c],v),R&&ae(O[f],R),M&&ae(O[u],M),!0}let V=[];for(let E=0;E<n.length;E++)V[E]=B(n[E],i);return V}function et(e,n){if(!n){const u=[];for(let f in e){const _=Je.exec(f);let y=_&&_[1];if(y&&(!n||y===n)){const T=e[f];if(T)for(let m=0;m<T.length;m++)u.push(T[m])}}return u}let i=ee[n];i||(Qe(n),i=ee[n]);const r=e[i[ie]],c=e[i[se]];return r?c?r.concat(c):r.slice():c?c.slice():[]}function gt(e,n){const i=e.Event;i&&i.prototype&&n.patchMethod(i.prototype,"stopImmediatePropagation",r=>function(c,u){c[xe]=!0,r&&r.apply(c,u)})}function yt(e,n,i,r,c){const u=Zone.__symbol__(r);if(n[u])return;const f=n[u]=n[r];n[r]=function(_,y,T){return y&&y.prototype&&c.forEach(function(m){const S=`${i}.${r}::`+m,D=y.prototype;if(D.hasOwnProperty(m)){const Z=e.ObjectGetOwnPropertyDescriptor(D,m);Z&&Z.value?(Z.value=e.wrapWithCurrentZone(Z.value,S),e._redefineProperty(y.prototype,m,Z)):D[m]&&(D[m]=e.wrapWithCurrentZone(D[m],S))}else D[m]&&(D[m]=e.wrapWithCurrentZone(D[m],S))}),f.call(n,_,y,T)},e.attachOriginToPatched(n[r],f)}const Ve=["absolutedeviceorientation","afterinput","afterprint","appinstalled","beforeinstallprompt","beforeprint","beforeunload","devicelight","devicemotion","deviceorientation","deviceorientationabsolute","deviceproximity","hashchange","languagechange","message","mozbeforepaint","offline","online","paint","pageshow","pagehide","popstate","rejectionhandled","storage","unhandledrejection","unload","userproximity","vrdisplayconnected","vrdisplaydisconnected","vrdisplaypresentchange"],wt=["encrypted","waitingforkey","msneedkey","mozinterruptbegin","mozinterruptend"],tt=["load"],nt=["blur","error","focus","load","resize","scroll","messageerror"],Dt=["bounce","finish","start"],rt=["loadstart","progress","abort","error","load","progress","timeout","loadend","readystatechange"],Ee=["upgradeneeded","complete","abort","success","error","blocked","versionchange","close"],St=["close","error","open","message"],Ot=["error","message"],Te=["abort","animationcancel","animationend","animationiteration","auxclick","beforeinput","blur","cancel","canplay","canplaythrough","change","compositionstart","compositionupdate","compositionend","cuechange","click","close","contextmenu","curechange","dblclick","drag","dragend","dragenter","dragexit","dragleave","dragover","drop","durationchange","emptied","ended","error","focus","focusin","focusout","gotpointercapture","input","invalid","keydown","keypress","keyup","load","loadstart","loadeddata","loadedmetadata","lostpointercapture","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","mousewheel","orientationchange","pause","play","playing","pointercancel","pointerdown","pointerenter","pointerleave","pointerlockchange","mozpointerlockchange","webkitpointerlockerchange","pointerlockerror","mozpointerlockerror","webkitpointerlockerror","pointermove","pointout","pointerover","pointerup","progress","ratechange","reset","resize","scroll","seeked","seeking","select","selectionchange","selectstart","show","sort","stalled","submit","suspend","timeupdate","volumechange","touchcancel","touchmove","touchstart","touchend","transitioncancel","transitionend","waiting","wheel"].concat(["webglcontextrestored","webglcontextlost","webglcontextcreationerror"],["autocomplete","autocompleteerror"],["toggle"],["afterscriptexecute","beforescriptexecute","DOMContentLoaded","freeze","fullscreenchange","mozfullscreenchange","webkitfullscreenchange","msfullscreenchange","fullscreenerror","mozfullscreenerror","webkitfullscreenerror","msfullscreenerror","readystatechange","visibilitychange","resume"],Ve,["beforecopy","beforecut","beforepaste","copy","cut","paste","dragstart","loadend","animationstart","search","transitionrun","transitionstart","webkitanimationend","webkitanimationiteration","webkitanimationstart","webkittransitionend"],["activate","afterupdate","ariarequest","beforeactivate","beforedeactivate","beforeeditfocus","beforeupdate","cellchange","controlselect","dataavailable","datasetchanged","datasetcomplete","errorupdate","filterchange","layoutcomplete","losecapture","move","moveend","movestart","propertychange","resizeend","resizestart","rowenter","rowexit","rowsdelete","rowsinserted","command","compassneedscalibration","deactivate","help","mscontentzoom","msmanipulationstatechanged","msgesturechange","msgesturedoubletap","msgestureend","msgesturehold","msgesturestart","msgesturetap","msgotpointercapture","msinertiastart","mslostpointercapture","mspointercancel","mspointerdown","mspointerenter","mspointerhover","mspointerleave","mspointermove","mspointerout","mspointerover","mspointerup","pointerout","mssitemodejumplistitemremoved","msthumbnailclick","stop","storagecommit"]);function ot(e,n,i){if(!i||0===i.length)return n;const r=i.filter(u=>u.target===e);if(!r||0===r.length)return n;const c=r[0].ignoreProperties;return n.filter(u=>-1===c.indexOf(u))}function W(e,n,i,r){e&&Ye(e,ot(e,n,i),r)}Zone.__load_patch("util",(e,n,i)=>{i.patchOnProperties=Ye,i.patchMethod=ce,i.bindArguments=Ae,i.patchMacroTask=_t;const r=n.__symbol__("BLACK_LISTED_EVENTS"),c=n.__symbol__("UNPATCHED_EVENTS");e[c]&&(e[r]=e[c]),e[r]&&(n[r]=n[c]=e[r]),i.patchEventPrototype=gt,i.patchEventTarget=Tt,i.isIEOrEdge=mt,i.ObjectDefineProperty=he,i.ObjectGetOwnPropertyDescriptor=ue,i.ObjectCreate=Be,i.ArraySlice=ut,i.patchClass=ve,i.wrapWithCurrentZone=Le,i.filterProperties=ot,i.attachOriginToPatched=ae,i._redefineProperty=Object.defineProperty,i.patchCallbacks=yt,i.getGlobalObjects=()=>({globalSources:Ke,zoneSymbolEventNames:ee,eventNames:Te,isBrowser:je,isMix:We,isNode:Re,TRUE_STR:se,FALSE_STR:ie,ZONE_SYMBOL_PREFIX:ke,ADD_EVENT_LISTENER_STR:Se,REMOVE_EVENT_LISTENER_STR:Oe})});const Ne=x("zoneTask");function ge(e,n,i,r){let c=null,u=null;i+=r;const f={};function _(T){const m=T.data;return m.args[0]=function(){return T.invoke.apply(this,arguments)},m.handleId=c.apply(e,m.args),T}function y(T){return u.call(e,T.data.handleId)}c=ce(e,n+=r,T=>function(m,S){if("function"==typeof S[0]){const D={isPeriodic:"Interval"===r,delay:"Timeout"===r||"Interval"===r?S[1]||0:void 0,args:S},Z=S[0];S[0]=function(){try{return Z.apply(this,arguments)}finally{D.isPeriodic||("number"==typeof D.handleId?delete f[D.handleId]:D.handleId&&(D.handleId[Ne]=null))}};const B=Me(n,S[0],D,_,y);if(!B)return B;const V=B.data.handleId;return"number"==typeof V?f[V]=B:V&&(V[Ne]=B),V&&V.ref&&V.unref&&"function"==typeof V.ref&&"function"==typeof V.unref&&(B.ref=V.ref.bind(V),B.unref=V.unref.bind(V)),"number"==typeof V||V?V:B}return T.apply(e,S)}),u=ce(e,i,T=>function(m,S){const D=S[0];let Z;"number"==typeof D?Z=f[D]:(Z=D&&D[Ne],Z||(Z=D)),Z&&"string"==typeof Z.type?"notScheduled"!==Z.state&&(Z.cancelFn&&Z.data.isPeriodic||0===Z.runCount)&&("number"==typeof D?delete f[D]:D&&(D[Ne]=null),Z.zone.cancelTask(Z)):T.apply(e,S)})}Zone.__load_patch("legacy",e=>{const n=e[Zone.__symbol__("legacyPatch")];n&&n()}),Zone.__load_patch("queueMicrotask",(e,n,i)=>{i.patchMethod(e,"queueMicrotask",r=>function(c,u){n.current.scheduleMicroTask("queueMicrotask",u[0])})}),Zone.__load_patch("timers",e=>{const n="set",i="clear";ge(e,n,i,"Timeout"),ge(e,n,i,"Interval"),ge(e,n,i,"Immediate")}),Zone.__load_patch("requestAnimationFrame",e=>{ge(e,"request","cancel","AnimationFrame"),ge(e,"mozRequest","mozCancel","AnimationFrame"),ge(e,"webkitRequest","webkitCancel","AnimationFrame")}),Zone.__load_patch("blocking",(e,n)=>{const i=["alert","prompt","confirm"];for(let r=0;r<i.length;r++)ce(e,i[r],(u,f,_)=>function(y,T){return n.current.run(u,e,T,_)})}),Zone.__load_patch("EventTarget",(e,n,i)=>{(function Mt(e,n){n.patchEventPrototype(e,n)})(e,i),function Lt(e,n){if(Zone[n.symbol("patchEventTarget")])return;const{eventNames:i,zoneSymbolEventNames:r,TRUE_STR:c,FALSE_STR:u,ZONE_SYMBOL_PREFIX:f}=n.getGlobalObjects();for(let y=0;y<i.length;y++){const T=i[y],D=f+(T+u),Z=f+(T+c);r[T]={},r[T][u]=D,r[T][c]=Z}const _=e.EventTarget;_&&_.prototype&&n.patchEventTarget(e,[_&&_.prototype])}(e,i);const r=e.XMLHttpRequestEventTarget;r&&r.prototype&&i.patchEventTarget(e,[r.prototype])}),Zone.__load_patch("MutationObserver",(e,n,i)=>{ve("MutationObserver"),ve("WebKitMutationObserver")}),Zone.__load_patch("IntersectionObserver",(e,n,i)=>{ve("IntersectionObserver")}),Zone.__load_patch("FileReader",(e,n,i)=>{ve("FileReader")}),Zone.__load_patch("on_property",(e,n,i)=>{!function Zt(e,n){if(Re&&!We||Zone[e.symbol("patchEvents")])return;const i="undefined"!=typeof WebSocket,r=n.__Zone_ignore_on_properties;if(je){const f=window,_=function pt(){try{const e=pe.navigator.userAgent;if(-1!==e.indexOf("MSIE ")||-1!==e.indexOf("Trident/"))return!0}catch(e){}return!1}()?[{target:f,ignoreProperties:["error"]}]:[];W(f,Te.concat(["messageerror"]),r&&r.concat(_),de(f)),W(Document.prototype,Te,r),void 0!==f.SVGElement&&W(f.SVGElement.prototype,Te,r),W(Element.prototype,Te,r),W(HTMLElement.prototype,Te,r),W(HTMLMediaElement.prototype,wt,r),W(HTMLFrameSetElement.prototype,Ve.concat(nt),r),W(HTMLBodyElement.prototype,Ve.concat(nt),r),W(HTMLFrameElement.prototype,tt,r),W(HTMLIFrameElement.prototype,tt,r);const y=f.HTMLMarqueeElement;y&&W(y.prototype,Dt,r);const T=f.Worker;T&&W(T.prototype,Ot,r)}const c=n.XMLHttpRequest;c&&W(c.prototype,rt,r);const u=n.XMLHttpRequestEventTarget;u&&W(u&&u.prototype,rt,r),"undefined"!=typeof IDBIndex&&(W(IDBIndex.prototype,Ee,r),W(IDBRequest.prototype,Ee,r),W(IDBOpenDBRequest.prototype,Ee,r),W(IDBDatabase.prototype,Ee,r),W(IDBTransaction.prototype,Ee,r),W(IDBCursor.prototype,Ee,r)),i&&W(WebSocket.prototype,St,r)}(i,e)}),Zone.__load_patch("customElements",(e,n,i)=>{!function It(e,n){const{isBrowser:i,isMix:r}=n.getGlobalObjects();(i||r)&&e.customElements&&"customElements"in e&&n.patchCallbacks(n,e.customElements,"customElements","define",["connectedCallback","disconnectedCallback","adoptedCallback","attributeChangedCallback"])}(e,i)}),Zone.__load_patch("XHR",(e,n)=>{!function y(T){const m=T.XMLHttpRequest;if(!m)return;const S=m.prototype;let Z=S[Ze],B=S[Ie];if(!Z){const v=T.XMLHttpRequestEventTarget;if(v){const M=v.prototype;Z=M[Ze],B=M[Ie]}}const V="readystatechange",E="scheduled";function d(v){const M=v.data,R=M.target;R[u]=!1,R[_]=!1;const J=R[c];Z||(Z=R[Ze],B=R[Ie]),J&&B.call(R,V,J);const le=R[c]=()=>{if(R.readyState===R.DONE)if(!M.aborted&&R[u]&&v.state===E){const te=R[n.__symbol__("loadfalse")];if(0!==R.status&&te&&te.length>0){const re=v.invoke;v.invoke=function(){const F=R[n.__symbol__("loadfalse")];for(let I=0;I<F.length;I++)F[I]===v&&F.splice(I,1);!M.aborted&&v.state===E&&re.call(v)},te.push(v)}else v.invoke()}else!M.aborted&&!1===R[u]&&(R[_]=!0)};return Z.call(R,V,le),R[i]||(R[i]=v),A.apply(R,M.args),R[u]=!0,v}function L(){}function z(v){const M=v.data;return M.aborted=!0,Y.apply(M.target,M.args)}const j=ce(S,"open",()=>function(v,M){return v[r]=0==M[2],v[f]=M[1],j.apply(v,M)}),O=x("fetchTaskAborting"),X=x("fetchTaskScheduling"),A=ce(S,"send",()=>function(v,M){if(!0===n.current[X]||v[r])return A.apply(v,M);{const R={target:v,url:v[f],isPeriodic:!1,args:M,aborted:!1},J=Me("XMLHttpRequest.send",L,R,d,z);v&&!0===v[_]&&!R.aborted&&J.state===E&&J.invoke()}}),Y=ce(S,"abort",()=>function(v,M){const R=function D(v){return v[i]}(v);if(R&&"string"==typeof R.type){if(null==R.cancelFn||R.data&&R.data.aborted)return;R.zone.cancelTask(R)}else if(!0===n.current[O])return Y.apply(v,M)})}(e);const i=x("xhrTask"),r=x("xhrSync"),c=x("xhrListener"),u=x("xhrScheduled"),f=x("xhrURL"),_=x("xhrErrorBeforeScheduled")}),Zone.__load_patch("geolocation",e=>{e.navigator&&e.navigator.geolocation&&function dt(e,n){const i=e.constructor.name;for(let r=0;r<n.length;r++){const c=n[r],u=e[c];if(u){if(!Fe(ue(e,c)))continue;e[c]=(_=>{const y=function(){return _.apply(this,Ae(arguments,i+"."+c))};return ae(y,_),y})(u)}}}(e.navigator.geolocation,["getCurrentPosition","watchPosition"])}),Zone.__load_patch("PromiseRejectionEvent",(e,n)=>{function i(r){return function(c){et(e,r).forEach(f=>{const _=e.PromiseRejectionEvent;if(_){const y=new _(r,{promise:c.promise,reason:c.rejection});f.invoke(y)}})}}e.PromiseRejectionEvent&&(n[x("unhandledPromiseRejectionHandler")]=i("unhandledrejection"),n[x("rejectionHandledHandler")]=i("rejectionhandled"))})}},we=>{we(we.s=435)}]); + +"use strict";(self.webpackChunkcoverage_app=self.webpackChunkcoverage_app||[]).push([[179],{873:()=>{function pe(e){return"function"==typeof e}function xo(e){const n=e(r=>{Error.call(r),r.stack=(new Error).stack});return n.prototype=Object.create(Error.prototype),n.prototype.constructor=n,n}const No=xo(e=>function(n){e(this),this.message=n?`${n.length} errors occurred during unsubscription:\n${n.map((r,o)=>`${o+1}) ${r.toString()}`).join("\n ")}`:"",this.name="UnsubscriptionError",this.errors=n});function Fr(e,t){if(e){const n=e.indexOf(t);0<=n&&e.splice(n,1)}}class Tt{constructor(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._teardowns=null}unsubscribe(){let t;if(!this.closed){this.closed=!0;const{_parentage:n}=this;if(n)if(this._parentage=null,Array.isArray(n))for(const i of n)i.remove(this);else n.remove(this);const{initialTeardown:r}=this;if(pe(r))try{r()}catch(i){t=i instanceof No?i.errors:[i]}const{_teardowns:o}=this;if(o){this._teardowns=null;for(const i of o)try{uc(i)}catch(s){t=null!=t?t:[],s instanceof No?t=[...t,...s.errors]:t.push(s)}}if(t)throw new No(t)}}add(t){var n;if(t&&t!==this)if(this.closed)uc(t);else{if(t instanceof Tt){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._teardowns=null!==(n=this._teardowns)&&void 0!==n?n:[]).push(t)}}_hasParent(t){const{_parentage:n}=this;return n===t||Array.isArray(n)&&n.includes(t)}_addParent(t){const{_parentage:n}=this;this._parentage=Array.isArray(n)?(n.push(t),n):n?[n,t]:t}_removeParent(t){const{_parentage:n}=this;n===t?this._parentage=null:Array.isArray(n)&&Fr(n,t)}remove(t){const{_teardowns:n}=this;n&&Fr(n,t),t instanceof Tt&&t._removeParent(this)}}Tt.EMPTY=(()=>{const e=new Tt;return e.closed=!0,e})();const ac=Tt.EMPTY;function lc(e){return e instanceof Tt||e&&"closed"in e&&pe(e.remove)&&pe(e.add)&&pe(e.unsubscribe)}function uc(e){pe(e)?e():e.unsubscribe()}const yn={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1},Fo={setTimeout(...e){const{delegate:t}=Fo;return((null==t?void 0:t.setTimeout)||setTimeout)(...e)},clearTimeout(e){const{delegate:t}=Fo;return((null==t?void 0:t.clearTimeout)||clearTimeout)(e)},delegate:void 0};function cc(e){Fo.setTimeout(()=>{const{onUnhandledError:t}=yn;if(!t)throw e;t(e)})}function Oo(){}const Z_=gs("C",void 0,void 0);function gs(e,t,n){return{kind:e,value:t,error:n}}let Cn=null;function Ro(e){if(yn.useDeprecatedSynchronousErrorHandling){const t=!Cn;if(t&&(Cn={errorThrown:!1,error:null}),e(),t){const{errorThrown:n,error:r}=Cn;if(Cn=null,n)throw r}}else e()}class ms extends Tt{constructor(t){super(),this.isStopped=!1,t?(this.destination=t,lc(t)&&t.add(this)):this.destination=X_}static create(t,n,r){return new _s(t,n,r)}next(t){this.isStopped?ys(function K_(e){return gs("N",e,void 0)}(t),this):this._next(t)}error(t){this.isStopped?ys(function Y_(e){return gs("E",void 0,e)}(t),this):(this.isStopped=!0,this._error(t))}complete(){this.isStopped?ys(Z_,this):(this.isStopped=!0,this._complete())}unsubscribe(){this.closed||(this.isStopped=!0,super.unsubscribe(),this.destination=null)}_next(t){this.destination.next(t)}_error(t){try{this.destination.error(t)}finally{this.unsubscribe()}}_complete(){try{this.destination.complete()}finally{this.unsubscribe()}}}class _s extends ms{constructor(t,n,r){let o;if(super(),pe(t))o=t;else if(t){let i;({next:o,error:n,complete:r}=t),this&&yn.useDeprecatedNextContext?(i=Object.create(t),i.unsubscribe=()=>this.unsubscribe()):i=t,o=null==o?void 0:o.bind(i),n=null==n?void 0:n.bind(i),r=null==r?void 0:r.bind(i)}this.destination={next:o?vs(o):Oo,error:vs(null!=n?n:dc),complete:r?vs(r):Oo}}}function vs(e,t){return(...n)=>{try{e(...n)}catch(r){yn.useDeprecatedSynchronousErrorHandling?function J_(e){yn.useDeprecatedSynchronousErrorHandling&&Cn&&(Cn.errorThrown=!0,Cn.error=e)}(r):cc(r)}}}function dc(e){throw e}function ys(e,t){const{onStoppedNotification:n}=yn;n&&Fo.setTimeout(()=>n(e,t))}const X_={closed:!0,next:Oo,error:dc,complete:Oo},Cs="function"==typeof Symbol&&Symbol.observable||"@@observable";function fc(e){return e}let Le=(()=>{class e{constructor(n){n&&(this._subscribe=n)}lift(n){const r=new e;return r.source=this,r.operator=n,r}subscribe(n,r,o){const i=function tv(e){return e&&e instanceof ms||function ev(e){return e&&pe(e.next)&&pe(e.error)&&pe(e.complete)}(e)&&lc(e)}(n)?n:new _s(n,r,o);return Ro(()=>{const{operator:s,source:a}=this;i.add(s?s.call(i,a):a?this._subscribe(i):this._trySubscribe(i))}),i}_trySubscribe(n){try{return this._subscribe(n)}catch(r){n.error(r)}}forEach(n,r){return new(r=pc(r))((o,i)=>{let s;s=this.subscribe(a=>{try{n(a)}catch(l){i(l),null==s||s.unsubscribe()}},i,o)})}_subscribe(n){var r;return null===(r=this.source)||void 0===r?void 0:r.subscribe(n)}[Cs](){return this}pipe(...n){return function hc(e){return 0===e.length?fc:1===e.length?e[0]:function(n){return e.reduce((r,o)=>o(r),n)}}(n)(this)}toPromise(n){return new(n=pc(n))((r,o)=>{let i;this.subscribe(s=>i=s,s=>o(s),()=>r(i))})}}return e.create=t=>new e(t),e})();function pc(e){var t;return null!==(t=null!=e?e:yn.Promise)&&void 0!==t?t:Promise}const nv=xo(e=>function(){e(this),this.name="ObjectUnsubscribedError",this.message="object unsubscribed"});let Ds=(()=>{class e extends Le{constructor(){super(),this.closed=!1,this.observers=[],this.isStopped=!1,this.hasError=!1,this.thrownError=null}lift(n){const r=new gc(this,this);return r.operator=n,r}_throwIfClosed(){if(this.closed)throw new nv}next(n){Ro(()=>{if(this._throwIfClosed(),!this.isStopped){const r=this.observers.slice();for(const o of r)o.next(n)}})}error(n){Ro(()=>{if(this._throwIfClosed(),!this.isStopped){this.hasError=this.isStopped=!0,this.thrownError=n;const{observers:r}=this;for(;r.length;)r.shift().error(n)}})}complete(){Ro(()=>{if(this._throwIfClosed(),!this.isStopped){this.isStopped=!0;const{observers:n}=this;for(;n.length;)n.shift().complete()}})}unsubscribe(){this.isStopped=this.closed=!0,this.observers=null}get observed(){var n;return(null===(n=this.observers)||void 0===n?void 0:n.length)>0}_trySubscribe(n){return this._throwIfClosed(),super._trySubscribe(n)}_subscribe(n){return this._throwIfClosed(),this._checkFinalizedStatuses(n),this._innerSubscribe(n)}_innerSubscribe(n){const{hasError:r,isStopped:o,observers:i}=this;return r||o?ac:(i.push(n),new Tt(()=>Fr(i,n)))}_checkFinalizedStatuses(n){const{hasError:r,thrownError:o,isStopped:i}=this;r?n.error(o):i&&n.complete()}asObservable(){const n=new Le;return n.source=this,n}}return e.create=(t,n)=>new gc(t,n),e})();class gc extends Ds{constructor(t,n){super(),this.destination=t,this.source=n}next(t){var n,r;null===(r=null===(n=this.destination)||void 0===n?void 0:n.next)||void 0===r||r.call(n,t)}error(t){var n,r;null===(r=null===(n=this.destination)||void 0===n?void 0:n.error)||void 0===r||r.call(n,t)}complete(){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.complete)||void 0===n||n.call(t)}_subscribe(t){var n,r;return null!==(r=null===(n=this.source)||void 0===n?void 0:n.subscribe(t))&&void 0!==r?r:ac}}function Ln(e){return t=>{if(function rv(e){return pe(null==e?void 0:e.lift)}(t))return t.lift(function(n){try{return e(n,this)}catch(r){this.error(r)}});throw new TypeError("Unable to lift unknown Observable type")}}class Bn extends ms{constructor(t,n,r,o,i){super(t),this.onFinalize=i,this._next=n?function(s){try{n(s)}catch(a){t.error(a)}}:super._next,this._error=o?function(s){try{o(s)}catch(a){t.error(a)}finally{this.unsubscribe()}}:super._error,this._complete=r?function(){try{r()}catch(s){t.error(s)}finally{this.unsubscribe()}}:super._complete}unsubscribe(){var t;const{closed:n}=this;super.unsubscribe(),!n&&(null===(t=this.onFinalize)||void 0===t||t.call(this))}}function ws(e,t){return Ln((n,r)=>{let o=0;n.subscribe(new Bn(r,i=>{r.next(e.call(t,i,o++))}))})}function Dn(e){return this instanceof Dn?(this.v=e,this):new Dn(e)}function sv(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o,r=n.apply(e,t||[]),i=[];return o={},s("next"),s("throw"),s("return"),o[Symbol.asyncIterator]=function(){return this},o;function s(f){r[f]&&(o[f]=function(p){return new Promise(function(m,D){i.push([f,p,m,D])>1||a(f,p)})})}function a(f,p){try{!function l(f){f.value instanceof Dn?Promise.resolve(f.value.v).then(u,c):d(i[0][2],f)}(r[f](p))}catch(m){d(i[0][3],m)}}function u(f){a("next",f)}function c(f){a("throw",f)}function d(f,p){f(p),i.shift(),i.length&&a(i[0][0],i[0][1])}}function av(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var n,t=e[Symbol.asyncIterator];return t?t.call(e):(e=function vc(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}(e),n={},r("next"),r("throw"),r("return"),n[Symbol.asyncIterator]=function(){return this},n);function r(i){n[i]=e[i]&&function(s){return new Promise(function(a,l){!function o(i,s,a,l){Promise.resolve(l).then(function(u){i({value:u,done:a})},s)}(a,l,(s=e[i](s)).done,s.value)})}}}const yc=e=>e&&"number"==typeof e.length&&"function"!=typeof e;function Cc(e){return pe(null==e?void 0:e.then)}function Dc(e){return pe(e[Cs])}function wc(e){return Symbol.asyncIterator&&pe(null==e?void 0:e[Symbol.asyncIterator])}function bc(e){return new TypeError(`You provided ${null!==e&&"object"==typeof e?"an invalid object":`'${e}'`} where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`)}const Ec=function uv(){return"function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}();function Mc(e){return pe(null==e?void 0:e[Ec])}function Ic(e){return sv(this,arguments,function*(){const n=e.getReader();try{for(;;){const{value:r,done:o}=yield Dn(n.read());if(o)return yield Dn(void 0);yield yield Dn(r)}}finally{n.releaseLock()}})}function Ac(e){return pe(null==e?void 0:e.getReader)}function wn(e){if(e instanceof Le)return e;if(null!=e){if(Dc(e))return function cv(e){return new Le(t=>{const n=e[Cs]();if(pe(n.subscribe))return n.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}(e);if(yc(e))return function dv(e){return new Le(t=>{for(let n=0;n<e.length&&!t.closed;n++)t.next(e[n]);t.complete()})}(e);if(Cc(e))return function fv(e){return new Le(t=>{e.then(n=>{t.closed||(t.next(n),t.complete())},n=>t.error(n)).then(null,cc)})}(e);if(wc(e))return Tc(e);if(Mc(e))return function hv(e){return new Le(t=>{for(const n of e)if(t.next(n),t.closed)return;t.complete()})}(e);if(Ac(e))return function pv(e){return Tc(Ic(e))}(e)}throw bc(e)}function Tc(e){return new Le(t=>{(function gv(e,t){var n,r,o,i;return function ov(e,t,n,r){return new(n||(n=Promise))(function(i,s){function a(c){try{u(r.next(c))}catch(d){s(d)}}function l(c){try{u(r.throw(c))}catch(d){s(d)}}function u(c){c.done?i(c.value):function o(i){return i instanceof n?i:new n(function(s){s(i)})}(c.value).then(a,l)}u((r=r.apply(e,t||[])).next())})}(this,void 0,void 0,function*(){try{for(n=av(e);!(r=yield n.next()).done;)if(t.next(r.value),t.closed)return}catch(s){o={error:s}}finally{try{r&&!r.done&&(i=n.return)&&(yield i.call(n))}finally{if(o)throw o.error}}t.complete()})})(e,t).catch(n=>t.error(n))})}function en(e,t,n,r=0,o=!1){const i=t.schedule(function(){n(),o?e.add(this.schedule(null,r)):this.unsubscribe()},r);if(e.add(i),!o)return i}function Sc(e,t,n=1/0){return pe(t)?Sc((r,o)=>ws((i,s)=>t(r,i,o,s))(wn(e(r,o))),n):("number"==typeof t&&(n=t),Ln((r,o)=>function mv(e,t,n,r,o,i,s,a){const l=[];let u=0,c=0,d=!1;const f=()=>{d&&!l.length&&!u&&t.complete()},p=D=>u<r?m(D):l.push(D),m=D=>{i&&t.next(D),u++;let M=!1;wn(n(D,c++)).subscribe(new Bn(t,I=>{null==o||o(I),i?p(I):t.next(I)},()=>{M=!0},void 0,()=>{if(M)try{for(u--;l.length&&u<r;){const I=l.shift();s?en(t,s,()=>m(I)):m(I)}f()}catch(I){t.error(I)}}))};return e.subscribe(new Bn(t,p,()=>{d=!0,f()})),()=>{null==a||a()}}(r,o,e,n)))}const Es=new Le(e=>e.complete());function Ms(e){return e[e.length-1]}function xc(e,t=0){return Ln((n,r)=>{n.subscribe(new Bn(r,o=>en(r,e,()=>r.next(o),t),()=>en(r,e,()=>r.complete(),t),o=>en(r,e,()=>r.error(o),t)))})}function Nc(e,t=0){return Ln((n,r)=>{r.add(e.schedule(()=>n.subscribe(r),t))})}function Fc(e,t){if(!e)throw new Error("Iterable cannot be null");return new Le(n=>{en(n,t,()=>{const r=e[Symbol.asyncIterator]();en(n,t,()=>{r.next().then(o=>{o.done?n.complete():n.next(o.value)})},0,!0)})})}function Is(e,t){return t?function Tv(e,t){if(null!=e){if(Dc(e))return function bv(e,t){return wn(e).pipe(Nc(t),xc(t))}(e,t);if(yc(e))return function Mv(e,t){return new Le(n=>{let r=0;return t.schedule(function(){r===e.length?n.complete():(n.next(e[r++]),n.closed||this.schedule())})})}(e,t);if(Cc(e))return function Ev(e,t){return wn(e).pipe(Nc(t),xc(t))}(e,t);if(wc(e))return Fc(e,t);if(Mc(e))return function Iv(e,t){return new Le(n=>{let r;return en(n,t,()=>{r=e[Ec](),en(n,t,()=>{let o,i;try{({value:o,done:i}=r.next())}catch(s){return void n.error(s)}i?n.complete():n.next(o)},0,!0)}),()=>pe(null==r?void 0:r.return)&&r.return()})}(e,t);if(Ac(e))return function Av(e,t){return Fc(Ic(e),t)}(e,t)}throw bc(e)}(e,t):wn(e)}function Sv(...e){const t=function Dv(e){return function yv(e){return e&&pe(e.schedule)}(Ms(e))?e.pop():void 0}(e),n=function wv(e,t){return"number"==typeof Ms(e)?e.pop():t}(e,1/0),r=e;return r.length?1===r.length?wn(r[0]):function _v(e=1/0){return Sc(fc,e)}(n)(Is(r,t)):Es}function As(e,t,...n){return!0===t?(e(),null):!1===t?null:t(...n).pipe(function xv(e){return e<=0?()=>Es:Ln((t,n)=>{let r=0;t.subscribe(new Bn(n,o=>{++r<=e&&(n.next(o),e<=r&&n.complete())}))})}(1)).subscribe(()=>e())}function ie(e){for(let t in e)if(e[t]===ie)return t;throw Error("Could not find renamed property on target object.")}function Ts(e,t){for(const n in t)t.hasOwnProperty(n)&&!e.hasOwnProperty(n)&&(e[n]=t[n])}function te(e){if("string"==typeof e)return e;if(Array.isArray(e))return"["+e.map(te).join(", ")+"]";if(null==e)return""+e;if(e.overriddenName)return`${e.overriddenName}`;if(e.name)return`${e.name}`;const t=e.toString();if(null==t)return""+t;const n=t.indexOf("\n");return-1===n?t:t.substring(0,n)}function Ss(e,t){return null==e||""===e?null===t?"":t:null==t||""===t?e:e+" "+t}const Fv=ie({__forward_ref__:ie});function ae(e){return e.__forward_ref__=ae,e.toString=function(){return te(this())},e}function H(e){return Oc(e)?e():e}function Oc(e){return"function"==typeof e&&e.hasOwnProperty(Fv)&&e.__forward_ref__===ae}class Y extends Error{constructor(t,n){super(function xs(e,t){return`NG0${Math.abs(e)}${t?": "+t:""}`}(t,n)),this.code=t}}function V(e){return"string"==typeof e?e:null==e?"":String(e)}function Be(e){return"function"==typeof e?e.name||e.toString():"object"==typeof e&&null!=e&&"function"==typeof e.type?e.type.name||e.type.toString():V(e)}function Po(e,t){const n=t?` in ${t}`:"";throw new Y(-201,`No provider for ${Be(e)} found${n}`)}function Ke(e,t){null==e&&function ce(e,t,n,r){throw new Error(`ASSERTION ERROR: ${e}`+(null==r?"":` [Expected=> ${n} ${r} ${t} <=Actual]`))}(t,e,null,"!=")}function de(e){return{token:e.token,providedIn:e.providedIn||null,factory:e.factory,value:void 0}}function Gt(e){return{providers:e.providers||[],imports:e.imports||[]}}function Ns(e){return Rc(e,Vo)||Rc(e,Vc)}function Rc(e,t){return e.hasOwnProperty(t)?e[t]:null}function Pc(e){return e&&(e.hasOwnProperty(Fs)||e.hasOwnProperty(Bv))?e[Fs]:null}const Vo=ie({\u0275prov:ie}),Fs=ie({\u0275inj:ie}),Vc=ie({ngInjectableDef:ie}),Bv=ie({ngInjectorDef:ie});var B=(()=>((B=B||{})[B.Default=0]="Default",B[B.Host=1]="Host",B[B.Self=2]="Self",B[B.SkipSelf=4]="SkipSelf",B[B.Optional=8]="Optional",B))();let Os;function tn(e){const t=Os;return Os=e,t}function kc(e,t,n){const r=Ns(e);return r&&"root"==r.providedIn?void 0===r.value?r.value=r.factory():r.value:n&B.Optional?null:void 0!==t?t:void Po(te(e),"Injector")}function nn(e){return{toString:e}.toString()}var gt=(()=>((gt=gt||{})[gt.OnPush=0]="OnPush",gt[gt.Default=1]="Default",gt))(),St=(()=>{return(e=St||(St={}))[e.Emulated=0]="Emulated",e[e.None=2]="None",e[e.ShadowDom=3]="ShadowDom",St;var e})();const jv="undefined"!=typeof globalThis&&globalThis,$v="undefined"!=typeof window&&window,Uv="undefined"!=typeof self&&"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&self,re=jv||"undefined"!=typeof global&&global||$v||Uv,Hn={},se=[],ko=ie({\u0275cmp:ie}),Rs=ie({\u0275dir:ie}),Ps=ie({\u0275pipe:ie}),Lc=ie({\u0275mod:ie}),qt=ie({\u0275fac:ie}),Or=ie({__NG_ELEMENT_ID__:ie});let zv=0;function rn(e){return nn(()=>{const n={},r={type:e.type,providersResolver:null,decls:e.decls,vars:e.vars,factory:null,template:e.template||null,consts:e.consts||null,ngContentSelectors:e.ngContentSelectors,hostBindings:e.hostBindings||null,hostVars:e.hostVars||0,hostAttrs:e.hostAttrs||null,contentQueries:e.contentQueries||null,declaredInputs:n,inputs:null,outputs:null,exportAs:e.exportAs||null,onPush:e.changeDetection===gt.OnPush,directiveDefs:null,pipeDefs:null,selectors:e.selectors||se,viewQuery:e.viewQuery||null,features:e.features||null,data:e.data||{},encapsulation:e.encapsulation||St.Emulated,id:"c",styles:e.styles||se,_:null,setInput:null,schemas:e.schemas||null,tView:null},o=e.directives,i=e.features,s=e.pipes;return r.id+=zv++,r.inputs=$c(e.inputs,n),r.outputs=$c(e.outputs),i&&i.forEach(a=>a(r)),r.directiveDefs=o?()=>("function"==typeof o?o():o).map(Bc):null,r.pipeDefs=s?()=>("function"==typeof s?s():s).map(Hc):null,r})}function Bc(e){return Ne(e)||function sn(e){return e[Rs]||null}(e)}function Hc(e){return function bn(e){return e[Ps]||null}(e)}const jc={};function on(e){return nn(()=>{const t={type:e.type,bootstrap:e.bootstrap||se,declarations:e.declarations||se,imports:e.imports||se,exports:e.exports||se,transitiveCompileScopes:null,schemas:e.schemas||null,id:e.id||null};return null!=e.id&&(jc[e.id]=e.type),t})}function $c(e,t){if(null==e)return Hn;const n={};for(const r in e)if(e.hasOwnProperty(r)){let o=e[r],i=o;Array.isArray(o)&&(i=o[1],o=o[0]),n[o]=r,t&&(t[o]=i)}return n}const k=rn;function qe(e){return{type:e.type,name:e.name,factory:null,pure:!1!==e.pure,onDestroy:e.type.prototype.ngOnDestroy||null}}function Ne(e){return e[ko]||null}function it(e,t){const n=e[Lc]||null;if(!n&&!0===t)throw new Error(`Type ${te(e)} does not have '\u0275mod' property.`);return n}const j=11;function xt(e){return Array.isArray(e)&&"object"==typeof e[1]}function _t(e){return Array.isArray(e)&&!0===e[1]}function Ls(e){return 0!=(8&e.flags)}function jo(e){return 2==(2&e.flags)}function $o(e){return 1==(1&e.flags)}function vt(e){return null!==e.template}function Yv(e){return 0!=(512&e[2])}function An(e,t){return e.hasOwnProperty(qt)?e[qt]:null}class Xv{constructor(t,n,r){this.previousValue=t,this.currentValue=n,this.firstChange=r}isFirstChange(){return this.firstChange}}function Wt(){return zc}function zc(e){return e.type.prototype.ngOnChanges&&(e.setInput=ty),ey}function ey(){const e=qc(this),t=null==e?void 0:e.current;if(t){const n=e.previous;if(n===Hn)e.previous=t;else for(let r in t)n[r]=t[r];e.current=null,this.ngOnChanges(t)}}function ty(e,t,n,r){const o=qc(e)||function ny(e,t){return e[Gc]=t}(e,{previous:Hn,current:null}),i=o.current||(o.current={}),s=o.previous,a=this.declaredInputs[n],l=s[a];i[a]=new Xv(l&&l.currentValue,t,s===Hn),e[r]=t}Wt.ngInherit=!0;const Gc="__ngSimpleChanges__";function qc(e){return e[Gc]||null}let Us;function me(e){return!!e.listen}const Wc={createRenderer:(e,t)=>function zs(){return void 0!==Us?Us:"undefined"!=typeof document?document:void 0}()};function De(e){for(;Array.isArray(e);)e=e[0];return e}function Uo(e,t){return De(t[e])}function lt(e,t){return De(t[e.index])}function Gs(e,t){return e.data[t]}function Xe(e,t){const n=t[e];return xt(n)?n:n[0]}function qs(e){return 128==(128&e[2])}function an(e,t){return null==t?null:e[t]}function Zc(e){e[18]=0}function Ws(e,t){e[5]+=t;let n=e,r=e[3];for(;null!==r&&(1===t&&1===n[5]||-1===t&&0===n[5]);)r[5]+=t,n=r,r=r[3]}const P={lFrame:rd(null),bindingsEnabled:!0,isInCheckNoChangesMode:!1};function Yc(){return P.bindingsEnabled}function w(){return P.lFrame.lView}function K(){return P.lFrame.tView}function ee(e){return P.lFrame.contextLView=e,e[8]}function Me(){let e=Kc();for(;null!==e&&64===e.type;)e=e.parent;return e}function Kc(){return P.lFrame.currentTNode}function Nt(e,t){const n=P.lFrame;n.currentTNode=e,n.isParent=t}function Qs(){return P.lFrame.isParent}function Zs(){P.lFrame.isParent=!1}function zo(){return P.isInCheckNoChangesMode}function Go(e){P.isInCheckNoChangesMode=e}function He(){const e=P.lFrame;let t=e.bindingRootIndex;return-1===t&&(t=e.bindingRootIndex=e.tView.bindingStartIndex),t}function qn(){return P.lFrame.bindingIndex++}function Zt(e){const t=P.lFrame,n=t.bindingIndex;return t.bindingIndex=t.bindingIndex+e,n}function yy(e,t){const n=P.lFrame;n.bindingIndex=n.bindingRootIndex=e,Ys(t)}function Ys(e){P.lFrame.currentDirectiveIndex=e}function Js(e){P.lFrame.currentQueryIndex=e}function Dy(e){const t=e[1];return 2===t.type?t.declTNode:1===t.type?e[6]:null}function td(e,t,n){if(n&B.SkipSelf){let o=t,i=e;for(;!(o=o.parent,null!==o||n&B.Host||(o=Dy(i),null===o||(i=i[15],10&o.type))););if(null===o)return!1;t=o,e=i}const r=P.lFrame=nd();return r.currentTNode=t,r.lView=e,!0}function qo(e){const t=nd(),n=e[1];P.lFrame=t,t.currentTNode=n.firstChild,t.lView=e,t.tView=n,t.contextLView=e,t.bindingIndex=n.bindingStartIndex,t.inI18n=!1}function nd(){const e=P.lFrame,t=null===e?null:e.child;return null===t?rd(e):t}function rd(e){const t={currentTNode:null,isParent:!0,lView:null,tView:null,selectedIndex:-1,contextLView:null,elementDepthCount:0,currentNamespace:null,currentDirectiveIndex:-1,bindingRootIndex:-1,bindingIndex:-1,currentQueryIndex:0,parent:e,child:null,inI18n:!1};return null!==e&&(e.child=t),t}function od(){const e=P.lFrame;return P.lFrame=e.parent,e.currentTNode=null,e.lView=null,e}const id=od;function Wo(){const e=od();e.isParent=!0,e.tView=null,e.selectedIndex=-1,e.contextLView=null,e.elementDepthCount=0,e.currentDirectiveIndex=-1,e.currentNamespace=null,e.bindingRootIndex=-1,e.bindingIndex=-1,e.currentQueryIndex=0}function je(){return P.lFrame.selectedIndex}function ln(e){P.lFrame.selectedIndex=e}function _e(){const e=P.lFrame;return Gs(e.tView,e.selectedIndex)}function Qo(e,t){for(let n=t.directiveStart,r=t.directiveEnd;n<r;n++){const i=e.data[n].type.prototype,{ngAfterContentInit:s,ngAfterContentChecked:a,ngAfterViewInit:l,ngAfterViewChecked:u,ngOnDestroy:c}=i;s&&(e.contentHooks||(e.contentHooks=[])).push(-n,s),a&&((e.contentHooks||(e.contentHooks=[])).push(n,a),(e.contentCheckHooks||(e.contentCheckHooks=[])).push(n,a)),l&&(e.viewHooks||(e.viewHooks=[])).push(-n,l),u&&((e.viewHooks||(e.viewHooks=[])).push(n,u),(e.viewCheckHooks||(e.viewCheckHooks=[])).push(n,u)),null!=c&&(e.destroyHooks||(e.destroyHooks=[])).push(n,c)}}function Zo(e,t,n){ad(e,t,3,n)}function Yo(e,t,n,r){(3&e[2])===n&&ad(e,t,n,r)}function Xs(e,t){let n=e[2];(3&n)===t&&(n&=2047,n+=1,e[2]=n)}function ad(e,t,n,r){const i=null!=r?r:-1,s=t.length-1;let a=0;for(let l=void 0!==r?65535&e[18]:0;l<s;l++)if("number"==typeof t[l+1]){if(a=t[l],null!=r&&a>=r)break}else t[l]<0&&(e[18]+=65536),(a<i||-1==i)&&(Sy(e,n,t,l),e[18]=(4294901760&e[18])+l+2),l++}function Sy(e,t,n,r){const o=n[r]<0,i=n[r+1],a=e[o?-n[r]:n[r]];if(o){if(e[2]>>11<e[18]>>16&&(3&e[2])===t){e[2]+=2048;try{i.call(a)}finally{}}}else try{i.call(a)}finally{}}class Lr{constructor(t,n,r){this.factory=t,this.resolving=!1,this.canSeeViewProviders=n,this.injectImpl=r}}function Ko(e,t,n){const r=me(e);let o=0;for(;o<n.length;){const i=n[o];if("number"==typeof i){if(0!==i)break;o++;const s=n[o++],a=n[o++],l=n[o++];r?e.setAttribute(t,a,l,s):t.setAttributeNS(s,a,l)}else{const s=i,a=n[++o];ta(s)?r&&e.setProperty(t,s,a):r?e.setAttribute(t,s,a):t.setAttribute(s,a),o++}}return o}function ld(e){return 3===e||4===e||6===e}function ta(e){return 64===e.charCodeAt(0)}function Jo(e,t){if(null!==t&&0!==t.length)if(null===e||0===e.length)e=t.slice();else{let n=-1;for(let r=0;r<t.length;r++){const o=t[r];"number"==typeof o?n=o:0===n||ud(e,n,o,null,-1===n||2===n?t[++r]:null)}}return e}function ud(e,t,n,r,o){let i=0,s=e.length;if(-1===t)s=-1;else for(;i<e.length;){const a=e[i++];if("number"==typeof a){if(a===t){s=-1;break}if(a>t){s=i-1;break}}}for(;i<e.length;){const a=e[i];if("number"==typeof a)break;if(a===n){if(null===r)return void(null!==o&&(e[i+1]=o));if(r===e[i+1])return void(e[i+2]=o)}i++,null!==r&&i++,null!==o&&i++}-1!==s&&(e.splice(s,0,t),i=s+1),e.splice(i++,0,n),null!==r&&e.splice(i++,0,r),null!==o&&e.splice(i++,0,o)}function cd(e){return-1!==e}function Wn(e){return 32767&e}function Qn(e,t){let n=function Ry(e){return e>>16}(e),r=t;for(;n>0;)r=r[15],n--;return r}let na=!0;function Xo(e){const t=na;return na=e,t}let Py=0;function Hr(e,t){const n=oa(e,t);if(-1!==n)return n;const r=t[1];r.firstCreatePass&&(e.injectorIndex=t.length,ra(r.data,e),ra(t,null),ra(r.blueprint,null));const o=ei(e,t),i=e.injectorIndex;if(cd(o)){const s=Wn(o),a=Qn(o,t),l=a[1].data;for(let u=0;u<8;u++)t[i+u]=a[s+u]|l[s+u]}return t[i+8]=o,i}function ra(e,t){e.push(0,0,0,0,0,0,0,0,t)}function oa(e,t){return-1===e.injectorIndex||e.parent&&e.parent.injectorIndex===e.injectorIndex||null===t[e.injectorIndex+8]?-1:e.injectorIndex}function ei(e,t){if(e.parent&&-1!==e.parent.injectorIndex)return e.parent.injectorIndex;let n=0,r=null,o=t;for(;null!==o;){const i=o[1],s=i.type;if(r=2===s?i.declTNode:1===s?o[6]:null,null===r)return-1;if(n++,o=o[15],-1!==r.injectorIndex)return r.injectorIndex|n<<16}return-1}function ti(e,t,n){!function Vy(e,t,n){let r;"string"==typeof n?r=n.charCodeAt(0)||0:n.hasOwnProperty(Or)&&(r=n[Or]),null==r&&(r=n[Or]=Py++);const o=255&r;t.data[e+(o>>5)]|=1<<o}(e,t,n)}function hd(e,t,n){if(n&B.Optional)return e;Po(t,"NodeInjector")}function pd(e,t,n,r){if(n&B.Optional&&void 0===r&&(r=null),0==(n&(B.Self|B.Host))){const o=e[9],i=tn(void 0);try{return o?o.get(t,r,n&B.Optional):kc(t,r,n&B.Optional)}finally{tn(i)}}return hd(r,t,n)}function gd(e,t,n,r=B.Default,o){if(null!==e){const i=function Hy(e){if("string"==typeof e)return e.charCodeAt(0)||0;const t=e.hasOwnProperty(Or)?e[Or]:void 0;return"number"==typeof t?t>=0?255&t:Ly:t}(n);if("function"==typeof i){if(!td(t,e,r))return r&B.Host?hd(o,n,r):pd(t,n,r,o);try{const s=i(r);if(null!=s||r&B.Optional)return s;Po(n)}finally{id()}}else if("number"==typeof i){let s=null,a=oa(e,t),l=-1,u=r&B.Host?t[16][6]:null;for((-1===a||r&B.SkipSelf)&&(l=-1===a?ei(e,t):t[a+8],-1!==l&&vd(r,!1)?(s=t[1],a=Wn(l),t=Qn(l,t)):a=-1);-1!==a;){const c=t[1];if(_d(i,a,c.data)){const d=By(a,t,n,s,r,u);if(d!==md)return d}l=t[a+8],-1!==l&&vd(r,t[1].data[a+8]===u)&&_d(i,a,t)?(s=c,a=Wn(l),t=Qn(l,t)):a=-1}}}return pd(t,n,r,o)}const md={};function Ly(){return new Zn(Me(),w())}function By(e,t,n,r,o,i){const s=t[1],a=s.data[e+8],c=function ni(e,t,n,r,o){const i=e.providerIndexes,s=t.data,a=1048575&i,l=e.directiveStart,c=i>>20,f=o?a+c:e.directiveEnd;for(let p=r?a:a+c;p<f;p++){const m=s[p];if(p<l&&n===m||p>=l&&m.type===n)return p}if(o){const p=s[l];if(p&&vt(p)&&p.type===n)return l}return null}(a,s,n,null==r?jo(a)&&na:r!=s&&0!=(3&a.type),o&B.Host&&i===a);return null!==c?jr(t,s,c,a):md}function jr(e,t,n,r){let o=e[n];const i=t.data;if(function xy(e){return e instanceof Lr}(o)){const s=o;s.resolving&&function Ov(e,t){const n=t?`. Dependency path: ${t.join(" > ")} > ${e}`:"";throw new Y(-200,`Circular dependency in DI detected for ${e}${n}`)}(Be(i[n]));const a=Xo(s.canSeeViewProviders);s.resolving=!0;const l=s.injectImpl?tn(s.injectImpl):null;td(e,r,B.Default);try{o=e[n]=s.factory(void 0,i,e,r),t.firstCreatePass&&n>=r.directiveStart&&function Ty(e,t,n){const{ngOnChanges:r,ngOnInit:o,ngDoCheck:i}=t.type.prototype;if(r){const s=zc(t);(n.preOrderHooks||(n.preOrderHooks=[])).push(e,s),(n.preOrderCheckHooks||(n.preOrderCheckHooks=[])).push(e,s)}o&&(n.preOrderHooks||(n.preOrderHooks=[])).push(0-e,o),i&&((n.preOrderHooks||(n.preOrderHooks=[])).push(e,i),(n.preOrderCheckHooks||(n.preOrderCheckHooks=[])).push(e,i))}(n,i[n],t)}finally{null!==l&&tn(l),Xo(a),s.resolving=!1,id()}}return o}function _d(e,t,n){return!!(n[t+(e>>5)]&1<<e)}function vd(e,t){return!(e&B.Self||e&B.Host&&t)}class Zn{constructor(t,n){this._tNode=t,this._lView=n}get(t,n,r){return gd(this._tNode,this._lView,t,r,n)}}function Oe(e){return nn(()=>{const t=e.prototype.constructor,n=t[qt]||ia(t),r=Object.prototype;let o=Object.getPrototypeOf(e.prototype).constructor;for(;o&&o!==r;){const i=o[qt]||ia(o);if(i&&i!==n)return i;o=Object.getPrototypeOf(o)}return i=>new i})}function ia(e){return Oc(e)?()=>{const t=ia(H(e));return t&&t()}:An(e)}const Kn="__parameters__";function Xn(e,t,n){return nn(()=>{const r=function aa(e){return function(...n){if(e){const r=e(...n);for(const o in r)this[o]=r[o]}}}(t);function o(...i){if(this instanceof o)return r.apply(this,i),this;const s=new o(...i);return a.annotation=s,a;function a(l,u,c){const d=l.hasOwnProperty(Kn)?l[Kn]:Object.defineProperty(l,Kn,{value:[]})[Kn];for(;d.length<=c;)d.push(null);return(d[c]=d[c]||[]).push(s),l}}return n&&(o.prototype=Object.create(n.prototype)),o.prototype.ngMetadataName=e,o.annotationCls=o,o})}class J{constructor(t,n){this._desc=t,this.ngMetadataName="InjectionToken",this.\u0275prov=void 0,"number"==typeof n?this.__NG_ELEMENT_ID__=n:void 0!==n&&(this.\u0275prov=de({token:this,providedIn:n.providedIn||"root",factory:n.factory}))}toString(){return`InjectionToken ${this._desc}`}}function Ft(e,t){e.forEach(n=>Array.isArray(n)?Ft(n,t):t(n))}function Cd(e,t,n){t>=e.length?e.push(n):e.splice(t,0,n)}function ri(e,t){return t>=e.length-1?e.pop():e.splice(t,1)[0]}function et(e,t,n){let r=er(e,t);return r>=0?e[1|r]=n:(r=~r,function zy(e,t,n,r){let o=e.length;if(o==t)e.push(n,r);else if(1===o)e.push(r,e[0]),e[0]=n;else{for(o--,e.push(e[o-1],e[o]);o>t;)e[o]=e[o-2],o--;e[t]=n,e[t+1]=r}}(e,r,t,n)),r}function ua(e,t){const n=er(e,t);if(n>=0)return e[1|n]}function er(e,t){return function bd(e,t,n){let r=0,o=e.length>>n;for(;o!==r;){const i=r+(o-r>>1),s=e[i<<n];if(t===s)return i<<n;s>t?o=i:r=i+1}return~(o<<n)}(e,t,1)}const Gr={},da="__NG_DI_FLAG__",ii="ngTempTokenPath",Ky=/\n/gm,Md="__source",Xy=ie({provide:String,useValue:ie});let qr;function Id(e){const t=qr;return qr=e,t}function eC(e,t=B.Default){if(void 0===qr)throw new Y(203,"");return null===qr?kc(e,void 0,t):qr.get(e,t&B.Optional?null:void 0,t)}function oe(e,t=B.Default){return(function Hv(){return Os}()||eC)(H(e),t)}const tC=oe;function fa(e){const t=[];for(let n=0;n<e.length;n++){const r=H(e[n]);if(Array.isArray(r)){if(0===r.length)throw new Y(900,"");let o,i=B.Default;for(let s=0;s<r.length;s++){const a=r[s],l=nC(a);"number"==typeof l?-1===l?o=a.token:i|=l:o=a}t.push(oe(o,i))}else t.push(oe(r))}return t}function Wr(e,t){return e[da]=t,e.prototype[da]=t,e}function nC(e){return e[da]}const si=Wr(Xn("Optional"),8),ai=Wr(Xn("SkipSelf"),4);class Pd{constructor(t){this.changingThisBreaksApplicationSecurity=t}toString(){return`SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity} (see https://g.co/ng/security#xss)`}}function cn(e){return e instanceof Pd?e.changingThisBreaksApplicationSecurity:e}const EC=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^&:/?#]*(?:[/?#]|$))/gi,MC=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;var we=(()=>((we=we||{})[we.NONE=0]="NONE",we[we.HTML=1]="HTML",we[we.STYLE=2]="STYLE",we[we.SCRIPT=3]="SCRIPT",we[we.URL=4]="URL",we[we.RESOURCE_URL=5]="RESOURCE_URL",we))();function rr(e){const t=function Kr(){const e=w();return e&&e[12]}();return t?t.sanitize(we.URL,e)||"":function Zr(e,t){const n=function CC(e){return e instanceof Pd&&e.getTypeName()||null}(e);if(null!=n&&n!==t){if("ResourceURL"===n&&"URL"===t)return!0;throw new Error(`Required a safe ${t}, got a ${n} (see https://g.co/ng/security#xss)`)}return n===t}(e,"URL")?cn(e):function di(e){return(e=String(e)).match(EC)||e.match(MC)?e:"unsafe:"+e}(V(e))}const Gd="__ngContext__";function Re(e,t){e[Gd]=t}function wa(e){const t=function Jr(e){return e[Gd]||null}(e);return t?Array.isArray(t)?t:t.lView:null}function Ea(e){return e.ngOriginalError}function QC(e,...t){e.error(...t)}class Xr{constructor(){this._console=console}handleError(t){const n=this._findOriginalError(t),r=function WC(e){return e&&e.ngErrorLogger||QC}(t);r(this._console,"ERROR",t),n&&r(this._console,"ORIGINAL ERROR",n)}_findOriginalError(t){let n=t&&Ea(t);for(;n&&Ea(n);)n=Ea(n);return n||null}}const oD=(()=>("undefined"!=typeof requestAnimationFrame&&requestAnimationFrame||setTimeout).bind(re))();function Ma(e){return e.ownerDocument.defaultView}function Rt(e){return e instanceof Function?e():e}var tt=(()=>((tt=tt||{})[tt.Important=1]="Important",tt[tt.DashCase=2]="DashCase",tt))();function Aa(e,t){return undefined(e,t)}function eo(e){const t=e[3];return _t(t)?t[3]:t}function Ta(e){return ef(e[13])}function Sa(e){return ef(e[4])}function ef(e){for(;null!==e&&!_t(e);)e=e[4];return e}function ir(e,t,n,r,o){if(null!=r){let i,s=!1;_t(r)?i=r:xt(r)&&(s=!0,r=r[0]);const a=De(r);0===e&&null!==n?null==o?af(t,n,a):Tn(t,n,a,o||null,!0):1===e&&null!==n?Tn(t,n,a,o||null,!0):2===e?function pf(e,t,n){const r=hi(e,t);r&&function _D(e,t,n,r){me(e)?e.removeChild(t,n,r):t.removeChild(n)}(e,r,t,n)}(t,a,s):3===e&&t.destroyNode(a),null!=i&&function CD(e,t,n,r,o){const i=n[7];i!==De(n)&&ir(t,e,r,i,o);for(let a=10;a<n.length;a++){const l=n[a];to(l[1],l,e,t,r,i)}}(t,e,i,n,o)}}function Na(e,t,n){if(me(e))return e.createElement(t,n);{const r=null!==n?function sy(e){const t=e.toLowerCase();return"svg"===t?"http://www.w3.org/2000/svg":"math"===t?"http://www.w3.org/1998/MathML/":null}(n):null;return null===r?e.createElement(t):e.createElementNS(r,t)}}function nf(e,t){const n=e[9],r=n.indexOf(t),o=t[3];1024&t[2]&&(t[2]&=-1025,Ws(o,-1)),n.splice(r,1)}function Fa(e,t){if(e.length<=10)return;const n=10+t,r=e[n];if(r){const o=r[17];null!==o&&o!==e&&nf(o,r),t>0&&(e[n-1][4]=r[4]);const i=ri(e,10+t);!function uD(e,t){to(e,t,t[j],2,null,null),t[0]=null,t[6]=null}(r[1],r);const s=i[19];null!==s&&s.detachView(i[1]),r[3]=null,r[4]=null,r[2]&=-129}return r}function rf(e,t){if(!(256&t[2])){const n=t[j];me(n)&&n.destroyNode&&to(e,t,n,3,null,null),function fD(e){let t=e[13];if(!t)return Oa(e[1],e);for(;t;){let n=null;if(xt(t))n=t[13];else{const r=t[10];r&&(n=r)}if(!n){for(;t&&!t[4]&&t!==e;)xt(t)&&Oa(t[1],t),t=t[3];null===t&&(t=e),xt(t)&&Oa(t[1],t),n=t&&t[4]}t=n}}(t)}}function Oa(e,t){if(!(256&t[2])){t[2]&=-129,t[2]|=256,function mD(e,t){let n;if(null!=e&&null!=(n=e.destroyHooks))for(let r=0;r<n.length;r+=2){const o=t[n[r]];if(!(o instanceof Lr)){const i=n[r+1];if(Array.isArray(i))for(let s=0;s<i.length;s+=2){const a=o[i[s]],l=i[s+1];try{l.call(a)}finally{}}else try{i.call(o)}finally{}}}}(e,t),function gD(e,t){const n=e.cleanup,r=t[7];let o=-1;if(null!==n)for(let i=0;i<n.length-1;i+=2)if("string"==typeof n[i]){const s=n[i+1],a="function"==typeof s?s(t):De(t[s]),l=r[o=n[i+2]],u=n[i+3];"boolean"==typeof u?a.removeEventListener(n[i],l,u):u>=0?r[o=u]():r[o=-u].unsubscribe(),i+=2}else{const s=r[o=n[i+1]];n[i].call(s)}if(null!==r){for(let i=o+1;i<r.length;i++)r[i]();t[7]=null}}(e,t),1===t[1].type&&me(t[j])&&t[j].destroy();const n=t[17];if(null!==n&&_t(t[3])){n!==t[3]&&nf(n,t);const r=t[19];null!==r&&r.detachView(e)}}}function of(e,t,n){return function sf(e,t,n){let r=t;for(;null!==r&&40&r.type;)r=(t=r).parent;if(null===r)return n[0];if(2&r.flags){const o=e.data[r.directiveStart].encapsulation;if(o===St.None||o===St.Emulated)return null}return lt(r,n)}(e,t.parent,n)}function Tn(e,t,n,r,o){me(e)?e.insertBefore(t,n,r,o):t.insertBefore(n,r,o)}function af(e,t,n){me(e)?e.appendChild(t,n):t.appendChild(n)}function lf(e,t,n,r,o){null!==r?Tn(e,t,n,r,o):af(e,t,n)}function hi(e,t){return me(e)?e.parentNode(t):t.parentNode}let df=function cf(e,t,n){return 40&e.type?lt(e,n):null};function pi(e,t,n,r){const o=of(e,r,t),i=t[j],a=function uf(e,t,n){return df(e,t,n)}(r.parent||t[6],r,t);if(null!=o)if(Array.isArray(n))for(let l=0;l<n.length;l++)lf(i,o,n[l],a,!1);else lf(i,o,n,a,!1)}function gi(e,t){if(null!==t){const n=t.type;if(3&n)return lt(t,e);if(4&n)return Pa(-1,e[t.index]);if(8&n){const r=t.child;if(null!==r)return gi(e,r);{const o=e[t.index];return _t(o)?Pa(-1,o):De(o)}}if(32&n)return Aa(t,e)()||De(e[t.index]);{const r=hf(e,t);return null!==r?Array.isArray(r)?r[0]:gi(eo(e[16]),r):gi(e,t.next)}}return null}function hf(e,t){return null!==t?e[16][6].projection[t.projection]:null}function Pa(e,t){const n=10+e+1;if(n<t.length){const r=t[n],o=r[1].firstChild;if(null!==o)return gi(r,o)}return t[7]}function Va(e,t,n,r,o,i,s){for(;null!=n;){const a=r[n.index],l=n.type;if(s&&0===t&&(a&&Re(De(a),r),n.flags|=4),64!=(64&n.flags))if(8&l)Va(e,t,n.child,r,o,i,!1),ir(t,e,o,a,i);else if(32&l){const u=Aa(n,r);let c;for(;c=u();)ir(t,e,o,c,i);ir(t,e,o,a,i)}else 16&l?gf(e,t,r,n,o,i):ir(t,e,o,a,i);n=s?n.projectionNext:n.next}}function to(e,t,n,r,o,i){Va(n,r,e.firstChild,t,o,i,!1)}function gf(e,t,n,r,o,i){const s=n[16],l=s[6].projection[r.projection];if(Array.isArray(l))for(let u=0;u<l.length;u++)ir(t,e,o,l[u],i);else Va(e,t,l,s[3],o,i,!0)}function mf(e,t,n){me(e)?e.setAttribute(t,"style",n):t.style.cssText=n}function ka(e,t,n){me(e)?""===n?e.removeAttribute(t,"class"):e.setAttribute(t,"class",n):t.className=n}function _f(e,t,n){let r=e.length;for(;;){const o=e.indexOf(t,n);if(-1===o)return o;if(0===o||e.charCodeAt(o-1)<=32){const i=t.length;if(o+i===r||e.charCodeAt(o+i)<=32)return o}n=o+1}}const vf="ng-template";function wD(e,t,n){let r=0;for(;r<e.length;){let o=e[r++];if(n&&"class"===o){if(o=e[r],-1!==_f(o.toLowerCase(),t,0))return!0}else if(1===o){for(;r<e.length&&"string"==typeof(o=e[r++]);)if(o.toLowerCase()===t)return!0;return!1}}return!1}function yf(e){return 4===e.type&&e.value!==vf}function bD(e,t,n){return t===(4!==e.type||n?e.value:vf)}function ED(e,t,n){let r=4;const o=e.attrs||[],i=function AD(e){for(let t=0;t<e.length;t++)if(ld(e[t]))return t;return e.length}(o);let s=!1;for(let a=0;a<t.length;a++){const l=t[a];if("number"!=typeof l){if(!s)if(4&r){if(r=2|1&r,""!==l&&!bD(e,l,n)||""===l&&1===t.length){if(yt(r))return!1;s=!0}}else{const u=8&r?l:t[++a];if(8&r&&null!==e.attrs){if(!wD(e.attrs,u,n)){if(yt(r))return!1;s=!0}continue}const d=MD(8&r?"class":l,o,yf(e),n);if(-1===d){if(yt(r))return!1;s=!0;continue}if(""!==u){let f;f=d>i?"":o[d+1].toLowerCase();const p=8&r?f:null;if(p&&-1!==_f(p,u,0)||2&r&&u!==f){if(yt(r))return!1;s=!0}}}}else{if(!s&&!yt(r)&&!yt(l))return!1;if(s&&yt(l))continue;s=!1,r=l|1&r}}return yt(r)||s}function yt(e){return 0==(1&e)}function MD(e,t,n,r){if(null===t)return-1;let o=0;if(r||!n){let i=!1;for(;o<t.length;){const s=t[o];if(s===e)return o;if(3===s||6===s)i=!0;else{if(1===s||2===s){let a=t[++o];for(;"string"==typeof a;)a=t[++o];continue}if(4===s)break;if(0===s){o+=4;continue}}o+=i?1:2}return-1}return function TD(e,t){let n=e.indexOf(4);if(n>-1)for(n++;n<e.length;){const r=e[n];if("number"==typeof r)return-1;if(r===t)return n;n++}return-1}(t,e)}function Cf(e,t,n=!1){for(let r=0;r<t.length;r++)if(ED(e,t[r],n))return!0;return!1}function Df(e,t){return e?":not("+t.trim()+")":t}function xD(e){let t=e[0],n=1,r=2,o="",i=!1;for(;n<e.length;){let s=e[n];if("string"==typeof s)if(2&r){const a=e[++n];o+="["+s+(a.length>0?'="'+a+'"':"")+"]"}else 8&r?o+="."+s:4&r&&(o+=" "+s);else""!==o&&!yt(s)&&(t+=Df(i,o),o=""),r=s,i=i||!yt(r);n++}return""!==o&&(t+=Df(i,o)),t}const L={};function h(e){wf(K(),w(),je()+e,zo())}function wf(e,t,n,r){if(!r)if(3==(3&t[2])){const i=e.preOrderCheckHooks;null!==i&&Zo(t,i,n)}else{const i=e.preOrderHooks;null!==i&&Yo(t,i,0,n)}ln(n)}function mi(e,t){return e<<17|t<<2}function Ct(e){return e>>17&32767}function La(e){return 2|e}function Yt(e){return(131068&e)>>2}function Ba(e,t){return-131069&e|t<<2}function Ha(e){return 1|e}function Of(e,t){const n=e.contentQueries;if(null!==n)for(let r=0;r<n.length;r+=2){const o=n[r],i=n[r+1];if(-1!==i){const s=e.data[i];Js(o),s.contentQueries(2,t[i],i)}}}function no(e,t,n,r,o,i,s,a,l,u){const c=t.blueprint.slice();return c[0]=o,c[2]=140|r,Zc(c),c[3]=c[15]=e,c[8]=n,c[10]=s||e&&e[10],c[j]=a||e&&e[j],c[12]=l||e&&e[12]||null,c[9]=u||e&&e[9]||null,c[6]=i,c[16]=2==t.type?e[16]:c,c}function sr(e,t,n,r,o){let i=e.data[t];if(null===i)i=function Za(e,t,n,r,o){const i=Kc(),s=Qs(),l=e.data[t]=function QD(e,t,n,r,o,i){return{type:n,index:r,insertBeforeIndex:null,injectorIndex:t?t.injectorIndex:-1,directiveStart:-1,directiveEnd:-1,directiveStylingLast:-1,propertyBindings:null,flags:0,providerIndexes:0,value:o,attrs:i,mergedAttrs:null,localNames:null,initialInputs:void 0,inputs:null,outputs:null,tViews:null,next:null,projectionNext:null,child:null,parent:t,projection:null,styles:null,stylesWithoutHost:null,residualStyles:void 0,classes:null,classesWithoutHost:null,residualClasses:void 0,classBindings:0,styleBindings:0}}(0,s?i:i&&i.parent,n,t,r,o);return null===e.firstChild&&(e.firstChild=l),null!==i&&(s?null==i.child&&null!==l.parent&&(i.child=l):null===i.next&&(i.next=l)),l}(e,t,n,r,o),function vy(){return P.lFrame.inI18n}()&&(i.flags|=64);else if(64&i.type){i.type=n,i.value=r,i.attrs=o;const s=function kr(){const e=P.lFrame,t=e.currentTNode;return e.isParent?t:t.parent}();i.injectorIndex=null===s?-1:s.injectorIndex}return Nt(i,!0),i}function ar(e,t,n,r){if(0===n)return-1;const o=t.length;for(let i=0;i<n;i++)t.push(r),e.blueprint.push(r),e.data.push(null);return o}function ro(e,t,n){qo(t);try{const r=e.viewQuery;null!==r&&ol(1,r,n);const o=e.template;null!==o&&Rf(e,t,o,1,n),e.firstCreatePass&&(e.firstCreatePass=!1),e.staticContentQueries&&Of(e,t),e.staticViewQueries&&ol(2,e.viewQuery,n);const i=e.components;null!==i&&function GD(e,t){for(let n=0;n<t.length;n++)fw(e,t[n])}(t,i)}catch(r){throw e.firstCreatePass&&(e.incompleteFirstPass=!0,e.firstCreatePass=!1),r}finally{t[2]&=-5,Wo()}}function lr(e,t,n,r){const o=t[2];if(256==(256&o))return;qo(t);const i=zo();try{Zc(t),function Jc(e){return P.lFrame.bindingIndex=e}(e.bindingStartIndex),null!==n&&Rf(e,t,n,2,r);const s=3==(3&o);if(!i)if(s){const u=e.preOrderCheckHooks;null!==u&&Zo(t,u,null)}else{const u=e.preOrderHooks;null!==u&&Yo(t,u,0,null),Xs(t,0)}if(function cw(e){for(let t=Ta(e);null!==t;t=Sa(t)){if(!t[2])continue;const n=t[9];for(let r=0;r<n.length;r++){const o=n[r],i=o[3];0==(1024&o[2])&&Ws(i,1),o[2]|=1024}}}(t),function uw(e){for(let t=Ta(e);null!==t;t=Sa(t))for(let n=10;n<t.length;n++){const r=t[n],o=r[1];qs(r)&&lr(o,r,o.template,r[8])}}(t),null!==e.contentQueries&&Of(e,t),!i)if(s){const u=e.contentCheckHooks;null!==u&&Zo(t,u)}else{const u=e.contentHooks;null!==u&&Yo(t,u,1),Xs(t,1)}!function UD(e,t){const n=e.hostBindingOpCodes;if(null!==n)try{for(let r=0;r<n.length;r++){const o=n[r];if(o<0)ln(~o);else{const i=o,s=n[++r],a=n[++r];yy(s,i),a(2,t[i])}}}finally{ln(-1)}}(e,t);const a=e.components;null!==a&&function zD(e,t){for(let n=0;n<t.length;n++)dw(e,t[n])}(t,a);const l=e.viewQuery;if(null!==l&&ol(2,l,r),!i)if(s){const u=e.viewCheckHooks;null!==u&&Zo(t,u)}else{const u=e.viewHooks;null!==u&&Yo(t,u,2),Xs(t,2)}!0===e.firstUpdatePass&&(e.firstUpdatePass=!1),i||(t[2]&=-73),1024&t[2]&&(t[2]&=-1025,Ws(t[3],-1))}finally{Wo()}}function qD(e,t,n,r){const o=t[10],i=!zo(),s=function Qc(e){return 4==(4&e[2])}(t);try{i&&!s&&o.begin&&o.begin(),s&&ro(e,t,r),lr(e,t,n,r)}finally{i&&!s&&o.end&&o.end()}}function Rf(e,t,n,r,o){const i=je(),s=2&r;try{ln(-1),s&&t.length>20&&wf(e,t,20,zo()),n(r,o)}finally{ln(i)}}function Pf(e,t,n){if(Ls(t)){const o=t.directiveEnd;for(let i=t.directiveStart;i<o;i++){const s=e.data[i];s.contentQueries&&s.contentQueries(1,n[i],i)}}}function Ya(e,t,n){!Yc()||(function tw(e,t,n,r){const o=n.directiveStart,i=n.directiveEnd;e.firstCreatePass||Hr(n,t),Re(r,t);const s=n.initialInputs;for(let a=o;a<i;a++){const l=e.data[a],u=vt(l);u&&sw(t,n,l);const c=jr(t,e,a,n);Re(c,t),null!==s&&aw(0,a-o,c,l,0,s),u&&(Xe(n.index,t)[8]=c)}}(e,t,n,lt(n,t)),128==(128&n.flags)&&function nw(e,t,n){const r=n.directiveStart,o=n.directiveEnd,s=n.index,a=function Cy(){return P.lFrame.currentDirectiveIndex}();try{ln(s);for(let l=r;l<o;l++){const u=e.data[l],c=t[l];Ys(l),(null!==u.hostBindings||0!==u.hostVars||null!==u.hostAttrs)&&Uf(u,c)}}finally{ln(-1),Ys(a)}}(e,t,n))}function Ka(e,t,n=lt){const r=t.localNames;if(null!==r){let o=t.index+1;for(let i=0;i<r.length;i+=2){const s=r[i+1],a=-1===s?n(t,e):e[s];e[o++]=a}}}function Vf(e){const t=e.tView;return null===t||t.incompleteFirstPass?e.tView=yi(1,null,e.template,e.decls,e.vars,e.directiveDefs,e.pipeDefs,e.viewQuery,e.schemas,e.consts):t}function yi(e,t,n,r,o,i,s,a,l,u){const c=20+r,d=c+o,f=function WD(e,t){const n=[];for(let r=0;r<t;r++)n.push(r<e?null:L);return n}(c,d),p="function"==typeof u?u():u;return f[1]={type:e,blueprint:f,template:n,queries:null,viewQuery:a,declTNode:t,data:f.slice().fill(null,c),bindingStartIndex:c,expandoStartIndex:d,hostBindingOpCodes:null,firstCreatePass:!0,firstUpdatePass:!0,staticViewQueries:!1,staticContentQueries:!1,preOrderHooks:null,preOrderCheckHooks:null,contentHooks:null,contentCheckHooks:null,viewHooks:null,viewCheckHooks:null,destroyHooks:null,cleanup:null,contentQueries:null,components:null,directiveRegistry:"function"==typeof i?i():i,pipeRegistry:"function"==typeof s?s():s,firstChild:null,schemas:l,consts:p,incompleteFirstPass:!1}}function Hf(e,t,n){for(let r in e)if(e.hasOwnProperty(r)){const o=e[r];(n=null===n?{}:n).hasOwnProperty(r)?n[r].push(t,o):n[r]=[t,o]}return n}function nt(e,t,n,r,o,i,s,a){const l=lt(t,n);let c,u=t.inputs;!a&&null!=u&&(c=u[r])?(Xf(e,n,c,r,o),jo(t)&&function KD(e,t){const n=Xe(t,e);16&n[2]||(n[2]|=64)}(n,t.index)):3&t.type&&(r=function YD(e){return"class"===e?"className":"for"===e?"htmlFor":"formaction"===e?"formAction":"innerHtml"===e?"innerHTML":"readonly"===e?"readOnly":"tabindex"===e?"tabIndex":e}(r),o=null!=s?s(o,t.value||"",r):o,me(i)?i.setProperty(l,r,o):ta(r)||(l.setProperty?l.setProperty(r,o):l[r]=o))}function Ja(e,t,n,r){let o=!1;if(Yc()){const i=function rw(e,t,n){const r=e.directiveRegistry;let o=null;if(r)for(let i=0;i<r.length;i++){const s=r[i];Cf(n,s.selectors,!1)&&(o||(o=[]),ti(Hr(n,t),e,s.type),vt(s)?(zf(e,n),o.unshift(s)):o.push(s))}return o}(e,t,n),s=null===r?null:{"":-1};if(null!==i){o=!0,Gf(n,e.data.length,i.length);for(let c=0;c<i.length;c++){const d=i[c];d.providersResolver&&d.providersResolver(d)}let a=!1,l=!1,u=ar(e,t,i.length,null);for(let c=0;c<i.length;c++){const d=i[c];n.mergedAttrs=Jo(n.mergedAttrs,d.hostAttrs),qf(e,n,t,u,d),iw(u,d,s),null!==d.contentQueries&&(n.flags|=8),(null!==d.hostBindings||null!==d.hostAttrs||0!==d.hostVars)&&(n.flags|=128);const f=d.type.prototype;!a&&(f.ngOnChanges||f.ngOnInit||f.ngDoCheck)&&((e.preOrderHooks||(e.preOrderHooks=[])).push(n.index),a=!0),!l&&(f.ngOnChanges||f.ngDoCheck)&&((e.preOrderCheckHooks||(e.preOrderCheckHooks=[])).push(n.index),l=!0),u++}!function ZD(e,t){const r=t.directiveEnd,o=e.data,i=t.attrs,s=[];let a=null,l=null;for(let u=t.directiveStart;u<r;u++){const c=o[u],d=c.inputs,f=null===i||yf(t)?null:lw(d,i);s.push(f),a=Hf(d,u,a),l=Hf(c.outputs,u,l)}null!==a&&(a.hasOwnProperty("class")&&(t.flags|=16),a.hasOwnProperty("style")&&(t.flags|=32)),t.initialInputs=s,t.inputs=a,t.outputs=l}(e,n)}s&&function ow(e,t,n){if(t){const r=e.localNames=[];for(let o=0;o<t.length;o+=2){const i=n[t[o+1]];if(null==i)throw new Y(-301,!1);r.push(t[o],i)}}}(n,r,s)}return n.mergedAttrs=Jo(n.mergedAttrs,n.attrs),o}function $f(e,t,n,r,o,i){const s=i.hostBindings;if(s){let a=e.hostBindingOpCodes;null===a&&(a=e.hostBindingOpCodes=[]);const l=~t.index;(function ew(e){let t=e.length;for(;t>0;){const n=e[--t];if("number"==typeof n&&n<0)return n}return 0})(a)!=l&&a.push(l),a.push(r,o,s)}}function Uf(e,t){null!==e.hostBindings&&e.hostBindings(1,t)}function zf(e,t){t.flags|=2,(e.components||(e.components=[])).push(t.index)}function iw(e,t,n){if(n){if(t.exportAs)for(let r=0;r<t.exportAs.length;r++)n[t.exportAs[r]]=e;vt(t)&&(n[""]=e)}}function Gf(e,t,n){e.flags|=1,e.directiveStart=t,e.directiveEnd=t+n,e.providerIndexes=t}function qf(e,t,n,r,o){e.data[r]=o;const i=o.factory||(o.factory=An(o.type)),s=new Lr(i,vt(o),null);e.blueprint[r]=s,n[r]=s,$f(e,t,0,r,ar(e,n,o.hostVars,L),o)}function sw(e,t,n){const r=lt(t,e),o=Vf(n),i=e[10],s=Ci(e,no(e,o,null,n.onPush?64:16,r,t,i,i.createRenderer(r,n),null,null));e[t.index]=s}function Pt(e,t,n,r,o,i){const s=lt(e,t);!function Xa(e,t,n,r,o,i,s){if(null==i)me(e)?e.removeAttribute(t,o,n):t.removeAttribute(o);else{const a=null==s?V(i):s(i,r||"",o);me(e)?e.setAttribute(t,o,a,n):n?t.setAttributeNS(n,o,a):t.setAttribute(o,a)}}(t[j],s,i,e.value,n,r,o)}function aw(e,t,n,r,o,i){const s=i[t];if(null!==s){const a=r.setInput;for(let l=0;l<s.length;){const u=s[l++],c=s[l++],d=s[l++];null!==a?r.setInput(n,d,u,c):n[c]=d}}}function lw(e,t){let n=null,r=0;for(;r<t.length;){const o=t[r];if(0!==o)if(5!==o){if("number"==typeof o)break;e.hasOwnProperty(o)&&(null===n&&(n=[]),n.push(o,e[o],t[r+1])),r+=2}else r+=2;else r+=4}return n}function Wf(e,t,n,r){return new Array(e,!0,!1,t,null,0,r,n,null,null)}function dw(e,t){const n=Xe(t,e);if(qs(n)){const r=n[1];80&n[2]?lr(r,n,r.template,n[8]):n[5]>0&&el(n)}}function el(e){for(let r=Ta(e);null!==r;r=Sa(r))for(let o=10;o<r.length;o++){const i=r[o];if(1024&i[2]){const s=i[1];lr(s,i,s.template,i[8])}else i[5]>0&&el(i)}const n=e[1].components;if(null!==n)for(let r=0;r<n.length;r++){const o=Xe(n[r],e);qs(o)&&o[5]>0&&el(o)}}function fw(e,t){const n=Xe(t,e),r=n[1];(function hw(e,t){for(let n=t.length;n<e.blueprint.length;n++)t.push(e.blueprint[n])})(r,n),ro(r,n,n[8])}function Ci(e,t){return e[13]?e[14][4]=t:e[13]=t,e[14]=t,t}function tl(e){for(;e;){e[2]|=64;const t=eo(e);if(Yv(e)&&!t)return e;e=t}return null}function rl(e,t,n){const r=t[10];r.begin&&r.begin();try{lr(e,t,e.template,n)}catch(o){throw Jf(t,o),o}finally{r.end&&r.end()}}function Qf(e){!function nl(e){for(let t=0;t<e.components.length;t++){const n=e.components[t],r=wa(n),o=r[1];qD(o,r,o.template,n)}}(e[8])}function ol(e,t,n){Js(0),t(e,n)}const _w=(()=>Promise.resolve(null))();function Zf(e){return e[7]||(e[7]=[])}function Yf(e){return e.cleanup||(e.cleanup=[])}function Jf(e,t){const n=e[9],r=n?n.get(Xr,null):null;r&&r.handleError(t)}function Xf(e,t,n,r,o){for(let i=0;i<n.length;){const s=n[i++],a=n[i++],l=t[s],u=e.data[s];null!==u.setInput?u.setInput(l,o,r,a):l[a]=o}}function Kt(e,t,n){const r=Uo(t,e);!function tf(e,t,n){me(e)?e.setValue(t,n):t.textContent=n}(e[j],r,n)}function Di(e,t,n){let r=n?e.styles:null,o=n?e.classes:null,i=0;if(null!==t)for(let s=0;s<t.length;s++){const a=t[s];"number"==typeof a?i=a:1==i?o=Ss(o,a):2==i&&(r=Ss(r,a+": "+t[++s]+";"))}n?e.styles=r:e.stylesWithoutHost=r,n?e.classes=o:e.classesWithoutHost=o}const il=new J("INJECTOR",-1);class eh{get(t,n=Gr){if(n===Gr){const r=new Error(`NullInjectorError: No provider for ${te(t)}!`);throw r.name="NullInjectorError",r}return n}}const sl=new J("Set Injector scope."),oo={},Cw={};let al;function th(){return void 0===al&&(al=new eh),al}function nh(e,t=null,n=null,r){const o=rh(e,t,n,r);return o._resolveInjectorDefTypes(),o}function rh(e,t=null,n=null,r){return new Dw(e,n,t||th(),r)}class Dw{constructor(t,n,r,o=null){this.parent=r,this.records=new Map,this.injectorDefTypes=new Set,this.onDestroy=new Set,this._destroyed=!1;const i=[];n&&Ft(n,a=>this.processProvider(a,t,n)),Ft([t],a=>this.processInjectorType(a,[],i)),this.records.set(il,ur(void 0,this));const s=this.records.get(sl);this.scope=null!=s?s.value:null,this.source=o||("object"==typeof t?null:te(t))}get destroyed(){return this._destroyed}destroy(){this.assertNotDestroyed(),this._destroyed=!0;try{this.onDestroy.forEach(t=>t.ngOnDestroy())}finally{this.records.clear(),this.onDestroy.clear(),this.injectorDefTypes.clear()}}get(t,n=Gr,r=B.Default){this.assertNotDestroyed();const o=Id(this),i=tn(void 0);try{if(!(r&B.SkipSelf)){let a=this.records.get(t);if(void 0===a){const l=function Sw(e){return"function"==typeof e||"object"==typeof e&&e instanceof J}(t)&&Ns(t);a=l&&this.injectableDefInScope(l)?ur(ll(t),oo):null,this.records.set(t,a)}if(null!=a)return this.hydrate(t,a)}return(r&B.Self?th():this.parent).get(t,n=r&B.Optional&&n===Gr?null:n)}catch(s){if("NullInjectorError"===s.name){if((s[ii]=s[ii]||[]).unshift(te(t)),o)throw s;return function rC(e,t,n,r){const o=e[ii];throw t[Md]&&o.unshift(t[Md]),e.message=function oC(e,t,n,r=null){e=e&&"\n"===e.charAt(0)&&"\u0275"==e.charAt(1)?e.substr(2):e;let o=te(t);if(Array.isArray(t))o=t.map(te).join(" -> ");else if("object"==typeof t){let i=[];for(let s in t)if(t.hasOwnProperty(s)){let a=t[s];i.push(s+":"+("string"==typeof a?JSON.stringify(a):te(a)))}o=`{${i.join(", ")}}`}return`${n}${r?"("+r+")":""}[${o}]: ${e.replace(Ky,"\n ")}`}("\n"+e.message,o,n,r),e.ngTokenPath=o,e[ii]=null,e}(s,t,"R3InjectorError",this.source)}throw s}finally{tn(i),Id(o)}}_resolveInjectorDefTypes(){this.injectorDefTypes.forEach(t=>this.get(t))}toString(){const t=[];return this.records.forEach((r,o)=>t.push(te(o))),`R3Injector[${t.join(", ")}]`}assertNotDestroyed(){if(this._destroyed)throw new Y(205,!1)}processInjectorType(t,n,r){if(!(t=H(t)))return!1;let o=Pc(t);const i=null==o&&t.ngModule||void 0,s=void 0===i?t:i,a=-1!==r.indexOf(s);if(void 0!==i&&(o=Pc(i)),null==o)return!1;if(null!=o.imports&&!a){let c;r.push(s);try{Ft(o.imports,d=>{this.processInjectorType(d,n,r)&&(void 0===c&&(c=[]),c.push(d))})}finally{}if(void 0!==c)for(let d=0;d<c.length;d++){const{ngModule:f,providers:p}=c[d];Ft(p,m=>this.processProvider(m,f,p||se))}}this.injectorDefTypes.add(s);const l=An(s)||(()=>new s);this.records.set(s,ur(l,oo));const u=o.providers;if(null!=u&&!a){const c=t;Ft(u,d=>this.processProvider(d,c,u))}return void 0!==i&&void 0!==t.providers}processProvider(t,n,r){let o=cr(t=H(t))?t:H(t&&t.provide);const i=function bw(e,t,n){return ih(e)?ur(void 0,e.useValue):ur(oh(e),oo)}(t);if(cr(t)||!0!==t.multi)this.records.get(o);else{let s=this.records.get(o);s||(s=ur(void 0,oo,!0),s.factory=()=>fa(s.multi),this.records.set(o,s)),o=t,s.multi.push(t)}this.records.set(o,i)}hydrate(t,n){return n.value===oo&&(n.value=Cw,n.value=n.factory()),"object"==typeof n.value&&n.value&&function Tw(e){return null!==e&&"object"==typeof e&&"function"==typeof e.ngOnDestroy}(n.value)&&this.onDestroy.add(n.value),n.value}injectableDefInScope(t){if(!t.providedIn)return!1;const n=H(t.providedIn);return"string"==typeof n?"any"===n||n===this.scope:this.injectorDefTypes.has(n)}}function ll(e){const t=Ns(e),n=null!==t?t.factory:An(e);if(null!==n)return n;if(e instanceof J)throw new Y(204,!1);if(e instanceof Function)return function ww(e){const t=e.length;if(t>0)throw function zr(e,t){const n=[];for(let r=0;r<e;r++)n.push(t);return n}(t,"?"),new Y(204,!1);const n=function kv(e){const t=e&&(e[Vo]||e[Vc]);if(t){const n=function Lv(e){if(e.hasOwnProperty("name"))return e.name;const t=(""+e).match(/^function\s*([^\s(]+)/);return null===t?"":t[1]}(e);return console.warn(`DEPRECATED: DI is instantiating a token "${n}" that inherits its @Injectable decorator but does not provide one itself.\nThis will become an error in a future version of Angular. Please add @Injectable() to the "${n}" class.`),t}return null}(e);return null!==n?()=>n.factory(e):()=>new e}(e);throw new Y(204,!1)}function oh(e,t,n){let r;if(cr(e)){const o=H(e);return An(o)||ll(o)}if(ih(e))r=()=>H(e.useValue);else if(function Mw(e){return!(!e||!e.useFactory)}(e))r=()=>e.useFactory(...fa(e.deps||[]));else if(function Ew(e){return!(!e||!e.useExisting)}(e))r=()=>oe(H(e.useExisting));else{const o=H(e&&(e.useClass||e.provide));if(!function Aw(e){return!!e.deps}(e))return An(o)||ll(o);r=()=>new o(...fa(e.deps))}return r}function ur(e,t,n=!1){return{factory:e,value:t,multi:n?[]:void 0}}function ih(e){return null!==e&&"object"==typeof e&&Xy in e}function cr(e){return"function"==typeof e}let ct=(()=>{class e{static create(n,r){var o;if(Array.isArray(n))return nh({name:""},r,n,"");{const i=null!==(o=n.name)&&void 0!==o?o:"";return nh({name:i},n.parent,n.providers,i)}}}return e.THROW_IF_NOT_FOUND=Gr,e.NULL=new eh,e.\u0275prov=de({token:e,providedIn:"any",factory:()=>oe(il)}),e.__NG_ELEMENT_ID__=-1,e})();function kw(e,t){Qo(wa(e)[1],Me())}function ne(e){let t=function _h(e){return Object.getPrototypeOf(e.prototype).constructor}(e.type),n=!0;const r=[e];for(;t;){let o;if(vt(e))o=t.\u0275cmp||t.\u0275dir;else{if(t.\u0275cmp)throw new Y(903,"");o=t.\u0275dir}if(o){if(n){r.push(o);const s=e;s.inputs=dl(e.inputs),s.declaredInputs=dl(e.declaredInputs),s.outputs=dl(e.outputs);const a=o.hostBindings;a&&jw(e,a);const l=o.viewQuery,u=o.contentQueries;if(l&&Bw(e,l),u&&Hw(e,u),Ts(e.inputs,o.inputs),Ts(e.declaredInputs,o.declaredInputs),Ts(e.outputs,o.outputs),vt(o)&&o.data.animation){const c=e.data;c.animation=(c.animation||[]).concat(o.data.animation)}}const i=o.features;if(i)for(let s=0;s<i.length;s++){const a=i[s];a&&a.ngInherit&&a(e),a===ne&&(n=!1)}}t=Object.getPrototypeOf(t)}!function Lw(e){let t=0,n=null;for(let r=e.length-1;r>=0;r--){const o=e[r];o.hostVars=t+=o.hostVars,o.hostAttrs=Jo(o.hostAttrs,n=Jo(n,o.hostAttrs))}}(r)}function dl(e){return e===Hn?{}:e===se?[]:e}function Bw(e,t){const n=e.viewQuery;e.viewQuery=n?(r,o)=>{t(r,o),n(r,o)}:t}function Hw(e,t){const n=e.contentQueries;e.contentQueries=n?(r,o,i)=>{t(r,o,i),n(r,o,i)}:t}function jw(e,t){const n=e.hostBindings;e.hostBindings=n?(r,o)=>{t(r,o),n(r,o)}:t}let wi=null;function dr(){if(!wi){const e=re.Symbol;if(e&&e.iterator)wi=e.iterator;else{const t=Object.getOwnPropertyNames(Map.prototype);for(let n=0;n<t.length;++n){const r=t[n];"entries"!==r&&"size"!==r&&Map.prototype[r]===Map.prototype.entries&&(wi=r)}}}return wi}function io(e){return!!fl(e)&&(Array.isArray(e)||!(e instanceof Map)&&dr()in e)}function fl(e){return null!==e&&("function"==typeof e||"object"==typeof e)}function Vt(e,t,n){return e[t]=n}function Pe(e,t,n){return!Object.is(e[t],n)&&(e[t]=n,!0)}function Sn(e,t,n,r){const o=Pe(e,t,n);return Pe(e,t+1,r)||o}function kt(e,t,n,r){const o=w();return Pe(o,qn(),t)&&(K(),Pt(_e(),o,e,t,n,r)),kt}function hr(e,t,n,r){return Pe(e,qn(),n)?t+V(n)+r:L}function E(e,t,n,r,o,i,s,a){const l=w(),u=K(),c=e+20,d=u.firstCreatePass?function Qw(e,t,n,r,o,i,s,a,l){const u=t.consts,c=sr(t,e,4,s||null,an(u,a));Ja(t,n,c,an(u,l)),Qo(t,c);const d=c.tViews=yi(2,c,r,o,i,t.directiveRegistry,t.pipeRegistry,null,t.schemas,u);return null!==t.queries&&(t.queries.template(t,c),d.queries=t.queries.embeddedTView(c)),c}(c,u,l,t,n,r,o,i,s):u.data[c];Nt(d,!1);const f=l[j].createComment("");pi(u,l,f,d),Re(f,l),Ci(l,l[c]=Wf(f,l,f,d)),$o(d)&&Ya(u,l,d),null!=s&&Ka(l,d,a)}function A(e,t=B.Default){const n=w();return null===n?oe(e,t):gd(Me(),n,H(e),t)}function g(e,t,n){const r=w();return Pe(r,qn(),t)&&nt(K(),_e(),r,e,t,r[j],n,!1),g}function _l(e,t,n,r,o){const s=o?"class":"style";Xf(e,n,t.inputs[s],s,r)}function y(e,t,n,r){const o=w(),i=K(),s=20+e,a=o[j],l=o[s]=Na(a,t,function Ay(){return P.lFrame.currentNamespace}()),u=i.firstCreatePass?function _b(e,t,n,r,o,i,s){const a=t.consts,u=sr(t,e,2,o,an(a,i));return Ja(t,n,u,an(a,s)),null!==u.attrs&&Di(u,u.attrs,!1),null!==u.mergedAttrs&&Di(u,u.mergedAttrs,!0),null!==t.queries&&t.queries.elementStart(t,u),u}(s,i,o,0,t,n,r):i.data[s];Nt(u,!0);const c=u.mergedAttrs;null!==c&&Ko(a,l,c);const d=u.classes;null!==d&&ka(a,l,d);const f=u.styles;return null!==f&&mf(a,l,f),64!=(64&u.flags)&&pi(i,o,l,u),0===function fy(){return P.lFrame.elementDepthCount}()&&Re(l,o),function hy(){P.lFrame.elementDepthCount++}(),$o(u)&&(Ya(i,o,u),Pf(i,u,o)),null!==r&&Ka(o,u),y}function v(){let e=Me();Qs()?Zs():(e=e.parent,Nt(e,!1));const t=e;!function py(){P.lFrame.elementDepthCount--}();const n=K();return n.firstCreatePass&&(Qo(n,e),Ls(e)&&n.queries.elementEnd(e)),null!=t.classesWithoutHost&&function Fy(e){return 0!=(16&e.flags)}(t)&&_l(n,t,w(),t.classesWithoutHost,!0),null!=t.stylesWithoutHost&&function Oy(e){return 0!=(32&e.flags)}(t)&&_l(n,t,w(),t.stylesWithoutHost,!1),v}function F(e,t,n,r){return y(e,t,n,r),v(),F}function Q(e,t,n){const r=w(),o=K(),i=e+20,s=o.firstCreatePass?function vb(e,t,n,r,o){const i=t.consts,s=an(i,r),a=sr(t,e,8,"ng-container",s);return null!==s&&Di(a,s,!0),Ja(t,n,a,an(i,o)),null!==t.queries&&t.queries.elementStart(t,a),a}(i,o,r,t,n):o.data[i];Nt(s,!0);const a=r[i]=r[j].createComment("");return pi(o,r,a,s),Re(a,r),$o(s)&&(Ya(o,r,s),Pf(o,s,r)),null!=n&&Ka(r,s),Q}function Z(){let e=Me();const t=K();return Qs()?Zs():(e=e.parent,Nt(e,!1)),t.firstCreatePass&&(Qo(t,e),Ls(e)&&t.queries.elementEnd(e)),Z}function rt(){return w()}function Mi(e){return!!e&&"function"==typeof e.then}const Bh=function Lh(e){return!!e&&"function"==typeof e.subscribe};function z(e,t,n,r){const o=w(),i=K(),s=Me();return function jh(e,t,n,r,o,i,s,a){const l=$o(r),c=e.firstCreatePass&&Yf(e),d=t[8],f=Zf(t);let p=!0;if(3&r.type||a){const M=lt(r,t),I=a?a(M):M,_=f.length,N=a?U=>a(De(U[r.index])):r.index;if(me(n)){let U=null;if(!a&&l&&(U=function yb(e,t,n,r){const o=e.cleanup;if(null!=o)for(let i=0;i<o.length-1;i+=2){const s=o[i];if(s===n&&o[i+1]===r){const a=t[7],l=o[i+2];return a.length>l?a[l]:null}"string"==typeof s&&(i+=2)}return null}(e,t,o,r.index)),null!==U)(U.__ngLastListenerFn__||U).__ngNextListenerFn__=i,U.__ngLastListenerFn__=i,p=!1;else{i=vl(r,t,d,i,!1);const X=n.listen(I,o,i);f.push(i,X),c&&c.push(o,N,_,_+1)}}else i=vl(r,t,d,i,!0),I.addEventListener(o,i,s),f.push(i),c&&c.push(o,N,_,s)}else i=vl(r,t,d,i,!1);const m=r.outputs;let D;if(p&&null!==m&&(D=m[o])){const M=D.length;if(M)for(let I=0;I<M;I+=2){const ot=t[D[I]][D[I+1]].subscribe(i),kn=f.length;f.push(i,ot),c&&c.push(o,r.index,kn,-(kn+1))}}}(i,o,o[j],s,e,t,!!n,r),z}function $h(e,t,n,r){try{return!1!==n(r)}catch(o){return Jf(e,o),!1}}function vl(e,t,n,r,o){return function i(s){if(s===Function)return r;const a=2&e.flags?Xe(e.index,t):t;0==(32&t[2])&&tl(a);let l=$h(t,0,r,s),u=i.__ngNextListenerFn__;for(;u;)l=$h(t,0,u,s)&&l,u=u.__ngNextListenerFn__;return o&&!1===l&&(s.preventDefault(),s.returnValue=!1),l}}function C(e=1){return function wy(e){return(P.lFrame.contextLView=function by(e,t){for(;e>0;)t=t[15],e--;return t}(e,P.lFrame.contextLView))[8]}(e)}function wr(e,t,n){return yl(e,"",t,"",n),wr}function yl(e,t,n,r,o){const i=w(),s=hr(i,t,n,r);return s!==L&&nt(K(),_e(),i,e,s,i[j],o,!1),yl}function Kh(e,t,n,r,o){const i=e[n+1],s=null===t;let a=r?Ct(i):Yt(i),l=!1;for(;0!==a&&(!1===l||s);){const c=e[a+1];Mb(e[a],t)&&(l=!0,e[a+1]=r?Ha(c):La(c)),a=r?Ct(c):Yt(c)}l&&(e[n+1]=r?La(i):Ha(i))}function Mb(e,t){return null===e||null==t||(Array.isArray(e)?e[1]:e)===t||!(!Array.isArray(e)||"string"!=typeof t)&&er(e,t)>=0}const Ae={textEnd:0,key:0,keyEnd:0,value:0,valueEnd:0};function Jh(e){return e.substring(Ae.key,Ae.keyEnd)}function Xh(e,t){const n=Ae.textEnd;return n===t?-1:(t=Ae.keyEnd=function Sb(e,t,n){for(;t<n&&e.charCodeAt(t)>32;)t++;return t}(e,Ae.key=t,n),br(e,t,n))}function br(e,t,n){for(;t<n&&e.charCodeAt(t)<=32;)t++;return t}function Ii(e,t){return function wt(e,t,n,r){const o=w(),i=K(),s=Zt(2);i.firstUpdatePass&&sp(i,e,s,r),t!==L&&Pe(o,s,t)&&lp(i,i.data[je()],o,o[j],e,o[s+1]=function Hb(e,t){return null==e||("string"==typeof t?e+=t:"object"==typeof e&&(e=te(cn(e)))),e}(t,n),r,s)}(e,t,null,!0),Ii}function Bt(e,t){for(let n=function Ab(e){return function tp(e){Ae.key=0,Ae.keyEnd=0,Ae.value=0,Ae.valueEnd=0,Ae.textEnd=e.length}(e),Xh(e,br(e,0,Ae.textEnd))}(t);n>=0;n=Xh(t,n))et(e,Jh(t),!0)}function ip(e,t){return t>=e.expandoStartIndex}function sp(e,t,n,r){const o=e.data;if(null===o[n+1]){const i=o[je()],s=ip(e,n);cp(i,r)&&null===t&&!s&&(t=!1),t=function Rb(e,t,n,r){const o=function Ks(e){const t=P.lFrame.currentDirectiveIndex;return-1===t?null:e[t]}(e);let i=r?t.residualClasses:t.residualStyles;if(null===o)0===(r?t.classBindings:t.styleBindings)&&(n=ao(n=Cl(null,e,t,n,r),t.attrs,r),i=null);else{const s=t.directiveStylingLast;if(-1===s||e[s]!==o)if(n=Cl(o,e,t,n,r),null===i){let l=function Pb(e,t,n){const r=n?t.classBindings:t.styleBindings;if(0!==Yt(r))return e[Ct(r)]}(e,t,r);void 0!==l&&Array.isArray(l)&&(l=Cl(null,e,t,l[1],r),l=ao(l,t.attrs,r),function Vb(e,t,n,r){e[Ct(n?t.classBindings:t.styleBindings)]=r}(e,t,r,l))}else i=function kb(e,t,n){let r;const o=t.directiveEnd;for(let i=1+t.directiveStylingLast;i<o;i++)r=ao(r,e[i].hostAttrs,n);return ao(r,t.attrs,n)}(e,t,r)}return void 0!==i&&(r?t.residualClasses=i:t.residualStyles=i),n}(o,i,t,r),function bb(e,t,n,r,o,i){let s=i?t.classBindings:t.styleBindings,a=Ct(s),l=Yt(s);e[r]=n;let c,u=!1;if(Array.isArray(n)){const d=n;c=d[1],(null===c||er(d,c)>0)&&(u=!0)}else c=n;if(o)if(0!==l){const f=Ct(e[a+1]);e[r+1]=mi(f,a),0!==f&&(e[f+1]=Ba(e[f+1],r)),e[a+1]=function OD(e,t){return 131071&e|t<<17}(e[a+1],r)}else e[r+1]=mi(a,0),0!==a&&(e[a+1]=Ba(e[a+1],r)),a=r;else e[r+1]=mi(l,0),0===a?a=r:e[l+1]=Ba(e[l+1],r),l=r;u&&(e[r+1]=La(e[r+1])),Kh(e,c,r,!0),Kh(e,c,r,!1),function Eb(e,t,n,r,o){const i=o?e.residualClasses:e.residualStyles;null!=i&&"string"==typeof t&&er(i,t)>=0&&(n[r+1]=Ha(n[r+1]))}(t,c,e,r,i),s=mi(a,l),i?t.classBindings=s:t.styleBindings=s}(o,i,t,n,s,r)}}function Cl(e,t,n,r,o){let i=null;const s=n.directiveEnd;let a=n.directiveStylingLast;for(-1===a?a=n.directiveStart:a++;a<s&&(i=t[a],r=ao(r,i.hostAttrs,o),i!==e);)a++;return null!==e&&(n.directiveStylingLast=a),r}function ao(e,t,n){const r=n?1:2;let o=-1;if(null!==t)for(let i=0;i<t.length;i++){const s=t[i];"number"==typeof s?o=s:o===r&&(Array.isArray(e)||(e=void 0===e?[]:["",e]),et(e,s,!!n||t[++i]))}return void 0===e?null:e}function lp(e,t,n,r,o,i,s,a){if(!(3&t.type))return;const l=e.data,u=l[a+1];Ai(function Mf(e){return 1==(1&e)}(u)?up(l,t,n,o,Yt(u),s):void 0)||(Ai(i)||function Ef(e){return 2==(2&e)}(u)&&(i=up(l,null,n,o,a,s)),function DD(e,t,n,r,o){const i=me(e);if(t)o?i?e.addClass(n,r):n.classList.add(r):i?e.removeClass(n,r):n.classList.remove(r);else{let s=-1===r.indexOf("-")?void 0:tt.DashCase;if(null==o)i?e.removeStyle(n,r,s):n.style.removeProperty(r);else{const a="string"==typeof o&&o.endsWith("!important");a&&(o=o.slice(0,-10),s|=tt.Important),i?e.setStyle(n,r,o,s):n.style.setProperty(r,o,a?"important":"")}}}(r,s,Uo(je(),n),o,i))}function up(e,t,n,r,o,i){const s=null===t;let a;for(;o>0;){const l=e[o],u=Array.isArray(l),c=u?l[1]:l,d=null===c;let f=n[o+1];f===L&&(f=d?se:void 0);let p=d?ua(f,r):c===r?f:void 0;if(u&&!Ai(p)&&(p=ua(l,r)),Ai(p)&&(a=p,s))return a;const m=e[o+1];o=s?Ct(m):Yt(m)}if(null!==t){let l=i?t.residualClasses:t.residualStyles;null!=l&&(a=ua(l,r))}return a}function Ai(e){return void 0!==e}function cp(e,t){return 0!=(e.flags&(t?16:32))}function b(e,t=""){const n=w(),r=K(),o=e+20,i=r.firstCreatePass?sr(r,o,1,t,null):r.data[o],s=n[o]=function xa(e,t){return me(e)?e.createText(t):e.createTextNode(t)}(n[j],t);pi(r,n,s,i),Nt(i,!1)}function x(e){return q("",e,""),x}function q(e,t,n){const r=w(),o=hr(r,e,t,n);return o!==L&&Kt(r,je(),o),q}function Ht(e,t,n){!function bt(e,t,n,r){const o=K(),i=Zt(2);o.firstUpdatePass&&sp(o,null,i,r);const s=w();if(n!==L&&Pe(s,i,n)){const a=o.data[je()];if(cp(a,r)&&!ip(o,i)){let l=r?a.classesWithoutHost:a.stylesWithoutHost;null!==l&&(n=Ss(l,n||"")),_l(o,a,s,n,r)}else!function Bb(e,t,n,r,o,i,s,a){o===L&&(o=se);let l=0,u=0,c=0<o.length?o[0]:null,d=0<i.length?i[0]:null;for(;null!==c||null!==d;){const f=l<o.length?o[l+1]:void 0,p=u<i.length?i[u+1]:void 0;let D,m=null;c===d?(l+=2,u+=2,f!==p&&(m=d,D=p)):null===d||null!==c&&c<d?(l+=2,m=c):(u+=2,m=d,D=p),null!==m&&lp(e,t,n,r,m,D,s,a),c=l<o.length?o[l]:null,d=u<i.length?i[u]:null}}(o,a,s,s[j],s[i+1],s[i+1]=function Lb(e,t,n){if(null==n||""===n)return se;const r=[],o=cn(n);if(Array.isArray(o))for(let i=0;i<o.length;i++)e(r,o[i],!0);else if("object"==typeof o)for(const i in o)o.hasOwnProperty(i)&&e(r,i,o[i]);else"string"==typeof o&&t(r,o);return r}(e,t,n),r,i)}}(et,Bt,hr(w(),e,t,n),!0)}const Ti="en-US";let Fp=Ti;function bl(e,t,n,r,o){if(e=H(e),Array.isArray(e))for(let i=0;i<e.length;i++)bl(e[i],t,n,r,o);else{const i=K(),s=w();let a=cr(e)?e:H(e.provide),l=oh(e);const u=Me(),c=1048575&u.providerIndexes,d=u.directiveStart,f=u.providerIndexes>>20;if(cr(e)||!e.multi){const p=new Lr(l,o,A),m=Ml(a,t,o?c:c+f,d);-1===m?(ti(Hr(u,s),i,a),El(i,e,t.length),t.push(a),u.directiveStart++,u.directiveEnd++,o&&(u.providerIndexes+=1048576),n.push(p),s.push(p)):(n[m]=p,s[m]=p)}else{const p=Ml(a,t,c+f,d),m=Ml(a,t,c,c+f),D=p>=0&&n[p],M=m>=0&&n[m];if(o&&!M||!o&&!D){ti(Hr(u,s),i,a);const I=function iE(e,t,n,r,o){const i=new Lr(e,n,A);return i.multi=[],i.index=t,i.componentProviders=0,ng(i,o,r&&!n),i}(o?oE:rE,n.length,o,r,l);!o&&M&&(n[m].providerFactory=I),El(i,e,t.length,0),t.push(a),u.directiveStart++,u.directiveEnd++,o&&(u.providerIndexes+=1048576),n.push(I),s.push(I)}else El(i,e,p>-1?p:m,ng(n[o?m:p],l,!o&&r));!o&&r&&M&&n[m].componentProviders++}}}function El(e,t,n,r){const o=cr(t),i=function Iw(e){return!!e.useClass}(t);if(o||i){const l=(i?H(t.useClass):t).prototype.ngOnDestroy;if(l){const u=e.destroyHooks||(e.destroyHooks=[]);if(!o&&t.multi){const c=u.indexOf(n);-1===c?u.push(n,[r,l]):u[c+1].push(r,l)}else u.push(n,l)}}}function ng(e,t,n){return n&&e.componentProviders++,e.multi.push(t)-1}function Ml(e,t,n,r){for(let o=n;o<r;o++)if(t[o]===e)return o;return-1}function rE(e,t,n,r){return Il(this.multi,[])}function oE(e,t,n,r){const o=this.multi;let i;if(this.providerFactory){const s=this.providerFactory.componentProviders,a=jr(n,n[1],this.providerFactory.index,r);i=a.slice(0,s),Il(o,i);for(let l=s;l<a.length;l++)i.push(a[l])}else i=[],Il(o,i);return i}function Il(e,t){for(let n=0;n<e.length;n++)t.push((0,e[n])());return t}function he(e,t=[]){return n=>{n.providersResolver=(r,o)=>function nE(e,t,n){const r=K();if(r.firstCreatePass){const o=vt(e);bl(n,r.data,r.blueprint,o,!0),bl(t,r.data,r.blueprint,o,!1)}}(r,o?o(e):e,t)}}class rg{}class lE{resolveComponentFactory(t){throw function aE(e){const t=Error(`No component factory found for ${te(e)}. Did you add it to @NgModule.entryComponents?`);return t.ngComponent=e,t}(t)}}let Oi=(()=>{class e{}return e.NULL=new lE,e})();function uE(){return Ir(Me(),w())}function Ir(e,t){return new Et(lt(e,t))}let Et=(()=>{class e{constructor(n){this.nativeElement=n}}return e.__NG_ELEMENT_ID__=uE,e})();class ig{}let Nn=(()=>{class e{}return e.__NG_ELEMENT_ID__=()=>function fE(){const e=w(),n=Xe(Me().index,e);return function dE(e){return e[j]}(xt(n)?n:e)}(),e})(),hE=(()=>{class e{}return e.\u0275prov=de({token:e,providedIn:"root",factory:()=>null}),e})();class Ri{constructor(t){this.full=t,this.major=t.split(".")[0],this.minor=t.split(".")[1],this.patch=t.split(".").slice(2).join(".")}}const pE=new Ri("13.3.0"),Al={};function Pi(e,t,n,r,o=!1){for(;null!==n;){const i=t[n.index];if(null!==i&&r.push(De(i)),_t(i))for(let a=10;a<i.length;a++){const l=i[a],u=l[1].firstChild;null!==u&&Pi(l[1],l,u,r)}const s=n.type;if(8&s)Pi(e,t,n.child,r);else if(32&s){const a=Aa(n,t);let l;for(;l=a();)r.push(l)}else if(16&s){const a=hf(t,n);if(Array.isArray(a))r.push(...a);else{const l=eo(t[16]);Pi(l[1],l,a,r,!0)}}n=o?n.projectionNext:n.next}return r}class ho{constructor(t,n){this._lView=t,this._cdRefInjectingView=n,this._appRef=null,this._attachedToViewContainer=!1}get rootNodes(){const t=this._lView,n=t[1];return Pi(n,t,n.firstChild,[])}get context(){return this._lView[8]}set context(t){this._lView[8]=t}get destroyed(){return 256==(256&this._lView[2])}destroy(){if(this._appRef)this._appRef.detachView(this);else if(this._attachedToViewContainer){const t=this._lView[3];if(_t(t)){const n=t[8],r=n?n.indexOf(this):-1;r>-1&&(Fa(t,r),ri(n,r))}this._attachedToViewContainer=!1}rf(this._lView[1],this._lView)}onDestroy(t){!function Bf(e,t,n,r){const o=Zf(t);null===n?o.push(r):(o.push(n),e.firstCreatePass&&Yf(e).push(r,o.length-1))}(this._lView[1],this._lView,null,t)}markForCheck(){tl(this._cdRefInjectingView||this._lView)}detach(){this._lView[2]&=-129}reattach(){this._lView[2]|=128}detectChanges(){rl(this._lView[1],this._lView,this.context)}checkNoChanges(){!function gw(e,t,n){Go(!0);try{rl(e,t,n)}finally{Go(!1)}}(this._lView[1],this._lView,this.context)}attachToViewContainerRef(){if(this._appRef)throw new Y(902,"");this._attachedToViewContainer=!0}detachFromAppRef(){this._appRef=null,function dD(e,t){to(e,t,t[j],2,null,null)}(this._lView[1],this._lView)}attachToAppRef(t){if(this._attachedToViewContainer)throw new Y(902,"");this._appRef=t}}class gE extends ho{constructor(t){super(t),this._view=t}detectChanges(){Qf(this._view)}checkNoChanges(){!function mw(e){Go(!0);try{Qf(e)}finally{Go(!1)}}(this._view)}get context(){return null}}class sg extends Oi{constructor(t){super(),this.ngModule=t}resolveComponentFactory(t){const n=Ne(t);return new Tl(n,this.ngModule)}}function ag(e){const t=[];for(let n in e)e.hasOwnProperty(n)&&t.push({propName:e[n],templateName:n});return t}class Tl extends rg{constructor(t,n){super(),this.componentDef=t,this.ngModule=n,this.componentType=t.type,this.selector=function ND(e){return e.map(xD).join(",")}(t.selectors),this.ngContentSelectors=t.ngContentSelectors?t.ngContentSelectors:[],this.isBoundToModule=!!n}get inputs(){return ag(this.componentDef.inputs)}get outputs(){return ag(this.componentDef.outputs)}create(t,n,r,o){const i=(o=o||this.ngModule)?function _E(e,t){return{get:(n,r,o)=>{const i=e.get(n,Al,o);return i!==Al||r===Al?i:t.get(n,r,o)}}}(t,o.injector):t,s=i.get(ig,Wc),a=i.get(hE,null),l=s.createRenderer(null,this.componentDef),u=this.componentDef.selectors[0][0]||"div",c=r?function Lf(e,t,n){if(me(e))return e.selectRootElement(t,n===St.ShadowDom);let r="string"==typeof t?e.querySelector(t):t;return r.textContent="",r}(l,r,this.componentDef.encapsulation):Na(s.createRenderer(null,this.componentDef),u,function mE(e){const t=e.toLowerCase();return"svg"===t?"svg":"math"===t?"math":null}(u)),d=this.componentDef.onPush?576:528,f=function mh(e,t){return{components:[],scheduler:e||oD,clean:_w,playerHandler:t||null,flags:0}}(),p=yi(0,null,null,1,0,null,null,null,null,null),m=no(null,p,f,d,null,null,s,l,a,i);let D,M;qo(m);try{const I=function ph(e,t,n,r,o,i){const s=n[1];n[20]=e;const l=sr(s,20,2,"#host",null),u=l.mergedAttrs=t.hostAttrs;null!==u&&(Di(l,u,!0),null!==e&&(Ko(o,e,u),null!==l.classes&&ka(o,e,l.classes),null!==l.styles&&mf(o,e,l.styles)));const c=r.createRenderer(e,t),d=no(n,Vf(t),null,t.onPush?64:16,n[20],l,r,c,i||null,null);return s.firstCreatePass&&(ti(Hr(l,n),s,t.type),zf(s,l),Gf(l,n.length,1)),Ci(n,d),n[20]=d}(c,this.componentDef,m,s,l);if(c)if(r)Ko(l,c,["ng-version",pE.full]);else{const{attrs:_,classes:N}=function FD(e){const t=[],n=[];let r=1,o=2;for(;r<e.length;){let i=e[r];if("string"==typeof i)2===o?""!==i&&t.push(i,e[++r]):8===o&&n.push(i);else{if(!yt(o))break;o=i}r++}return{attrs:t,classes:n}}(this.componentDef.selectors[0]);_&&Ko(l,c,_),N&&N.length>0&&ka(l,c,N.join(" "))}if(M=Gs(p,20),void 0!==n){const _=M.projection=[];for(let N=0;N<this.ngContentSelectors.length;N++){const U=n[N];_.push(null!=U?Array.from(U):null)}}D=function gh(e,t,n,r,o){const i=n[1],s=function XD(e,t,n){const r=Me();e.firstCreatePass&&(n.providersResolver&&n.providersResolver(n),qf(e,r,t,ar(e,t,1,null),n));const o=jr(t,e,r.directiveStart,r);Re(o,t);const i=lt(r,t);return i&&Re(i,t),o}(i,n,t);if(r.components.push(s),e[8]=s,o&&o.forEach(l=>l(s,t)),t.contentQueries){const l=Me();t.contentQueries(1,s,l.directiveStart)}const a=Me();return!i.firstCreatePass||null===t.hostBindings&&null===t.hostAttrs||(ln(a.index),$f(n[1],a,0,a.directiveStart,a.directiveEnd,t),Uf(t,s)),s}(I,this.componentDef,m,f,[kw]),ro(p,m,null)}finally{Wo()}return new yE(this.componentType,D,Ir(M,m),m,M)}}class yE extends class sE{}{constructor(t,n,r,o,i){super(),this.location=r,this._rootLView=o,this._tNode=i,this.instance=n,this.hostView=this.changeDetectorRef=new gE(o),this.componentType=t}get injector(){return new Zn(this._tNode,this._rootLView)}destroy(){this.hostView.destroy()}onDestroy(t){this.hostView.onDestroy(t)}}class Ar{}const Tr=new Map;class cg extends Ar{constructor(t,n){super(),this._parent=n,this._bootstrapComponents=[],this.injector=this,this.destroyCbs=[],this.componentFactoryResolver=new sg(this);const r=it(t);this._bootstrapComponents=Rt(r.bootstrap),this._r3Injector=rh(t,n,[{provide:Ar,useValue:this},{provide:Oi,useValue:this.componentFactoryResolver}],te(t)),this._r3Injector._resolveInjectorDefTypes(),this.instance=this.get(t)}get(t,n=ct.THROW_IF_NOT_FOUND,r=B.Default){return t===ct||t===Ar||t===il?this:this._r3Injector.get(t,n,r)}destroy(){const t=this._r3Injector;!t.destroyed&&t.destroy(),this.destroyCbs.forEach(n=>n()),this.destroyCbs=null}onDestroy(t){this.destroyCbs.push(t)}}class Sl extends class DE{}{constructor(t){super(),this.moduleType=t,null!==it(t)&&function wE(e){const t=new Set;!function n(r){const o=it(r,!0),i=o.id;null!==i&&(function lg(e,t,n){if(t&&t!==n)throw new Error(`Duplicate module registered for ${e} - ${te(t)} vs ${te(t.name)}`)}(i,Tr.get(i),r),Tr.set(i,r));const s=Rt(o.imports);for(const a of s)t.has(a)||(t.add(a),n(a))}(e)}(t)}create(t){return new cg(this.moduleType,t)}}function Vi(e,t,n,r){return function dg(e,t,n,r,o,i){const s=t+n;return Pe(e,s,o)?Vt(e,s+1,i?r.call(i,o):r(o)):po(e,s+1)}(w(),He(),e,t,n,r)}function xl(e,t,n,r,o){return function fg(e,t,n,r,o,i,s){const a=t+n;return Sn(e,a,o,i)?Vt(e,a+2,s?r.call(s,o,i):r(o,i)):po(e,a+2)}(w(),He(),e,t,n,r,o)}function xe(e,t,n,r,o,i){return hg(w(),He(),e,t,n,r,o,i)}function po(e,t){const n=e[t];return n===L?void 0:n}function hg(e,t,n,r,o,i,s,a){const l=t+n;return function bi(e,t,n,r,o){const i=Sn(e,t,n,r);return Pe(e,t+2,o)||i}(e,l,o,i,s)?Vt(e,l+3,a?r.call(a,o,i,s):r(o,i,s)):po(e,l+3)}function Nl(e){return t=>{setTimeout(e,void 0,t)}}const Ve=class PE extends Ds{constructor(t=!1){super(),this.__isAsync=t}emit(t){super.next(t)}subscribe(t,n,r){var o,i,s;let a=t,l=n||(()=>null),u=r;if(t&&"object"==typeof t){const d=t;a=null===(o=d.next)||void 0===o?void 0:o.bind(d),l=null===(i=d.error)||void 0===i?void 0:i.bind(d),u=null===(s=d.complete)||void 0===s?void 0:s.bind(d)}this.__isAsync&&(l=Nl(l),a&&(a=Nl(a)),u&&(u=Nl(u)));const c=super.subscribe({next:a,error:l,complete:u});return t instanceof Tt&&t.add(c),c}};Symbol;let Jt=(()=>{class e{}return e.__NG_ELEMENT_ID__=BE,e})();const kE=Jt,LE=class extends kE{constructor(t,n,r){super(),this._declarationLView=t,this._declarationTContainer=n,this.elementRef=r}createEmbeddedView(t){const n=this._declarationTContainer.tViews,r=no(this._declarationLView,n,t,16,null,n.declTNode,null,null,null,null);r[17]=this._declarationLView[this._declarationTContainer.index];const i=this._declarationLView[19];return null!==i&&(r[19]=i.createEmbeddedView(n)),ro(n,r,t),new ho(r)}};function BE(){return function ki(e,t){return 4&e.type?new LE(t,e,Ir(e,t)):null}(Me(),w())}let jt=(()=>{class e{}return e.__NG_ELEMENT_ID__=HE,e})();function HE(){return function Cg(e,t){let n;const r=t[e.index];if(_t(r))n=r;else{let o;if(8&e.type)o=De(r);else{const i=t[j];o=i.createComment("");const s=lt(e,t);Tn(i,hi(i,s),o,function vD(e,t){return me(e)?e.nextSibling(t):t.nextSibling}(i,s),!1)}t[e.index]=n=Wf(r,t,o,e),Ci(t,n)}return new vg(n,e,t)}(Me(),w())}const jE=jt,vg=class extends jE{constructor(t,n,r){super(),this._lContainer=t,this._hostTNode=n,this._hostLView=r}get element(){return Ir(this._hostTNode,this._hostLView)}get injector(){return new Zn(this._hostTNode,this._hostLView)}get parentInjector(){const t=ei(this._hostTNode,this._hostLView);if(cd(t)){const n=Qn(t,this._hostLView),r=Wn(t);return new Zn(n[1].data[r+8],n)}return new Zn(null,this._hostLView)}clear(){for(;this.length>0;)this.remove(this.length-1)}get(t){const n=yg(this._lContainer);return null!==n&&n[t]||null}get length(){return this._lContainer.length-10}createEmbeddedView(t,n,r){const o=t.createEmbeddedView(n||{});return this.insert(o,r),o}createComponent(t,n,r,o,i){const s=t&&!function Ur(e){return"function"==typeof e}(t);let a;if(s)a=n;else{const d=n||{};a=d.index,r=d.injector,o=d.projectableNodes,i=d.ngModuleRef}const l=s?t:new Tl(Ne(t)),u=r||this.parentInjector;if(!i&&null==l.ngModule){const f=(s?u:this.parentInjector).get(Ar,null);f&&(i=f)}const c=l.create(u,o,void 0,i);return this.insert(c.hostView,a),c}insert(t,n){const r=t._lView,o=r[1];if(function dy(e){return _t(e[3])}(r)){const c=this.indexOf(t);if(-1!==c)this.detach(c);else{const d=r[3],f=new vg(d,d[6],d[3]);f.detach(f.indexOf(t))}}const i=this._adjustIndex(n),s=this._lContainer;!function hD(e,t,n,r){const o=10+r,i=n.length;r>0&&(n[o-1][4]=t),r<i-10?(t[4]=n[o],Cd(n,10+r,t)):(n.push(t),t[4]=null),t[3]=n;const s=t[17];null!==s&&n!==s&&function pD(e,t){const n=e[9];t[16]!==t[3][3][16]&&(e[2]=!0),null===n?e[9]=[t]:n.push(t)}(s,t);const a=t[19];null!==a&&a.insertView(e),t[2]|=128}(o,r,s,i);const a=Pa(i,s),l=r[j],u=hi(l,s[7]);return null!==u&&function cD(e,t,n,r,o,i){r[0]=o,r[6]=t,to(e,r,n,1,o,i)}(o,s[6],l,r,u,a),t.attachToViewContainerRef(),Cd(Ol(s),i,t),t}move(t,n){return this.insert(t,n)}indexOf(t){const n=yg(this._lContainer);return null!==n?n.indexOf(t):-1}remove(t){const n=this._adjustIndex(t,-1),r=Fa(this._lContainer,n);r&&(ri(Ol(this._lContainer),n),rf(r[1],r))}detach(t){const n=this._adjustIndex(t,-1),r=Fa(this._lContainer,n);return r&&null!=ri(Ol(this._lContainer),n)?new ho(r):null}_adjustIndex(t,n=0){return null==t?this.length+n:t}};function yg(e){return e[8]}function Ol(e){return e[8]||(e[8]=[])}function Hi(...e){}const $g=new J("Application Initializer");let zl=(()=>{class e{constructor(n){this.appInits=n,this.resolve=Hi,this.reject=Hi,this.initialized=!1,this.done=!1,this.donePromise=new Promise((r,o)=>{this.resolve=r,this.reject=o})}runInitializers(){if(this.initialized)return;const n=[],r=()=>{this.done=!0,this.resolve()};if(this.appInits)for(let o=0;o<this.appInits.length;o++){const i=this.appInits[o]();if(Mi(i))n.push(i);else if(Bh(i)){const s=new Promise((a,l)=>{i.subscribe({complete:a,error:l})});n.push(s)}}Promise.all(n).then(()=>{r()}).catch(o=>{this.reject(o)}),0===n.length&&r(),this.initialized=!0}}return e.\u0275fac=function(n){return new(n||e)(oe($g,8))},e.\u0275prov=de({token:e,factory:e.\u0275fac,providedIn:"root"}),e})();const _o=new J("AppId",{providedIn:"root",factory:function Ug(){return`${Gl()}${Gl()}${Gl()}`}});function Gl(){return String.fromCharCode(97+Math.floor(25*Math.random()))}const zg=new J("Platform Initializer"),ql=new J("Platform ID"),_1=new J("appBootstrapListener");let v1=(()=>{class e{log(n){console.log(n)}warn(n){console.warn(n)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const hn=new J("LocaleId",{providedIn:"root",factory:()=>tC(hn,B.Optional|B.SkipSelf)||function y1(){return"undefined"!=typeof $localize&&$localize.locale||Ti}()}),b1=(()=>Promise.resolve(0))();function Wl(e){"undefined"==typeof Zone?b1.then(()=>{e&&e.apply(null,null)}):Zone.current.scheduleMicroTask("scheduleMicrotask",e)}class Qe{constructor({enableLongStackTrace:t=!1,shouldCoalesceEventChangeDetection:n=!1,shouldCoalesceRunChangeDetection:r=!1}){if(this.hasPendingMacrotasks=!1,this.hasPendingMicrotasks=!1,this.isStable=!0,this.onUnstable=new Ve(!1),this.onMicrotaskEmpty=new Ve(!1),this.onStable=new Ve(!1),this.onError=new Ve(!1),"undefined"==typeof Zone)throw new Error("In this configuration Angular requires Zone.js");Zone.assertZonePatched();const o=this;o._nesting=0,o._outer=o._inner=Zone.current,Zone.TaskTrackingZoneSpec&&(o._inner=o._inner.fork(new Zone.TaskTrackingZoneSpec)),t&&Zone.longStackTraceZoneSpec&&(o._inner=o._inner.fork(Zone.longStackTraceZoneSpec)),o.shouldCoalesceEventChangeDetection=!r&&n,o.shouldCoalesceRunChangeDetection=r,o.lastRequestAnimationFrameId=-1,o.nativeRequestAnimationFrame=function E1(){let e=re.requestAnimationFrame,t=re.cancelAnimationFrame;if("undefined"!=typeof Zone&&e&&t){const n=e[Zone.__symbol__("OriginalDelegate")];n&&(e=n);const r=t[Zone.__symbol__("OriginalDelegate")];r&&(t=r)}return{nativeRequestAnimationFrame:e,nativeCancelAnimationFrame:t}}().nativeRequestAnimationFrame,function A1(e){const t=()=>{!function I1(e){e.isCheckStableRunning||-1!==e.lastRequestAnimationFrameId||(e.lastRequestAnimationFrameId=e.nativeRequestAnimationFrame.call(re,()=>{e.fakeTopEventTask||(e.fakeTopEventTask=Zone.root.scheduleEventTask("fakeTopEventTask",()=>{e.lastRequestAnimationFrameId=-1,Zl(e),e.isCheckStableRunning=!0,Ql(e),e.isCheckStableRunning=!1},void 0,()=>{},()=>{})),e.fakeTopEventTask.invoke()}),Zl(e))}(e)};e._inner=e._inner.fork({name:"angular",properties:{isAngularZone:!0},onInvokeTask:(n,r,o,i,s,a)=>{try{return Gg(e),n.invokeTask(o,i,s,a)}finally{(e.shouldCoalesceEventChangeDetection&&"eventTask"===i.type||e.shouldCoalesceRunChangeDetection)&&t(),qg(e)}},onInvoke:(n,r,o,i,s,a,l)=>{try{return Gg(e),n.invoke(o,i,s,a,l)}finally{e.shouldCoalesceRunChangeDetection&&t(),qg(e)}},onHasTask:(n,r,o,i)=>{n.hasTask(o,i),r===o&&("microTask"==i.change?(e._hasPendingMicrotasks=i.microTask,Zl(e),Ql(e)):"macroTask"==i.change&&(e.hasPendingMacrotasks=i.macroTask))},onHandleError:(n,r,o,i)=>(n.handleError(o,i),e.runOutsideAngular(()=>e.onError.emit(i)),!1)})}(o)}static isInAngularZone(){return"undefined"!=typeof Zone&&!0===Zone.current.get("isAngularZone")}static assertInAngularZone(){if(!Qe.isInAngularZone())throw new Error("Expected to be in Angular Zone, but it is not!")}static assertNotInAngularZone(){if(Qe.isInAngularZone())throw new Error("Expected to not be in Angular Zone, but it is!")}run(t,n,r){return this._inner.run(t,n,r)}runTask(t,n,r,o){const i=this._inner,s=i.scheduleEventTask("NgZoneEvent: "+o,t,M1,Hi,Hi);try{return i.runTask(s,n,r)}finally{i.cancelTask(s)}}runGuarded(t,n,r){return this._inner.runGuarded(t,n,r)}runOutsideAngular(t){return this._outer.run(t)}}const M1={};function Ql(e){if(0==e._nesting&&!e.hasPendingMicrotasks&&!e.isStable)try{e._nesting++,e.onMicrotaskEmpty.emit(null)}finally{if(e._nesting--,!e.hasPendingMicrotasks)try{e.runOutsideAngular(()=>e.onStable.emit(null))}finally{e.isStable=!0}}}function Zl(e){e.hasPendingMicrotasks=!!(e._hasPendingMicrotasks||(e.shouldCoalesceEventChangeDetection||e.shouldCoalesceRunChangeDetection)&&-1!==e.lastRequestAnimationFrameId)}function Gg(e){e._nesting++,e.isStable&&(e.isStable=!1,e.onUnstable.emit(null))}function qg(e){e._nesting--,Ql(e)}class T1{constructor(){this.hasPendingMicrotasks=!1,this.hasPendingMacrotasks=!1,this.isStable=!0,this.onUnstable=new Ve,this.onMicrotaskEmpty=new Ve,this.onStable=new Ve,this.onError=new Ve}run(t,n,r){return t.apply(n,r)}runGuarded(t,n,r){return t.apply(n,r)}runOutsideAngular(t){return t()}runTask(t,n,r,o){return t.apply(n,r)}}let Yl=(()=>{class e{constructor(n){this._ngZone=n,this._pendingCount=0,this._isZoneStable=!0,this._didWork=!1,this._callbacks=[],this.taskTrackingZone=null,this._watchAngularEvents(),n.run(()=>{this.taskTrackingZone="undefined"==typeof Zone?null:Zone.current.get("TaskTrackingZone")})}_watchAngularEvents(){this._ngZone.onUnstable.subscribe({next:()=>{this._didWork=!0,this._isZoneStable=!1}}),this._ngZone.runOutsideAngular(()=>{this._ngZone.onStable.subscribe({next:()=>{Qe.assertNotInAngularZone(),Wl(()=>{this._isZoneStable=!0,this._runCallbacksIfReady()})}})})}increasePendingRequestCount(){return this._pendingCount+=1,this._didWork=!0,this._pendingCount}decreasePendingRequestCount(){if(this._pendingCount-=1,this._pendingCount<0)throw new Error("pending async requests below zero");return this._runCallbacksIfReady(),this._pendingCount}isStable(){return this._isZoneStable&&0===this._pendingCount&&!this._ngZone.hasPendingMacrotasks}_runCallbacksIfReady(){if(this.isStable())Wl(()=>{for(;0!==this._callbacks.length;){let n=this._callbacks.pop();clearTimeout(n.timeoutId),n.doneCb(this._didWork)}this._didWork=!1});else{let n=this.getPendingTasks();this._callbacks=this._callbacks.filter(r=>!r.updateCb||!r.updateCb(n)||(clearTimeout(r.timeoutId),!1)),this._didWork=!0}}getPendingTasks(){return this.taskTrackingZone?this.taskTrackingZone.macroTasks.map(n=>({source:n.source,creationLocation:n.creationLocation,data:n.data})):[]}addCallback(n,r,o){let i=-1;r&&r>0&&(i=setTimeout(()=>{this._callbacks=this._callbacks.filter(s=>s.timeoutId!==i),n(this._didWork,this.getPendingTasks())},r)),this._callbacks.push({doneCb:n,timeoutId:i,updateCb:o})}whenStable(n,r,o){if(o&&!this.taskTrackingZone)throw new Error('Task tracking zone is required when passing an update callback to whenStable(). Is "zone.js/plugins/task-tracking" loaded?');this.addCallback(n,r,o),this._runCallbacksIfReady()}getPendingRequestCount(){return this._pendingCount}findProviders(n,r,o){return[]}}return e.\u0275fac=function(n){return new(n||e)(oe(Qe))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})(),Wg=(()=>{class e{constructor(){this._applications=new Map,Kl.addToWindow(this)}registerApplication(n,r){this._applications.set(n,r)}unregisterApplication(n){this._applications.delete(n)}unregisterAllApplications(){this._applications.clear()}getTestability(n){return this._applications.get(n)||null}getAllTestabilities(){return Array.from(this._applications.values())}getAllRootElements(){return Array.from(this._applications.keys())}findTestabilityInTree(n,r=!0){return Kl.findTestabilityInTree(this,n,r)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();class S1{addToWindow(t){}findTestabilityInTree(t,n,r){return null}}let Mt,Kl=new S1;const Qg=new J("AllowMultipleToken");function Zg(e,t,n=[]){const r=`Platform: ${t}`,o=new J(r);return(i=[])=>{let s=Yg();if(!s||s.injector.get(Qg,!1))if(e)e(n.concat(i).concat({provide:o,useValue:!0}));else{const a=n.concat(i).concat({provide:o,useValue:!0},{provide:sl,useValue:"platform"});!function O1(e){if(Mt&&!Mt.destroyed&&!Mt.injector.get(Qg,!1))throw new Y(400,"");Mt=e.get(Kg);const t=e.get(zg,null);t&&t.forEach(n=>n())}(ct.create({providers:a,name:r}))}return function R1(e){const t=Yg();if(!t)throw new Y(401,"");return t}()}}function Yg(){return Mt&&!Mt.destroyed?Mt:null}let Kg=(()=>{class e{constructor(n){this._injector=n,this._modules=[],this._destroyListeners=[],this._destroyed=!1}bootstrapModuleFactory(n,r){const a=function P1(e,t){let n;return n="noop"===e?new T1:("zone.js"===e?void 0:e)||new Qe({enableLongStackTrace:!1,shouldCoalesceEventChangeDetection:!!(null==t?void 0:t.ngZoneEventCoalescing),shouldCoalesceRunChangeDetection:!!(null==t?void 0:t.ngZoneRunCoalescing)}),n}(r?r.ngZone:void 0,{ngZoneEventCoalescing:r&&r.ngZoneEventCoalescing||!1,ngZoneRunCoalescing:r&&r.ngZoneRunCoalescing||!1}),l=[{provide:Qe,useValue:a}];return a.run(()=>{const u=ct.create({providers:l,parent:this.injector,name:n.moduleType.name}),c=n.create(u),d=c.injector.get(Xr,null);if(!d)throw new Y(402,"");return a.runOutsideAngular(()=>{const f=a.onError.subscribe({next:p=>{d.handleError(p)}});c.onDestroy(()=>{Jl(this._modules,c),f.unsubscribe()})}),function V1(e,t,n){try{const r=n();return Mi(r)?r.catch(o=>{throw t.runOutsideAngular(()=>e.handleError(o)),o}):r}catch(r){throw t.runOutsideAngular(()=>e.handleError(r)),r}}(d,a,()=>{const f=c.injector.get(zl);return f.runInitializers(),f.donePromise.then(()=>(function d0(e){Ke(e,"Expected localeId to be defined"),"string"==typeof e&&(Fp=e.toLowerCase().replace(/_/g,"-"))}(c.injector.get(hn,Ti)||Ti),this._moduleDoBootstrap(c),c))})})}bootstrapModule(n,r=[]){const o=Jg({},r);return function N1(e,t,n){const r=new Sl(n);return Promise.resolve(r)}(0,0,n).then(i=>this.bootstrapModuleFactory(i,o))}_moduleDoBootstrap(n){const r=n.injector.get(Xg);if(n._bootstrapComponents.length>0)n._bootstrapComponents.forEach(o=>r.bootstrap(o));else{if(!n.instance.ngDoBootstrap)throw new Y(403,"");n.instance.ngDoBootstrap(r)}this._modules.push(n)}onDestroy(n){this._destroyListeners.push(n)}get injector(){return this._injector}destroy(){if(this._destroyed)throw new Y(404,"");this._modules.slice().forEach(n=>n.destroy()),this._destroyListeners.forEach(n=>n()),this._destroyed=!0}get destroyed(){return this._destroyed}}return e.\u0275fac=function(n){return new(n||e)(oe(ct))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();function Jg(e,t){return Array.isArray(t)?t.reduce(Jg,e):Object.assign(Object.assign({},e),t)}let Xg=(()=>{class e{constructor(n,r,o,i,s){this._zone=n,this._injector=r,this._exceptionHandler=o,this._componentFactoryResolver=i,this._initStatus=s,this._bootstrapListeners=[],this._views=[],this._runningTick=!1,this._stable=!0,this.componentTypes=[],this.components=[],this._onMicrotaskEmptySubscription=this._zone.onMicrotaskEmpty.subscribe({next:()=>{this._zone.run(()=>{this.tick()})}});const a=new Le(u=>{this._stable=this._zone.isStable&&!this._zone.hasPendingMacrotasks&&!this._zone.hasPendingMicrotasks,this._zone.runOutsideAngular(()=>{u.next(this._stable),u.complete()})}),l=new Le(u=>{let c;this._zone.runOutsideAngular(()=>{c=this._zone.onStable.subscribe(()=>{Qe.assertNotInAngularZone(),Wl(()=>{!this._stable&&!this._zone.hasPendingMacrotasks&&!this._zone.hasPendingMicrotasks&&(this._stable=!0,u.next(!0))})})});const d=this._zone.onUnstable.subscribe(()=>{Qe.assertInAngularZone(),this._stable&&(this._stable=!1,this._zone.runOutsideAngular(()=>{u.next(!1)}))});return()=>{c.unsubscribe(),d.unsubscribe()}});this.isStable=Sv(a,l.pipe(function Nv(e={}){const{connector:t=(()=>new Ds),resetOnError:n=!0,resetOnComplete:r=!0,resetOnRefCountZero:o=!0}=e;return i=>{let s=null,a=null,l=null,u=0,c=!1,d=!1;const f=()=>{null==a||a.unsubscribe(),a=null},p=()=>{f(),s=l=null,c=d=!1},m=()=>{const D=s;p(),null==D||D.unsubscribe()};return Ln((D,M)=>{u++,!d&&!c&&f();const I=l=null!=l?l:t();M.add(()=>{u--,0===u&&!d&&!c&&(a=As(m,o))}),I.subscribe(M),s||(s=new _s({next:_=>I.next(_),error:_=>{d=!0,f(),a=As(p,n,_),I.error(_)},complete:()=>{c=!0,f(),a=As(p,r),I.complete()}}),Is(D).subscribe(s))})(i)}}()))}bootstrap(n,r){if(!this._initStatus.done)throw new Y(405,"");let o;o=n instanceof rg?n:this._componentFactoryResolver.resolveComponentFactory(n),this.componentTypes.push(o.componentType);const i=function F1(e){return e.isBoundToModule}(o)?void 0:this._injector.get(Ar),a=o.create(ct.NULL,[],r||o.selector,i),l=a.location.nativeElement,u=a.injector.get(Yl,null),c=u&&a.injector.get(Wg);return u&&c&&c.registerApplication(l,u),a.onDestroy(()=>{this.detachView(a.hostView),Jl(this.components,a),c&&c.unregisterApplication(l)}),this._loadComponent(a),a}tick(){if(this._runningTick)throw new Y(101,"");try{this._runningTick=!0;for(let n of this._views)n.detectChanges()}catch(n){this._zone.runOutsideAngular(()=>this._exceptionHandler.handleError(n))}finally{this._runningTick=!1}}attachView(n){const r=n;this._views.push(r),r.attachToAppRef(this)}detachView(n){const r=n;Jl(this._views,r),r.detachFromAppRef()}_loadComponent(n){this.attachView(n.hostView),this.tick(),this.components.push(n),this._injector.get(_1,[]).concat(this._bootstrapListeners).forEach(o=>o(n))}ngOnDestroy(){this._views.slice().forEach(n=>n.destroy()),this._onMicrotaskEmptySubscription.unsubscribe()}get viewCount(){return this._views.length}}return e.\u0275fac=function(n){return new(n||e)(oe(Qe),oe(ct),oe(Xr),oe(Oi),oe(zl))},e.\u0275prov=de({token:e,factory:e.\u0275fac,providedIn:"root"}),e})();function Jl(e,t){const n=e.indexOf(t);n>-1&&e.splice(n,1)}let tm=!0,om=(()=>{class e{}return e.__NG_ELEMENT_ID__=B1,e})();function B1(e){return function H1(e,t,n){if(jo(e)&&!n){const r=Xe(e.index,t);return new ho(r,r)}return 47&e.type?new ho(t[16],t):null}(Me(),w(),16==(16&e))}class am{constructor(){}supports(t){return io(t)}create(t){return new q1(t)}}const G1=(e,t)=>t;class q1{constructor(t){this.length=0,this._linkedRecords=null,this._unlinkedRecords=null,this._previousItHead=null,this._itHead=null,this._itTail=null,this._additionsHead=null,this._additionsTail=null,this._movesHead=null,this._movesTail=null,this._removalsHead=null,this._removalsTail=null,this._identityChangesHead=null,this._identityChangesTail=null,this._trackByFn=t||G1}forEachItem(t){let n;for(n=this._itHead;null!==n;n=n._next)t(n)}forEachOperation(t){let n=this._itHead,r=this._removalsHead,o=0,i=null;for(;n||r;){const s=!r||n&&n.currentIndex<um(r,o,i)?n:r,a=um(s,o,i),l=s.currentIndex;if(s===r)o--,r=r._nextRemoved;else if(n=n._next,null==s.previousIndex)o++;else{i||(i=[]);const u=a-o,c=l-o;if(u!=c){for(let f=0;f<u;f++){const p=f<i.length?i[f]:i[f]=0,m=p+f;c<=m&&m<u&&(i[f]=p+1)}i[s.previousIndex]=c-u}}a!==l&&t(s,a,l)}}forEachPreviousItem(t){let n;for(n=this._previousItHead;null!==n;n=n._nextPrevious)t(n)}forEachAddedItem(t){let n;for(n=this._additionsHead;null!==n;n=n._nextAdded)t(n)}forEachMovedItem(t){let n;for(n=this._movesHead;null!==n;n=n._nextMoved)t(n)}forEachRemovedItem(t){let n;for(n=this._removalsHead;null!==n;n=n._nextRemoved)t(n)}forEachIdentityChange(t){let n;for(n=this._identityChangesHead;null!==n;n=n._nextIdentityChange)t(n)}diff(t){if(null==t&&(t=[]),!io(t))throw new Y(900,"");return this.check(t)?this:null}onDestroy(){}check(t){this._reset();let o,i,s,n=this._itHead,r=!1;if(Array.isArray(t)){this.length=t.length;for(let a=0;a<this.length;a++)i=t[a],s=this._trackByFn(a,i),null!==n&&Object.is(n.trackById,s)?(r&&(n=this._verifyReinsertion(n,i,s,a)),Object.is(n.item,i)||this._addIdentityChange(n,i)):(n=this._mismatch(n,i,s,a),r=!0),n=n._next}else o=0,function Ww(e,t){if(Array.isArray(e))for(let n=0;n<e.length;n++)t(e[n]);else{const n=e[dr()]();let r;for(;!(r=n.next()).done;)t(r.value)}}(t,a=>{s=this._trackByFn(o,a),null!==n&&Object.is(n.trackById,s)?(r&&(n=this._verifyReinsertion(n,a,s,o)),Object.is(n.item,a)||this._addIdentityChange(n,a)):(n=this._mismatch(n,a,s,o),r=!0),n=n._next,o++}),this.length=o;return this._truncate(n),this.collection=t,this.isDirty}get isDirty(){return null!==this._additionsHead||null!==this._movesHead||null!==this._removalsHead||null!==this._identityChangesHead}_reset(){if(this.isDirty){let t;for(t=this._previousItHead=this._itHead;null!==t;t=t._next)t._nextPrevious=t._next;for(t=this._additionsHead;null!==t;t=t._nextAdded)t.previousIndex=t.currentIndex;for(this._additionsHead=this._additionsTail=null,t=this._movesHead;null!==t;t=t._nextMoved)t.previousIndex=t.currentIndex;this._movesHead=this._movesTail=null,this._removalsHead=this._removalsTail=null,this._identityChangesHead=this._identityChangesTail=null}}_mismatch(t,n,r,o){let i;return null===t?i=this._itTail:(i=t._prev,this._remove(t)),null!==(t=null===this._unlinkedRecords?null:this._unlinkedRecords.get(r,null))?(Object.is(t.item,n)||this._addIdentityChange(t,n),this._reinsertAfter(t,i,o)):null!==(t=null===this._linkedRecords?null:this._linkedRecords.get(r,o))?(Object.is(t.item,n)||this._addIdentityChange(t,n),this._moveAfter(t,i,o)):t=this._addAfter(new W1(n,r),i,o),t}_verifyReinsertion(t,n,r,o){let i=null===this._unlinkedRecords?null:this._unlinkedRecords.get(r,null);return null!==i?t=this._reinsertAfter(i,t._prev,o):t.currentIndex!=o&&(t.currentIndex=o,this._addToMoves(t,o)),t}_truncate(t){for(;null!==t;){const n=t._next;this._addToRemovals(this._unlink(t)),t=n}null!==this._unlinkedRecords&&this._unlinkedRecords.clear(),null!==this._additionsTail&&(this._additionsTail._nextAdded=null),null!==this._movesTail&&(this._movesTail._nextMoved=null),null!==this._itTail&&(this._itTail._next=null),null!==this._removalsTail&&(this._removalsTail._nextRemoved=null),null!==this._identityChangesTail&&(this._identityChangesTail._nextIdentityChange=null)}_reinsertAfter(t,n,r){null!==this._unlinkedRecords&&this._unlinkedRecords.remove(t);const o=t._prevRemoved,i=t._nextRemoved;return null===o?this._removalsHead=i:o._nextRemoved=i,null===i?this._removalsTail=o:i._prevRemoved=o,this._insertAfter(t,n,r),this._addToMoves(t,r),t}_moveAfter(t,n,r){return this._unlink(t),this._insertAfter(t,n,r),this._addToMoves(t,r),t}_addAfter(t,n,r){return this._insertAfter(t,n,r),this._additionsTail=null===this._additionsTail?this._additionsHead=t:this._additionsTail._nextAdded=t,t}_insertAfter(t,n,r){const o=null===n?this._itHead:n._next;return t._next=o,t._prev=n,null===o?this._itTail=t:o._prev=t,null===n?this._itHead=t:n._next=t,null===this._linkedRecords&&(this._linkedRecords=new lm),this._linkedRecords.put(t),t.currentIndex=r,t}_remove(t){return this._addToRemovals(this._unlink(t))}_unlink(t){null!==this._linkedRecords&&this._linkedRecords.remove(t);const n=t._prev,r=t._next;return null===n?this._itHead=r:n._next=r,null===r?this._itTail=n:r._prev=n,t}_addToMoves(t,n){return t.previousIndex===n||(this._movesTail=null===this._movesTail?this._movesHead=t:this._movesTail._nextMoved=t),t}_addToRemovals(t){return null===this._unlinkedRecords&&(this._unlinkedRecords=new lm),this._unlinkedRecords.put(t),t.currentIndex=null,t._nextRemoved=null,null===this._removalsTail?(this._removalsTail=this._removalsHead=t,t._prevRemoved=null):(t._prevRemoved=this._removalsTail,this._removalsTail=this._removalsTail._nextRemoved=t),t}_addIdentityChange(t,n){return t.item=n,this._identityChangesTail=null===this._identityChangesTail?this._identityChangesHead=t:this._identityChangesTail._nextIdentityChange=t,t}}class W1{constructor(t,n){this.item=t,this.trackById=n,this.currentIndex=null,this.previousIndex=null,this._nextPrevious=null,this._prev=null,this._next=null,this._prevDup=null,this._nextDup=null,this._prevRemoved=null,this._nextRemoved=null,this._nextAdded=null,this._nextMoved=null,this._nextIdentityChange=null}}class Q1{constructor(){this._head=null,this._tail=null}add(t){null===this._head?(this._head=this._tail=t,t._nextDup=null,t._prevDup=null):(this._tail._nextDup=t,t._prevDup=this._tail,t._nextDup=null,this._tail=t)}get(t,n){let r;for(r=this._head;null!==r;r=r._nextDup)if((null===n||n<=r.currentIndex)&&Object.is(r.trackById,t))return r;return null}remove(t){const n=t._prevDup,r=t._nextDup;return null===n?this._head=r:n._nextDup=r,null===r?this._tail=n:r._prevDup=n,null===this._head}}class lm{constructor(){this.map=new Map}put(t){const n=t.trackById;let r=this.map.get(n);r||(r=new Q1,this.map.set(n,r)),r.add(t)}get(t,n){const o=this.map.get(t);return o?o.get(t,n):null}remove(t){const n=t.trackById;return this.map.get(n).remove(t)&&this.map.delete(n),t}get isEmpty(){return 0===this.map.size}clear(){this.map.clear()}}function um(e,t,n){const r=e.previousIndex;if(null===r)return r;let o=0;return n&&r<n.length&&(o=n[r]),r+t+o}class cm{constructor(){}supports(t){return t instanceof Map||fl(t)}create(){return new Z1}}class Z1{constructor(){this._records=new Map,this._mapHead=null,this._appendAfter=null,this._previousMapHead=null,this._changesHead=null,this._changesTail=null,this._additionsHead=null,this._additionsTail=null,this._removalsHead=null,this._removalsTail=null}get isDirty(){return null!==this._additionsHead||null!==this._changesHead||null!==this._removalsHead}forEachItem(t){let n;for(n=this._mapHead;null!==n;n=n._next)t(n)}forEachPreviousItem(t){let n;for(n=this._previousMapHead;null!==n;n=n._nextPrevious)t(n)}forEachChangedItem(t){let n;for(n=this._changesHead;null!==n;n=n._nextChanged)t(n)}forEachAddedItem(t){let n;for(n=this._additionsHead;null!==n;n=n._nextAdded)t(n)}forEachRemovedItem(t){let n;for(n=this._removalsHead;null!==n;n=n._nextRemoved)t(n)}diff(t){if(t){if(!(t instanceof Map||fl(t)))throw new Y(900,"")}else t=new Map;return this.check(t)?this:null}onDestroy(){}check(t){this._reset();let n=this._mapHead;if(this._appendAfter=null,this._forEach(t,(r,o)=>{if(n&&n.key===o)this._maybeAddToChanges(n,r),this._appendAfter=n,n=n._next;else{const i=this._getOrCreateRecordForKey(o,r);n=this._insertBeforeOrAppend(n,i)}}),n){n._prev&&(n._prev._next=null),this._removalsHead=n;for(let r=n;null!==r;r=r._nextRemoved)r===this._mapHead&&(this._mapHead=null),this._records.delete(r.key),r._nextRemoved=r._next,r.previousValue=r.currentValue,r.currentValue=null,r._prev=null,r._next=null}return this._changesTail&&(this._changesTail._nextChanged=null),this._additionsTail&&(this._additionsTail._nextAdded=null),this.isDirty}_insertBeforeOrAppend(t,n){if(t){const r=t._prev;return n._next=t,n._prev=r,t._prev=n,r&&(r._next=n),t===this._mapHead&&(this._mapHead=n),this._appendAfter=t,t}return this._appendAfter?(this._appendAfter._next=n,n._prev=this._appendAfter):this._mapHead=n,this._appendAfter=n,null}_getOrCreateRecordForKey(t,n){if(this._records.has(t)){const o=this._records.get(t);this._maybeAddToChanges(o,n);const i=o._prev,s=o._next;return i&&(i._next=s),s&&(s._prev=i),o._next=null,o._prev=null,o}const r=new Y1(t);return this._records.set(t,r),r.currentValue=n,this._addToAdditions(r),r}_reset(){if(this.isDirty){let t;for(this._previousMapHead=this._mapHead,t=this._previousMapHead;null!==t;t=t._next)t._nextPrevious=t._next;for(t=this._changesHead;null!==t;t=t._nextChanged)t.previousValue=t.currentValue;for(t=this._additionsHead;null!=t;t=t._nextAdded)t.previousValue=t.currentValue;this._changesHead=this._changesTail=null,this._additionsHead=this._additionsTail=null,this._removalsHead=null}}_maybeAddToChanges(t,n){Object.is(n,t.currentValue)||(t.previousValue=t.currentValue,t.currentValue=n,this._addToChanges(t))}_addToAdditions(t){null===this._additionsHead?this._additionsHead=this._additionsTail=t:(this._additionsTail._nextAdded=t,this._additionsTail=t)}_addToChanges(t){null===this._changesHead?this._changesHead=this._changesTail=t:(this._changesTail._nextChanged=t,this._changesTail=t)}_forEach(t,n){t instanceof Map?t.forEach(n):Object.keys(t).forEach(r=>n(t[r],r))}}class Y1{constructor(t){this.key=t,this.previousValue=null,this.currentValue=null,this._nextPrevious=null,this._next=null,this._prev=null,this._nextAdded=null,this._nextRemoved=null,this._nextChanged=null}}function dm(){return new Ui([new am])}let Ui=(()=>{class e{constructor(n){this.factories=n}static create(n,r){if(null!=r){const o=r.factories.slice();n=n.concat(o)}return new e(n)}static extend(n){return{provide:e,useFactory:r=>e.create(n,r||dm()),deps:[[e,new ai,new si]]}}find(n){const r=this.factories.find(o=>o.supports(n));if(null!=r)return r;throw new Y(901,"")}}return e.\u0275prov=de({token:e,providedIn:"root",factory:dm}),e})();function fm(){return new vo([new cm])}let vo=(()=>{class e{constructor(n){this.factories=n}static create(n,r){if(r){const o=r.factories.slice();n=n.concat(o)}return new e(n)}static extend(n){return{provide:e,useFactory:r=>e.create(n,r||fm()),deps:[[e,new ai,new si]]}}find(n){const r=this.factories.find(i=>i.supports(n));if(r)return r;throw new Y(901,"")}}return e.\u0275prov=de({token:e,providedIn:"root",factory:fm}),e})();const X1=Zg(null,"core",[{provide:ql,useValue:"unknown"},{provide:Kg,deps:[ct]},{provide:Wg,deps:[]},{provide:v1,deps:[]}]);let eM=(()=>{class e{constructor(n){}}return e.\u0275fac=function(n){return new(n||e)(oe(Xg))},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({}),e})(),zi=null;function On(){return zi}const $t=new J("DocumentToken");let Do=(()=>{class e{constructor(n,r,o,i){this._iterableDiffers=n,this._keyValueDiffers=r,this._ngEl=o,this._renderer=i,this._iterableDiffer=null,this._keyValueDiffer=null,this._initialClasses=[],this._rawClass=null}set klass(n){this._removeClasses(this._initialClasses),this._initialClasses="string"==typeof n?n.split(/\s+/):[],this._applyClasses(this._initialClasses),this._applyClasses(this._rawClass)}set ngClass(n){this._removeClasses(this._rawClass),this._applyClasses(this._initialClasses),this._iterableDiffer=null,this._keyValueDiffer=null,this._rawClass="string"==typeof n?n.split(/\s+/):n,this._rawClass&&(io(this._rawClass)?this._iterableDiffer=this._iterableDiffers.find(this._rawClass).create():this._keyValueDiffer=this._keyValueDiffers.find(this._rawClass).create())}ngDoCheck(){if(this._iterableDiffer){const n=this._iterableDiffer.diff(this._rawClass);n&&this._applyIterableChanges(n)}else if(this._keyValueDiffer){const n=this._keyValueDiffer.diff(this._rawClass);n&&this._applyKeyValueChanges(n)}}_applyKeyValueChanges(n){n.forEachAddedItem(r=>this._toggleClass(r.key,r.currentValue)),n.forEachChangedItem(r=>this._toggleClass(r.key,r.currentValue)),n.forEachRemovedItem(r=>{r.previousValue&&this._toggleClass(r.key,!1)})}_applyIterableChanges(n){n.forEachAddedItem(r=>{if("string"!=typeof r.item)throw new Error(`NgClass can only toggle CSS classes expressed as strings, got ${te(r.item)}`);this._toggleClass(r.item,!0)}),n.forEachRemovedItem(r=>this._toggleClass(r.item,!1))}_applyClasses(n){n&&(Array.isArray(n)||n instanceof Set?n.forEach(r=>this._toggleClass(r,!0)):Object.keys(n).forEach(r=>this._toggleClass(r,!!n[r])))}_removeClasses(n){n&&(Array.isArray(n)||n instanceof Set?n.forEach(r=>this._toggleClass(r,!1)):Object.keys(n).forEach(r=>this._toggleClass(r,!1)))}_toggleClass(n,r){(n=n.trim())&&n.split(/\s+/g).forEach(o=>{r?this._renderer.addClass(this._ngEl.nativeElement,o):this._renderer.removeClass(this._ngEl.nativeElement,o)})}}return e.\u0275fac=function(n){return new(n||e)(A(Ui),A(vo),A(Et),A(Nn))},e.\u0275dir=k({type:e,selectors:[["","ngClass",""]],inputs:{klass:["class","klass"],ngClass:"ngClass"}}),e})();class GM{constructor(t,n,r,o){this.$implicit=t,this.ngForOf=n,this.index=r,this.count=o}get first(){return 0===this.index}get last(){return this.index===this.count-1}get even(){return this.index%2==0}get odd(){return!this.even}}let fu=(()=>{class e{constructor(n,r,o){this._viewContainer=n,this._template=r,this._differs=o,this._ngForOf=null,this._ngForOfDirty=!0,this._differ=null}set ngForOf(n){this._ngForOf=n,this._ngForOfDirty=!0}set ngForTrackBy(n){this._trackByFn=n}get ngForTrackBy(){return this._trackByFn}set ngForTemplate(n){n&&(this._template=n)}ngDoCheck(){if(this._ngForOfDirty){this._ngForOfDirty=!1;const n=this._ngForOf;!this._differ&&n&&(this._differ=this._differs.find(n).create(this.ngForTrackBy))}if(this._differ){const n=this._differ.diff(this._ngForOf);n&&this._applyChanges(n)}}_applyChanges(n){const r=this._viewContainer;n.forEachOperation((o,i,s)=>{if(null==o.previousIndex)r.createEmbeddedView(this._template,new GM(o.item,this._ngForOf,-1,-1),null===s?void 0:s);else if(null==s)r.remove(null===i?void 0:i);else if(null!==i){const a=r.get(i);r.move(a,s),bm(a,o)}});for(let o=0,i=r.length;o<i;o++){const a=r.get(o).context;a.index=o,a.count=i,a.ngForOf=this._ngForOf}n.forEachIdentityChange(o=>{bm(r.get(o.currentIndex),o)})}static ngTemplateContextGuard(n,r){return!0}}return e.\u0275fac=function(n){return new(n||e)(A(jt),A(Jt),A(Ui))},e.\u0275dir=k({type:e,selectors:[["","ngFor","","ngForOf",""]],inputs:{ngForOf:"ngForOf",ngForTrackBy:"ngForTrackBy",ngForTemplate:"ngForTemplate"}}),e})();function bm(e,t){e.context.$implicit=t.item}let xr=(()=>{class e{constructor(n,r){this._viewContainer=n,this._context=new qM,this._thenTemplateRef=null,this._elseTemplateRef=null,this._thenViewRef=null,this._elseViewRef=null,this._thenTemplateRef=r}set ngIf(n){this._context.$implicit=this._context.ngIf=n,this._updateView()}set ngIfThen(n){Em("ngIfThen",n),this._thenTemplateRef=n,this._thenViewRef=null,this._updateView()}set ngIfElse(n){Em("ngIfElse",n),this._elseTemplateRef=n,this._elseViewRef=null,this._updateView()}_updateView(){this._context.$implicit?this._thenViewRef||(this._viewContainer.clear(),this._elseViewRef=null,this._thenTemplateRef&&(this._thenViewRef=this._viewContainer.createEmbeddedView(this._thenTemplateRef,this._context))):this._elseViewRef||(this._viewContainer.clear(),this._thenViewRef=null,this._elseTemplateRef&&(this._elseViewRef=this._viewContainer.createEmbeddedView(this._elseTemplateRef,this._context)))}static ngTemplateContextGuard(n,r){return!0}}return e.\u0275fac=function(n){return new(n||e)(A(jt),A(Jt))},e.\u0275dir=k({type:e,selectors:[["","ngIf",""]],inputs:{ngIf:"ngIf",ngIfThen:"ngIfThen",ngIfElse:"ngIfElse"}}),e})();class qM{constructor(){this.$implicit=null,this.ngIf=null}}function Em(e,t){if(t&&!t.createEmbeddedView)throw new Error(`${e} must be a TemplateRef, but received '${te(t)}'.`)}let Am=(()=>{class e{transform(n,r,o){if(null==n)return null;if(!this.supports(n))throw function At(e,t){return new Y(2100,"")}();return n.slice(r,o)}supports(n){return"string"==typeof n||Array.isArray(n)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275pipe=qe({name:"slice",type:e,pure:!1}),e})(),vI=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({}),e})();class _u extends class EI extends class rM{}{constructor(){super(...arguments),this.supportsDOMEvents=!0}}{static makeCurrent(){!function nM(e){zi||(zi=e)}(new _u)}onAndCancel(t,n,r){return t.addEventListener(n,r,!1),()=>{t.removeEventListener(n,r,!1)}}dispatchEvent(t,n){t.dispatchEvent(n)}remove(t){t.parentNode&&t.parentNode.removeChild(t)}createElement(t,n){return(n=n||this.getDefaultDocument()).createElement(t)}createHtmlDocument(){return document.implementation.createHTMLDocument("fakeTitle")}getDefaultDocument(){return document}isElementNode(t){return t.nodeType===Node.ELEMENT_NODE}isShadowRoot(t){return t instanceof DocumentFragment}getGlobalEventTarget(t,n){return"window"===n?window:"document"===n?t:"body"===n?t.body:null}getBaseHref(t){const n=function MI(){return wo=wo||document.querySelector("base"),wo?wo.getAttribute("href"):null}();return null==n?null:function II(e){es=es||document.createElement("a"),es.setAttribute("href",e);const t=es.pathname;return"/"===t.charAt(0)?t:`/${t}`}(n)}resetBaseElement(){wo=null}getUserAgent(){return window.navigator.userAgent}getCookie(t){return function UM(e,t){t=encodeURIComponent(t);for(const n of e.split(";")){const r=n.indexOf("="),[o,i]=-1==r?[n,""]:[n.slice(0,r),n.slice(r+1)];if(o.trim()===t)return decodeURIComponent(i)}return null}(document.cookie,t)}}let es,wo=null;const xm=new J("TRANSITION_ID"),TI=[{provide:$g,useFactory:function AI(e,t,n){return()=>{n.get(zl).donePromise.then(()=>{const r=On(),o=t.querySelectorAll(`style[ng-transition="${e}"]`);for(let i=0;i<o.length;i++)r.remove(o[i])})}},deps:[xm,$t,ct],multi:!0}];class vu{static init(){!function x1(e){Kl=e}(new vu)}addToWindow(t){re.getAngularTestability=(r,o=!0)=>{const i=t.findTestabilityInTree(r,o);if(null==i)throw new Error("Could not find testability for element.");return i},re.getAllAngularTestabilities=()=>t.getAllTestabilities(),re.getAllAngularRootElements=()=>t.getAllRootElements(),re.frameworkStabilizers||(re.frameworkStabilizers=[]),re.frameworkStabilizers.push(r=>{const o=re.getAllAngularTestabilities();let i=o.length,s=!1;const a=function(l){s=s||l,i--,0==i&&r(s)};o.forEach(function(l){l.whenStable(a)})})}findTestabilityInTree(t,n,r){if(null==n)return null;const o=t.getTestability(n);return null!=o?o:r?On().isShadowRoot(n)?this.findTestabilityInTree(t,n.host,!0):this.findTestabilityInTree(t,n.parentElement,!0):null}}let SI=(()=>{class e{build(){return new XMLHttpRequest}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const ts=new J("EventManagerPlugins");let ns=(()=>{class e{constructor(n,r){this._zone=r,this._eventNameToPlugin=new Map,n.forEach(o=>o.manager=this),this._plugins=n.slice().reverse()}addEventListener(n,r,o){return this._findPluginFor(r).addEventListener(n,r,o)}addGlobalEventListener(n,r,o){return this._findPluginFor(r).addGlobalEventListener(n,r,o)}getZone(){return this._zone}_findPluginFor(n){const r=this._eventNameToPlugin.get(n);if(r)return r;const o=this._plugins;for(let i=0;i<o.length;i++){const s=o[i];if(s.supports(n))return this._eventNameToPlugin.set(n,s),s}throw new Error(`No event manager plugin found for event ${n}`)}}return e.\u0275fac=function(n){return new(n||e)(oe(ts),oe(Qe))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();class Nm{constructor(t){this._doc=t}addGlobalEventListener(t,n,r){const o=On().getGlobalEventTarget(this._doc,t);if(!o)throw new Error(`Unsupported event target ${o} for event ${n}`);return this.addEventListener(o,n,r)}}let Fm=(()=>{class e{constructor(){this._stylesSet=new Set}addStyles(n){const r=new Set;n.forEach(o=>{this._stylesSet.has(o)||(this._stylesSet.add(o),r.add(o))}),this.onStylesAdded(r)}onStylesAdded(n){}getAllStyles(){return Array.from(this._stylesSet)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})(),bo=(()=>{class e extends Fm{constructor(n){super(),this._doc=n,this._hostNodes=new Map,this._hostNodes.set(n.head,[])}_addStylesToHost(n,r,o){n.forEach(i=>{const s=this._doc.createElement("style");s.textContent=i,o.push(r.appendChild(s))})}addHost(n){const r=[];this._addStylesToHost(this._stylesSet,n,r),this._hostNodes.set(n,r)}removeHost(n){const r=this._hostNodes.get(n);r&&r.forEach(Om),this._hostNodes.delete(n)}onStylesAdded(n){this._hostNodes.forEach((r,o)=>{this._addStylesToHost(n,o,r)})}ngOnDestroy(){this._hostNodes.forEach(n=>n.forEach(Om))}}return e.\u0275fac=function(n){return new(n||e)(oe($t))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();function Om(e){On().remove(e)}const yu={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/",math:"http://www.w3.org/1998/MathML/"},Cu=/%COMP%/g;function rs(e,t,n){for(let r=0;r<t.length;r++){let o=t[r];Array.isArray(o)?rs(e,o,n):(o=o.replace(Cu,e),n.push(o))}return n}function Vm(e){return t=>{if("__ngUnwrap__"===t)return e;!1===e(t)&&(t.preventDefault(),t.returnValue=!1)}}let Du=(()=>{class e{constructor(n,r,o){this.eventManager=n,this.sharedStylesHost=r,this.appId=o,this.rendererByCompId=new Map,this.defaultRenderer=new wu(n)}createRenderer(n,r){if(!n||!r)return this.defaultRenderer;switch(r.encapsulation){case St.Emulated:{let o=this.rendererByCompId.get(r.id);return o||(o=new PI(this.eventManager,this.sharedStylesHost,r,this.appId),this.rendererByCompId.set(r.id,o)),o.applyToHost(n),o}case 1:case St.ShadowDom:return new VI(this.eventManager,this.sharedStylesHost,n,r);default:if(!this.rendererByCompId.has(r.id)){const o=rs(r.id,r.styles,[]);this.sharedStylesHost.addStyles(o),this.rendererByCompId.set(r.id,this.defaultRenderer)}return this.defaultRenderer}}begin(){}end(){}}return e.\u0275fac=function(n){return new(n||e)(oe(ns),oe(bo),oe(_o))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();class wu{constructor(t){this.eventManager=t,this.data=Object.create(null),this.destroyNode=null}destroy(){}createElement(t,n){return n?document.createElementNS(yu[n]||n,t):document.createElement(t)}createComment(t){return document.createComment(t)}createText(t){return document.createTextNode(t)}appendChild(t,n){t.appendChild(n)}insertBefore(t,n,r){t&&t.insertBefore(n,r)}removeChild(t,n){t&&t.removeChild(n)}selectRootElement(t,n){let r="string"==typeof t?document.querySelector(t):t;if(!r)throw new Error(`The selector "${t}" did not match any elements`);return n||(r.textContent=""),r}parentNode(t){return t.parentNode}nextSibling(t){return t.nextSibling}setAttribute(t,n,r,o){if(o){n=o+":"+n;const i=yu[o];i?t.setAttributeNS(i,n,r):t.setAttribute(n,r)}else t.setAttribute(n,r)}removeAttribute(t,n,r){if(r){const o=yu[r];o?t.removeAttributeNS(o,n):t.removeAttribute(`${r}:${n}`)}else t.removeAttribute(n)}addClass(t,n){t.classList.add(n)}removeClass(t,n){t.classList.remove(n)}setStyle(t,n,r,o){o&(tt.DashCase|tt.Important)?t.style.setProperty(n,r,o&tt.Important?"important":""):t.style[n]=r}removeStyle(t,n,r){r&tt.DashCase?t.style.removeProperty(n):t.style[n]=""}setProperty(t,n,r){t[n]=r}setValue(t,n){t.nodeValue=n}listen(t,n,r){return"string"==typeof t?this.eventManager.addGlobalEventListener(t,n,Vm(r)):this.eventManager.addEventListener(t,n,Vm(r))}}class PI extends wu{constructor(t,n,r,o){super(t),this.component=r;const i=rs(o+"-"+r.id,r.styles,[]);n.addStyles(i),this.contentAttr=function FI(e){return"_ngcontent-%COMP%".replace(Cu,e)}(o+"-"+r.id),this.hostAttr=function OI(e){return"_nghost-%COMP%".replace(Cu,e)}(o+"-"+r.id)}applyToHost(t){super.setAttribute(t,this.hostAttr,"")}createElement(t,n){const r=super.createElement(t,n);return super.setAttribute(r,this.contentAttr,""),r}}class VI extends wu{constructor(t,n,r,o){super(t),this.sharedStylesHost=n,this.hostEl=r,this.shadowRoot=r.attachShadow({mode:"open"}),this.sharedStylesHost.addHost(this.shadowRoot);const i=rs(o.id,o.styles,[]);for(let s=0;s<i.length;s++){const a=document.createElement("style");a.textContent=i[s],this.shadowRoot.appendChild(a)}}nodeOrShadowRoot(t){return t===this.hostEl?this.shadowRoot:t}destroy(){this.sharedStylesHost.removeHost(this.shadowRoot)}appendChild(t,n){return super.appendChild(this.nodeOrShadowRoot(t),n)}insertBefore(t,n,r){return super.insertBefore(this.nodeOrShadowRoot(t),n,r)}removeChild(t,n){return super.removeChild(this.nodeOrShadowRoot(t),n)}parentNode(t){return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(t)))}}let kI=(()=>{class e extends Nm{constructor(n){super(n)}supports(n){return!0}addEventListener(n,r,o){return n.addEventListener(r,o,!1),()=>this.removeEventListener(n,r,o)}removeEventListener(n,r,o){return n.removeEventListener(r,o)}}return e.\u0275fac=function(n){return new(n||e)(oe($t))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const Lm=["alt","control","meta","shift"],BI={"\b":"Backspace","\t":"Tab","\x7f":"Delete","\x1b":"Escape",Del:"Delete",Esc:"Escape",Left:"ArrowLeft",Right:"ArrowRight",Up:"ArrowUp",Down:"ArrowDown",Menu:"ContextMenu",Scroll:"ScrollLock",Win:"OS"},Bm={A:"1",B:"2",C:"3",D:"4",E:"5",F:"6",G:"7",H:"8",I:"9",J:"*",K:"+",M:"-",N:".",O:"/","`":"0","\x90":"NumLock"},HI={alt:e=>e.altKey,control:e=>e.ctrlKey,meta:e=>e.metaKey,shift:e=>e.shiftKey};let jI=(()=>{class e extends Nm{constructor(n){super(n)}supports(n){return null!=e.parseEventName(n)}addEventListener(n,r,o){const i=e.parseEventName(r),s=e.eventCallback(i.fullKey,o,this.manager.getZone());return this.manager.getZone().runOutsideAngular(()=>On().onAndCancel(n,i.domEventName,s))}static parseEventName(n){const r=n.toLowerCase().split("."),o=r.shift();if(0===r.length||"keydown"!==o&&"keyup"!==o)return null;const i=e._normalizeKey(r.pop());let s="";if(Lm.forEach(l=>{const u=r.indexOf(l);u>-1&&(r.splice(u,1),s+=l+".")}),s+=i,0!=r.length||0===i.length)return null;const a={};return a.domEventName=o,a.fullKey=s,a}static getEventFullKey(n){let r="",o=function $I(e){let t=e.key;if(null==t){if(t=e.keyIdentifier,null==t)return"Unidentified";t.startsWith("U+")&&(t=String.fromCharCode(parseInt(t.substring(2),16)),3===e.location&&Bm.hasOwnProperty(t)&&(t=Bm[t]))}return BI[t]||t}(n);return o=o.toLowerCase()," "===o?o="space":"."===o&&(o="dot"),Lm.forEach(i=>{i!=o&&HI[i](n)&&(r+=i+".")}),r+=o,r}static eventCallback(n,r,o){return i=>{e.getEventFullKey(i)===n&&o.runGuarded(()=>r(i))}}static _normalizeKey(n){return"esc"===n?"escape":n}}return e.\u0275fac=function(n){return new(n||e)(oe($t))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const qI=Zg(X1,"browser",[{provide:ql,useValue:"browser"},{provide:zg,useValue:function UI(){_u.makeCurrent(),vu.init()},multi:!0},{provide:$t,useFactory:function GI(){return function ay(e){Us=e}(document),document},deps:[]}]),WI=[{provide:sl,useValue:"root"},{provide:Xr,useFactory:function zI(){return new Xr},deps:[]},{provide:ts,useClass:kI,multi:!0,deps:[$t,Qe,ql]},{provide:ts,useClass:jI,multi:!0,deps:[$t]},{provide:Du,useClass:Du,deps:[ns,bo,_o]},{provide:ig,useExisting:Du},{provide:Fm,useExisting:bo},{provide:bo,useClass:bo,deps:[$t]},{provide:Yl,useClass:Yl,deps:[Qe]},{provide:ns,useClass:ns,deps:[ts,Qe]},{provide:class bI{},useClass:SI,deps:[]}];let QI=(()=>{class e{constructor(n){if(n)throw new Error("BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.")}static withServerTransition(n){return{ngModule:e,providers:[{provide:_o,useValue:n.appId},{provide:xm,useExisting:_o},TI]}}}return e.\u0275fac=function(n){return new(n||e)(oe(e,12))},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({providers:WI,imports:[vI,eM]}),e})();"undefined"!=typeof window&&window;const{isArray:iA}=Array,{getPrototypeOf:sA,prototype:aA,keys:lA}=Object;const{isArray:dA}=Array;function pA(e,t){return e.reduce((n,r,o)=>(n[r]=t[o],n),{})}function gA(...e){const t=function Cv(e){return pe(Ms(e))?e.pop():void 0}(e),{args:n,keys:r}=function uA(e){if(1===e.length){const t=e[0];if(iA(t))return{args:t,keys:null};if(function cA(e){return e&&"object"==typeof e&&sA(e)===aA}(t)){const n=lA(t);return{args:n.map(r=>t[r]),keys:n}}}return{args:e,keys:null}}(e),o=new Le(i=>{const{length:s}=n;if(!s)return void i.complete();const a=new Array(s);let l=s,u=s;for(let c=0;c<s;c++){let d=!1;wn(n[c]).subscribe(new Bn(i,f=>{d||(d=!0,u--),a[c]=f},()=>l--,void 0,()=>{(!l||!d)&&(u||i.next(r?pA(r,a):a),i.complete())}))}});return t?o.pipe(function hA(e){return ws(t=>function fA(e,t){return dA(t)?e(...t):e(t)}(e,t))}(t)):o}let $m=(()=>{class e{constructor(n,r){this._renderer=n,this._elementRef=r,this.onChange=o=>{},this.onTouched=()=>{}}setProperty(n,r){this._renderer.setProperty(this._elementRef.nativeElement,n,r)}registerOnTouched(n){this.onTouched=n}registerOnChange(n){this.onChange=n}setDisabledState(n){this.setProperty("disabled",n)}}return e.\u0275fac=function(n){return new(n||e)(A(Nn),A(Et))},e.\u0275dir=k({type:e}),e})(),Rn=(()=>{class e extends $m{}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,features:[ne]}),e})();const Ut=new J("NgValueAccessor"),_A={provide:Ut,useExisting:ae(()=>Eo),multi:!0},yA=new J("CompositionEventMode");let Eo=(()=>{class e extends $m{constructor(n,r,o){super(n,r),this._compositionMode=o,this._composing=!1,null==this._compositionMode&&(this._compositionMode=!function vA(){const e=On()?On().getUserAgent():"";return/android (\d+)/.test(e.toLowerCase())}())}writeValue(n){this.setProperty("value",null==n?"":n)}_handleInput(n){(!this._compositionMode||this._compositionMode&&!this._composing)&&this.onChange(n)}_compositionStart(){this._composing=!0}_compositionEnd(n){this._composing=!1,this._compositionMode&&this.onChange(n)}}return e.\u0275fac=function(n){return new(n||e)(A(Nn),A(Et),A(yA,8))},e.\u0275dir=k({type:e,selectors:[["input","formControlName","",3,"type","checkbox"],["textarea","formControlName",""],["input","formControl","",3,"type","checkbox"],["textarea","formControl",""],["input","ngModel","",3,"type","checkbox"],["textarea","ngModel",""],["","ngDefaultControl",""]],hostBindings:function(n,r){1&n&&z("input",function(i){return r._handleInput(i.target.value)})("blur",function(){return r.onTouched()})("compositionstart",function(){return r._compositionStart()})("compositionend",function(i){return r._compositionEnd(i.target.value)})},features:[he([_A]),ne]}),e})();const ke=new J("NgValidators"),mn=new J("NgAsyncValidators");function Xm(e){return null!=e}function e_(e){const t=Mi(e)?Is(e):e;return Bh(t),t}function t_(e){let t={};return e.forEach(n=>{t=null!=n?Object.assign(Object.assign({},t),n):t}),0===Object.keys(t).length?null:t}function n_(e,t){return t.map(n=>n(e))}function r_(e){return e.map(t=>function DA(e){return!e.validate}(t)?t:n=>t.validate(n))}function Eu(e){return null!=e?function o_(e){if(!e)return null;const t=e.filter(Xm);return 0==t.length?null:function(n){return t_(n_(n,t))}}(r_(e)):null}function Mu(e){return null!=e?function i_(e){if(!e)return null;const t=e.filter(Xm);return 0==t.length?null:function(n){return gA(n_(n,t).map(e_)).pipe(ws(t_))}}(r_(e)):null}function s_(e,t){return null===e?[t]:Array.isArray(e)?[...e,t]:[e,t]}function Iu(e){return e?Array.isArray(e)?e:[e]:[]}function is(e,t){return Array.isArray(e)?e.includes(t):e===t}function u_(e,t){const n=Iu(t);return Iu(e).forEach(o=>{is(n,o)||n.push(o)}),n}function c_(e,t){return Iu(t).filter(n=>!is(e,n))}class d_{constructor(){this._rawValidators=[],this._rawAsyncValidators=[],this._onDestroyCallbacks=[]}get value(){return this.control?this.control.value:null}get valid(){return this.control?this.control.valid:null}get invalid(){return this.control?this.control.invalid:null}get pending(){return this.control?this.control.pending:null}get disabled(){return this.control?this.control.disabled:null}get enabled(){return this.control?this.control.enabled:null}get errors(){return this.control?this.control.errors:null}get pristine(){return this.control?this.control.pristine:null}get dirty(){return this.control?this.control.dirty:null}get touched(){return this.control?this.control.touched:null}get status(){return this.control?this.control.status:null}get untouched(){return this.control?this.control.untouched:null}get statusChanges(){return this.control?this.control.statusChanges:null}get valueChanges(){return this.control?this.control.valueChanges:null}get path(){return null}_setValidators(t){this._rawValidators=t||[],this._composedValidatorFn=Eu(this._rawValidators)}_setAsyncValidators(t){this._rawAsyncValidators=t||[],this._composedAsyncValidatorFn=Mu(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn||null}get asyncValidator(){return this._composedAsyncValidatorFn||null}_registerOnDestroy(t){this._onDestroyCallbacks.push(t)}_invokeOnDestroyCallbacks(){this._onDestroyCallbacks.forEach(t=>t()),this._onDestroyCallbacks=[]}reset(t){this.control&&this.control.reset(t)}hasError(t,n){return!!this.control&&this.control.hasError(t,n)}getError(t,n){return this.control?this.control.getError(t,n):null}}class _n extends d_{constructor(){super(...arguments),this._parent=null,this.name=null,this.valueAccessor=null}}class Ge extends d_{get formDirective(){return null}get path(){return null}}let Au=(()=>{class e extends class f_{constructor(t){this._cd=t}is(t){var n,r,o;return"submitted"===t?!!(null===(n=this._cd)||void 0===n?void 0:n.submitted):!!(null===(o=null===(r=this._cd)||void 0===r?void 0:r.control)||void 0===o?void 0:o[t])}}{constructor(n){super(n)}}return e.\u0275fac=function(n){return new(n||e)(A(_n,2))},e.\u0275dir=k({type:e,selectors:[["","formControlName",""],["","ngModel",""],["","formControl",""]],hostVars:14,hostBindings:function(n,r){2&n&&Ii("ng-untouched",r.is("untouched"))("ng-touched",r.is("touched"))("ng-pristine",r.is("pristine"))("ng-dirty",r.is("dirty"))("ng-valid",r.is("valid"))("ng-invalid",r.is("invalid"))("ng-pending",r.is("pending"))},features:[ne]}),e})();function Mo(e,t){(function xu(e,t){const n=function a_(e){return e._rawValidators}(e);null!==t.validator?e.setValidators(s_(n,t.validator)):"function"==typeof n&&e.setValidators([n]);const r=function l_(e){return e._rawAsyncValidators}(e);null!==t.asyncValidator?e.setAsyncValidators(s_(r,t.asyncValidator)):"function"==typeof r&&e.setAsyncValidators([r]);const o=()=>e.updateValueAndValidity();us(t._rawValidators,o),us(t._rawAsyncValidators,o)})(e,t),t.valueAccessor.writeValue(e.value),function xA(e,t){t.valueAccessor.registerOnChange(n=>{e._pendingValue=n,e._pendingChange=!0,e._pendingDirty=!0,"change"===e.updateOn&&p_(e,t)})}(e,t),function FA(e,t){const n=(r,o)=>{t.valueAccessor.writeValue(r),o&&t.viewToModelUpdate(r)};e.registerOnChange(n),t._registerOnDestroy(()=>{e._unregisterOnChange(n)})}(e,t),function NA(e,t){t.valueAccessor.registerOnTouched(()=>{e._pendingTouched=!0,"blur"===e.updateOn&&e._pendingChange&&p_(e,t),"submit"!==e.updateOn&&e.markAsTouched()})}(e,t),function SA(e,t){if(t.valueAccessor.setDisabledState){const n=r=>{t.valueAccessor.setDisabledState(r)};e.registerOnDisabledChange(n),t._registerOnDestroy(()=>{e._unregisterOnDisabledChange(n)})}}(e,t)}function us(e,t){e.forEach(n=>{n.registerOnValidatorChange&&n.registerOnValidatorChange(t)})}function p_(e,t){e._pendingDirty&&e.markAsDirty(),e.setValue(e._pendingValue,{emitModelToViewChange:!1}),t.viewToModelUpdate(e._pendingValue),e._pendingChange=!1}function Ou(e,t){const n=e.indexOf(t);n>-1&&e.splice(n,1)}const Io="VALID",ds="INVALID",Nr="PENDING",Ao="DISABLED";function Pu(e){return(fs(e)?e.validators:e)||null}function v_(e){return Array.isArray(e)?Eu(e):e||null}function Vu(e,t){return(fs(t)?t.asyncValidators:e)||null}function y_(e){return Array.isArray(e)?Mu(e):e||null}function fs(e){return null!=e&&!Array.isArray(e)&&"object"==typeof e}const ku=e=>e instanceof Bu;function D_(e){return(e=>e instanceof E_)(e)?e.value:e.getRawValue()}function w_(e,t){const n=ku(e),r=e.controls;if(!(n?Object.keys(r):r).length)throw new Y(1e3,"");if(!r[t])throw new Y(1001,"")}function b_(e,t){ku(e),e._forEachChild((r,o)=>{if(void 0===t[o])throw new Y(1002,"")})}class Lu{constructor(t,n){this._pendingDirty=!1,this._hasOwnPendingAsyncValidator=!1,this._pendingTouched=!1,this._onCollectionChange=()=>{},this._parent=null,this.pristine=!0,this.touched=!1,this._onDisabledChange=[],this._rawValidators=t,this._rawAsyncValidators=n,this._composedValidatorFn=v_(this._rawValidators),this._composedAsyncValidatorFn=y_(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn}set validator(t){this._rawValidators=this._composedValidatorFn=t}get asyncValidator(){return this._composedAsyncValidatorFn}set asyncValidator(t){this._rawAsyncValidators=this._composedAsyncValidatorFn=t}get parent(){return this._parent}get valid(){return this.status===Io}get invalid(){return this.status===ds}get pending(){return this.status==Nr}get disabled(){return this.status===Ao}get enabled(){return this.status!==Ao}get dirty(){return!this.pristine}get untouched(){return!this.touched}get updateOn(){return this._updateOn?this._updateOn:this.parent?this.parent.updateOn:"change"}setValidators(t){this._rawValidators=t,this._composedValidatorFn=v_(t)}setAsyncValidators(t){this._rawAsyncValidators=t,this._composedAsyncValidatorFn=y_(t)}addValidators(t){this.setValidators(u_(t,this._rawValidators))}addAsyncValidators(t){this.setAsyncValidators(u_(t,this._rawAsyncValidators))}removeValidators(t){this.setValidators(c_(t,this._rawValidators))}removeAsyncValidators(t){this.setAsyncValidators(c_(t,this._rawAsyncValidators))}hasValidator(t){return is(this._rawValidators,t)}hasAsyncValidator(t){return is(this._rawAsyncValidators,t)}clearValidators(){this.validator=null}clearAsyncValidators(){this.asyncValidator=null}markAsTouched(t={}){this.touched=!0,this._parent&&!t.onlySelf&&this._parent.markAsTouched(t)}markAllAsTouched(){this.markAsTouched({onlySelf:!0}),this._forEachChild(t=>t.markAllAsTouched())}markAsUntouched(t={}){this.touched=!1,this._pendingTouched=!1,this._forEachChild(n=>{n.markAsUntouched({onlySelf:!0})}),this._parent&&!t.onlySelf&&this._parent._updateTouched(t)}markAsDirty(t={}){this.pristine=!1,this._parent&&!t.onlySelf&&this._parent.markAsDirty(t)}markAsPristine(t={}){this.pristine=!0,this._pendingDirty=!1,this._forEachChild(n=>{n.markAsPristine({onlySelf:!0})}),this._parent&&!t.onlySelf&&this._parent._updatePristine(t)}markAsPending(t={}){this.status=Nr,!1!==t.emitEvent&&this.statusChanges.emit(this.status),this._parent&&!t.onlySelf&&this._parent.markAsPending(t)}disable(t={}){const n=this._parentMarkedDirty(t.onlySelf);this.status=Ao,this.errors=null,this._forEachChild(r=>{r.disable(Object.assign(Object.assign({},t),{onlySelf:!0}))}),this._updateValue(),!1!==t.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._updateAncestors(Object.assign(Object.assign({},t),{skipPristineCheck:n})),this._onDisabledChange.forEach(r=>r(!0))}enable(t={}){const n=this._parentMarkedDirty(t.onlySelf);this.status=Io,this._forEachChild(r=>{r.enable(Object.assign(Object.assign({},t),{onlySelf:!0}))}),this.updateValueAndValidity({onlySelf:!0,emitEvent:t.emitEvent}),this._updateAncestors(Object.assign(Object.assign({},t),{skipPristineCheck:n})),this._onDisabledChange.forEach(r=>r(!1))}_updateAncestors(t){this._parent&&!t.onlySelf&&(this._parent.updateValueAndValidity(t),t.skipPristineCheck||this._parent._updatePristine(),this._parent._updateTouched())}setParent(t){this._parent=t}updateValueAndValidity(t={}){this._setInitialStatus(),this._updateValue(),this.enabled&&(this._cancelExistingSubscription(),this.errors=this._runValidator(),this.status=this._calculateStatus(),(this.status===Io||this.status===Nr)&&this._runAsyncValidator(t.emitEvent)),!1!==t.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._parent&&!t.onlySelf&&this._parent.updateValueAndValidity(t)}_updateTreeValidity(t={emitEvent:!0}){this._forEachChild(n=>n._updateTreeValidity(t)),this.updateValueAndValidity({onlySelf:!0,emitEvent:t.emitEvent})}_setInitialStatus(){this.status=this._allControlsDisabled()?Ao:Io}_runValidator(){return this.validator?this.validator(this):null}_runAsyncValidator(t){if(this.asyncValidator){this.status=Nr,this._hasOwnPendingAsyncValidator=!0;const n=e_(this.asyncValidator(this));this._asyncValidationSubscription=n.subscribe(r=>{this._hasOwnPendingAsyncValidator=!1,this.setErrors(r,{emitEvent:t})})}}_cancelExistingSubscription(){this._asyncValidationSubscription&&(this._asyncValidationSubscription.unsubscribe(),this._hasOwnPendingAsyncValidator=!1)}setErrors(t,n={}){this.errors=t,this._updateControlsErrors(!1!==n.emitEvent)}get(t){return function VA(e,t,n){if(null==t||(Array.isArray(t)||(t=t.split(n)),Array.isArray(t)&&0===t.length))return null;let r=e;return t.forEach(o=>{r=ku(r)?r.controls.hasOwnProperty(o)?r.controls[o]:null:(e=>e instanceof LA)(r)&&r.at(o)||null}),r}(this,t,".")}getError(t,n){const r=n?this.get(n):this;return r&&r.errors?r.errors[t]:null}hasError(t,n){return!!this.getError(t,n)}get root(){let t=this;for(;t._parent;)t=t._parent;return t}_updateControlsErrors(t){this.status=this._calculateStatus(),t&&this.statusChanges.emit(this.status),this._parent&&this._parent._updateControlsErrors(t)}_initObservables(){this.valueChanges=new Ve,this.statusChanges=new Ve}_calculateStatus(){return this._allControlsDisabled()?Ao:this.errors?ds:this._hasOwnPendingAsyncValidator||this._anyControlsHaveStatus(Nr)?Nr:this._anyControlsHaveStatus(ds)?ds:Io}_anyControlsHaveStatus(t){return this._anyControls(n=>n.status===t)}_anyControlsDirty(){return this._anyControls(t=>t.dirty)}_anyControlsTouched(){return this._anyControls(t=>t.touched)}_updatePristine(t={}){this.pristine=!this._anyControlsDirty(),this._parent&&!t.onlySelf&&this._parent._updatePristine(t)}_updateTouched(t={}){this.touched=this._anyControlsTouched(),this._parent&&!t.onlySelf&&this._parent._updateTouched(t)}_isBoxedValue(t){return"object"==typeof t&&null!==t&&2===Object.keys(t).length&&"value"in t&&"disabled"in t}_registerOnCollectionChange(t){this._onCollectionChange=t}_setUpdateStrategy(t){fs(t)&&null!=t.updateOn&&(this._updateOn=t.updateOn)}_parentMarkedDirty(t){return!t&&!(!this._parent||!this._parent.dirty)&&!this._parent._anyControlsDirty()}}class E_ extends Lu{constructor(t=null,n,r){super(Pu(n),Vu(r,n)),this.defaultValue=null,this._onChange=[],this._pendingChange=!1,this._applyFormState(t),this._setUpdateStrategy(n),this._initObservables(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator}),fs(n)&&n.initialValueIsDefault&&(this.defaultValue=this._isBoxedValue(t)?t.value:t)}setValue(t,n={}){this.value=this._pendingValue=t,this._onChange.length&&!1!==n.emitModelToViewChange&&this._onChange.forEach(r=>r(this.value,!1!==n.emitViewToModelChange)),this.updateValueAndValidity(n)}patchValue(t,n={}){this.setValue(t,n)}reset(t=this.defaultValue,n={}){this._applyFormState(t),this.markAsPristine(n),this.markAsUntouched(n),this.setValue(this.value,n),this._pendingChange=!1}_updateValue(){}_anyControls(t){return!1}_allControlsDisabled(){return this.disabled}registerOnChange(t){this._onChange.push(t)}_unregisterOnChange(t){Ou(this._onChange,t)}registerOnDisabledChange(t){this._onDisabledChange.push(t)}_unregisterOnDisabledChange(t){Ou(this._onDisabledChange,t)}_forEachChild(t){}_syncPendingControls(){return!("submit"!==this.updateOn||(this._pendingDirty&&this.markAsDirty(),this._pendingTouched&&this.markAsTouched(),!this._pendingChange)||(this.setValue(this._pendingValue,{onlySelf:!0,emitModelToViewChange:!1}),0))}_applyFormState(t){this._isBoxedValue(t)?(this.value=this._pendingValue=t.value,t.disabled?this.disable({onlySelf:!0,emitEvent:!1}):this.enable({onlySelf:!0,emitEvent:!1})):this.value=this._pendingValue=t}}class Bu extends Lu{constructor(t,n,r){super(Pu(n),Vu(r,n)),this.controls=t,this._initObservables(),this._setUpdateStrategy(n),this._setUpControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator})}registerControl(t,n){return this.controls[t]?this.controls[t]:(this.controls[t]=n,n.setParent(this),n._registerOnCollectionChange(this._onCollectionChange),n)}addControl(t,n,r={}){this.registerControl(t,n),this.updateValueAndValidity({emitEvent:r.emitEvent}),this._onCollectionChange()}removeControl(t,n={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),delete this.controls[t],this.updateValueAndValidity({emitEvent:n.emitEvent}),this._onCollectionChange()}setControl(t,n,r={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),delete this.controls[t],n&&this.registerControl(t,n),this.updateValueAndValidity({emitEvent:r.emitEvent}),this._onCollectionChange()}contains(t){return this.controls.hasOwnProperty(t)&&this.controls[t].enabled}setValue(t,n={}){b_(this,t),Object.keys(t).forEach(r=>{w_(this,r),this.controls[r].setValue(t[r],{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n)}patchValue(t,n={}){null!=t&&(Object.keys(t).forEach(r=>{this.controls[r]&&this.controls[r].patchValue(t[r],{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n))}reset(t={},n={}){this._forEachChild((r,o)=>{r.reset(t[o],{onlySelf:!0,emitEvent:n.emitEvent})}),this._updatePristine(n),this._updateTouched(n),this.updateValueAndValidity(n)}getRawValue(){return this._reduceChildren({},(t,n,r)=>(t[r]=D_(n),t))}_syncPendingControls(){let t=this._reduceChildren(!1,(n,r)=>!!r._syncPendingControls()||n);return t&&this.updateValueAndValidity({onlySelf:!0}),t}_forEachChild(t){Object.keys(this.controls).forEach(n=>{const r=this.controls[n];r&&t(r,n)})}_setUpControls(){this._forEachChild(t=>{t.setParent(this),t._registerOnCollectionChange(this._onCollectionChange)})}_updateValue(){this.value=this._reduceValue()}_anyControls(t){for(const n of Object.keys(this.controls)){const r=this.controls[n];if(this.contains(n)&&t(r))return!0}return!1}_reduceValue(){return this._reduceChildren({},(t,n,r)=>((n.enabled||this.disabled)&&(t[r]=n.value),t))}_reduceChildren(t,n){let r=t;return this._forEachChild((o,i)=>{r=n(r,o,i)}),r}_allControlsDisabled(){for(const t of Object.keys(this.controls))if(this.controls[t].enabled)return!1;return Object.keys(this.controls).length>0||this.disabled}}class LA extends Lu{constructor(t,n,r){super(Pu(n),Vu(r,n)),this.controls=t,this._initObservables(),this._setUpdateStrategy(n),this._setUpControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator})}at(t){return this.controls[t]}push(t,n={}){this.controls.push(t),this._registerControl(t),this.updateValueAndValidity({emitEvent:n.emitEvent}),this._onCollectionChange()}insert(t,n,r={}){this.controls.splice(t,0,n),this._registerControl(n),this.updateValueAndValidity({emitEvent:r.emitEvent})}removeAt(t,n={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),this.controls.splice(t,1),this.updateValueAndValidity({emitEvent:n.emitEvent})}setControl(t,n,r={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),this.controls.splice(t,1),n&&(this.controls.splice(t,0,n),this._registerControl(n)),this.updateValueAndValidity({emitEvent:r.emitEvent}),this._onCollectionChange()}get length(){return this.controls.length}setValue(t,n={}){b_(this,t),t.forEach((r,o)=>{w_(this,o),this.at(o).setValue(r,{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n)}patchValue(t,n={}){null!=t&&(t.forEach((r,o)=>{this.at(o)&&this.at(o).patchValue(r,{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n))}reset(t=[],n={}){this._forEachChild((r,o)=>{r.reset(t[o],{onlySelf:!0,emitEvent:n.emitEvent})}),this._updatePristine(n),this._updateTouched(n),this.updateValueAndValidity(n)}getRawValue(){return this.controls.map(t=>D_(t))}clear(t={}){this.controls.length<1||(this._forEachChild(n=>n._registerOnCollectionChange(()=>{})),this.controls.splice(0),this.updateValueAndValidity({emitEvent:t.emitEvent}))}_syncPendingControls(){let t=this.controls.reduce((n,r)=>!!r._syncPendingControls()||n,!1);return t&&this.updateValueAndValidity({onlySelf:!0}),t}_forEachChild(t){this.controls.forEach((n,r)=>{t(n,r)})}_updateValue(){this.value=this.controls.filter(t=>t.enabled||this.disabled).map(t=>t.value)}_anyControls(t){return this.controls.some(n=>n.enabled&&t(n))}_setUpControls(){this._forEachChild(t=>this._registerControl(t))}_allControlsDisabled(){for(const t of this.controls)if(t.enabled)return!1;return this.controls.length>0||this.disabled}_registerControl(t){t.setParent(this),t._registerOnCollectionChange(this._onCollectionChange)}}const jA={provide:_n,useExisting:ae(()=>hs)},A_=(()=>Promise.resolve(null))();let hs=(()=>{class e extends _n{constructor(n,r,o,i,s){super(),this._changeDetectorRef=s,this.control=new E_,this._registered=!1,this.update=new Ve,this._parent=n,this._setValidators(r),this._setAsyncValidators(o),this.valueAccessor=function Fu(e,t){if(!t)return null;let n,r,o;return Array.isArray(t),t.forEach(i=>{i.constructor===Eo?n=i:function PA(e){return Object.getPrototypeOf(e.constructor)===Rn}(i)?r=i:o=i}),o||r||n||null}(0,i)}ngOnChanges(n){if(this._checkForErrors(),!this._registered||"name"in n){if(this._registered&&(this._checkName(),this.formDirective)){const r=n.name.previousValue;this.formDirective.removeControl({name:r,path:this._getPath(r)})}this._setUpControl()}"isDisabled"in n&&this._updateDisabled(n),function Nu(e,t){if(!e.hasOwnProperty("model"))return!1;const n=e.model;return!!n.isFirstChange()||!Object.is(t,n.currentValue)}(n,this.viewModel)&&(this._updateValue(this.model),this.viewModel=this.model)}ngOnDestroy(){this.formDirective&&this.formDirective.removeControl(this)}get path(){return this._getPath(this.name)}get formDirective(){return this._parent?this._parent.formDirective:null}viewToModelUpdate(n){this.viewModel=n,this.update.emit(n)}_setUpControl(){this._setUpdateStrategy(),this._isStandalone()?this._setUpStandalone():this.formDirective.addControl(this),this._registered=!0}_setUpdateStrategy(){this.options&&null!=this.options.updateOn&&(this.control._updateOn=this.options.updateOn)}_isStandalone(){return!this._parent||!(!this.options||!this.options.standalone)}_setUpStandalone(){Mo(this.control,this),this.control.updateValueAndValidity({emitEvent:!1})}_checkForErrors(){this._isStandalone()||this._checkParentType(),this._checkName()}_checkParentType(){}_checkName(){this.options&&this.options.name&&(this.name=this.options.name),this._isStandalone()}_updateValue(n){A_.then(()=>{var r;this.control.setValue(n,{emitViewToModelChange:!1}),null===(r=this._changeDetectorRef)||void 0===r||r.markForCheck()})}_updateDisabled(n){const r=n.isDisabled.currentValue,o=""===r||r&&"false"!==r;A_.then(()=>{var i;o&&!this.control.disabled?this.control.disable():!o&&this.control.disabled&&this.control.enable(),null===(i=this._changeDetectorRef)||void 0===i||i.markForCheck()})}_getPath(n){return this._parent?function as(e,t){return[...t.path,e]}(n,this._parent):[n]}}return e.\u0275fac=function(n){return new(n||e)(A(Ge,9),A(ke,10),A(mn,10),A(Ut,10),A(om,8))},e.\u0275dir=k({type:e,selectors:[["","ngModel","",3,"formControlName","",3,"formControl",""]],inputs:{name:"name",isDisabled:["disabled","isDisabled"],model:["ngModel","model"],options:["ngModelOptions","options"]},outputs:{update:"ngModelChange"},exportAs:["ngModel"],features:[he([jA]),ne,Wt]}),e})(),S_=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({}),e})();const qA={provide:Ut,useExisting:ae(()=>ju),multi:!0};let ju=(()=>{class e extends Rn{writeValue(n){this.setProperty("value",parseFloat(n))}registerOnChange(n){this.onChange=r=>{n(""==r?null:parseFloat(r))}}}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,selectors:[["input","type","range","formControlName",""],["input","type","range","formControl",""],["input","type","range","ngModel",""]],hostBindings:function(n,r){1&n&&z("change",function(i){return r.onChange(i.target.value)})("input",function(i){return r.onChange(i.target.value)})("blur",function(){return r.onTouched()})},features:[he([qA]),ne]}),e})();const JA={provide:Ut,useExisting:ae(()=>So),multi:!0};function P_(e,t){return null==e?`${t}`:(t&&"object"==typeof t&&(t="Object"),`${e}: ${t}`.slice(0,50))}let So=(()=>{class e extends Rn{constructor(){super(...arguments),this._optionMap=new Map,this._idCounter=0,this._compareWith=Object.is}set compareWith(n){this._compareWith=n}writeValue(n){this.value=n;const o=P_(this._getOptionId(n),n);this.setProperty("value",o)}registerOnChange(n){this.onChange=r=>{this.value=this._getOptionValue(r),n(this.value)}}_registerOption(){return(this._idCounter++).toString()}_getOptionId(n){for(const r of Array.from(this._optionMap.keys()))if(this._compareWith(this._optionMap.get(r),n))return r;return null}_getOptionValue(n){const r=function XA(e){return e.split(":")[0]}(n);return this._optionMap.has(r)?this._optionMap.get(r):n}}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,selectors:[["select","formControlName","",3,"multiple",""],["select","formControl","",3,"multiple",""],["select","ngModel","",3,"multiple",""]],hostBindings:function(n,r){1&n&&z("change",function(i){return r.onChange(i.target.value)})("blur",function(){return r.onTouched()})},inputs:{compareWith:"compareWith"},features:[he([JA]),ne]}),e})(),Gu=(()=>{class e{constructor(n,r,o){this._element=n,this._renderer=r,this._select=o,this._select&&(this.id=this._select._registerOption())}set ngValue(n){null!=this._select&&(this._select._optionMap.set(this.id,n),this._setElementValue(P_(this.id,n)),this._select.writeValue(this._select.value))}set value(n){this._setElementValue(n),this._select&&this._select.writeValue(this._select.value)}_setElementValue(n){this._renderer.setProperty(this._element.nativeElement,"value",n)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))}}return e.\u0275fac=function(n){return new(n||e)(A(Et),A(Nn),A(So,9))},e.\u0275dir=k({type:e,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"}}),e})();const eT={provide:Ut,useExisting:ae(()=>qu),multi:!0};function V_(e,t){return null==e?`${t}`:("string"==typeof t&&(t=`'${t}'`),t&&"object"==typeof t&&(t="Object"),`${e}: ${t}`.slice(0,50))}let qu=(()=>{class e extends Rn{constructor(){super(...arguments),this._optionMap=new Map,this._idCounter=0,this._compareWith=Object.is}set compareWith(n){this._compareWith=n}writeValue(n){let r;if(this.value=n,Array.isArray(n)){const o=n.map(i=>this._getOptionId(i));r=(i,s)=>{i._setSelected(o.indexOf(s.toString())>-1)}}else r=(o,i)=>{o._setSelected(!1)};this._optionMap.forEach(r)}registerOnChange(n){this.onChange=r=>{const o=[],i=r.selectedOptions;if(void 0!==i){const s=i;for(let a=0;a<s.length;a++){const u=this._getOptionValue(s[a].value);o.push(u)}}else{const s=r.options;for(let a=0;a<s.length;a++){const l=s[a];if(l.selected){const u=this._getOptionValue(l.value);o.push(u)}}}this.value=o,n(o)}}_registerOption(n){const r=(this._idCounter++).toString();return this._optionMap.set(r,n),r}_getOptionId(n){for(const r of Array.from(this._optionMap.keys()))if(this._compareWith(this._optionMap.get(r)._value,n))return r;return null}_getOptionValue(n){const r=function tT(e){return e.split(":")[0]}(n);return this._optionMap.has(r)?this._optionMap.get(r)._value:n}}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,selectors:[["select","multiple","","formControlName",""],["select","multiple","","formControl",""],["select","multiple","","ngModel",""]],hostBindings:function(n,r){1&n&&z("change",function(i){return r.onChange(i.target)})("blur",function(){return r.onTouched()})},inputs:{compareWith:"compareWith"},features:[he([eT]),ne]}),e})(),Wu=(()=>{class e{constructor(n,r,o){this._element=n,this._renderer=r,this._select=o,this._select&&(this.id=this._select._registerOption(this))}set ngValue(n){null!=this._select&&(this._value=n,this._setElementValue(V_(this.id,n)),this._select.writeValue(this._select.value))}set value(n){this._select?(this._value=n,this._setElementValue(V_(this.id,n)),this._select.writeValue(this._select.value)):this._setElementValue(n)}_setElementValue(n){this._renderer.setProperty(this._element.nativeElement,"value",n)}_setSelected(n){this._renderer.setProperty(this._element.nativeElement,"selected",n)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))}}return e.\u0275fac=function(n){return new(n||e)(A(Et),A(Nn),A(qu,9))},e.\u0275dir=k({type:e,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"}}),e})(),dT=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({imports:[[S_]]}),e})(),fT=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({imports:[dT]}),e})();class q_{constructor(){this.riskHotspotsSettings=null,this.coverageInfoSettings=null}}class hT{constructor(){this.groupingMaximum=0,this.grouping=0,this.historyComparisionDate="",this.historyComparisionType="",this.filter="",this.sortBy="name",this.sortOrder="asc",this.collapseStates=[]}}class pT{constructor(t){this.et="",this.et=t.et,this.cl=t.cl,this.ucl=t.ucl,this.cal=t.cal,this.tl=t.tl,this.lcq=t.lcq,this.cb=t.cb,this.tb=t.tb,this.bcq=t.bcq,this.cm=t.cm,this.tm=t.tm,this.mcq=t.mcq}get coverageRatioText(){return 0===this.tl?"-":this.cl+"/"+this.cal}get branchCoverageRatioText(){return 0===this.tb?"-":this.cb+"/"+this.tb}get methodCoverageRatioText(){return 0===this.tm?"-":this.cm+"/"+this.tm}}class Vn{static roundNumber(t,n){return Math.floor(t*Math.pow(10,n))/Math.pow(10,n)}static getNthOrLastIndexOf(t,n,r){let o=0,i=-1,s=-1;for(;o<r&&(s=t.indexOf(n,i+1),-1!==s);)i=s,o++;return i}}class W_{constructor(){this.name="",this.coveredLines=0,this.uncoveredLines=0,this.coverableLines=0,this.totalLines=0,this.coveredBranches=0,this.totalBranches=0,this.coveredMethods=0,this.totalMethods=0}get coverage(){return 0===this.coverableLines?NaN:Vn.roundNumber(100*this.coveredLines/this.coverableLines,1)}get coveragePercentage(){return 0===this.coverableLines?"":this.coverage+"%"}get coverageRatioText(){return 0===this.coverableLines?"-":this.coveredLines+"/"+this.coverableLines}get branchCoverage(){return 0===this.totalBranches?NaN:Vn.roundNumber(100*this.coveredBranches/this.totalBranches,1)}get branchCoveragePercentage(){return 0===this.totalBranches?"":this.branchCoverage+"%"}get branchCoverageRatioText(){return 0===this.totalBranches?"-":this.coveredBranches+"/"+this.totalBranches}get methodCoverage(){return 0===this.totalMethods?NaN:Vn.roundNumber(100*this.coveredMethods/this.totalMethods,1)}get methodCoveragePercentage(){return 0===this.totalMethods?"":this.methodCoverage+"%"}get methodCoverageRatioText(){return 0===this.totalMethods?"-":this.coveredMethods+"/"+this.totalMethods}}class Zu extends W_{constructor(t,n){super(),this.reportPath="",this._coverageType="",this.coverageByMethod="",this.lineCoverageHistory=[],this.branchCoverageHistory=[],this.methodCoverageHistory=[],this.historicCoverages=[],this.currentHistoricCoverage=null,this.name=t.name,this.reportPath=t.rp?t.rp+n:t.rp,this.coveredLines=t.cl,this.uncoveredLines=t.ucl,this.coverableLines=t.cal,this.totalLines=t.tl,this._coverageType=t.ct,this.coverageByMethod=t.cbm,this.coveredBranches=t.cb,this.totalBranches=t.tb,this.coveredMethods=t.cm,this.totalMethods=t.tm,this.lineCoverageHistory=t.lch,this.branchCoverageHistory=t.bch,this.methodCoverageHistory=t.mch,t.hc.forEach(r=>{this.historicCoverages.push(new pT(r))})}get coverage(){return 0===this.coverableLines?"-"!==this.coverageByMethod?parseFloat(this.coverageByMethod):NaN:Vn.roundNumber(100*this.coveredLines/this.coverableLines,1)}get coverageType(){return 0===this.coverableLines?"-"!==this.coverageByMethod?this._coverageType:"":this._coverageType}visible(t,n){if(""!==t&&-1===this.name.toLowerCase().indexOf(t.toLowerCase()))return!1;if(""===n||null===this.currentHistoricCoverage)return!0;if("allChanges"===n){if(this.coveredLines===this.currentHistoricCoverage.cl&&this.uncoveredLines===this.currentHistoricCoverage.ucl&&this.coverableLines===this.currentHistoricCoverage.cal&&this.totalLines===this.currentHistoricCoverage.tl&&this.coveredBranches===this.currentHistoricCoverage.cb&&this.totalBranches===this.currentHistoricCoverage.tb&&this.coveredMethods===this.currentHistoricCoverage.cm&&this.totalMethods===this.currentHistoricCoverage.tm)return!1}else if("lineCoverageIncreaseOnly"===n){let r=this.coverage;if(isNaN(r)||r<=this.currentHistoricCoverage.lcq)return!1}else if("lineCoverageDecreaseOnly"===n){let r=this.coverage;if(isNaN(r)||r>=this.currentHistoricCoverage.lcq)return!1}else if("branchCoverageIncreaseOnly"===n){let r=this.branchCoverage;if(isNaN(r)||r<=this.currentHistoricCoverage.bcq)return!1}else if("branchCoverageDecreaseOnly"===n){let r=this.branchCoverage;if(isNaN(r)||r>=this.currentHistoricCoverage.bcq)return!1}else if("methodCoverageIncreaseOnly"===n){let r=this.methodCoverage;if(isNaN(r)||r<=this.currentHistoricCoverage.mcq)return!1}else if("methodCoverageDecreaseOnly"===n){let r=this.methodCoverage;if(isNaN(r)||r>=this.currentHistoricCoverage.mcq)return!1}return!0}updateCurrentHistoricCoverage(t){if(this.currentHistoricCoverage=null,""!==t)for(let n=0;n<this.historicCoverages.length;n++)if(this.historicCoverages[n].et===t){this.currentHistoricCoverage=this.historicCoverages[n];break}}}class vn extends W_{constructor(t,n){super(),this.subElements=[],this.classes=[],this.collapsed=!1,this.name=t,this.collapsed=t.indexOf("Test")>-1&&null===n}visible(t,n){if(""!==t&&this.name.toLowerCase().indexOf(t.toLowerCase())>-1)return!0;for(let r=0;r<this.subElements.length;r++)if(this.subElements[r].visible(t,n))return!0;for(let r=0;r<this.classes.length;r++)if(this.classes[r].visible(t,n))return!0;return!1}insertClass(t,n){if(this.coveredLines+=t.coveredLines,this.uncoveredLines+=t.uncoveredLines,this.coverableLines+=t.coverableLines,this.totalLines+=t.totalLines,this.coveredBranches+=t.coveredBranches,this.totalBranches+=t.totalBranches,this.coveredMethods+=t.coveredMethods,this.totalMethods+=t.totalMethods,null===n)return void this.classes.push(t);let r=Vn.getNthOrLastIndexOf(t.name,".",n),o=-1===r?"-":t.name.substr(0,r);for(let s=0;s<this.subElements.length;s++)if(this.subElements[s].name===o)return void this.subElements[s].insertClass(t,null);let i=new vn(o,this);this.subElements.push(i),i.insertClass(t,null)}collapse(){this.collapsed=!0;for(let t=0;t<this.subElements.length;t++)this.subElements[t].collapse()}expand(){this.collapsed=!1;for(let t=0;t<this.subElements.length;t++)this.subElements[t].expand()}toggleCollapse(t){t.preventDefault(),this.collapsed=!this.collapsed}updateCurrentHistoricCoverage(t){for(let n=0;n<this.subElements.length;n++)this.subElements[n].updateCurrentHistoricCoverage(t);for(let n=0;n<this.classes.length;n++)this.classes[n].updateCurrentHistoricCoverage(t)}static sortCodeElementViewModels(t,n,r){let o=r?-1:1,i=r?1:-1;"name"===n?t.sort(function(s,a){return s.name===a.name?0:s.name<a.name?o:i}):"covered"===n?t.sort(function(s,a){return s.coveredLines===a.coveredLines?0:s.coveredLines<a.coveredLines?o:i}):"uncovered"===n?t.sort(function(s,a){return s.uncoveredLines===a.uncoveredLines?0:s.uncoveredLines<a.uncoveredLines?o:i}):"coverable"===n?t.sort(function(s,a){return s.coverableLines===a.coverableLines?0:s.coverableLines<a.coverableLines?o:i}):"total"===n?t.sort(function(s,a){return s.totalLines===a.totalLines?0:s.totalLines<a.totalLines?o:i}):"coverage"===n?t.sort(function(s,a){return s.coverage===a.coverage?0:isNaN(s.coverage)?o:isNaN(a.coverage)?i:s.coverage<a.coverage?o:i}):"branchcoverage"===n?t.sort(function(s,a){return s.branchCoverage===a.branchCoverage?0:isNaN(s.branchCoverage)?o:isNaN(a.branchCoverage)?i:s.branchCoverage<a.branchCoverage?o:i}):"methodcoverage"===n&&t.sort(function(s,a){return s.methodCoverage===a.methodCoverage?0:isNaN(s.methodCoverage)?o:isNaN(a.methodCoverage)?i:s.methodCoverage<a.methodCoverage?o:i})}changeSorting(t,n){vn.sortCodeElementViewModels(this.subElements,t,n);let r=n?-1:1,o=n?1:-1;"name"===t?this.classes.sort(function(i,s){return i.name===s.name?0:i.name<s.name?r:o}):"covered"===t?this.classes.sort(function(i,s){return i.coveredLines===s.coveredLines?0:i.coveredLines<s.coveredLines?r:o}):"uncovered"===t?this.classes.sort(function(i,s){return i.uncoveredLines===s.uncoveredLines?0:i.uncoveredLines<s.uncoveredLines?r:o}):"coverable"===t?this.classes.sort(function(i,s){return i.coverableLines===s.coverableLines?0:i.coverableLines<s.coverableLines?r:o}):"total"===t?this.classes.sort(function(i,s){return i.totalLines===s.totalLines?0:i.totalLines<s.totalLines?r:o}):"coverage"===t?this.classes.sort(function(i,s){return i.coverage===s.coverage?0:isNaN(i.coverage)?r:isNaN(s.coverage)?o:i.coverage<s.coverage?r:o}):"covered_branches"===t?this.classes.sort(function(i,s){return i.coveredBranches===s.coveredBranches?0:i.coveredBranches<s.coveredBranches?r:o}):"total_branches"===t?this.classes.sort(function(i,s){return i.totalBranches===s.totalBranches?0:i.totalBranches<s.totalBranches?r:o}):"branchcoverage"===t?this.classes.sort(function(i,s){return i.branchCoverage===s.branchCoverage?0:isNaN(i.branchCoverage)?r:isNaN(s.branchCoverage)?o:i.branchCoverage<s.branchCoverage?r:o}):"covered_methods"===t?this.classes.sort(function(i,s){return i.coveredMethods===s.coveredMethods?0:i.coveredMethods<s.coveredMethods?r:o}):"total_methods"===t?this.classes.sort(function(i,s){return i.totalMethods===s.totalMethods?0:i.totalMethods<s.totalMethods?r:o}):"methodcoverage"===t&&this.classes.sort(function(i,s){return i.methodCoverage===s.methodCoverage?0:isNaN(i.methodCoverage)?r:isNaN(s.methodCoverage)?o:i.methodCoverage<s.methodCoverage?r:o});for(let i=0;i<this.subElements.length;i++)this.subElements[i].changeSorting(t,n)}}let Yu=(()=>{class e{get nativeWindow(){return function gT(){return window}()}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();function mT(e,t){1&e&&F(0,"td",3)}function _T(e,t){1&e&&F(0,"td"),2&e&&Ht("green ",C().greenClass,"")}function vT(e,t){1&e&&F(0,"td"),2&e&&Ht("red ",C().redClass,"")}let Q_=(()=>{class e{constructor(){this.grayVisible=!0,this.greenVisible=!1,this.redVisible=!1,this.greenClass="",this.redClass="",this._percentage=NaN}get percentage(){return this._percentage}set percentage(n){this._percentage=n,this.grayVisible=isNaN(n),this.greenVisible=!isNaN(n)&&Math.round(n)>0,this.redVisible=!isNaN(n)&&100-Math.round(n)>0,this.greenClass="covered"+Math.round(n),this.redClass="covered"+(100-Math.round(n))}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["coverage-bar"]],inputs:{percentage:"percentage"},decls:4,vars:3,consts:[[1,"coverage"],["class","gray covered100",4,"ngIf"],[3,"class",4,"ngIf"],[1,"gray","covered100"]],template:function(n,r){1&n&&(y(0,"table",0),E(1,mT,1,0,"td",1),E(2,_T,1,3,"td",2),E(3,vT,1,3,"td",2),v()),2&n&&(h(1),g("ngIf",r.grayVisible),h(1),g("ngIf",r.greenVisible),h(1),g("ngIf",r.redVisible))},directives:[xr],encapsulation:2,changeDetection:0}),e})();const yT=["codeelement-row",""];function CT(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.coveredBranches)}}function DT(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.totalBranches)}}function wT(e,t){if(1&e&&(y(0,"th",3),b(1),v()),2&e){const n=C();g("title",n.element.branchCoverageRatioText),h(1),x(n.element.branchCoveragePercentage)}}function bT(e,t){if(1&e&&(y(0,"th",2),F(1,"coverage-bar",4),v()),2&e){const n=C();h(1),g("percentage",n.element.branchCoverage)}}function ET(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.coveredMethods)}}function MT(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.totalMethods)}}function IT(e,t){if(1&e&&(y(0,"th",3),b(1),v()),2&e){const n=C();g("title",n.element.methodCoverageRatioText),h(1),x(n.element.methodCoveragePercentage)}}function AT(e,t){if(1&e&&(y(0,"th",2),F(1,"coverage-bar",4),v()),2&e){const n=C();h(1),g("percentage",n.element.methodCoverage)}}const TT=function(e,t){return{"icon-plus":e,"icon-minus":t}};let ST=(()=>{class e{constructor(){this.collapsed=!1,this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["","codeelement-row",""]],inputs:{element:"element",collapsed:"collapsed",branchCoverageAvailable:"branchCoverageAvailable",methodCoverageAvailable:"methodCoverageAvailable"},attrs:yT,decls:24,vars:20,consts:[["href","#",3,"click"],[3,"ngClass"],[1,"right"],[1,"right",3,"title"],[3,"percentage"],["class","right",4,"ngIf"],["class","right",3,"title",4,"ngIf"]],template:function(n,r){1&n&&(y(0,"th")(1,"a",0),z("click",function(i){return r.element.toggleCollapse(i)}),F(2,"i",1),b(3),v()(),y(4,"th",2),b(5),v(),y(6,"th",2),b(7),v(),y(8,"th",2),b(9),v(),y(10,"th",2),b(11),v(),y(12,"th",3),b(13),v(),y(14,"th",2),F(15,"coverage-bar",4),v(),E(16,CT,2,1,"th",5),E(17,DT,2,1,"th",5),E(18,wT,2,2,"th",6),E(19,bT,2,1,"th",5),E(20,ET,2,1,"th",5),E(21,MT,2,1,"th",5),E(22,IT,2,2,"th",6),E(23,AT,2,1,"th",5)),2&n&&(h(2),g("ngClass",xl(17,TT,r.element.collapsed,!r.element.collapsed)),h(1),q(" ",r.element.name,""),h(2),x(r.element.coveredLines),h(2),x(r.element.uncoveredLines),h(2),x(r.element.coverableLines),h(2),x(r.element.totalLines),h(1),g("title",r.element.coverageRatioText),h(1),x(r.element.coveragePercentage),h(2),g("percentage",r.element.coverage),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable))},directives:[Do,Q_,xr],encapsulation:2,changeDetection:0}),e})();const xT=["coverage-history-chart",""];let NT=(()=>{class e{constructor(){this.path=null,this._historicCoverages=[]}get historicCoverages(){return this._historicCoverages}set historicCoverages(n){if(this._historicCoverages=n,n.length>1){let r="";for(let o=0;o<n.length;o++)r+=0===o?"M":"L",r+=`${Vn.roundNumber(30*o/(n.length-1),1)}`,r+=`,${Vn.roundNumber(18-18*n[o]/100,1)}`;this.path=r}else this.path=null}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["","coverage-history-chart",""]],inputs:{historicCoverages:"historicCoverages"},attrs:xT,decls:3,vars:1,consts:[["width","30","height","18",1,"ct-chart-line"],[1,"ct-series","ct-series-a"],[1,"ct-line"]],template:function(n,r){1&n&&(function sd(){P.lFrame.currentNamespace="svg"}(),y(0,"svg",0)(1,"g",1),F(2,"path",2),v()()),2&n&&(h(2),kt("d",r.path))},encapsulation:2,changeDetection:0}),e})();const FT=["class-row",""];function OT(e,t){if(1&e&&(y(0,"a",8),b(1),v()),2&e){const n=C();g("href",n.clazz.reportPath,rr),h(1),x(n.clazz.name)}}function RT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),x(n.clazz.name)}}function PT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(1),Ht("currenthistory ",n.getClassName(n.clazz.coveredLines,n.clazz.currentHistoricCoverage.cl),""),h(1),q(" ",n.clazz.coveredLines," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.cl," ")}}function VT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.coveredLines," ")}}function kT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(1),Ht("currenthistory ",n.getClassName(n.clazz.currentHistoricCoverage.ucl,n.clazz.uncoveredLines),""),h(1),q(" ",n.clazz.uncoveredLines," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.ucl," ")}}function LT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.uncoveredLines," ")}}function BT(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(2),x(n.clazz.coverableLines),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.cal)}}function HT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.coverableLines," ")}}function jT(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(2),x(n.clazz.totalLines),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.tl)}}function $T(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.totalLines," ")}}const Ku=function(e){return{historiccoverageoffset:e}};function UT(e,t){if(1&e&&F(0,"div",11),2&e){const n=C();wr("title",n.translations.history+": "+n.translations.coverage),g("historicCoverages",n.clazz.lineCoverageHistory)("ngClass",Vi(3,Ku,null!==n.clazz.currentHistoricCoverage))}}function zT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(1),Ht("currenthistory ",n.getClassName(n.clazz.coverage,n.clazz.currentHistoricCoverage.lcq),""),h(1),q(" ",n.clazz.coveragePercentage," "),h(1),g("title",n.clazz.currentHistoricCoverage.et+": "+n.clazz.currentHistoricCoverage.coverageRatioText),h(1),q("",n.clazz.currentHistoricCoverage.lcq,"%")}}function GT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.coveragePercentage," ")}}function qT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.coveredBranches,n.clazz.currentHistoricCoverage.cb),""),h(1),q(" ",n.clazz.coveredBranches," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.cb," ")}}function WT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.coveredBranches," ")}}function QT(e,t){if(1&e&&(y(0,"td",2),E(1,qT,5,6,"ng-container",1),E(2,WT,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function ZT(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(2),x(n.clazz.totalBranches),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.tb)}}function YT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.totalBranches," ")}}function KT(e,t){if(1&e&&(y(0,"td",2),E(1,ZT,5,3,"ng-container",1),E(2,YT,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function JT(e,t){if(1&e&&F(0,"div",13),2&e){const n=C(2);wr("title",n.translations.history+": "+n.translations.branchCoverage),g("historicCoverages",n.clazz.branchCoverageHistory)("ngClass",Vi(3,Ku,null!==n.clazz.currentHistoricCoverage))}}function XT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.branchCoverage,n.clazz.currentHistoricCoverage.bcq),""),h(1),q(" ",n.clazz.branchCoveragePercentage," "),h(1),g("title",n.clazz.currentHistoricCoverage.et+": "+n.clazz.currentHistoricCoverage.branchCoverageRatioText),h(1),q("",n.clazz.currentHistoricCoverage.bcq,"%")}}function eS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.branchCoveragePercentage," ")}}function tS(e,t){if(1&e&&(y(0,"td",3),E(1,JT,1,5,"div",12),E(2,XT,5,6,"ng-container",1),E(3,eS,2,1,"ng-container",1),v()),2&e){const n=C();g("title",n.clazz.branchCoverageRatioText),h(1),g("ngIf",n.clazz.branchCoverageHistory.length>1),h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function nS(e,t){if(1&e&&(y(0,"td",2),F(1,"coverage-bar",5),v()),2&e){const n=C();h(1),g("percentage",n.clazz.branchCoverage)}}function rS(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.coveredMethods,n.clazz.currentHistoricCoverage.cm),""),h(1),q(" ",n.clazz.coveredMethods," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.cm," ")}}function oS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.coveredMethods," ")}}function iS(e,t){if(1&e&&(y(0,"td",2),E(1,rS,5,6,"ng-container",1),E(2,oS,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function sS(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(2),x(n.clazz.totalMethods),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.tm)}}function aS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.totalMethods," ")}}function lS(e,t){if(1&e&&(y(0,"td",2),E(1,sS,5,3,"ng-container",1),E(2,aS,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function uS(e,t){if(1&e&&F(0,"div",15),2&e){const n=C(2);wr("title",n.translations.history+": "+n.translations.methodCoverage),g("historicCoverages",n.clazz.methodCoverageHistory)("ngClass",Vi(3,Ku,null!==n.clazz.currentHistoricCoverage))}}function cS(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.methodCoverage,n.clazz.currentHistoricCoverage.mcq),""),h(1),q(" ",n.clazz.methodCoveragePercentage," "),h(1),g("title",n.clazz.currentHistoricCoverage.et+": "+n.clazz.currentHistoricCoverage.methodCoverageRatioText),h(1),q("",n.clazz.currentHistoricCoverage.mcq,"%")}}function dS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.methodCoveragePercentage," ")}}function fS(e,t){if(1&e&&(y(0,"td",3),E(1,uS,1,5,"div",14),E(2,cS,5,6,"ng-container",1),E(3,dS,2,1,"ng-container",1),v()),2&e){const n=C();g("title",n.clazz.methodCoverageRatioText),h(1),g("ngIf",n.clazz.methodCoverageHistory.length>1),h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function hS(e,t){if(1&e&&(y(0,"td",2),F(1,"coverage-bar",5),v()),2&e){const n=C();h(1),g("percentage",n.clazz.methodCoverage)}}let pS=(()=>{class e{constructor(){this.translations={},this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.historyComparisionDate=""}getClassName(n,r){return n>r?"lightgreen":n<r?"lightred":"lightgraybg"}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["","class-row",""]],inputs:{clazz:"clazz",translations:"translations",branchCoverageAvailable:"branchCoverageAvailable",methodCoverageAvailable:"methodCoverageAvailable",historyComparisionDate:"historyComparisionDate"},attrs:FT,decls:29,vars:23,consts:[[3,"href",4,"ngIf"],[4,"ngIf"],[1,"right"],[1,"right",3,"title"],["coverage-history-chart","","class","tinylinecoveragechart ct-chart",3,"historicCoverages","ngClass","title",4,"ngIf"],[3,"percentage"],["class","right",4,"ngIf"],["class","right",3,"title",4,"ngIf"],[3,"href"],[3,"title"],[1,"currenthistory"],["coverage-history-chart","",1,"tinylinecoveragechart","ct-chart",3,"historicCoverages","ngClass","title"],["coverage-history-chart","","class","tinybranchcoveragechart ct-chart",3,"historicCoverages","ngClass","title",4,"ngIf"],["coverage-history-chart","",1,"tinybranchcoveragechart","ct-chart",3,"historicCoverages","ngClass","title"],["coverage-history-chart","","class","tinymethodcoveragechart ct-chart",3,"historicCoverages","ngClass","title",4,"ngIf"],["coverage-history-chart","",1,"tinymethodcoveragechart","ct-chart",3,"historicCoverages","ngClass","title"]],template:function(n,r){1&n&&(y(0,"td"),E(1,OT,2,2,"a",0),E(2,RT,2,1,"ng-container",1),v(),y(3,"td",2),E(4,PT,5,6,"ng-container",1),E(5,VT,2,1,"ng-container",1),v(),y(6,"td",2),E(7,kT,5,6,"ng-container",1),E(8,LT,2,1,"ng-container",1),v(),y(9,"td",2),E(10,BT,5,3,"ng-container",1),E(11,HT,2,1,"ng-container",1),v(),y(12,"td",2),E(13,jT,5,3,"ng-container",1),E(14,$T,2,1,"ng-container",1),v(),y(15,"td",3),E(16,UT,1,5,"div",4),E(17,zT,5,6,"ng-container",1),E(18,GT,2,1,"ng-container",1),v(),y(19,"td",2),F(20,"coverage-bar",5),v(),E(21,QT,3,2,"td",6),E(22,KT,3,2,"td",6),E(23,tS,4,4,"td",7),E(24,nS,2,1,"td",6),E(25,iS,3,2,"td",6),E(26,lS,3,2,"td",6),E(27,fS,4,4,"td",7),E(28,hS,2,1,"td",6)),2&n&&(h(1),g("ngIf",""!==r.clazz.reportPath),h(1),g("ngIf",""===r.clazz.reportPath),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(1),g("title",r.clazz.coverageType+": "+r.clazz.coverageRatioText),h(1),g("ngIf",r.clazz.lineCoverageHistory.length>1),h(1),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("percentage",r.clazz.coverage),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable))},directives:[xr,NT,Do,Q_],encapsulation:2,changeDetection:0}),e})();function gS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),x(n.translations.noGrouping)}}function mS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),x(n.translations.byAssembly)}}function _S(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),x(n.translations.byNamespace+" "+n.settings.grouping)}}function vS(e,t){if(1&e&&(y(0,"option",31),b(1),v()),2&e){const n=t.$implicit;g("value",n),h(1),x(n)}}function yS(e,t){1&e&&F(0,"br")}function CS(e,t){if(1&e&&(y(0,"option",39),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.branchCoverageIncreaseOnly," ")}}function DS(e,t){if(1&e&&(y(0,"option",40),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.branchCoverageDecreaseOnly," ")}}function wS(e,t){if(1&e&&(y(0,"option",41),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.methodCoverageIncreaseOnly," ")}}function bS(e,t){if(1&e&&(y(0,"option",42),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.methodCoverageDecreaseOnly," ")}}function ES(e,t){if(1&e){const n=rt();y(0,"div")(1,"select",28),z("ngModelChange",function(o){return ee(n),C(3).settings.historyComparisionType=o}),y(2,"option",29),b(3),v(),y(4,"option",32),b(5),v(),y(6,"option",33),b(7),v(),y(8,"option",34),b(9),v(),E(10,CS,2,1,"option",35),E(11,DS,2,1,"option",36),E(12,wS,2,1,"option",37),E(13,bS,2,1,"option",38),v()()}if(2&e){const n=C(3);h(1),g("ngModel",n.settings.historyComparisionType),h(2),x(n.translations.filter),h(2),x(n.translations.allChanges),h(2),x(n.translations.lineCoverageIncreaseOnly),h(2),x(n.translations.lineCoverageDecreaseOnly),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable)}}function MS(e,t){if(1&e){const n=rt();Q(0),y(1,"div"),b(2),y(3,"select",28),z("ngModelChange",function(o){return ee(n),C(2).settings.historyComparisionDate=o})("ngModelChange",function(){return ee(n),C(2).updateCurrentHistoricCoverage()}),y(4,"option",29),b(5),v(),E(6,vS,2,2,"option",30),v()(),E(7,yS,1,0,"br",0),E(8,ES,14,9,"div",0),Z()}if(2&e){const n=C(2);h(2),q(" ",n.translations.compareHistory," "),h(1),g("ngModel",n.settings.historyComparisionDate),h(2),x(n.translations.date),h(1),g("ngForOf",n.historicCoverageExecutionTimes),h(1),g("ngIf",""!==n.settings.historyComparisionDate),h(1),g("ngIf",""!==n.settings.historyComparisionDate)}}function IS(e,t){1&e&&F(0,"col",10)}function AS(e,t){1&e&&F(0,"col",13)}function TS(e,t){1&e&&F(0,"col",14)}function SS(e,t){1&e&&F(0,"col",15)}function xS(e,t){1&e&&F(0,"col",10)}function NS(e,t){1&e&&F(0,"col",13)}function FS(e,t){1&e&&F(0,"col",14)}function OS(e,t){1&e&&F(0,"col",15)}function RS(e,t){if(1&e&&(y(0,"th",43),b(1),v()),2&e){const n=C(2);h(1),x(n.translations.branchCoverage)}}function PS(e,t){if(1&e&&(y(0,"th",43),b(1),v()),2&e){const n=C(2);h(1),x(n.translations.methodCoverage)}}const pt=function(e,t,n){return{"icon-up-dir_active":e,"icon-down-dir_active":t,"icon-down-dir":n}};function VS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("covered_branches",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"covered_branches"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"covered_branches"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"covered_branches"!==n.settings.sortBy)),h(1),x(n.translations.covered)}}function kS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("total_branches",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"total_branches"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"total_branches"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"total_branches"!==n.settings.sortBy)),h(1),x(n.translations.total)}}function LS(e,t){if(1&e){const n=rt();y(0,"th",24)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("branchcoverage",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"branchcoverage"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"branchcoverage"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"branchcoverage"!==n.settings.sortBy)),h(1),x(n.translations.percentage)}}function BS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("covered_methods",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"covered_methods"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"covered_methods"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"covered_methods"!==n.settings.sortBy)),h(1),x(n.translations.covered)}}function HS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("total_methods",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"total_methods"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"total_methods"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"total_methods"!==n.settings.sortBy)),h(1),x(n.translations.total)}}function jS(e,t){if(1&e){const n=rt();y(0,"th",24)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("methodcoverage",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"methodcoverage"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"methodcoverage"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"methodcoverage"!==n.settings.sortBy)),h(1),x(n.translations.percentage)}}function $S(e,t){if(1&e&&F(0,"tr",45),2&e){const n=C().$implicit,r=C(2);g("element",n)("collapsed",n.collapsed)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable)}}function US(e,t){if(1&e&&F(0,"tr",47),2&e){const n=C().$implicit,r=C(3);g("clazz",n)("translations",r.translations)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable)("historyComparisionDate",r.settings.historyComparisionDate)}}function zS(e,t){if(1&e&&(Q(0),E(1,US,1,5,"tr",46),Z()),2&e){const n=t.$implicit,r=C().$implicit,o=C(2);h(1),g("ngIf",!r.collapsed&&n.visible(o.settings.filter,o.settings.historyComparisionType))}}function GS(e,t){if(1&e&&F(0,"tr",50),2&e){const n=C().$implicit,r=C(5);g("clazz",n)("translations",r.translations)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable)("historyComparisionDate",r.settings.historyComparisionDate)}}function qS(e,t){if(1&e&&(Q(0),E(1,GS,1,5,"tr",49),Z()),2&e){const n=t.$implicit,r=C(2).$implicit,o=C(3);h(1),g("ngIf",!r.collapsed&&n.visible(o.settings.filter,o.settings.historyComparisionType))}}function WS(e,t){if(1&e&&(Q(0),F(1,"tr",48),E(2,qS,2,1,"ng-container",27),Z()),2&e){const n=C().$implicit,r=C(3);h(1),g("element",n)("collapsed",n.collapsed)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable),h(1),g("ngForOf",n.classes)}}function QS(e,t){if(1&e&&(Q(0),E(1,WS,3,5,"ng-container",0),Z()),2&e){const n=t.$implicit,r=C().$implicit,o=C(2);h(1),g("ngIf",!r.collapsed&&n.visible(o.settings.filter,o.settings.historyComparisionType))}}function ZS(e,t){if(1&e&&(Q(0),E(1,$S,1,4,"tr",44),E(2,zS,2,1,"ng-container",27),E(3,QS,2,1,"ng-container",27),Z()),2&e){const n=t.$implicit,r=C(2);h(1),g("ngIf",n.visible(r.settings.filter,r.settings.historyComparisionType)),h(1),g("ngForOf",n.classes),h(1),g("ngForOf",n.subElements)}}function YS(e,t){if(1&e){const n=rt();y(0,"div")(1,"div",1)(2,"div")(3,"a",2),z("click",function(o){return ee(n),C().collapseAll(o)}),b(4),v(),b(5," | "),y(6,"a",2),z("click",function(o){return ee(n),C().expandAll(o)}),b(7),v()(),y(8,"div",3),E(9,gS,2,1,"ng-container",0),E(10,mS,2,1,"ng-container",0),E(11,_S,2,1,"ng-container",0),F(12,"br"),b(13),y(14,"input",4),z("ngModelChange",function(o){return ee(n),C().settings.grouping=o})("ngModelChange",function(){return ee(n),C().updateCoverageInfo()}),v()(),y(15,"div",3),E(16,MS,9,6,"ng-container",0),v(),y(17,"div",5)(18,"span"),b(19),v(),y(20,"input",6),z("ngModelChange",function(o){return ee(n),C().settings.filter=o}),v()()(),y(21,"div",7)(22,"table",8)(23,"colgroup"),F(24,"col",9)(25,"col",10)(26,"col",11)(27,"col",12)(28,"col",13)(29,"col",14)(30,"col",15),E(31,IS,1,0,"col",16),E(32,AS,1,0,"col",17),E(33,TS,1,0,"col",18),E(34,SS,1,0,"col",19),E(35,xS,1,0,"col",16),E(36,NS,1,0,"col",17),E(37,FS,1,0,"col",18),E(38,OS,1,0,"col",19),v(),y(39,"thead")(40,"tr",20),F(41,"th"),y(42,"th",21),b(43),v(),E(44,RS,2,1,"th",22),E(45,PS,2,1,"th",22),v(),y(46,"tr")(47,"th")(48,"a",2),z("click",function(o){return ee(n),C().updateSorting("name",o)}),F(49,"i",23),b(50),v()(),y(51,"th",5)(52,"a",2),z("click",function(o){return ee(n),C().updateSorting("covered",o)}),F(53,"i",23),b(54),v()(),y(55,"th",5)(56,"a",2),z("click",function(o){return ee(n),C().updateSorting("uncovered",o)}),F(57,"i",23),b(58),v()(),y(59,"th",5)(60,"a",2),z("click",function(o){return ee(n),C().updateSorting("coverable",o)}),F(61,"i",23),b(62),v()(),y(63,"th",5)(64,"a",2),z("click",function(o){return ee(n),C().updateSorting("total",o)}),F(65,"i",23),b(66),v()(),y(67,"th",24)(68,"a",2),z("click",function(o){return ee(n),C().updateSorting("coverage",o)}),F(69,"i",23),b(70),v()(),E(71,VS,4,6,"th",25),E(72,kS,4,6,"th",25),E(73,LS,4,6,"th",26),E(74,BS,4,6,"th",25),E(75,HS,4,6,"th",25),E(76,jS,4,6,"th",26),v()(),y(77,"tbody"),E(78,ZS,4,3,"ng-container",27),v()()()()}if(2&e){const n=C();h(4),x(n.translations.collapseAll),h(3),x(n.translations.expandAll),h(2),g("ngIf",-1===n.settings.grouping),h(1),g("ngIf",0===n.settings.grouping),h(1),g("ngIf",n.settings.grouping>0),h(2),q(" ",n.translations.grouping," "),h(1),g("max",n.settings.groupingMaximum)("ngModel",n.settings.grouping),h(2),g("ngIf",n.historicCoverageExecutionTimes.length>0),h(3),q("",n.translations.filter," "),h(1),g("ngModel",n.settings.filter),h(11),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(5),x(n.translations.coverage),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(4),g("ngClass",xe(41,pt,"name"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"name"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"name"!==n.settings.sortBy)),h(1),x(n.translations.name),h(3),g("ngClass",xe(45,pt,"covered"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"covered"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"covered"!==n.settings.sortBy)),h(1),x(n.translations.covered),h(3),g("ngClass",xe(49,pt,"uncovered"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"uncovered"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"uncovered"!==n.settings.sortBy)),h(1),x(n.translations.uncovered),h(3),g("ngClass",xe(53,pt,"coverable"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"coverable"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"coverable"!==n.settings.sortBy)),h(1),x(n.translations.coverable),h(3),g("ngClass",xe(57,pt,"total"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"total"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"total"!==n.settings.sortBy)),h(1),x(n.translations.total),h(3),g("ngClass",xe(61,pt,"coverage"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"coverage"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"coverage"!==n.settings.sortBy)),h(1),x(n.translations.percentage),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(2),g("ngForOf",n.codeElements)}}let KS=(()=>{class e{constructor(n){this.queryString="",this.historicCoverageExecutionTimes=[],this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.codeElements=[],this.translations={},this.settings=new hT,this.window=n.nativeWindow}ngOnInit(){this.historicCoverageExecutionTimes=this.window.historicCoverageExecutionTimes,this.branchCoverageAvailable=this.window.branchCoverageAvailable,this.methodCoverageAvailable=this.window.methodCoverageAvailable,this.translations=this.window.translations;let n=!1;if(void 0!==this.window.history&&void 0!==this.window.history.replaceState&&null!==this.window.history.state&&null!=this.window.history.state.coverageInfoSettings)console.log("Coverage info: Restoring from history",this.window.history.state.coverageInfoSettings),n=!0,this.settings=JSON.parse(JSON.stringify(this.window.history.state.coverageInfoSettings));else{let o=0,i=this.window.assemblies;for(let s=0;s<i.length;s++)for(let a=0;a<i[s].classes.length;a++)o=Math.max(o,(i[s].classes[a].name.match(/\./g)||[]).length);this.settings.groupingMaximum=o,console.log("Grouping maximum: "+o)}const r=window.location.href.indexOf("?");r>-1&&(this.queryString=window.location.href.substr(r)),this.updateCoverageInfo(),n&&this.restoreCollapseState()}onDonBeforeUnlodad(){if(this.saveCollapseState(),void 0!==this.window.history&&void 0!==this.window.history.replaceState){console.log("Coverage info: Updating history",this.settings);let n=new q_;null!==window.history.state&&(n=JSON.parse(JSON.stringify(this.window.history.state))),n.coverageInfoSettings=JSON.parse(JSON.stringify(this.settings)),window.history.replaceState(n,"")}}updateCoverageInfo(){let n=(new Date).getTime(),r=this.window.assemblies,o=[],i=0;if(0===this.settings.grouping)for(let l=0;l<r.length;l++){let u=new vn(r[l].name,null);o.push(u);for(let c=0;c<r[l].classes.length;c++)u.insertClass(new Zu(r[l].classes[c],this.queryString),null),i++}else if(-1===this.settings.grouping){let l=new vn(this.translations.all,null);o.push(l);for(let u=0;u<r.length;u++)for(let c=0;c<r[u].classes.length;c++)l.insertClass(new Zu(r[u].classes[c],this.queryString),null),i++}else for(let l=0;l<r.length;l++){let u=new vn(r[l].name,null);o.push(u);for(let c=0;c<r[l].classes.length;c++)u.insertClass(new Zu(r[l].classes[c],this.queryString),this.settings.grouping),i++}let s=-1,a=1;"name"===this.settings.sortBy&&(s="asc"===this.settings.sortOrder?-1:1,a="asc"===this.settings.sortOrder?1:-1),o.sort(function(l,u){return l.name===u.name?0:l.name<u.name?s:a}),vn.sortCodeElementViewModels(o,this.settings.sortBy,"asc"===this.settings.sortOrder);for(let l=0;l<o.length;l++)o[l].changeSorting(this.settings.sortBy,"asc"===this.settings.sortOrder);this.codeElements=o,console.log(`Processing assemblies finished (Duration: ${(new Date).getTime()-n}ms, Assemblies: ${o.length}, Classes: ${i})`),""!==this.settings.historyComparisionDate&&this.updateCurrentHistoricCoverage()}updateCurrentHistoricCoverage(){let n=(new Date).getTime();for(let r=0;r<this.codeElements.length;r++)this.codeElements[r].updateCurrentHistoricCoverage(this.settings.historyComparisionDate);console.log(`Updating current historic coverage finished (Duration: ${(new Date).getTime()-n}ms)`)}collapseAll(n){n.preventDefault();for(let r=0;r<this.codeElements.length;r++)this.codeElements[r].collapse()}expandAll(n){n.preventDefault();for(let r=0;r<this.codeElements.length;r++)this.codeElements[r].expand()}updateSorting(n,r){r.preventDefault(),this.settings.sortOrder=n===this.settings.sortBy&&"asc"===this.settings.sortOrder?"desc":"asc",this.settings.sortBy=n,console.log(`Updating sort column: '${this.settings.sortBy}' (${this.settings.sortOrder})`),vn.sortCodeElementViewModels(this.codeElements,this.settings.sortBy,"asc"===this.settings.sortOrder);for(let o=0;o<this.codeElements.length;o++)this.codeElements[o].changeSorting(this.settings.sortBy,"asc"===this.settings.sortOrder)}saveCollapseState(){this.settings.collapseStates=[];let n=r=>{for(let o=0;o<r.length;o++)this.settings.collapseStates.push(r[o].collapsed),n(r[o].subElements)};n(this.codeElements)}restoreCollapseState(){let n=0,r=o=>{for(let i=0;i<o.length;i++)this.settings.collapseStates.length>n&&(o[i].collapsed=this.settings.collapseStates[n]),n++,r(o[i].subElements)};r(this.codeElements)}}return e.\u0275fac=function(n){return new(n||e)(A(Yu))},e.\u0275cmp=rn({type:e,selectors:[["coverage-info"]],hostBindings:function(n,r){1&n&&z("beforeunload",function(){return r.onDonBeforeUnlodad()},!1,Ma)},decls:1,vars:1,consts:[[4,"ngIf"],[1,"customizebox"],["href","#",3,"click"],[1,"center"],["type","range","step","1","min","-1",3,"max","ngModel","ngModelChange"],[1,"right"],["type","text",3,"ngModel","ngModelChange"],[1,"table-responsive"],[1,"overview","table-fixed","stripped"],[1,"column-min-200"],[1,"column90"],[1,"column105"],[1,"column100"],[1,"column70"],[1,"column98"],[1,"column112"],["class","column90",4,"ngIf"],["class","column70",4,"ngIf"],["class","column98",4,"ngIf"],["class","column112",4,"ngIf"],[1,"header"],["colspan","6",1,"center"],["class","center","colspan","4",4,"ngIf"],[1,"icon-down-dir",3,"ngClass"],["colspan","2",1,"center"],["class","right",4,"ngIf"],["class","center","colspan","2",4,"ngIf"],[4,"ngFor","ngForOf"],[3,"ngModel","ngModelChange"],["value",""],[3,"value",4,"ngFor","ngForOf"],[3,"value"],["value","allChanges"],["value","lineCoverageIncreaseOnly"],["value","lineCoverageDecreaseOnly"],["value","branchCoverageIncreaseOnly",4,"ngIf"],["value","branchCoverageDecreaseOnly",4,"ngIf"],["value","methodCoverageIncreaseOnly",4,"ngIf"],["value","methodCoverageDecreaseOnly",4,"ngIf"],["value","branchCoverageIncreaseOnly"],["value","branchCoverageDecreaseOnly"],["value","methodCoverageIncreaseOnly"],["value","methodCoverageDecreaseOnly"],["colspan","4",1,"center"],["codeelement-row","",3,"element","collapsed","branchCoverageAvailable","methodCoverageAvailable",4,"ngIf"],["codeelement-row","",3,"element","collapsed","branchCoverageAvailable","methodCoverageAvailable"],["class-row","",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate",4,"ngIf"],["class-row","",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate"],["codeelement-row","",1,"namespace",3,"element","collapsed","branchCoverageAvailable","methodCoverageAvailable"],["class","namespace","class-row","",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate",4,"ngIf"],["class-row","",1,"namespace",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate"]],template:function(n,r){1&n&&E(0,YS,79,65,"div",0),2&n&&g("ngIf",r.codeElements.length>0)},directives:[xr,ju,Eo,Au,hs,So,Gu,Wu,fu,Do,ST,pS],encapsulation:2}),e})();class JS{constructor(){this.assembly="",this.numberOfRiskHotspots=10,this.filter="",this.sortBy="",this.sortOrder="asc"}}function XS(e,t){if(1&e&&(y(0,"option",15),b(1),v()),2&e){const n=t.$implicit;g("value",n),h(1),x(n)}}function ex(e,t){if(1&e&&(y(0,"span"),b(1),v()),2&e){const n=C(2);h(1),x(n.translations.top)}}function tx(e,t){1&e&&(y(0,"option",22),b(1,"20"),v())}function nx(e,t){1&e&&(y(0,"option",23),b(1,"50"),v())}function rx(e,t){1&e&&(y(0,"option",24),b(1,"100"),v())}function ox(e,t){if(1&e&&(y(0,"option",15),b(1),v()),2&e){const n=C(3);g("value",n.totalNumberOfRiskHotspots),h(1),x(n.translations.all)}}function ix(e,t){if(1&e){const n=rt();y(0,"select",16),z("ngModelChange",function(o){return ee(n),C(2).settings.numberOfRiskHotspots=o}),y(1,"option",17),b(2,"10"),v(),E(3,tx,2,0,"option",18),E(4,nx,2,0,"option",19),E(5,rx,2,0,"option",20),E(6,ox,2,2,"option",21),v()}if(2&e){const n=C(2);g("ngModel",n.settings.numberOfRiskHotspots),h(3),g("ngIf",n.totalNumberOfRiskHotspots>10),h(1),g("ngIf",n.totalNumberOfRiskHotspots>20),h(1),g("ngIf",n.totalNumberOfRiskHotspots>50),h(1),g("ngIf",n.totalNumberOfRiskHotspots>100)}}function sx(e,t){1&e&&F(0,"col",25)}const ps=function(e,t,n){return{"icon-up-dir_active":e,"icon-down-dir_active":t,"icon-down-dir":n}};function ax(e,t){if(1&e){const n=rt();y(0,"th")(1,"a",12),z("click",function(o){const s=ee(n).index;return C(2).updateSorting(""+s,o)}),F(2,"i",13),b(3),v(),y(4,"a",26),F(5,"i",27),v()()}if(2&e){const n=t.$implicit,r=t.index,o=C(2);h(2),g("ngClass",xe(3,ps,o.settings.sortBy===""+r&&"desc"===o.settings.sortOrder,o.settings.sortBy===""+r&&"asc"===o.settings.sortOrder,o.settings.sortBy!==""+r)),h(1),x(n.name),h(1),wr("href",n.explanationUrl,rr)}}const lx=function(e,t){return{lightred:e,lightgreen:t}};function ux(e,t){if(1&e&&(y(0,"td",30),b(1),v()),2&e){const n=t.$implicit;g("ngClass",xl(2,lx,n.exceeded,!n.exceeded)),h(1),x(n.value)}}function cx(e,t){if(1&e&&(y(0,"tr")(1,"td"),b(2),v(),y(3,"td")(4,"a",26),b(5),v()(),y(6,"td",28)(7,"a",26),b(8),v()(),E(9,ux,2,5,"td",29),v()),2&e){const n=t.$implicit,r=C(2);h(2),x(n.assembly),h(2),g("href",n.reportPath+r.queryString,rr),h(1),x(n.class),h(1),g("title",n.methodName),h(1),g("href",n.reportPath+r.queryString+"#file"+n.fileIndex+"_line"+n.line,rr),h(1),q(" ",n.methodShortName," "),h(1),g("ngForOf",n.metrics)}}function dx(e,t){if(1&e){const n=rt();y(0,"div")(1,"div",1)(2,"div")(3,"select",2),z("ngModelChange",function(o){return ee(n),C().settings.assembly=o})("ngModelChange",function(){return ee(n),C().updateRiskHotpots()}),y(4,"option",3),b(5),v(),E(6,XS,2,2,"option",4),v()(),y(7,"div",5),E(8,ex,2,1,"span",0),E(9,ix,7,5,"select",6),v(),F(10,"div",5),y(11,"div",7)(12,"span"),b(13),v(),y(14,"input",8),z("ngModelChange",function(o){return ee(n),C().settings.filter=o})("ngModelChange",function(){return ee(n),C().updateRiskHotpots()}),v()()(),y(15,"div",9)(16,"table",10)(17,"colgroup"),F(18,"col")(19,"col")(20,"col"),E(21,sx,1,0,"col",11),v(),y(22,"thead")(23,"tr")(24,"th")(25,"a",12),z("click",function(o){return ee(n),C().updateSorting("assembly",o)}),F(26,"i",13),b(27),v()(),y(28,"th")(29,"a",12),z("click",function(o){return ee(n),C().updateSorting("class",o)}),F(30,"i",13),b(31),v()(),y(32,"th")(33,"a",12),z("click",function(o){return ee(n),C().updateSorting("method",o)}),F(34,"i",13),b(35),v()(),E(36,ax,6,7,"th",14),v()(),y(37,"tbody"),E(38,cx,10,7,"tr",14),function mg(e,t){const n=K();let r;const o=e+20;n.firstCreatePass?(r=function xE(e,t){if(t)for(let n=t.length-1;n>=0;n--){const r=t[n];if(e===r.name)return r}}(t,n.pipeRegistry),n.data[o]=r,r.onDestroy&&(n.destroyHooks||(n.destroyHooks=[])).push(o,r.onDestroy)):r=n.data[o];const i=r.factory||(r.factory=An(r.type)),s=tn(A);try{const a=Xo(!1),l=i();return Xo(a),function Zw(e,t,n,r){n>=e.data.length&&(e.data[n]=null,e.blueprint[n]=null),t[n]=r}(n,w(),o,l),l}finally{tn(s)}}(39,"slice"),v()()()()}if(2&e){const n=C();h(3),g("ngModel",n.settings.assembly),h(2),x(n.translations.assembly),h(1),g("ngForOf",n.assemblies),h(2),g("ngIf",n.totalNumberOfRiskHotspots>10),h(1),g("ngIf",n.totalNumberOfRiskHotspots>10),h(4),q("",n.translations.filter," "),h(1),g("ngModel",n.settings.filter),h(7),g("ngForOf",n.riskHotspotMetrics),h(5),g("ngClass",xe(20,ps,"assembly"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"assembly"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"assembly"!==n.settings.sortBy)),h(1),x(n.translations.assembly),h(3),g("ngClass",xe(24,ps,"class"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"class"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"class"!==n.settings.sortBy)),h(1),x(n.translations.class),h(3),g("ngClass",xe(28,ps,"method"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"method"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"method"!==n.settings.sortBy)),h(1),x(n.translations.method),h(1),g("ngForOf",n.riskHotspotMetrics),h(2),g("ngForOf",function _g(e,t,n,r,o){const i=e+20,s=w(),a=function Gn(e,t){return e[t]}(s,i);return function go(e,t){return e[1].data[t].pure}(s,i)?hg(s,He(),t,a.transform,n,r,o,a):a.transform(n,r,o)}(39,16,n.riskHotspots,0,n.settings.numberOfRiskHotspots))}}let fx=(()=>{class e{constructor(n){this.queryString="",this.riskHotspotMetrics=[],this.riskHotspots=[],this.totalNumberOfRiskHotspots=0,this.assemblies=[],this.translations={},this.settings=new JS,this.window=n.nativeWindow}ngOnInit(){this.riskHotspotMetrics=this.window.riskHotspotMetrics,this.translations=this.window.translations,void 0!==this.window.history&&void 0!==this.window.history.replaceState&&null!==this.window.history.state&&null!=this.window.history.state.riskHotspotsSettings&&(console.log("Risk hotspots: Restoring from history",this.window.history.state.riskHotspotsSettings),this.settings=JSON.parse(JSON.stringify(this.window.history.state.riskHotspotsSettings)));const n=window.location.href.indexOf("?");n>-1&&(this.queryString=window.location.href.substr(n)),this.updateRiskHotpots()}onDonBeforeUnlodad(){if(void 0!==this.window.history&&void 0!==this.window.history.replaceState){console.log("Risk hotspots: Updating history",this.settings);let n=new q_;null!==window.history.state&&(n=JSON.parse(JSON.stringify(this.window.history.state))),n.riskHotspotsSettings=JSON.parse(JSON.stringify(this.settings)),window.history.replaceState(n,"")}}updateRiskHotpots(){const n=this.window.riskHotspots;if(this.totalNumberOfRiskHotspots=n.length,0===this.assemblies.length){let s=[];for(let a=0;a<n.length;a++)-1===s.indexOf(n[a].assembly)&&s.push(n[a].assembly);this.assemblies=s.sort()}let r=[];for(let s=0;s<n.length;s++)""!==this.settings.filter&&-1===n[s].class.toLowerCase().indexOf(this.settings.filter)||""!==this.settings.assembly&&n[s].assembly!==this.settings.assembly||r.push(n[s]);let o="asc"===this.settings.sortOrder?-1:1,i="asc"===this.settings.sortOrder?1:-1;if("assembly"===this.settings.sortBy)r.sort(function(s,a){return s.assembly===a.assembly?0:s.assembly<a.assembly?o:i});else if("class"===this.settings.sortBy)r.sort(function(s,a){return s.class===a.class?0:s.class<a.class?o:i});else if("method"===this.settings.sortBy)r.sort(function(s,a){return s.methodShortName===a.methodShortName?0:s.methodShortName<a.methodShortName?o:i});else if(""!==this.settings.sortBy){let s=parseInt(this.settings.sortBy,10);r.sort(function(a,l){return a.metrics[s].value===l.metrics[s].value?0:a.metrics[s].value<l.metrics[s].value?o:i})}this.riskHotspots=r}updateSorting(n,r){r.preventDefault(),this.settings.sortOrder=n===this.settings.sortBy&&"asc"===this.settings.sortOrder?"desc":"asc",this.settings.sortBy=n,console.log(`Updating sort column: '${this.settings.sortBy}' (${this.settings.sortOrder})`),this.updateRiskHotpots()}}return e.\u0275fac=function(n){return new(n||e)(A(Yu))},e.\u0275cmp=rn({type:e,selectors:[["risk-hotspots"]],hostBindings:function(n,r){1&n&&z("beforeunload",function(){return r.onDonBeforeUnlodad()},!1,Ma)},decls:1,vars:1,consts:[[4,"ngIf"],[1,"customizebox"],["name","assembly",3,"ngModel","ngModelChange"],["value",""],[3,"value",4,"ngFor","ngForOf"],[1,"center"],[3,"ngModel","ngModelChange",4,"ngIf"],[1,"right"],["type","text",3,"ngModel","ngModelChange"],[1,"table-responsive"],[1,"overview","table-fixed","stripped"],["class","column105",4,"ngFor","ngForOf"],["href","#",3,"click"],[1,"icon-down-dir",3,"ngClass"],[4,"ngFor","ngForOf"],[3,"value"],[3,"ngModel","ngModelChange"],["value","10"],["value","20",4,"ngIf"],["value","50",4,"ngIf"],["value","100",4,"ngIf"],[3,"value",4,"ngIf"],["value","20"],["value","50"],["value","100"],[1,"column105"],[3,"href"],[1,"icon-info-circled"],[3,"title"],["class","right",3,"ngClass",4,"ngFor","ngForOf"],[1,"right",3,"ngClass"]],template:function(n,r){1&n&&E(0,dx,40,32,"div",0),2&n&&g("ngIf",r.totalNumberOfRiskHotspots>0)},directives:[xr,So,Au,hs,Gu,Wu,fu,Eo,Do],pipes:[Am],encapsulation:2}),e})(),hx=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e,bootstrap:[fx,KS]}),e.\u0275inj=Gt({providers:[Yu],imports:[[QI,fT]]}),e})();(function L1(){tm=!1})(),qI().bootstrapModule(hx).catch(e=>console.error(e))}},pe=>{pe(pe.s=873)}]); \ No newline at end of file diff --git a/ld_client/doc/coverage/coveragereport/report.css b/ld_client/doc/coverage/coveragereport/report.css new file mode 100644 index 0000000..06b6d2d --- /dev/null +++ b/ld_client/doc/coverage/coveragereport/report.css @@ -0,0 +1,736 @@ +html { font-family: sans-serif; margin: 0; padding: 0; font-size: 0.9em; background-color: #d6d6d6; height: 100%; } +body { margin: 0; padding: 0; height: 100%; color: #000; } +h1 { font-family: 'Century Gothic', sans-serif; font-size: 1.2em; font-weight: normal; color: #fff; background-color: #6f6f6f; padding: 10px; margin: 20px -20px 20px -20px; } +h1:first-of-type { margin-top: 0; } +h2 { font-size: 1.0em; font-weight: bold; margin: 10px 0 15px 0; padding: 0; } +h3 { font-size: 1.0em; font-weight: bold; margin: 0 0 10px 0; padding: 0; display: inline-block; } +a { color: #c00; text-decoration: none; } +a:hover { color: #000; text-decoration: none; } +h1 a.back { color: #fff; background-color: #949494; display: inline-block; margin: -12px 5px -10px -10px; padding: 10px; border-right: 1px solid #fff; } +h1 a.back:hover { background-color: #ccc; } +h1 a.button { color: #000; background-color: #bebebe; margin: -5px 0 0 10px; padding: 5px 8px 5px 8px; border: 1px solid #fff; font-size: 0.9em; border-radius: 3px; float:right; } +h1 a.button:hover { background-color: #ccc; } +h1 a.button i { position: relative; top: 1px; } + +.container { margin: auto; max-width: 1650px; width: 90%; background-color: #fff; display: flex; box-shadow: 0 0 60px #7d7d7d; min-height: 100%; } +.containerleft { padding: 0 20px 20px 20px; flex: 1; min-width: 1%; } +.containerright { width: 340px; min-width: 340px; background-color: #e5e5e5; height: 100%; } +.containerrightfixed { position: fixed; padding: 0 20px 20px 20px; border-left: 1px solid #6f6f6f; width: 300px; overflow-y: auto; height: 100%; top: 0; bottom: 0; } +.containerrightfixed h1 { background-color: #c00; } +.containerrightfixed label, .containerright a { white-space: nowrap; overflow: hidden; display: inline-block; width: 100%; max-width: 300px; text-overflow: ellipsis; } +.containerright a { margin-bottom: 3px; } + +@media screen and (max-width:1200px){ + .container { box-shadow: none; width: 100%; } + .containerright { display: none; } +} + +.footer { font-size: 0.7em; text-align: center; margin-top: 35px; } + +.card-group { display: flex; flex-wrap: wrap; margin-top: -15px; margin-left: -15px; } +.card-group + .card-group { margin-top: 0; } +.card-group .card { margin-top: 15px; margin-left: 15px; display: flex; flex-direction: column; background-color: #e4e4e4; background: radial-gradient(circle, #fefefe 0%, #f6f6f6 100%); border: 1px solid #c1c1c1; padding: 15px; color: #6f6f6f; max-width: 100% } +.card-group .card .card-header { font-size: 1.5rem; font-family: 'Century Gothic', sans-serif; margin-bottom: 15px; flex-grow: 1; } +.card-group .card .card-body { display: flex; flex-direction: row; gap: 15px; flex-grow: 1; } +.card-group .card .card-body div.table { display: flex; flex-direction: column; } +.card-group .card .large { font-size: 5rem; line-height: 5rem; font-weight: bold; align-self: flex-end; border-left-width: 4px; padding-left: 10px; } +.card-group .card table { align-self: flex-end; border-collapse: collapse; } +.card-group .card table tr { border-bottom: 1px solid #c1c1c1; } +.card-group .card table tr:hover { background-color: #c1c1c1; } +.card-group .card table tr:last-child { border-bottom: none; } +.card-group .card table th, .card-group .card table td { padding: 2px; } +.card-group td.limit-width { max-width: 200px; text-overflow: ellipsis; overflow: hidden; } +.card-group td.overflow-wrap { overflow-wrap: anywhere; } + +.pro-button { color: #fff; background-color: #20A0D2; background-image: linear-gradient(50deg, #1c7ed6 0%, #23b8cf 100%); padding: 10px; border-radius: 3px; font-weight: bold; display: inline-block; } +.pro-button:hover { color: #fff; background-color: #1C8EB7; background-image: linear-gradient(50deg, #1A6FBA 0%, #1EA1B5 100%); } + +th { text-align: left; } +.table-fixed { table-layout: fixed; } +.table-responsive { overflow-x: auto; } +.overview { border: 1px solid #c1c1c1; border-collapse: collapse; width: 100%; word-wrap: break-word; } +.overview th { border: 1px solid #c1c1c1; border-collapse: collapse; padding: 2px 4px 2px 4px; background-color: #ddd; } +.overview tr.namespace th { background-color: #dcdcdc; } +.overview thead th { background-color: #d1d1d1; } +.overview th a { color: #000; } +.overview tr.namespace a { margin-left: 15px; display: block; } +.overview td { border: 1px solid #c1c1c1; border-collapse: collapse; padding: 2px 5px 2px 5px; } +.overview tr.header th { background-color: #d1d1d1; } +.overview tr.header th:nth-child(2n+1) { background-color: #ddd; } +.overview tr.header th:first-child { border-left: 1px solid #fff; border-top: 1px solid #fff; background-color: #fff; } + +div.currenthistory { margin: -2px -5px 0 -5px; padding: 2px 5px 2px 5px; height: 16px; } +.coverage { border-collapse: collapse; font-size: 5px; height: 10px; } +.coverage td { padding: 0; border: none; } +.stripped tr:nth-child(2n+1) { background-color: #F3F3F3; } + +.customizebox { font-size: 0.75em; margin-bottom: 7px; } +.customizebox>div { width: 25%; display: inline-block; } +.customizebox div.right input { width: 150px; } +#namespaceslider { width: 200px; display: inline-block; margin-left: 8px; } + +.percentagebar { + padding-left: 3px; +} +a.percentagebar { + padding-left: 6px; +} +.percentagebarundefined { + border-left: 2px solid #fff; +} +.percentagebar0 { + border-left: 2px solid #c10909; +} +.percentagebar10 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 90%, #0aad0a 90%, #0aad0a 100%) 1; +} +.percentagebar20 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 80%, #0aad0a 80%, #0aad0a 100%) 1; +} +.percentagebar30 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 70%, #0aad0a 70%, #0aad0a 100%) 1; +} +.percentagebar40 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 60%, #0aad0a 60%, #0aad0a 100%) 1; +} +.percentagebar50 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 50%, #0aad0a 50%, #0aad0a 100%) 1; +} +.percentagebar60 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 40%, #0aad0a 40%, #0aad0a 100%) 1; +} +.percentagebar70 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 30%, #0aad0a 30%, #0aad0a 100%) 1; +} +.percentagebar80 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 20%, #0aad0a 20%, #0aad0a 100%) 1; +} +.percentagebar90 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 10%, #0aad0a 10%, #0aad0a 100%) 1; +} +.percentagebar100 { + border-left: 2px solid #0aad0a; +} + +.hidden, .ng-hide { display: none; } +.right { text-align: right; } +.center { text-align: center; } +.rightmargin { padding-right: 8px; } +.leftmargin { padding-left: 5px; } +.green { background-color: #0aad0a; } +.lightgreen { background-color: #dcf4dc; } +.red { background-color: #c10909; } +.lightred { background-color: #f7dede; } +.orange { background-color: #FFA500; } +.lightorange { background-color: #FFEFD5; } +.gray { background-color: #dcdcdc; } +.lightgray { color: #888888; } +.lightgraybg { background-color: #dadada; } + +code { font-family: Consolas, monospace; font-size: 0.9em; } + +.toggleZoom { text-align:right; } + +.ct-chart { position: relative; } +.ct-chart .ct-line { stroke-width: 2px !important; } +.ct-chart .ct-point { stroke-width: 6px !important; transition: stroke-width .2s; } +.ct-chart .ct-point:hover { stroke-width: 10px !important; } +.ct-chart .ct-series.ct-series-a .ct-line, .ct-chart .ct-series.ct-series-a .ct-point { stroke: #c00 !important;} +.ct-chart .ct-series.ct-series-b .ct-line, .ct-chart .ct-series.ct-series-b .ct-point { stroke: #1c2298 !important;} +.ct-chart .ct-series.ct-series-c .ct-line, .ct-chart .ct-series.ct-series-c .ct-point { stroke: #0aad0a !important;} + +.tinylinecoveragechart, .tinybranchcoveragechart, .tinymethodcoveragechart { background-color: #fff; margin-left: -3px; float: left; border: 1px solid #c1c1c1; width: 30px; height: 18px; } +.historiccoverageoffset { margin-top: 7px; } + +.tinylinecoveragechart .ct-line, .tinybranchcoveragechart .ct-line, .tinymethodcoveragechart .ct-line { stroke-width: 1px !important; } +.tinybranchcoveragechart .ct-series.ct-series-a .ct-line { stroke: #1c2298 !important; } +.tinymethodcoveragechart .ct-series.ct-series-a .ct-line { stroke: #0aad0a !important; } + +.linecoverage { background-color: #c00; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; } +.branchcoverage { background-color: #1c2298; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; } +.codeelementcoverage { background-color: #0aad0a; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; } + +.tooltip { position: absolute; display: none; padding: 5px; background: #F4C63D; color: #453D3F; pointer-events: none; z-index: 1; min-width: 250px; } + +.column-min-200 { min-width: 200px; } +.column60 { width: 60px; } +.column70 { width: 70px; } +.column90 { width: 90px; } +.column98 { width: 98px; } +.column100 { width: 100px; } +.column105 { width: 105px; } +.column112 { width: 112px; } + +.cardpercentagebar { border-left-style: solid; } +.cardpercentagebar0 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 0%, #0aad0a 0%) 1; } +.cardpercentagebar1 { border-image: linear-gradient(to bottom, #c10909 1%, #c10909 1%, #0aad0a 1%) 1; } +.cardpercentagebar2 { border-image: linear-gradient(to bottom, #c10909 2%, #c10909 2%, #0aad0a 2%) 1; } +.cardpercentagebar3 { border-image: linear-gradient(to bottom, #c10909 3%, #c10909 3%, #0aad0a 3%) 1; } +.cardpercentagebar4 { border-image: linear-gradient(to bottom, #c10909 4%, #c10909 4%, #0aad0a 4%) 1; } +.cardpercentagebar5 { border-image: linear-gradient(to bottom, #c10909 5%, #c10909 5%, #0aad0a 5%) 1; } +.cardpercentagebar6 { border-image: linear-gradient(to bottom, #c10909 6%, #c10909 6%, #0aad0a 6%) 1; } +.cardpercentagebar7 { border-image: linear-gradient(to bottom, #c10909 7%, #c10909 7%, #0aad0a 7%) 1; } +.cardpercentagebar8 { border-image: linear-gradient(to bottom, #c10909 8%, #c10909 8%, #0aad0a 8%) 1; } +.cardpercentagebar9 { border-image: linear-gradient(to bottom, #c10909 9%, #c10909 9%, #0aad0a 9%) 1; } +.cardpercentagebar10 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 10%, #0aad0a 10%) 1; } +.cardpercentagebar11 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 11%, #0aad0a 11%) 1; } +.cardpercentagebar12 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 12%, #0aad0a 12%) 1; } +.cardpercentagebar13 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 13%, #0aad0a 13%) 1; } +.cardpercentagebar14 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 14%, #0aad0a 14%) 1; } +.cardpercentagebar15 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 15%, #0aad0a 15%) 1; } +.cardpercentagebar16 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 16%, #0aad0a 16%) 1; } +.cardpercentagebar17 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 17%, #0aad0a 17%) 1; } +.cardpercentagebar18 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 18%, #0aad0a 18%) 1; } +.cardpercentagebar19 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 19%, #0aad0a 19%) 1; } +.cardpercentagebar20 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 20%, #0aad0a 20%) 1; } +.cardpercentagebar21 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 21%, #0aad0a 21%) 1; } +.cardpercentagebar22 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 22%, #0aad0a 22%) 1; } +.cardpercentagebar23 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 23%, #0aad0a 23%) 1; } +.cardpercentagebar24 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 24%, #0aad0a 24%) 1; } +.cardpercentagebar25 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 25%, #0aad0a 25%) 1; } +.cardpercentagebar26 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 26%, #0aad0a 26%) 1; } +.cardpercentagebar27 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 27%, #0aad0a 27%) 1; } +.cardpercentagebar28 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 28%, #0aad0a 28%) 1; } +.cardpercentagebar29 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 29%, #0aad0a 29%) 1; } +.cardpercentagebar30 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 30%, #0aad0a 30%) 1; } +.cardpercentagebar31 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 31%, #0aad0a 31%) 1; } +.cardpercentagebar32 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 32%, #0aad0a 32%) 1; } +.cardpercentagebar33 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 33%, #0aad0a 33%) 1; } +.cardpercentagebar34 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 34%, #0aad0a 34%) 1; } +.cardpercentagebar35 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 35%, #0aad0a 35%) 1; } +.cardpercentagebar36 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 36%, #0aad0a 36%) 1; } +.cardpercentagebar37 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 37%, #0aad0a 37%) 1; } +.cardpercentagebar38 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 38%, #0aad0a 38%) 1; } +.cardpercentagebar39 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 39%, #0aad0a 39%) 1; } +.cardpercentagebar40 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 40%, #0aad0a 40%) 1; } +.cardpercentagebar41 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 41%, #0aad0a 41%) 1; } +.cardpercentagebar42 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 42%, #0aad0a 42%) 1; } +.cardpercentagebar43 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 43%, #0aad0a 43%) 1; } +.cardpercentagebar44 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 44%, #0aad0a 44%) 1; } +.cardpercentagebar45 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 45%, #0aad0a 45%) 1; } +.cardpercentagebar46 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 46%, #0aad0a 46%) 1; } +.cardpercentagebar47 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 47%, #0aad0a 47%) 1; } +.cardpercentagebar48 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 48%, #0aad0a 48%) 1; } +.cardpercentagebar49 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 49%, #0aad0a 49%) 1; } +.cardpercentagebar50 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 50%, #0aad0a 50%) 1; } +.cardpercentagebar51 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 51%, #0aad0a 51%) 1; } +.cardpercentagebar52 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 52%, #0aad0a 52%) 1; } +.cardpercentagebar53 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 53%, #0aad0a 53%) 1; } +.cardpercentagebar54 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 54%, #0aad0a 54%) 1; } +.cardpercentagebar55 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 55%, #0aad0a 55%) 1; } +.cardpercentagebar56 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 56%, #0aad0a 56%) 1; } +.cardpercentagebar57 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 57%, #0aad0a 57%) 1; } +.cardpercentagebar58 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 58%, #0aad0a 58%) 1; } +.cardpercentagebar59 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 59%, #0aad0a 59%) 1; } +.cardpercentagebar60 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 60%, #0aad0a 60%) 1; } +.cardpercentagebar61 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 61%, #0aad0a 61%) 1; } +.cardpercentagebar62 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 62%, #0aad0a 62%) 1; } +.cardpercentagebar63 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 63%, #0aad0a 63%) 1; } +.cardpercentagebar64 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 64%, #0aad0a 64%) 1; } +.cardpercentagebar65 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 65%, #0aad0a 65%) 1; } +.cardpercentagebar66 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 66%, #0aad0a 66%) 1; } +.cardpercentagebar67 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 67%, #0aad0a 67%) 1; } +.cardpercentagebar68 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 68%, #0aad0a 68%) 1; } +.cardpercentagebar69 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 69%, #0aad0a 69%) 1; } +.cardpercentagebar70 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 70%, #0aad0a 70%) 1; } +.cardpercentagebar71 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 71%, #0aad0a 71%) 1; } +.cardpercentagebar72 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 72%, #0aad0a 72%) 1; } +.cardpercentagebar73 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 73%, #0aad0a 73%) 1; } +.cardpercentagebar74 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 74%, #0aad0a 74%) 1; } +.cardpercentagebar75 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 75%, #0aad0a 75%) 1; } +.cardpercentagebar76 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 76%, #0aad0a 76%) 1; } +.cardpercentagebar77 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 77%, #0aad0a 77%) 1; } +.cardpercentagebar78 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 78%, #0aad0a 78%) 1; } +.cardpercentagebar79 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 79%, #0aad0a 79%) 1; } +.cardpercentagebar80 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 80%, #0aad0a 80%) 1; } +.cardpercentagebar81 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 81%, #0aad0a 81%) 1; } +.cardpercentagebar82 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 82%, #0aad0a 82%) 1; } +.cardpercentagebar83 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 83%, #0aad0a 83%) 1; } +.cardpercentagebar84 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 84%, #0aad0a 84%) 1; } +.cardpercentagebar85 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 85%, #0aad0a 85%) 1; } +.cardpercentagebar86 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 86%, #0aad0a 86%) 1; } +.cardpercentagebar87 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 87%, #0aad0a 87%) 1; } +.cardpercentagebar88 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 88%, #0aad0a 88%) 1; } +.cardpercentagebar89 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 89%, #0aad0a 89%) 1; } +.cardpercentagebar90 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 90%, #0aad0a 90%) 1; } +.cardpercentagebar91 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 91%, #0aad0a 91%) 1; } +.cardpercentagebar92 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 92%, #0aad0a 92%) 1; } +.cardpercentagebar93 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 93%, #0aad0a 93%) 1; } +.cardpercentagebar94 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 94%, #0aad0a 94%) 1; } +.cardpercentagebar95 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 95%, #0aad0a 95%) 1; } +.cardpercentagebar96 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 96%, #0aad0a 96%) 1; } +.cardpercentagebar97 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 97%, #0aad0a 97%) 1; } +.cardpercentagebar98 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 98%, #0aad0a 98%) 1; } +.cardpercentagebar99 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 99%, #0aad0a 99%) 1; } +.cardpercentagebar100 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 100%, #0aad0a 100%) 1; } + +.covered0 { width: 0px; } +.covered1 { width: 1px; } +.covered2 { width: 2px; } +.covered3 { width: 3px; } +.covered4 { width: 4px; } +.covered5 { width: 5px; } +.covered6 { width: 6px; } +.covered7 { width: 7px; } +.covered8 { width: 8px; } +.covered9 { width: 9px; } +.covered10 { width: 10px; } +.covered11 { width: 11px; } +.covered12 { width: 12px; } +.covered13 { width: 13px; } +.covered14 { width: 14px; } +.covered15 { width: 15px; } +.covered16 { width: 16px; } +.covered17 { width: 17px; } +.covered18 { width: 18px; } +.covered19 { width: 19px; } +.covered20 { width: 20px; } +.covered21 { width: 21px; } +.covered22 { width: 22px; } +.covered23 { width: 23px; } +.covered24 { width: 24px; } +.covered25 { width: 25px; } +.covered26 { width: 26px; } +.covered27 { width: 27px; } +.covered28 { width: 28px; } +.covered29 { width: 29px; } +.covered30 { width: 30px; } +.covered31 { width: 31px; } +.covered32 { width: 32px; } +.covered33 { width: 33px; } +.covered34 { width: 34px; } +.covered35 { width: 35px; } +.covered36 { width: 36px; } +.covered37 { width: 37px; } +.covered38 { width: 38px; } +.covered39 { width: 39px; } +.covered40 { width: 40px; } +.covered41 { width: 41px; } +.covered42 { width: 42px; } +.covered43 { width: 43px; } +.covered44 { width: 44px; } +.covered45 { width: 45px; } +.covered46 { width: 46px; } +.covered47 { width: 47px; } +.covered48 { width: 48px; } +.covered49 { width: 49px; } +.covered50 { width: 50px; } +.covered51 { width: 51px; } +.covered52 { width: 52px; } +.covered53 { width: 53px; } +.covered54 { width: 54px; } +.covered55 { width: 55px; } +.covered56 { width: 56px; } +.covered57 { width: 57px; } +.covered58 { width: 58px; } +.covered59 { width: 59px; } +.covered60 { width: 60px; } +.covered61 { width: 61px; } +.covered62 { width: 62px; } +.covered63 { width: 63px; } +.covered64 { width: 64px; } +.covered65 { width: 65px; } +.covered66 { width: 66px; } +.covered67 { width: 67px; } +.covered68 { width: 68px; } +.covered69 { width: 69px; } +.covered70 { width: 70px; } +.covered71 { width: 71px; } +.covered72 { width: 72px; } +.covered73 { width: 73px; } +.covered74 { width: 74px; } +.covered75 { width: 75px; } +.covered76 { width: 76px; } +.covered77 { width: 77px; } +.covered78 { width: 78px; } +.covered79 { width: 79px; } +.covered80 { width: 80px; } +.covered81 { width: 81px; } +.covered82 { width: 82px; } +.covered83 { width: 83px; } +.covered84 { width: 84px; } +.covered85 { width: 85px; } +.covered86 { width: 86px; } +.covered87 { width: 87px; } +.covered88 { width: 88px; } +.covered89 { width: 89px; } +.covered90 { width: 90px; } +.covered91 { width: 91px; } +.covered92 { width: 92px; } +.covered93 { width: 93px; } +.covered94 { width: 94px; } +.covered95 { width: 95px; } +.covered96 { width: 96px; } +.covered97 { width: 97px; } +.covered98 { width: 98px; } +.covered99 { width: 99px; } +.covered100 { width: 100px; } + + @media print { + html, body { background-color: #fff; } + .container { max-width: 100%; width: 100%; padding: 0; } + .overview colgroup col:first-child { width: 300px; } +} + +.icon-up-dir_active { + background-image: url(icon_up-dir.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNDA4IDEyMTZxMCAyNi0xOSA0NXQtNDUgMTloLTg5NnEtMjYgMC00NS0xOXQtMTktNDUgMTktNDVsNDQ4LTQ0OHExOS0xOSA0NS0xOXQ0NSAxOWw0NDggNDQ4cTE5IDE5IDE5IDQ1eiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-down-dir_active { + background-image: url(icon_up-dir_active.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNDA4IDcwNHEwIDI2LTE5IDQ1bC00NDggNDQ4cS0xOSAxOS00NSAxOXQtNDUtMTlsLTQ0OC00NDhxLTE5LTE5LTE5LTQ1dDE5LTQ1IDQ1LTE5aDg5NnEyNiAwIDQ1IDE5dDE5IDQ1eiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-down-dir { + background-image: url(icon_down-dir_active.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNDA4IDcwNHEwIDI2LTE5IDQ1bC00NDggNDQ4cS0xOSAxOS00NSAxOXQtNDUtMTlsLTQ0OC00NDhxLTE5LTE5LTE5LTQ1dDE5LTQ1IDQ1LTE5aDg5NnEyNiAwIDQ1IDE5dDE5IDQ1eiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-info-circled { + background-image: url(icon_info-circled.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxjaXJjbGUgY3g9Ijg5NiIgY3k9Ijg5NiIgcj0iNzUwIiBmaWxsPSIjZmZmIiAvPjxwYXRoIGZpbGw9IiMyOEE1RkYiIGQ9Ik0xMTUyIDEzNzZ2LTE2MHEwLTE0LTktMjN0LTIzLTloLTk2di01MTJxMC0xNC05LTIzdC0yMy05aC0zMjBxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloOTZ2MzIwaC05NnEtMTQgMC0yMyA5dC05IDIzdjE2MHEwIDE0IDkgMjN0MjMgOWg0NDhxMTQgMCAyMy05dDktMjN6bS0xMjgtODk2di0xNjBxMC0xNC05LTIzdC0yMy05aC0xOTJxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloMTkycTE0IDAgMjMtOXQ5LTIzem02NDAgNDE2cTAgMjA5LTEwMyAzODUuNXQtMjc5LjUgMjc5LjUtMzg1LjUgMTAzLTM4NS41LTEwMy0yNzkuNS0yNzkuNS0xMDMtMzg1LjUgMTAzLTM4NS41IDI3OS41LTI3OS41IDM4NS41LTEwMyAzODUuNSAxMDMgMjc5LjUgMjc5LjUgMTAzIDM4NS41eiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; +} +.icon-plus { + background-image: url(icon_plus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjAwIDczNnYxOTJxMCA0MC0yOCA2OHQtNjggMjhoLTQxNnY0MTZxMCA0MC0yOCA2OHQtNjggMjhoLTE5MnEtNDAgMC02OC0yOHQtMjgtNjh2LTQxNmgtNDE2cS00MCAwLTY4LTI4dC0yOC02OHYtMTkycTAtNDAgMjgtNjh0NjgtMjhoNDE2di00MTZxMC00MCAyOC02OHQ2OC0yOGgxOTJxNDAgMCA2OCAyOHQyOCA2OHY0MTZoNDE2cTQwIDAgNjggMjh0MjggNjh6Ii8+PC9zdmc+); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-minus { + background-image: url(icon_minus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNjAwIDczNnYxOTJxMCA0MC0yOCA2OHQtNjggMjhoLTEyMTZxLTQwIDAtNjgtMjh0LTI4LTY4di0xOTJxMC00MCAyOC02OHQ2OC0yOGgxMjE2cTQwIDAgNjggMjh0MjggNjh6Ii8+PC9zdmc+); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-wrench { + background-image: url(icon_wrench.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik00NDggMTQ3MnEwLTI2LTE5LTQ1dC00NS0xOS00NSAxOS0xOSA0NSAxOSA0NSA0NSAxOSA0NS0xOSAxOS00NXptNjQ0LTQyMGwtNjgyIDY4MnEtMzcgMzctOTAgMzctNTIgMC05MS0zN2wtMTA2LTEwOHEtMzgtMzYtMzgtOTAgMC01MyAzOC05MWw2ODEtNjgxcTM5IDk4IDExNC41IDE3My41dDE3My41IDExNC41em02MzQtNDM1cTAgMzktMjMgMTA2LTQ3IDEzNC0xNjQuNSAyMTcuNXQtMjU4LjUgODMuNXEtMTg1IDAtMzE2LjUtMTMxLjV0LTEzMS41LTMxNi41IDEzMS41LTMxNi41IDMxNi41LTEzMS41cTU4IDAgMTIxLjUgMTYuNXQxMDcuNSA0Ni41cTE2IDExIDE2IDI4dC0xNiAyOGwtMjkzIDE2OXYyMjRsMTkzIDEwN3E1LTMgNzktNDguNXQxMzUuNS04MSA3MC41LTM1LjVxMTUgMCAyMy41IDEwdDguNSAyNXoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-fork { + background-image: url(icon_fork.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHN0eWxlPSJmaWxsOiNmZmYiIC8+PHBhdGggZD0iTTY3MiAxNDcycTAtNDAtMjgtNjh0LTY4LTI4LTY4IDI4LTI4IDY4IDI4IDY4IDY4IDI4IDY4LTI4IDI4LTY4em0wLTExNTJxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTY0MCAxMjhxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTk2IDBxMCA1Mi0yNiA5Ni41dC03MCA2OS41cS0yIDI4Ny0yMjYgNDE0LTY3IDM4LTIwMyA4MS0xMjggNDAtMTY5LjUgNzF0LTQxLjUgMTAwdjI2cTQ0IDI1IDcwIDY5LjV0MjYgOTYuNXEwIDgwLTU2IDEzNnQtMTM2IDU2LTEzNi01Ni01Ni0xMzZxMC01MiAyNi05Ni41dDcwLTY5LjV2LTgyMHEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnEwIDUyLTI2IDk2LjV0LTcwIDY5LjV2NDk3cTU0LTI2IDE1NC01NyA1NS0xNyA4Ny41LTI5LjV0NzAuNS0zMSA1OS0zOS41IDQwLjUtNTEgMjgtNjkuNSA4LjUtOTEuNXEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-cube { + background-image: url(icon_cube.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04OTYgMTYyOWw2NDAtMzQ5di02MzZsLTY0MCAyMzN2NzUyem0tNjQtODY1bDY5OC0yNTQtNjk4LTI1NC02OTggMjU0em04MzItMjUydjc2OHEwIDM1LTE4IDY1dC00OSA0N2wtNzA0IDM4NHEtMjggMTYtNjEgMTZ0LTYxLTE2bC03MDQtMzg0cS0zMS0xNy00OS00N3QtMTgtNjV2LTc2OHEwLTQwIDIzLTczdDYxLTQ3bDcwNC0yNTZxMjItOCA0NC04dDQ0IDhsNzA0IDI1NnEzOCAxNCA2MSA0N3QyMyA3M3oiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-search-plus { + background-image: url(icon_search-plus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiM2ZjZmNmYiIGQ9Ik0xMDg4IDgwMHY2NHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtMjI0djIyNHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtNjRxLTEzIDAtMjIuNS05LjV0LTkuNS0yMi41di0yMjRoLTIyNHEtMTMgMC0yMi41LTkuNXQtOS41LTIyLjV2LTY0cTAtMTMgOS41LTIyLjV0MjIuNS05LjVoMjI0di0yMjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWg2NHExMyAwIDIyLjUgOS41dDkuNSAyMi41djIyNGgyMjRxMTMgMCAyMi41IDkuNXQ5LjUgMjIuNXptMTI4IDMycTAtMTg1LTEzMS41LTMxNi41dC0zMTYuNS0xMzEuNS0zMTYuNSAxMzEuNS0xMzEuNSAzMTYuNSAxMzEuNSAzMTYuNSAzMTYuNSAxMzEuNSAzMTYuNS0xMzEuNSAxMzEuNS0zMTYuNXptNTEyIDgzMnEwIDUzLTM3LjUgOTAuNXQtOTAuNSAzNy41cS01NCAwLTkwLTM4bC0zNDMtMzQycS0xNzkgMTI0LTM5OSAxMjQtMTQzIDAtMjczLjUtNTUuNXQtMjI1LTE1MC0xNTAtMjI1LTU1LjUtMjczLjUgNTUuNS0yNzMuNSAxNTAtMjI1IDIyNS0xNTAgMjczLjUtNTUuNSAyNzMuNSA1NS41IDIyNSAxNTAgMTUwIDIyNSA1NS41IDI3My41cTAgMjIwLTEyNCAzOTlsMzQzIDM0M3EzNyAzNyAzNyA5MHoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-search-minus { + background-image: url(icon_search-minus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiM2ZjZmNmYiIGQ9Ik0xMDg4IDgwMHY2NHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtNTc2cS0xMyAwLTIyLjUtOS41dC05LjUtMjIuNXYtNjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWg1NzZxMTMgMCAyMi41IDkuNXQ5LjUgMjIuNXptMTI4IDMycTAtMTg1LTEzMS41LTMxNi41dC0zMTYuNS0xMzEuNS0zMTYuNSAxMzEuNS0xMzEuNSAzMTYuNSAxMzEuNSAzMTYuNSAzMTYuNSAxMzEuNSAzMTYuNS0xMzEuNSAxMzEuNS0zMTYuNXptNTEyIDgzMnEwIDUzLTM3LjUgOTAuNXQtOTAuNSAzNy41cS01NCAwLTkwLTM4bC0zNDMtMzQycS0xNzkgMTI0LTM5OSAxMjQtMTQzIDAtMjczLjUtNTUuNXQtMjI1LTE1MC0xNTAtMjI1LTU1LjUtMjczLjUgNTUuNS0yNzMuNSAxNTAtMjI1IDIyNS0xNTAgMjczLjUtNTUuNSAyNzMuNSA1NS41IDIyNSAxNTAgMTUwIDIyNSA1NS41IDI3My41cTAgMjIwLTEyNCAzOTlsMzQzIDM0M3EzNyAzNyAzNyA5MHoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-star { + background-image: url(icon_star.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNzI4IDY0N3EwIDIyLTI2IDQ4bC0zNjMgMzU0IDg2IDUwMHExIDcgMSAyMCAwIDIxLTEwLjUgMzUuNXQtMzAuNSAxNC41cS0xOSAwLTQwLTEybC00NDktMjM2LTQ0OSAyMzZxLTIyIDEyLTQwIDEyLTIxIDAtMzEuNS0xNC41dC0xMC41LTM1LjVxMC02IDItMjBsODYtNTAwLTM2NC0zNTRxLTI1LTI3LTI1LTQ4IDAtMzcgNTYtNDZsNTAyLTczIDIyNS00NTVxMTktNDEgNDktNDF0NDkgNDFsMjI1IDQ1NSA1MDIgNzNxNTYgOSA1NiA0NnoiIGZpbGw9IiMwMDAiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-sponsor { + background-image: url(icon_sponsor.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04OTYgMTY2NHEtMjYgMC00NC0xOGwtNjI0LTYwMnEtMTAtOC0yNy41LTI2dC01NS41LTY1LjUtNjgtOTcuNS01My41LTEyMS0yMy41LTEzOHEwLTIyMCAxMjctMzQ0dDM1MS0xMjRxNjIgMCAxMjYuNSAyMS41dDEyMCA1OCA5NS41IDY4LjUgNzYgNjhxMzYtMzYgNzYtNjh0OTUuNS02OC41IDEyMC01OCAxMjYuNS0yMS41cTIyNCAwIDM1MSAxMjR0MTI3IDM0NHEwIDIyMS0yMjkgNDUwbC02MjMgNjAwcS0xOCAxOC00NCAxOHoiIGZpbGw9IiNlYTRhYWEiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} + + + +@media (prefers-color-scheme: dark) { + @media screen { + html { + background-color: #333; + color: #fff; + } + + body { + color: #fff; + } + + h1 { + background-color: #555453; + color: #fff; + } + + .container { + background-color: #333; + box-shadow: 0 0 60px #0c0c0c; + } + + .containerrightfixed { + background-color: #3D3C3C; + border-left: 1px solid #515050; + } + + .containerrightfixed h1 { + background-color: #484747; + } + + .card-group .card { + background-color: #333; + background: radial-gradient(circle, #444 0%, #333 100%); + border: 1px solid #545454; + color: #fff; + } + + .card-group .card table tr { + border-bottom: 1px solid #545454; + } + + .card-group .card table tr:hover { + background-color: #2E2D2C; + } + + .overview tr:hover { + background-color: #2E2D2C; + } + + .overview th { + background-color: #444; + border: 1px solid #3B3A39; + } + + .overview tr.namespace th { + background-color: #444; + } + + .overview thead th { + background-color: #444; + } + + .overview th a { + color: #fff; + color: rgba(255, 255, 255, 0.95); + } + + .overview th a:hover { + color: #0078d4; + } + + .overview td { + border: 1px solid #3B3A39; + } + + .overview .coverage td { + border: none; + } + + .overview tr.header th { + background-color: #444; + } + + .overview tr.header th:nth-child(2n+1) { + background-color: #3a3a3a; + } + + .overview tr.header th:first-child { + border-left: 1px solid #333; + border-top: 1px solid #333; + background-color: #333; + } + + .stripped tr:nth-child(2n+1) { + background-color: #3c3c3c; + } + + input, select { + background-color: #333; + color: #fff; + border: 1px solid #A19F9D; + } + + a { + color: #fff; + color: rgba(255, 255, 255, 0.95); + } + + a:hover { + color: #0078d4; + } + + h1 a.back { + background-color: #4a4846; + } + + h1 a.button { + color: #fff; + background-color: #565656; + border-color: #c1c1c1; + } + + h1 a.button:hover { + background-color: #8d8d8d; + } + + .gray { + background-color: #484747; + } + + .lightgray { + color: #ebebeb; + } + + .lightgraybg { + background-color: #474747; + } + + .lightgreen { + background-color: #406540; + } + + .lightorange { + background-color: #ab7f36; + } + + .lightred { + background-color: #954848; + } + + .ct-label { + color: #fff !important; + } + + .ct-grid { + stroke: #fff !important; + } + + .ct-chart .ct-series.ct-series-a .ct-line, .ct-chart .ct-series.ct-series-a .ct-point { + stroke: #0078D4 !important; + } + + .ct-chart .ct-series.ct-series-b .ct-line, .ct-chart .ct-series.ct-series-b .ct-point { + stroke: #6dc428 !important; + } + + .ct-chart .ct-series.ct-series-c .ct-line, .ct-chart .ct-series.ct-series-c .ct-point { + stroke: #e58f1d !important; + } + + .linecoverage { + background-color: #0078D4; + } + + .branchcoverage { + background-color: #6dc428; + } + .codeelementcoverage { + background-color: #e58f1d; + } + + .tinylinecoveragechart, .tinybranchcoveragechart, .tinymethodcoveragechart { + background-color: #333; + } + + .tinybranchcoveragechart .ct-series.ct-series-a .ct-line { + stroke: #6dc428 !important; + } + + .tinymethodcoveragechart .ct-series.ct-series-a .ct-line { + stroke: #e58f1d !important; + } + + .icon-down-dir { + background-image: url(icon_down-dir_active_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE0MDggNzA0cTAgMjYtMTkgNDVsLTQ0OCA0NDhxLTE5IDE5LTQ1IDE5dC00NS0xOWwtNDQ4LTQ0OHEtMTktMTktMTktNDV0MTktNDUgNDUtMTloODk2cTI2IDAgNDUgMTl0MTkgNDV6Ii8+PC9zdmc+); + } + + .icon-info-circled { + background-image: url(icon_info-circled_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxjaXJjbGUgY3g9Ijg5NiIgY3k9Ijg5NiIgcj0iNzUwIiBmaWxsPSIjZmZmIiAvPjxwYXRoIGZpbGw9IiMyOEE1RkYiIGQ9Ik0xMTUyIDEzNzZ2LTE2MHEwLTE0LTktMjN0LTIzLTloLTk2di01MTJxMC0xNC05LTIzdC0yMy05aC0zMjBxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloOTZ2MzIwaC05NnEtMTQgMC0yMyA5dC05IDIzdjE2MHEwIDE0IDkgMjN0MjMgOWg0NDhxMTQgMCAyMy05dDktMjN6bS0xMjgtODk2di0xNjBxMC0xNC05LTIzdC0yMy05aC0xOTJxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloMTkycTE0IDAgMjMtOXQ5LTIzem02NDAgNDE2cTAgMjA5LTEwMyAzODUuNXQtMjc5LjUgMjc5LjUtMzg1LjUgMTAzLTM4NS41LTEwMy0yNzkuNS0yNzkuNS0xMDMtMzg1LjUgMTAzLTM4NS41IDI3OS41LTI3OS41IDM4NS41LTEwMyAzODUuNSAxMDMgMjc5LjUgMjc5LjUgMTAzIDM4NS41eiIvPjwvc3ZnPg==); + } + + .icon-plus { + background-image: url(icon_plus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE2MDAgNzM2djE5MnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtMTkycS00MCAwLTY4LTI4dC0yOC02OHYtNDE2aC00MTZxLTQwIDAtNjgtMjh0LTI4LTY4di0xOTJxMC00MCAyOC02OHQ2OC0yOGg0MTZ2LTQxNnEwLTQwIDI4LTY4dDY4LTI4aDE5MnE0MCAwIDY4IDI4dDI4IDY4djQxNmg0MTZxNDAgMCA2OCAyOHQyOCA2OHoiLz48L3N2Zz4=); + } + + .icon-minus { + background-image: url(icon_minus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE2MDAgNzM2djE5MnEwIDQwLTI4IDY4dC02OCAyOGgtMTIxNnEtNDAgMC02OC0yOHQtMjgtNjh2LTE5MnEwLTQwIDI4LTY4dDY4LTI4aDEyMTZxNDAgMCA2OCAyOHQyOCA2OHoiLz48L3N2Zz4=); + } + + .icon-wrench { + background-image: url(icon_wrench_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JEQkRCRiIgZD0iTTQ0OCAxNDcycTAtMjYtMTktNDV0LTQ1LTE5LTQ1IDE5LTE5IDQ1IDE5IDQ1IDQ1IDE5IDQ1LTE5IDE5LTQ1em02NDQtNDIwbC02ODIgNjgycS0zNyAzNy05MCAzNy01MiAwLTkxLTM3bC0xMDYtMTA4cS0zOC0zNi0zOC05MCAwLTUzIDM4LTkxbDY4MS02ODFxMzkgOTggMTE0LjUgMTczLjV0MTczLjUgMTE0LjV6bTYzNC00MzVxMCAzOS0yMyAxMDYtNDcgMTM0LTE2NC41IDIxNy41dC0yNTguNSA4My41cS0xODUgMC0zMTYuNS0xMzEuNXQtMTMxLjUtMzE2LjUgMTMxLjUtMzE2LjUgMzE2LjUtMTMxLjVxNTggMCAxMjEuNSAxNi41dDEwNy41IDQ2LjVxMTYgMTEgMTYgMjh0LTE2IDI4bC0yOTMgMTY5djIyNGwxOTMgMTA3cTUtMyA3OS00OC41dDEzNS41LTgxIDcwLjUtMzUuNXExNSAwIDIzLjUgMTB0OC41IDI1eiIvPjwvc3ZnPg==); + } + + .icon-fork { + background-image: url(icon_fork_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTY3MiAxNDcycTAtNDAtMjgtNjh0LTY4LTI4LTY4IDI4LTI4IDY4IDI4IDY4IDY4IDI4IDY4LTI4IDI4LTY4em0wLTExNTJxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTY0MCAxMjhxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTk2IDBxMCA1Mi0yNiA5Ni41dC03MCA2OS41cS0yIDI4Ny0yMjYgNDE0LTY3IDM4LTIwMyA4MS0xMjggNDAtMTY5LjUgNzF0LTQxLjUgMTAwdjI2cTQ0IDI1IDcwIDY5LjV0MjYgOTYuNXEwIDgwLTU2IDEzNnQtMTM2IDU2LTEzNi01Ni01Ni0xMzZxMC01MiAyNi05Ni41dDcwLTY5LjV2LTgyMHEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnEwIDUyLTI2IDk2LjV0LTcwIDY5LjV2NDk3cTU0LTI2IDE1NC01NyA1NS0xNyA4Ny41LTI5LjV0NzAuNS0zMSA1OS0zOS41IDQwLjUtNTEgMjgtNjkuNSA4LjUtOTEuNXEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnoiLz48L3N2Zz4=); + } + + .icon-cube { + background-image: url(icon_cube_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTg5NiAxNjI5bDY0MC0zNDl2LTYzNmwtNjQwIDIzM3Y3NTJ6bS02NC04NjVsNjk4LTI1NC02OTgtMjU0LTY5OCAyNTR6bTgzMi0yNTJ2NzY4cTAgMzUtMTggNjV0LTQ5IDQ3bC03MDQgMzg0cS0yOCAxNi02MSAxNnQtNjEtMTZsLTcwNC0zODRxLTMxLTE3LTQ5LTQ3dC0xOC02NXYtNzY4cTAtNDAgMjMtNzN0NjEtNDdsNzA0LTI1NnEyMi04IDQ0LTh0NDQgOGw3MDQgMjU2cTM4IDE0IDYxIDQ3dDIzIDczeiIvPjwvc3ZnPg==); + } + + .icon-search-plus { + background-image: url(icon_search-plus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTEwODggODAwdjY0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC0yMjR2MjI0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC02NHEtMTMgMC0yMi41LTkuNXQtOS41LTIyLjV2LTIyNGgtMjI0cS0xMyAwLTIyLjUtOS41dC05LjUtMjIuNXYtNjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWgyMjR2LTIyNHEwLTEzIDkuNS0yMi41dDIyLjUtOS41aDY0cTEzIDAgMjIuNSA5LjV0OS41IDIyLjV2MjI0aDIyNHExMyAwIDIyLjUgOS41dDkuNSAyMi41em0xMjggMzJxMC0xODUtMTMxLjUtMzE2LjV0LTMxNi41LTEzMS41LTMxNi41IDEzMS41LTEzMS41IDMxNi41IDEzMS41IDMxNi41IDMxNi41IDEzMS41IDMxNi41LTEzMS41IDEzMS41LTMxNi41em01MTIgODMycTAgNTMtMzcuNSA5MC41dC05MC41IDM3LjVxLTU0IDAtOTAtMzhsLTM0My0zNDJxLTE3OSAxMjQtMzk5IDEyNC0xNDMgMC0yNzMuNS01NS41dC0yMjUtMTUwLTE1MC0yMjUtNTUuNS0yNzMuNSA1NS41LTI3My41IDE1MC0yMjUgMjI1LTE1MCAyNzMuNS01NS41IDI3My41IDU1LjUgMjI1IDE1MCAxNTAgMjI1IDU1LjUgMjczLjVxMCAyMjAtMTI0IDM5OWwzNDMgMzQzcTM3IDM3IDM3IDkweiIvPjwvc3ZnPg==); + } + + .icon-search-minus { + background-image: url(icon_search-minus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTEwODggODAwdjY0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC01NzZxLTEzIDAtMjIuNS05LjV0LTkuNS0yMi41di02NHEwLTEzIDkuNS0yMi41dDIyLjUtOS41aDU3NnExMyAwIDIyLjUgOS41dDkuNSAyMi41em0xMjggMzJxMC0xODUtMTMxLjUtMzE2LjV0LTMxNi41LTEzMS41LTMxNi41IDEzMS41LTEzMS41IDMxNi41IDEzMS41IDMxNi41IDMxNi41IDEzMS41IDMxNi41LTEzMS41IDEzMS41LTMxNi41em01MTIgODMycTAgNTMtMzcuNSA5MC41dC05MC41IDM3LjVxLTU0IDAtOTAtMzhsLTM0My0zNDJxLTE3OSAxMjQtMzk5IDEyNC0xNDMgMC0yNzMuNS01NS41dC0yMjUtMTUwLTE1MC0yMjUtNTUuNS0yNzMuNSA1NS41LTI3My41IDE1MC0yMjUgMjI1LTE1MCAyNzMuNS01NS41IDI3My41IDU1LjUgMjI1IDE1MCAxNTAgMjI1IDU1LjUgMjczLjVxMCAyMjAtMTI0IDM5OWwzNDMgMzQzcTM3IDM3IDM3IDkweiIvPjwvc3ZnPg==); + } + + .icon-star { + background-image: url(icon_star_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNzI4IDY0N3EwIDIyLTI2IDQ4bC0zNjMgMzU0IDg2IDUwMHExIDcgMSAyMCAwIDIxLTEwLjUgMzUuNXQtMzAuNSAxNC41cS0xOSAwLTQwLTEybC00NDktMjM2LTQ0OSAyMzZxLTIyIDEyLTQwIDEyLTIxIDAtMzEuNS0xNC41dC0xMC41LTM1LjVxMC02IDItMjBsODYtNTAwLTM2NC0zNTRxLTI1LTI3LTI1LTQ4IDAtMzcgNTYtNDZsNTAyLTczIDIyNS00NTVxMTktNDEgNDktNDF0NDkgNDFsMjI1IDQ1NSA1MDIgNzNxNTYgOSA1NiA0NnoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=); + } + } +} + +.ct-double-octave:after,.ct-golden-section:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-grid-background{fill:none}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{fill:none;stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{display:table}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0} \ No newline at end of file -- GitLab From 678a6a2b08dc538e3815f325d4fafdeb5827ce12 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Thu, 5 May 2022 18:44:05 +0200 Subject: [PATCH 44/67] re #9570 Commented ApiClient.cs --- ld_client/LDClient/network/ApiClient.cs | 107 ++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 7 deletions(-) diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index b5ca456..8668e54 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -8,36 +8,82 @@ using LDClient.network.data; namespace LDClient.network { + /// <summary> + /// This class implements IApiClient which is an interface + /// defining all the functionality required from an API client. + /// </summary> public sealed class ApiClient : IApiClient { + /// <summary> + /// Instance of an HTTP client the is used to send data off to the server + /// </summary> public IHttpClient _client; + /// <summary> + /// Flag used to stop the client (periodical retrieval from the cache) + /// </summary> public bool ClientRunning; + /// <summary> + /// Number of milliseconds after which the class tries to resend failed payloads to the server. + /// </summary> private readonly uint _retryPeriod; + + /// <summary> + /// Maximum number of entries (payloads) that can be sent to the server within one period (_retryPeriod). + /// </summary> private readonly uint _maxEntries; + + /// <summary> + /// Maximum number of failed payloads to be kept in the file-based cache (FIFO - when the maximum number is reached) + /// </summary> private readonly uint _maxRetries; private readonly IPersistentQueue _cache; + /// <summary> + /// Creates an instance of the class. + /// </summary> + /// <param name="url">IP address of the server (url in case a DNS server is being used)</param> + /// <param name="port">port that the API is running on</param> + /// <param name="path">path of the API e.g. /api/v1/lg-logs</param> + /// <param name="retryPeriod">number of milliseconds after which the class tries to resend failed payloads to the server</param> + /// <param name="maxEntries">maximum number of entries (payloads) that can be sent to the server within one period</param> + /// <param name="maxRetries">maximum number of failed payloads to be kept in the file-based cache</param> + /// <param name="cache">instance of a persistent cache for storing failed payloads</param> public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache) { + // Construct the entire path to the API. var uri = $"{url}:{port}{path}"; + + // Store the values into class variables. _retryPeriod = retryPeriod; _maxEntries = maxEntries; _maxRetries = maxRetries; + _cache = cache; + // Create an instance of a HttpClient which takes care of + // establishing a connection to the server; _client = new HttpClient(uri); - _cache = cache; } + /// <summary> + /// Sends a payload to the server (API). + /// </summary> + /// <param name="payload">instance of a payload to be sent off to the server</param> public async Task SendPayloadAsync(Payload payload) { try { + // Create an instance of Stopwatch (to measure how much + // the action took). Stopwatch stopWatch = new(); - stopWatch.Start(); + // Send the payload to the server. + stopWatch.Start(); var response = await _client.PostAsJsonAsync(payload); stopWatch.Stop(); + + // Create a log message. CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds); - + + // Make sure the request was successful. response.EnsureSuccessStatusCode(); } catch (Exception e) { Program.DefaultLogger.Error($"Failed to send {payload} to the server. Due to: {e.Message}"); @@ -45,24 +91,43 @@ namespace LDClient.network { } } + /// <summary> + /// Creates a request log message. + /// </summary> + /// <param name="payload">payload involved in the process of sending data to the server</param> + /// <param name="response">response from the server</param> + /// <param name="durationMs">duration in milliseconds (how much time it took to send off the payload)</param> private static void CreateRequestLog(Payload payload, HttpResponseMessage response, long durationMs) { + // Create the log message. var responseToLog = new { statusCode = response.StatusCode, content = response.Content, headers = response.Headers, errorMessage = response.RequestMessage, }; - + + // Log the message using the logger defined in Program (main class). Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" + - $"Request body: {payload},\n" + - $"Response: {responseToLog}"); + $"Request body: {payload},\n" + + $"Response: {responseToLog}"); } + /// <summary> + /// Resends unsuccessful payloads to the server. + /// </summary> private async Task ResendPayloadsAsync() { + // Calculate the maximum number of payloads to be sent to the server. var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue); + + // Create a list for those payloads var payloads = new List<Payload>(); + + // Retrieve the payloads from the cache. if (numberOfPayloadsToResend > 0) { + // Open up a session to the cache. using var session = _cache.OpenSession(); + + // Pop out payloads, deserialize them, and store them into the list. for (var i = 0; i < numberOfPayloadsToResend; i++) { var rawBytes = session.Dequeue(); var payload = JsonSerializer.Deserialize<Payload>(rawBytes); @@ -70,35 +135,63 @@ namespace LDClient.network { payloads.Add(payload); } } + // Flush the changes. session.Flush(); } - + + // If there are some payloads to be resent to the server. if (payloads.Count > 0) { Program.DefaultLogger.Debug($"ResendPayloadAsync -> {payloads.Count} unsent payloads"); var tasks = new List<Task>(); + + // Create a separate task for each payload - resend them to the server. foreach (var payload in payloads) { Program.DefaultLogger.Info($"Resending {payload}."); tasks.Add(SendPayloadAsync(payload)); } + // Wait until all tasks are finished. await Task.WhenAll(tasks); } } + /// <summary> + /// Stores a failed payload into a persistent cache. + /// </summary> + /// <param name="payload"></param> private void CachePayload(Payload payload) { Program.DefaultLogger.Info($"Storing {payload} into the cache."); + + // Number of payloads stored in the cache. var numberOfCachedPayloads = _cache.EstimatedCountOfItemsInQueue; + + // Open up a session to the cache. using var session = _cache.OpenSession(); + + // If the cache is "full", make room for the latest failed + // payload by discarding the oldest one. if (numberOfCachedPayloads >= _maxEntries) { session.Dequeue(); } + + // Store the payload into the cache. var payloadJson = JsonSerializer.Serialize(payload); session.Enqueue(Encoding.UTF8.GetBytes(payloadJson)); + + // Flush the changes. session.Flush(); } + /// <summary> + /// Runs the periodical retrieval of failed payloads stored + /// in a file-based cache. This method is instantiated as a thread. + /// </summary> public async void Run() { Program.DefaultLogger.Info("Api Client thread has started"); + + // Keep the thread running. ClientRunning = true; + + // Keep resending failed payloads to the server. while (ClientRunning) { await ResendPayloadsAsync(); Thread.Sleep((int) _retryPeriod); -- GitLab From a155a76350ed6c6804382370a8c7acfab1cf18f1 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Thu, 5 May 2022 18:55:11 +0200 Subject: [PATCH 45/67] re #9570 Commented HttpClient.cs, IHttpClient.cs, and IApiClient.cs --- ld_client/LDClient/network/HttpClient.cs | 23 ++++++++++++++++++++++- ld_client/LDClient/network/IApiClient.cs | 13 +++++++++++++ ld_client/LDClient/network/IHttpClient.cs | 10 ++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/ld_client/LDClient/network/HttpClient.cs b/ld_client/LDClient/network/HttpClient.cs index fa6f3d1..9672006 100644 --- a/ld_client/LDClient/network/HttpClient.cs +++ b/ld_client/LDClient/network/HttpClient.cs @@ -9,18 +9,39 @@ using System.Threading.Tasks; using LDClient.network.data; namespace LDClient.network { + + /// <summary> + /// Implementation of IHttpClient which defines the functionality + /// of a HTTP client that is used by the API client to send data to the server. + /// </summary> public class HttpClient : IHttpClient{ + /// <summary> + /// Instance of System.Net.Http.HttpClient + /// </summary> private readonly System.Net.Http.HttpClient _httpClient; + /// <summary> + /// URL to which the HTTP client will connect + /// </summary> private readonly string _uri; + + /// <summary> + /// Creates an instance of the class + /// </summary> + /// <param name="uri">URL to which the HTTP client will connect</param> public HttpClient(string uri) { - _httpClient = new System.Net.Http.HttpClient(); _uri = uri; } + /// <summary> + /// Asynchronically sends data in JSON format to the server. + /// </summary> + /// <param name="payload">Payload to be sent to the server</param> + /// <returns></returns> public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload) { + // Serialize the payload and send it to the server as JSON. return _httpClient.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions { Converters = { new JsonStringEnumConverter( JsonNamingPolicy.CamelCase) diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs index 5574d23..79d70e1 100644 --- a/ld_client/LDClient/network/IApiClient.cs +++ b/ld_client/LDClient/network/IApiClient.cs @@ -2,9 +2,22 @@ namespace LDClient.network { + /// <summary> + /// This interface defines the functionality of an API client + /// which is used to send information (payloads) to the server. + /// </summary> public interface IApiClient { + /// <summary> + /// Sends a payload to the server (API). + /// </summary> + /// <param name="payload">instance of a payload to be sent off to the server</param> public Task SendPayloadAsync(Payload payload); + + /// <summary> + /// Runs the periodical retrieval of failed payloads stored + /// in a file-based cache. This method is instantiated as a thread. + /// </summary> public void Run(); } } diff --git a/ld_client/LDClient/network/IHttpClient.cs b/ld_client/LDClient/network/IHttpClient.cs index daf0c60..0f3fc72 100644 --- a/ld_client/LDClient/network/IHttpClient.cs +++ b/ld_client/LDClient/network/IHttpClient.cs @@ -6,8 +6,18 @@ using System.Threading.Tasks; using LDClient.network.data; namespace LDClient.network { + + /// <summary> + /// This interface defines the functionality of a HTTP client + /// through which the API client sends data (payloads) to the server. + /// </summary> public interface IHttpClient { + /// <summary> + /// Asynchronically sends data in JSON format to the server. + /// </summary> + /// <param name="payload">Payload to be sent to the server</param> + /// <returns></returns> public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload); } } -- GitLab From 625c7c2ed9d2c1b536120b6363bcfb3989414a2d Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Thu, 5 May 2022 19:04:07 +0200 Subject: [PATCH 46/67] re #9570 Commented ConnectionStatus.cs, DebuggerInfo.cs, and Payload.cs --- .../LDClient/network/data/ConnectionStatus.cs | 11 +++++ .../LDClient/network/data/DebuggerInfo.cs | 8 ++++ ld_client/LDClient/network/data/Payload.cs | 41 +++++++++++++++++-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/ld_client/LDClient/network/data/ConnectionStatus.cs b/ld_client/LDClient/network/data/ConnectionStatus.cs index 9cd1ded..96d87ae 100644 --- a/ld_client/LDClient/network/data/ConnectionStatus.cs +++ b/ld_client/LDClient/network/data/ConnectionStatus.cs @@ -2,10 +2,21 @@ namespace LDClient.network.data { + /// <summary> + /// This enumeration defines different states in + /// which a debugger can be. + /// </summary> public enum ConnectionStatus { + /// <summary> + /// Debugger is connected + /// </summary> [EnumMember(Value = "connected")] Connected, + + /// <summary> + /// Debugger is disconnected + /// </summary> [EnumMember(Value = "disconnected")] Disconnected } diff --git a/ld_client/LDClient/network/data/DebuggerInfo.cs b/ld_client/LDClient/network/data/DebuggerInfo.cs index 9402110..fd7fa8a 100644 --- a/ld_client/LDClient/network/data/DebuggerInfo.cs +++ b/ld_client/LDClient/network/data/DebuggerInfo.cs @@ -1,8 +1,16 @@ using System.Text.Json.Serialization; namespace LDClient.network.data { + + /// <summary> + /// This class holds all the information about + /// a specific part of a debugger (head/body). + /// </summary> public class DebuggerInfo { + /// <summary> + /// Serial number of the part of a debugger. + /// </summary> [JsonPropertyName("serial_number")] public string? SerialNumber { get; set; } } diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs index ae7302a..afa714f 100644 --- a/ld_client/LDClient/network/data/Payload.cs +++ b/ld_client/LDClient/network/data/Payload.cs @@ -5,44 +5,77 @@ using JsonSerializer = System.Text.Json.JsonSerializer; namespace LDClient.network.data { + /// <summary> + /// This class represents a single payload that is sent to the server. + /// </summary> [JsonObject(MemberSerialization.OptIn)] public class Payload { + /// <summary> + /// Username of the currently logged user. + /// </summary> [JsonPropertyName("username")] public string? UserName { get; set; } + /// <summary> + /// Hostname of the pc. + /// </summary> [JsonPropertyName("hostname")] public string? HostName { get; set; } + /// <summary> + /// Timestamp (when a debugger was plugged/unplugged). + /// </summary> [JsonPropertyName("timestamp")] public string? TimeStamp { get; set; } + /// <summary> + /// Information about the head of the debugger. + /// </summary> [JsonPropertyName("head_device")] public DebuggerInfo? HeadDevice { get; set; } - + /// <summary> + /// Information about the body of the debugger. + /// </summary> [JsonPropertyName("body_device")] public DebuggerInfo? BodyDevice { get; set; } + /// <summary> + /// Status of the debugger (connected/disconnected). + /// </summary> [JsonPropertyName("status")] public ConnectionStatus Status { get; set; } - - + + /// <summary> + /// Returns a string representation of the payload. + /// </summary> + /// <returns></returns> public override string ToString() { return ParseToJson(this); } + /// <summary> + /// Parses (converts) the payload into JSON format. + /// </summary> + /// <returns></returns> public string ParseToJson() { return Payload.ParseToJson(this); } + /// <summary> + /// Serializes a given payload into JSON format. + /// </summary> + /// <param name="payload">payload to be serialized into JSON</param> + /// <returns></returns> public static string ParseToJson(Payload payload) { + // Create options for serialization. var options = new JsonSerializerOptions { Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } }; - + // Serialize the payload and return it. return JsonSerializer.Serialize(payload, options); } } -- GitLab From 9657d7e0e156d39c8deea6a2b318e894689255c5 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Thu, 5 May 2022 20:57:48 +0200 Subject: [PATCH 47/67] re #9570 Commented ConfigLoader.cs, FileUtils.cs, and IFileUtils.cs --- ld_client/LDClient/utils/ConfigLoader.cs | 139 +++++++++++++++++++++++ ld_client/LDClient/utils/FileUtils.cs | 11 ++ ld_client/LDClient/utils/IFileUtils.cs | 9 ++ 3 files changed, 159 insertions(+) diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index 251e663..6dc3cf7 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -3,69 +3,196 @@ using Microsoft.Extensions.Configuration; namespace LDClient.utils { + /// <summary> + /// This class loads up the configuration file (appsettingss.json). + /// </summary> internal class ConfigLoader { + /// <summary> + /// Status code indicating a successful termination of an application. + /// </summary> private const int ErrorExitCode = 1; + + /// <summary> + /// Path to the configuration file. + /// </summary> private const string ConfigFile = "appsettings.json"; + + /// <summary> + /// Name of the logging section defined in the config file. + /// </summary> private const string LoggingSection = "Logging"; + + /// <summary> + /// Name of the network section defined in the config file. + /// </summary> private const string NetworkSection = "Network"; + + /// <summary> + /// Name of the cache section defined in the config file. + /// </summary> private const string CacheSection = "Cache"; + + /// <summary> + /// Name of the detection section defined in the config file. + /// </summary> private const string DdSection = "DebuggerDetection"; #region Logger + /// <summary> + /// Maximum size of the log file (it will start to rotate when this limit is reached). + /// </summary> public int LogChunkSize { get; private set; } + + /// <summary> + /// Number of files to be created until there will be zipped up. + /// </summary> public int LogChunkMaxCount { get; private set; } + + /// <summary> + /// Maximum number of zip files + /// </summary> public int LogArchiveMaxCount { get; private set; } + + /// <summary> + /// Time after which the last logs will be cleaned up. + /// </summary> public int LogCleanupPeriod { get; private set; } + + /// <summary> + /// Level of verbosity. + /// </summary> public LogVerbosity LogVerbosityType { get; private set; } = LogVerbosity.Full; + + /// <summary> + /// Logger flow type. + /// </summary> public LogFlow LogFlowType { get; private set; } = LogFlow.Console; #endregion #region Api + /// <summary> + /// URL to the API (it can be an IP address or a domain name if a DNS server is being used). + /// </summary> public string ApiBaseAddress { get; private set; } = null!; + + /// <summary> + /// Path to the API (e.g. /api/v1/ld-logs). + /// </summary> public string ApiUsbEndPoint { get; private set; } = null!; + + /// <summary> + /// Number of the port that the API runs on. + /// </summary> public uint ApiPort { get; private set; } #endregion #region Cache + /// <summary> + /// Name of the cache (a directory of this name will be created). + /// </summary> public string CacheFileName { get; private set; } = null!; + + /// <summary> + /// Maximum number of payloads (entries) to be sent to the server at a time. + /// </summary> public uint MaxRetries { get; private set; } + + /// <summary> + /// Maximum number of entries that can be stored in the database. + /// </summary> public uint MaxEntries { get; private set; } + + /// <summary> + /// Period (how often) a certain number of entries will be resent to the server. + /// </summary> public uint RetryPeriod { get; private set; } #endregion #region Detection + + /// <summary> + /// Name of the process to be detected (the application programmers use to connect to the debugger). + /// </summary> public string T32ProcessName { get; private set; } = null!; + + /// <summary> + /// How often the application checks if there is the process (T32ProcessName) running on the PC. + /// </summary> public uint DetectionPeriod { get; private set; } + + /// <summary> + /// Location of the generated .txt file containing all information about a debugger. + /// </summary> public string T32InfoLocation { get; private set; } = null!; + + /// <summary> + /// Path to the t32rem.exe which is used to send commands to a debugger. + /// </summary> public string F32RemExecutable { get; private set; } = null!; + + /// <summary> + /// How many times the application attempts to check if there + /// has been a .txt file generated containing all the desired information. + /// </summary> public uint FetchInfoMaxAttempts { get; private set; } + + /// <summary> + /// Period in milliseconds after which the application tries to locate and parse the .txt file. + /// </summary> public uint FetchInfoAttemptPeriod { get; private set; } + + /// <summary> + /// Arguments (commands) sent to the t32rem.exe file. + /// </summary> public string[] F32RemArguments { get; private set; } = null!; + + /// <summary> + /// Status code indication successful execution of the t32rem.exe file. + /// </summary> public int T32RemSuccessExitCode { get; private set; } + + /// <summary> + /// Timeout of the execution of t32rem.exe (when sending one command). + /// </summary> public int T32RemWaitTimeoutMs { get; private set; } #endregion + /// <summary> + /// Creates an instance of the class. + /// </summary> public ConfigLoader() { + // Create a new config builder to read the configuration file. var configuration = new ConfigurationBuilder() .AddJsonFile(ConfigFile) .Build(); + // Parse the logger section. ReadLoggerSection(configuration); + + // Parse the api section. ReadApiSection(configuration); + + // Parse the cache section. ReadCacheSection(configuration); + + // Parse the detection section. ReadDebuggerSection(configuration); Console.WriteLine("Configuration successfully loaded!"); } + /// <summary> + /// Parses the logging section of the configuration file. + /// </summary> + /// <param name="configuration">configuration</param> private void ReadLoggerSection(IConfiguration configuration) { try { var logging = configuration.GetSection(LoggingSection); @@ -81,6 +208,10 @@ namespace LDClient.utils { } } + /// <summary> + /// Parses the api section of the configuration file. + /// </summary> + /// <param name="configuration">configuration</param> private void ReadApiSection(IConfiguration configuration) { try { var network = configuration.GetSection(NetworkSection); @@ -93,6 +224,10 @@ namespace LDClient.utils { } } + /// <summary> + /// Parses the cache section of the configuration file. + /// </summary> + /// <param name="configuration">configuration</param> private void ReadCacheSection(IConfiguration configuration) { try { var cache = configuration.GetSection(CacheSection); @@ -106,6 +241,10 @@ namespace LDClient.utils { } } + /// <summary> + /// Parses the detection section of the configuration file. + /// </summary> + /// <param name="configuration">configuration</param> private void ReadDebuggerSection(IConfiguration configuration) { try { var debugger = configuration.GetSection(DdSection); diff --git a/ld_client/LDClient/utils/FileUtils.cs b/ld_client/LDClient/utils/FileUtils.cs index abd3e98..b749389 100644 --- a/ld_client/LDClient/utils/FileUtils.cs +++ b/ld_client/LDClient/utils/FileUtils.cs @@ -5,7 +5,18 @@ using System.Text; using System.Threading.Tasks; namespace LDClient.utils { + + /// <summary> + /// This class implements the IFileUtils interface + /// which defines IO operations. + /// </summary> public class FileUtils : IFileUtils { + + /// <summary> + /// Reads all lines of a files and returns them as a array. + /// </summary> + /// <param name="file">path to the file</param> + /// <returns>all the lines of the file (as an array)</returns> public string[] ReadFileAllLines(string file) { return File.ReadAllLines(file); } diff --git a/ld_client/LDClient/utils/IFileUtils.cs b/ld_client/LDClient/utils/IFileUtils.cs index f3daf17..cc1547f 100644 --- a/ld_client/LDClient/utils/IFileUtils.cs +++ b/ld_client/LDClient/utils/IFileUtils.cs @@ -5,8 +5,17 @@ using System.Text; using System.Threading.Tasks; namespace LDClient.utils { + + /// <summary> + /// This interface defines IO operations. + /// </summary> public interface IFileUtils { + /// <summary> + /// Reads all lines of a files and returns them as a array. + /// </summary> + /// <param name="file">path to the file</param> + /// <returns>all the lines of the file (as an array)</returns> public string[] ReadFileAllLines(string file); } } -- GitLab From 31b6e8b723d1e34724104be7978ca00452d89207 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Thu, 5 May 2022 21:06:17 +0200 Subject: [PATCH 48/67] re #9570 Commented Program.cs --- ld_client/LDClient/Program.cs | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index d8a7cb4..98a61b2 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -9,14 +9,34 @@ using static System.Reflection.Assembly; namespace LDClient; +/// <summary> +/// This class represents the main class of the application. +/// </summary> internal static class Program { + /// <summary> + /// Sleep period of the main thread of the application. + /// </summary> private const int MainLoopDelayMs = 30000; + /// <summary> + /// Instance of a config loader. + /// </summary> public static ConfigLoader Config { get; } = new(); + + /// <summary> + /// Default logger used throughout the application. + /// </summary> public static ALogger DefaultLogger { get; } = ALogger.Current; + + /// <summary> + /// Instance of an API client. + /// </summary> private static IApiClient? DefaultApiClient { get; set; } + /// <summary> + /// Instance of an info fetcher. + /// </summary> private static readonly InfoFetcher InfoFetcher = new( Config.FetchInfoMaxAttempts, Config.FetchInfoAttemptPeriod, @@ -27,12 +47,19 @@ internal static class Program { Config.T32RemWaitTimeoutMs ); + /// <summary> + /// The main entry pint of the application. + /// </summary> + /// <returns>1 if something goes wrong, 0 otherwise.</returns> public static int Main() { + // Make sure that there is only one running instance of this application. if (GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1) { DefaultLogger.Error("Another instance of the application is already running"); return 1; } + // Create an instance of an API client with all + // the appropriate parameters defined in the config file. DefaultApiClient = new ApiClient( Config.ApiBaseAddress, Config.ApiPort, @@ -42,6 +69,7 @@ internal static class Program { new PersistentQueue(Config.CacheFileName) ); + // Create a new process detector. IProcessDetection processProcessDetection = new ProcessDetection( Config.T32ProcessName, Config.DetectionPeriod, @@ -50,18 +78,26 @@ internal static class Program { new ProcessUtils() ); + // Create and start a new thread that periodically + // resends filed payloads to the server. var apiClientThread = new Thread(DefaultApiClient.Run) { IsBackground = true }; apiClientThread.Start(); + // Create and start a new thread that periodically checks + // if the desired process is currently running or not. var processThread = new Thread(processProcessDetection.RunPeriodicDetection) { IsBackground = true }; processThread.Start(); + // The main thread does "nothing" while (true) { Thread.Sleep(MainLoopDelayMs); } + + // The execution of the program should never reach this point. + return 0; } } \ No newline at end of file -- GitLab From f63d5489ac5cb2fdeb659c4b7ef46667efdf40f5 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Fri, 6 May 2022 08:59:03 +0200 Subject: [PATCH 49/67] re #9570 Commented DebuggerInfoParser.cs, IInfoFetcher.cs, and InfoFetcher.cs --- .../LDClient/detection/DebuggerInfoParser.cs | 20 ++++ ld_client/LDClient/detection/IInfoFetcher.cs | 18 +++ ld_client/LDClient/detection/InfoFetcher.cs | 106 +++++++++++++++++- 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs index dec8bd0..27b80c6 100644 --- a/ld_client/LDClient/detection/DebuggerInfoParser.cs +++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs @@ -2,19 +2,39 @@ using System.Text.RegularExpressions; namespace LDClient.detection { + /// <summary> + /// This class parses the .txt file generated from the debugger. + /// Its primary interest is to find two serial numbers (head + body). + /// </summary> public static class DebuggerInfoParser { + /// <summary> + /// Number of serial numbers expected to be in the .txt file (number of matches - regex). + /// </summary> private const int ExpectedNumberOfMatches = 2; + /// <summary> + /// Regular expression used to find the serial numbers. + /// </summary> private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)"); + /// <summary> + /// Takes the content of a .txt file and tries to find the two serial numbers (head and body). + /// If it succeed, it will return the two numbers. + /// </summary> + /// <param name="dataTxt">the content of a .txt file (generated from the debugger)</param> + /// <returns>two serial numbers (head and body) of the debugger</returns> + /// <exception cref="ArgumentException">throws an exception if it fails to find the serial numbers</exception> public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) { + // Find all matches in the content of the file that satisfy the regular expression. var matches = SerialNumberRegex.Matches(dataTxt); + // Make sure an exact number of matches has been found. if (matches.Count != ExpectedNumberOfMatches) { throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})"); } + // Return the two serial numbers (head and body). return (matches[1].ToString().Trim(), matches[0].ToString().Trim()); } } diff --git a/ld_client/LDClient/detection/IInfoFetcher.cs b/ld_client/LDClient/detection/IInfoFetcher.cs index e48005c..f8c47a3 100644 --- a/ld_client/LDClient/detection/IInfoFetcher.cs +++ b/ld_client/LDClient/detection/IInfoFetcher.cs @@ -5,11 +5,29 @@ using System.Text; using System.Threading.Tasks; namespace LDClient.detection { + + /// <summary> + /// This interface defines the functionality of an info fetcher which + /// takes care of sending commands to the debugger. + /// </summary> public interface IInfoFetcher { + /// <summary> + /// Returns the head serial number of the debugger. + /// </summary> public string HeadSerialNumber { get; set; } + + /// <summary> + /// Returns the body serial number of the debugger. + /// </summary> public string BodySerialNumber { get; set; } + /// <summary> + /// Fetches data from the debugger. It sends the commands defined + /// in the appsettings.json file to the debugger and tries to + /// parse the .txt (contains the serial numbers). + /// </summary> + /// <returns>True, if data was fetched successfully. False otherwise.</returns> public Task<bool> FetchDataAsync(); } } diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs index 07ddba1..7854ea6 100644 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ b/ld_client/LDClient/detection/InfoFetcher.cs @@ -4,27 +4,88 @@ using LDClient.utils.loggers; namespace LDClient.detection { + /// <summary> + /// This class implements the IInfoFetcher interface + /// which defines the functionality of an info fetcher. + /// </summary> public class InfoFetcher : IInfoFetcher { + /// <summary> + /// Default value of a serial number (undefined). + /// </summary> private const string UndefinedSerialNumber = "number"; + /// <summary> + /// Path to the t32rem.exe file which is used to send commands to the debugger. + /// </summary> private readonly string _f32RemExecutable; + + /// <summary> + /// Arguments (commands) sent to the debugger in order to generate a .txt file + /// containing all the desired information. + /// </summary> private readonly string[] _f32RemArguments; + + /// <summary> + /// Status code indicating a successful termination of t32rem.exe + /// </summary> private readonly int _f32SuccessExitCode; + + /// <summary> + /// Timeout used when waiting for the t32rem.exe to finish. + /// </summary> private readonly int _f32WaitTimeoutMs; + + /// <summary> + /// Maximum number of attempts to locate and parse the .txt file. + /// </summary> private readonly uint _maxAttempts; + + /// <summary> + /// Period (how often) the application tries to locate and parse the .txt file. + /// </summary> private readonly uint _waitPeriodMs; + + /// <summary> + /// Path to the .txt file which is generated from the debugger. + /// </summary> private readonly string _infoFilePath; + /// <summary> + /// Instance of ProcessUtils which encapsulates common functionality + /// when it comes to dealing with processes (limited by the needs of this application). + /// </summary> public IProcessUtils ProcessUtils; + + /// <summary> + /// Instance of FileUtils which encapsulates common functionality + /// when it comes to dealing with files (limited by the needs of this application). + /// </summary> public IFileUtils FileUtils; + /// <summary> + /// Returns the head serial number of the debugger. + /// </summary> public string HeadSerialNumber { get; set; } = UndefinedSerialNumber; + + /// <summary> + /// Returns the body serial number of the debugger. + /// </summary> public string BodySerialNumber { get; set; } = UndefinedSerialNumber; - - + + /// <summary> + /// Creates an instance of this class. + /// </summary> + /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param> + /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param> + /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param> + /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param> + /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param> + /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param> + /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param> public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) { + // Store the parameters into the class variables. _maxAttempts = maxAttempts; _waitPeriodMs = waitPeriodMs; _infoFilePath = infoFilePath; @@ -32,36 +93,66 @@ namespace LDClient.detection { _f32RemArguments = f32RemArguments; _f32SuccessExitCode = f32SuccessExitCode; _f32WaitTimeoutMs = f32WaitTimeoutMs; + + // Create an instance of ProcessUtils. ProcessUtils = new ProcessUtils(); + + // Create an instance of FileUtils. FileUtils = new FileUtils(); - } + /// <summary> + /// Fetches data from the debugger. It sends the commands defined + /// in the appsettings.json file to the debugger and tries to + /// parse the .txt (contains the serial numbers). + /// </summary> + /// <returns>True, if data was fetched successfully. False otherwise.</returns> public async Task<bool> FetchDataAsync() { Program.DefaultLogger.Info("Fetching data from the debugger."); + + // Send the commands to the debugger. var success = SendRetrieveInfoCommands(_f32RemExecutable, _f32RemArguments, _f32SuccessExitCode, _f32WaitTimeoutMs); + + // Make sure that all commands were sent and executed successfully. if (!success) { Program.DefaultLogger.Error("Failed to fetch data from the debugger."); return false; } + + // Periodically try to parse the .txt file. for (var i = 0; i < _maxAttempts; i++) { Program.DefaultLogger.Info($"{i}. attempt to parse the info file."); + + // Try to parse .txt file. if (RetrieveDebuggerInfo(_infoFilePath)) { Program.DefaultLogger.Info($"Info file has been parsed successfully."); return true; } + // Wait for a specified number of milliseconds. await Task.Delay((int)_waitPeriodMs); } Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created."); return false; } + /// <summary> + /// Tries to retrieve information from the debugger. + /// </summary> + /// <param name="filePath">path to the .txt file that contains all information</param> + /// <returns>True if the information was retrieved successfully. False, otherwise.</returns> private bool RetrieveDebuggerInfo(string filePath) { try { + // Read the content of the .txt file. var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n"); + + // Parse it (try to find the serial numbers) var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent); + + // Store the serial numbers into class variables (properties) HeadSerialNumber = headSerialNumber; BodySerialNumber = bodySerialNumber; + + // Finally, delete the file. File.Delete(filePath); } catch (Exception exception) { Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}"); @@ -70,11 +161,20 @@ namespace LDClient.detection { return true; } + /// <summary> + /// Sends commands to the debugger. + /// </summary> + /// <param name="executableFile">Path to the t32rem.exe file</param> + /// <param name="arguments">Arguments sent to the debugger through t32rem.exe (one argument is one command)</param> + /// <param name="desiredExitCode">Status code indicating successful termination of t32rem.exe</param> + /// <param name="waitTimeoutMs">Timeout used when waiting for t32rem.exe to finish</param> + /// <returns>True if all the commands were executed successfully. False, otherwise.</returns> private bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int desiredExitCode, int waitTimeoutMs) { if (arguments == null) { Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given"); return false; } + // Execute one all arguments (commands) one by one. foreach (var argument in arguments) { if (!ProcessUtils.ExecuteNewProcess(executableFile, argument, waitTimeoutMs, desiredExitCode)) { return false; -- GitLab From 12899c8b237991309a93f0d2efd441d178183a60 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Fri, 6 May 2022 09:56:15 +0200 Subject: [PATCH 50/67] re #9570 - Commented IProcessDetection.cs, IProcessUtils.cs, ProcessDetection.cs, and ProcessUtils.cs --- .../LDClient/detection/IProcessDetection.cs | 9 ++ ld_client/LDClient/detection/IProcessUtils.cs | 20 +++ .../LDClient/detection/ProcessDetection.cs | 114 ++++++++++++++++-- ld_client/LDClient/detection/ProcessUtils.cs | 32 ++++- 4 files changed, 159 insertions(+), 16 deletions(-) diff --git a/ld_client/LDClient/detection/IProcessDetection.cs b/ld_client/LDClient/detection/IProcessDetection.cs index 26782e1..27383f5 100644 --- a/ld_client/LDClient/detection/IProcessDetection.cs +++ b/ld_client/LDClient/detection/IProcessDetection.cs @@ -1,7 +1,16 @@ namespace LDClient.detection { + /// <summary> + /// This interface defines the functionality of a process detector. + /// A process detector is used to determine whether a user is currently + /// using a debugger or not. + /// </summary> internal interface IProcessDetection { + /// <summary> + /// Periodically runs process detection. This method is instantiated + /// as a thread from the main class (Program.cs). + /// </summary> public void RunPeriodicDetection(); } } \ No newline at end of file diff --git a/ld_client/LDClient/detection/IProcessUtils.cs b/ld_client/LDClient/detection/IProcessUtils.cs index b900375..d55a663 100644 --- a/ld_client/LDClient/detection/IProcessUtils.cs +++ b/ld_client/LDClient/detection/IProcessUtils.cs @@ -5,9 +5,29 @@ using System.Text; using System.Threading.Tasks; namespace LDClient.detection { + + /// <summary> + /// This interface defines the functionality of all methods that + /// are used to work with processes (within this project). + /// </summary> public interface IProcessUtils { + + /// <summary> + /// Checks if a process is running or not. + /// </summary> + /// <param name="name">Name of the process</param> + /// <returns>True, if the process is running. False otherwise.</returns> public bool IsProcessRunning(string name); + /// <summary> + /// Executes a new process (t32rem.exe) with arguments which are passed in + /// as a parameter of the method. + /// </summary> + /// <param name="fileName">Path to the .exe file</param> + /// <param name="argument">Arguments passed into the .exe file</param> + /// <param name="timeout">Timeout used when waiting for the process to terminate</param> + /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param> + /// <returns>True, if the command was executed successfully. False otherwise.</returns> public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode); } } diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs index 27d5333..4bde0fd 100644 --- a/ld_client/LDClient/detection/ProcessDetection.cs +++ b/ld_client/LDClient/detection/ProcessDetection.cs @@ -3,24 +3,76 @@ using LDClient.network; using LDClient.network.data; namespace LDClient.detection { - - public sealed class ProcessDetection : IProcessDetection { - + + /// <summary> + /// This class takes care of process detection. When t32mtc (process) + /// is detected, it means that the debugger is currently being used. + /// The class keeps track of the current state of a debugger. + /// </summary> + public sealed class ProcessDetection : IProcessDetection { + + /// <summary> + /// Datetime format used when sending payloads to the server. + /// </summary> private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss"; + /// <summary> + /// Name of the process the application detects. + /// </summary> private readonly string _processName; + + /// <summary> + /// How often the application check the current status of the process (cunning / not running). + /// </summary> private readonly uint _detectionPeriodMs; + + /// <summary> + /// Instance of InfoFetcher used to fetch information from the debugger + /// (when the process is detected). + /// </summary> private readonly IInfoFetcher _infoFetcher; + + /// <summary> + /// Instance of API clients used for sending data off to the server. + /// </summary> private readonly IApiClient _apiClient; + + /// <summary> + /// Instance of ProcessUtils which encapsulates common functionality + /// when it comes to dealing with processes (limited by the needs of this application). + /// </summary> private readonly IProcessUtils _processUtils; + /// <summary> + /// Flag indicating whether the process is currently running or not. + /// </summary> private bool _processIsActive; + + /// <summary> + /// Flag if the application failed to retrieve data when the process was detected. + /// </summary> private bool _failedToRetrieveData; + + /// <summary> + /// Last payload that was sent to the server. + /// </summary> private Payload? _lastConnectedPayload; + /// <summary> + /// Flag used to stop the thread (process detection). + /// </summary> public bool DetectionRunning = false; - - public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, IApiClient apiClient, IProcessUtils processUtils) { + + /// <summary> + /// Creates an instance of this class. + /// </summary> + /// <param name="processName">Name of the process the application detects</param> + /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param> + /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param> + /// <param name="apiClient">Instance of API clients used for sending data off to the server</param> + /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param> + public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, + IApiClient apiClient, IProcessUtils processUtils) { _processName = processName; _detectionPeriodMs = detectionPeriodMs; _infoFetcher = infoFetcher; @@ -29,40 +81,75 @@ namespace LDClient.detection { _processUtils = processUtils; } + /// <summary> + /// Retrieves data from the debugger. + /// </summary> + /// <returns>True, if the data was fetched successfully. False, otherwise.</returns> private async Task<bool> RetrieveDataFromDebugger() { + // Try to fetch data from the debugger. var success = await _infoFetcher.FetchDataAsync(); + + // If the data was fetched successfully, send a payload off to the server. if (success) { - _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat); + _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, + _infoFetcher.BodySerialNumber, DatetimeFormat); } return success; } + /// <summary> + /// Sends a payload to the server when a debugger gets disconnected. + /// </summary> private async Task DebuggerDisconnected() { + // Make sure the debugger was connected in the first place. if (_lastConnectedPayload is not null) { + // Update the status and timestamp of the last payload + // (the serial numbers remain the same). _lastConnectedPayload.Status = ConnectionStatus.Disconnected; _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat); + + // Send the data to the server. await _apiClient.SendPayloadAsync(_lastConnectedPayload); + + // Clear the last payload. _lastConnectedPayload = null; } } + /// <summary> + /// Checks if the t32mtc process is running or not. + /// </summary> private async Task DetectProcessAsync() { + // Check if the process is running. var processExists = _processUtils.IsProcessRunning(_processName); + // Check if the process was not running but now it is (flip flop ON). if (processExists && !_processIsActive) { Program.DefaultLogger.Info($"Process started: {_processName}"); if (!_failedToRetrieveData) { _failedToRetrieveData = !await RetrieveDataFromDebugger(); } - } else if (!processExists && _processIsActive) { + } + // Check if the process was running but now it is not (fli flop OFF). + else if (!processExists && _processIsActive) { Program.DefaultLogger.Info($"Process stopped: {_processName}"); _failedToRetrieveData = false; await DebuggerDisconnected(); } + + // Keep track of the current state of the debugger. _processIsActive = processExists; } - + + /// <summary> + /// Creates a payload and sends it to the server. + /// </summary> + /// <param name="headSerialNumber">serial number of the head of the debugger</param> + /// <param name="bodySerialNumber">serial number of the body of the debugger</param> + /// <param name="datetimeFormat">datetime format (timestamp)</param> + /// <returns>the newly-created payload</returns> private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) { + // Create a new payload. Payload payload = new() { UserName = Environment.UserName, HostName = Environment.MachineName, @@ -75,16 +162,23 @@ namespace LDClient.detection { }, Status = ConnectionStatus.Connected }; + + // Send it to the server and return it. await _apiClient.SendPayloadAsync(payload); return payload; } - + + /// <summary> + /// Periodically runs process detection. This method is instantiated + /// as a thread from the main class (Program.cs). + /// </summary> public async void RunPeriodicDetection() { Program.DefaultLogger.Info("Process periodic detector has started"); DetectionRunning = true; + while (DetectionRunning) { await DetectProcessAsync(); - Thread.Sleep((int)_detectionPeriodMs); + Thread.Sleep((int) _detectionPeriodMs); } } } diff --git a/ld_client/LDClient/detection/ProcessUtils.cs b/ld_client/LDClient/detection/ProcessUtils.cs index b707f66..5c448e7 100644 --- a/ld_client/LDClient/detection/ProcessUtils.cs +++ b/ld_client/LDClient/detection/ProcessUtils.cs @@ -6,24 +6,46 @@ using System.Text; using System.Threading.Tasks; namespace LDClient.detection { - public class ProcessUtils : IProcessUtils{ + + /// <summary> + /// This class implements the IProcessUtils interface. + /// It implements methods that are used when dealing with processes. + /// </summary> + public class ProcessUtils : IProcessUtils { + /// <summary> + /// Checks if a process is running or not. + /// </summary> + /// <param name="name">Name of the process</param> + /// <returns>True, if the process is running. False otherwise.</returns> public bool IsProcessRunning(string name) { return Process.GetProcessesByName(name).Length > 0; } - - + + /// <summary> + /// Executes a new process (t32rem.exe) with arguments which are passed in + /// as a parameter of the method. + /// </summary> + /// <param name="fileName">Path to the .exe file</param> + /// <param name="argument">Arguments passed into the .exe file</param> + /// <param name="timeout">Timeout used when waiting for the process to terminate</param> + /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param> + /// <returns>True, if the command was executed successfully. False otherwise.</returns> public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) { - + // Create a new process. var t32RemProcess = new Process(); t32RemProcess.StartInfo.FileName = fileName; t32RemProcess.StartInfo.Arguments = argument; + try { + // Execute the process and wait until it terminates or until the timeout is up. t32RemProcess.Start(); if (!t32RemProcess.WaitForExit(timeout)) { Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms"); return false; } + + // Check if the process terminated successfully. if (t32RemProcess.ExitCode != desiredExitCode) { Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}"); return false; @@ -32,9 +54,7 @@ namespace LDClient.detection { Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}"); return false; } - return true; } - } } -- GitLab From d7aeccbac4b7bdcc86ca85c555107e8f4fcda80e Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 7 May 2022 23:30:02 +0200 Subject: [PATCH 51/67] re #9570 Added code documentation to logger classes and properties --- ld_client/LDClient/utils/loggers/ALogger.cs | 88 ++++++++++++++++++- .../LDClient/utils/loggers/ConsoleLogger.cs | 4 + .../LDClient/utils/loggers/FileLogger.cs | 41 ++++++++- ld_client/LDClient/utils/loggers/LogFlow.cs | 9 ++ ld_client/LDClient/utils/loggers/LogType.cs | 3 + .../LDClient/utils/loggers/LogVerbosity.cs | 4 + 6 files changed, 145 insertions(+), 4 deletions(-) diff --git a/ld_client/LDClient/utils/loggers/ALogger.cs b/ld_client/LDClient/utils/loggers/ALogger.cs index 260a03d..c89f161 100644 --- a/ld_client/LDClient/utils/loggers/ALogger.cs +++ b/ld_client/LDClient/utils/loggers/ALogger.cs @@ -2,17 +2,49 @@ namespace LDClient.utils.loggers { + /// <summary> + /// This class implements all abstract functions of the logger. + /// It contains all functions (error, info, debug) that are present in any other standard logger. + /// Class is used as singleton design pattern + /// </summary> public abstract class ALogger : IDisposable { + /// <summary> + /// Logger verbosity type identifies how much information should be actually logged + /// </summary> private readonly LogVerbosity _verbosity; + + /// <summary> + /// Current type of logger + /// </summary> private readonly LogFlow _logFlow; + /// <summary> + /// Queue of all not yet logged messages + /// </summary> private readonly Queue<Action> _queue = new(); + + /// <summary> + /// Synchronization prime used to identify if the is anything new in the queue + /// </summary> private readonly ManualResetEvent _hasNewItems = new(false); + /// <summary> + /// Synchronization prime used to identify if the logger should be terminated + /// </summary> private readonly ManualResetEvent _terminate = new(false); + /// <summary> + /// Synchronization prime used to identify if the current thread is waiting + /// </summary> private readonly ManualResetEvent _waiting = new(false); + + /// <summary> + /// Thread instance of logging thread + /// </summary> private readonly Thread _loggingThread; + /// <summary> + /// Instance of the default logger initialized with the lazy binding mechanism + /// </summary> private static readonly Lazy<ALogger> LazyLog = new(() => { switch (Program.Config.LogFlowType) { @@ -26,8 +58,14 @@ namespace LDClient.utils.loggers { } ); + /// <summary> + /// Instance of the current logger type + /// </summary> public static ALogger Current => LazyLog.Value; + /// <summary> + /// Singleton constructor that initialized and starts the logger with arguments parsed by the config loader + /// </summary> protected ALogger() { _verbosity = Program.Config.LogVerbosityType; _logFlow = Program.Config.LogFlowType; @@ -35,46 +73,87 @@ namespace LDClient.utils.loggers { _loggingThread.Start(); } + /// <summary> + /// Creates new log with Info identifier + /// </summary> + /// <param name="message">Desired message to be logged</param> public void Info(string message) { Log(message, LogType.Info); } + /// <summary> + /// Creates new log with Debug identifier + /// </summary> + /// <param name="message">Desired message to be logged</param> public void Debug(string message) { Log(message, LogType.Debug); } + /// <summary> + /// Creates new log with Error identifier + /// </summary> + /// <param name="message">Desired message to be logged</param> public void Error(string message) { Log(message, LogType.Error); } + /// <summary> + /// Creates new log from the catched exception + /// </summary> + /// <param name="e">catched exception tha should be logged</param> public void Error(Exception e) { if (_verbosity != LogVerbosity.None) { Log(UnwrapExceptionMessages(e), LogType.Error); } } + /// <summary> + /// Creates new string info about current logger configuration + /// </summary> + /// <returns></returns> public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, "; - + protected abstract void CreateLog(string message); + /// <summary> + /// Waits for the logger to finish the logging + /// </summary> public void Flush() => _waiting.WaitOne(); + /// <summary> + /// Function stops the logger thread + /// </summary> public void Dispose() { _terminate.Set(); _loggingThread.Join(); } + /// <summary> + /// Composes the log with actual timestamp, log type and its main message + /// </summary> + /// <param name="message">main message of the log</param> + /// <param name="logType">Type of the logged message</param> + /// <returns></returns> protected virtual string ComposeLogRow(string message, LogType logType) => $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}"; + /// <summary> + /// Function creates log from the catched exception + /// </summary> + /// <param name="ex">catched exception tha should be logged</param> + /// <returns></returns> protected virtual string UnwrapExceptionMessages(Exception? ex) => ex == null ? string.Empty : $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} "; - + /// <summary> + /// Function that periodically processes message queue + /// </summary> private void ProcessQueue() { while (true) { _waiting.Set(); + //wait until there is new item in the queue or until termination invoked var i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate }); + //was the termination invoked? if (i == 1) return; _hasNewItems.Reset(); _waiting.Reset(); @@ -91,6 +170,11 @@ namespace LDClient.utils.loggers { } } + /// <summary> + /// Creates new log string from the current timestamp + /// </summary> + /// <param name="message"></param> + /// <param name="logType"></param> private void Log(string message, LogType logType) { if (string.IsNullOrEmpty(message)) return; diff --git a/ld_client/LDClient/utils/loggers/ConsoleLogger.cs b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs index b108ed6..a893d02 100644 --- a/ld_client/LDClient/utils/loggers/ConsoleLogger.cs +++ b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs @@ -1,5 +1,9 @@ namespace LDClient.utils.loggers { public class ConsoleLogger : ALogger { + /// <summary> + /// CreateLog function for the ConsoleLogger prints the desired message to the console + /// </summary> + /// <param name="message">Desired message to be printed</param> protected override void CreateLog(string message) { Console.WriteLine(message); } diff --git a/ld_client/LDClient/utils/loggers/FileLogger.cs b/ld_client/LDClient/utils/loggers/FileLogger.cs index d63ab05..6651ff9 100644 --- a/ld_client/LDClient/utils/loggers/FileLogger.cs +++ b/ld_client/LDClient/utils/loggers/FileLogger.cs @@ -4,17 +4,37 @@ namespace LDClient.utils.loggers; public class FileLogger : ALogger { + /// <summary> + /// Folder name for the created log files + /// </summary> private const string LogFolderName = "logs"; + /// <summary> + /// Base name of the log file + /// </summary> private const string LogFileName = "app_info.log"; + private readonly int _logChunkSize = Program.Config.LogChunkSize; private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount; private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount; private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod; + /// <summary> + /// Destination folder used to store the created logs and zipped chunks + /// </summary> private const string LogFolderPath = $"ldClient\\{LogFolderName}"; + /// <summary> + /// Flag that indicates that the log folder is already created + /// </summary> private bool _logDirExists; + /// <summary> + /// Creates one entry in the rotating file. + /// If the current log file is too big, it creates new log file. + /// If there is too many log files it archives them. + /// Deletes all archived files that are too old + /// </summary> + /// <param name="message">Desired message to be logged<</param> protected override void CreateLog(string message) { if (!_logDirExists) { @@ -33,6 +53,10 @@ public class FileLogger : ALogger { sw.WriteLine(message); } + /// <summary> + /// Rotates last log file by creating new logging file in the process + /// </summary> + /// <param name="filePath">path to the last log file</param> private void Rotate(string filePath) { if (!File.Exists(filePath)) { return; @@ -60,6 +84,13 @@ public class FileLogger : ALogger { DeleteOldArchives(logFolderContent); } + /// <summary> + /// Archives the all the last log files (chunks) + /// </summary> + /// <param name="chunks">All log files that will be archived</param> + /// <param name="rotatedPath">path to the log files, which will be archived</param> + /// <param name="fileTime">current time stamp in string</param> + /// <param name="folderPath">path to to the exported archives</param> private void Archive(IEnumerable<FileSystemInfo> chunks, string rotatedPath, string fileTime, string? folderPath) { var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath) ?? LogFolderPath, $"{LogFolderName}_{fileTime}")); @@ -73,15 +104,22 @@ public class FileLogger : ALogger { Directory.Delete(archiveFolderInfo.FullName, true); } + /// <summary> + /// This function deletes all archives that are too old and exceeds the maximum zip files. + /// Cleanup period and zip max count can be specified in the configuration file. + /// </summary> + /// <param name="logFolderContent">filesystem info of the log folder</param> private void DeleteOldArchives(FileSystemInfo[] logFolderContent) { var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray(); - + if (archives.Length <= _logArchiveMaxCount) return; + //find oldest archive in the folder var oldestArchive = archives.OrderBy(x => x.CreationTime).First(); var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod); + //is there any file older than specified cleanup cleanup period if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) { foreach (var file in logFolderContent) { file.Delete(); @@ -90,6 +128,5 @@ public class FileLogger : ALogger { File.Delete(oldestArchive.FullName); } } - public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]"; } \ No newline at end of file diff --git a/ld_client/LDClient/utils/loggers/LogFlow.cs b/ld_client/LDClient/utils/loggers/LogFlow.cs index 5041b12..92555cd 100644 --- a/ld_client/LDClient/utils/loggers/LogFlow.cs +++ b/ld_client/LDClient/utils/loggers/LogFlow.cs @@ -1,6 +1,15 @@ namespace LDClient.utils.loggers { + /// <summary> + /// This enum specifies all possible types of loggers + /// </summary> public enum LogFlow { + /// <summary> + /// Console logger + /// </summary> Console = 0, + /// <summary> + /// Rotating file logger + /// </summary> File } } diff --git a/ld_client/LDClient/utils/loggers/LogType.cs b/ld_client/LDClient/utils/loggers/LogType.cs index 370057f..b3caad6 100644 --- a/ld_client/LDClient/utils/loggers/LogType.cs +++ b/ld_client/LDClient/utils/loggers/LogType.cs @@ -1,4 +1,7 @@ namespace LDClient.utils.loggers { + /// <summary> + /// Types of all possible logs + /// </summary> public enum LogType { Info = 0, Debug, diff --git a/ld_client/LDClient/utils/loggers/LogVerbosity.cs b/ld_client/LDClient/utils/loggers/LogVerbosity.cs index 03c292b..af525a9 100644 --- a/ld_client/LDClient/utils/loggers/LogVerbosity.cs +++ b/ld_client/LDClient/utils/loggers/LogVerbosity.cs @@ -1,4 +1,8 @@ namespace LDClient.utils.loggers { + + /// <summary> + /// Enum specifies the verbosity of the log messages + /// </summary> public enum LogVerbosity { None = 0, Exceptions, -- GitLab From 605fed4f4af530aa79f1ba709b08fbc5e9285530 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sat, 7 May 2022 23:31:56 +0200 Subject: [PATCH 52/67] re #9570 Added generated html documentation --- ld_client/doc/pdoc/annotated.html | 124 ++ ld_client/doc/pdoc/annotated_dup.js | 31 + ld_client/doc/pdoc/bc_s.png | Bin 0 -> 676 bytes ld_client/doc/pdoc/bdwn.png | Bin 0 -> 147 bytes .../doc/pdoc/class_file_logger-members.html | 103 + ld_client/doc/pdoc/class_file_logger.html | 154 ++ ld_client/doc/pdoc/class_file_logger.js | 4 + ...1_1detection_1_1_info_fetcher-members.html | 107 + ..._client_1_1detection_1_1_info_fetcher.html | 301 +++ ..._d_client_1_1detection_1_1_info_fetcher.js | 9 + ...tection_1_1_process_detection-members.html | 104 + ...nt_1_1detection_1_1_process_detection.html | 188 ++ ...ient_1_1detection_1_1_process_detection.js | 6 + ..._1detection_1_1_process_utils-members.html | 103 + ...client_1_1detection_1_1_process_utils.html | 210 ++ ...d_client_1_1detection_1_1_process_utils.js | 5 + ...ent_1_1network_1_1_api_client-members.html | 106 + ..._l_d_client_1_1network_1_1_api_client.html | 264 +++ ...ss_l_d_client_1_1network_1_1_api_client.js | 8 + ...nt_1_1network_1_1_http_client-members.html | 103 + ...l_d_client_1_1network_1_1_http_client.html | 180 ++ ...s_l_d_client_1_1network_1_1_http_client.js | 5 + ...ork_1_1data_1_1_debugger_info-members.html | 102 + ..._1_1network_1_1data_1_1_debugger_info.html | 118 ++ ...nt_1_1network_1_1data_1_1_debugger_info.js | 4 + ..._1network_1_1data_1_1_payload-members.html | 110 + ...client_1_1network_1_1data_1_1_payload.html | 231 +++ ...d_client_1_1network_1_1data_1_1_payload.js | 11 + ...lient_1_1utils_1_1_file_utils-members.html | 102 + ...ss_l_d_client_1_1utils_1_1_file_utils.html | 150 ++ ...lass_l_d_client_1_1utils_1_1_file_utils.js | 4 + ...utils_1_1loggers_1_1_a_logger-members.html | 113 + ...ient_1_1utils_1_1loggers_1_1_a_logger.html | 395 ++++ ...client_1_1utils_1_1loggers_1_1_a_logger.js | 13 + ...1_1loggers_1_1_console_logger-members.html | 113 + ..._1utils_1_1loggers_1_1_console_logger.html | 194 ++ ..._1_1utils_1_1loggers_1_1_console_logger.js | 4 + ld_client/doc/pdoc/classes.html | 122 ++ ld_client/doc/pdoc/closed.png | Bin 0 -> 132 bytes .../dir_08b4fbe3d60d6d41472a6a22c750d4c7.html | 99 + .../dir_43724e81dd40e09f32417973865cdd64.html | 99 + .../dir_7212c827820ef56532d3599ed27e3aff.html | 99 + .../dir_754926843367c7eee8b48719e3f14adf.html | 99 + .../dir_a71c3b2ad23b9ff58220dd012d201987.html | 105 + .../dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html | 99 + .../dir_c901c14b65aa229498a52b725b3d4a2c.html | 105 + .../dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html | 105 + ld_client/doc/pdoc/doc.png | Bin 0 -> 746 bytes ld_client/doc/pdoc/doxygen.css | 1841 +++++++++++++++++ ld_client/doc/pdoc/doxygen.svg | 26 + ld_client/doc/pdoc/dynsections.js | 121 ++ ld_client/doc/pdoc/folderclosed.png | Bin 0 -> 616 bytes ld_client/doc/pdoc/folderopen.png | Bin 0 -> 597 bytes ld_client/doc/pdoc/functions.html | 189 ++ ld_client/doc/pdoc/functions_func.html | 166 ++ ld_client/doc/pdoc/functions_prop.html | 107 + ld_client/doc/pdoc/functions_vars.html | 102 + ld_client/doc/pdoc/hierarchy.html | 120 ++ ld_client/doc/pdoc/hierarchy.js | 29 + ld_client/doc/pdoc/index.html | 98 + ...1detection_1_1_i_info_fetcher-members.html | 104 + ...lient_1_1detection_1_1_i_info_fetcher.html | 203 ++ ..._client_1_1detection_1_1_i_info_fetcher.js | 6 + ...detection_1_1_i_process_utils-members.html | 103 + ...ient_1_1detection_1_1_i_process_utils.html | 204 ++ ...client_1_1detection_1_1_i_process_utils.js | 5 + ...t_1_1network_1_1_i_api_client-members.html | 103 + ..._d_client_1_1network_1_1_i_api_client.html | 170 ++ ..._l_d_client_1_1network_1_1_i_api_client.js | 5 + ..._1_1network_1_1_i_http_client-members.html | 102 + ...d_client_1_1network_1_1_i_http_client.html | 147 ++ ...l_d_client_1_1network_1_1_i_http_client.js | 4 + ...ent_1_1utils_1_1_i_file_utils-members.html | 102 + ..._l_d_client_1_1utils_1_1_i_file_utils.html | 147 ++ ...ce_l_d_client_1_1utils_1_1_i_file_utils.js | 4 + ld_client/doc/pdoc/jquery.js | 35 + ld_client/doc/pdoc/menu.js | 135 ++ ld_client/doc/pdoc/menudata.js | 66 + ld_client/doc/pdoc/namespace_l_d_client.html | 99 + ld_client/doc/pdoc/namespace_l_d_client.js | 6 + .../namespace_l_d_client_1_1detection.html | 126 ++ .../pdoc/namespace_l_d_client_1_1detection.js | 8 + .../pdoc/namespace_l_d_client_1_1network.html | 117 ++ .../pdoc/namespace_l_d_client_1_1network.js | 8 + ...mespace_l_d_client_1_1network_1_1data.html | 143 ++ ...namespace_l_d_client_1_1network_1_1data.js | 9 + .../pdoc/namespace_l_d_client_1_1utils.html | 114 + .../doc/pdoc/namespace_l_d_client_1_1utils.js | 6 + ...espace_l_d_client_1_1utils_1_1loggers.html | 154 ++ ...amespace_l_d_client_1_1utils_1_1loggers.js | 19 + ld_client/doc/pdoc/namespacemembers.html | 101 + ld_client/doc/pdoc/namespacemembers_enum.html | 101 + ld_client/doc/pdoc/namespaces.html | 123 ++ ld_client/doc/pdoc/namespaces_dup.js | 4 + ld_client/doc/pdoc/nav_f.png | Bin 0 -> 153 bytes ld_client/doc/pdoc/nav_g.png | Bin 0 -> 95 bytes ld_client/doc/pdoc/nav_h.png | Bin 0 -> 98 bytes ld_client/doc/pdoc/navtree.css | 147 ++ ld_client/doc/pdoc/navtree.js | 549 +++++ ld_client/doc/pdoc/navtreedata.js | 55 + ld_client/doc/pdoc/navtreeindex0.js | 163 ++ ld_client/doc/pdoc/open.png | Bin 0 -> 123 bytes ld_client/doc/pdoc/resize.js | 150 ++ ld_client/doc/pdoc/search/all_0.html | 37 + ld_client/doc/pdoc/search/all_0.js | 4 + ld_client/doc/pdoc/search/all_1.html | 37 + ld_client/doc/pdoc/search/all_1.js | 5 + ld_client/doc/pdoc/search/all_2.html | 37 + ld_client/doc/pdoc/search/all_2.js | 5 + ld_client/doc/pdoc/search/all_3.html | 37 + ld_client/doc/pdoc/search/all_3.js | 11 + ld_client/doc/pdoc/search/all_4.html | 37 + ld_client/doc/pdoc/search/all_4.js | 8 + ld_client/doc/pdoc/search/all_5.html | 37 + ld_client/doc/pdoc/search/all_5.js | 5 + ld_client/doc/pdoc/search/all_6.html | 37 + ld_client/doc/pdoc/search/all_6.js | 8 + ld_client/doc/pdoc/search/all_7.html | 37 + ld_client/doc/pdoc/search/all_7.js | 7 + ld_client/doc/pdoc/search/all_8.html | 37 + ld_client/doc/pdoc/search/all_8.js | 11 + ld_client/doc/pdoc/search/all_9.html | 37 + ld_client/doc/pdoc/search/all_9.js | 12 + ld_client/doc/pdoc/search/all_a.html | 37 + ld_client/doc/pdoc/search/all_a.js | 8 + ld_client/doc/pdoc/search/all_b.html | 37 + ld_client/doc/pdoc/search/all_b.js | 6 + ld_client/doc/pdoc/search/all_c.html | 37 + ld_client/doc/pdoc/search/all_c.js | 6 + ld_client/doc/pdoc/search/all_d.html | 37 + ld_client/doc/pdoc/search/all_d.js | 5 + ld_client/doc/pdoc/search/all_e.html | 37 + ld_client/doc/pdoc/search/all_e.js | 5 + ld_client/doc/pdoc/search/classes_0.html | 37 + ld_client/doc/pdoc/search/classes_0.js | 5 + ld_client/doc/pdoc/search/classes_1.html | 37 + ld_client/doc/pdoc/search/classes_1.js | 4 + ld_client/doc/pdoc/search/classes_2.html | 37 + ld_client/doc/pdoc/search/classes_2.js | 4 + ld_client/doc/pdoc/search/classes_3.html | 37 + ld_client/doc/pdoc/search/classes_3.js | 5 + ld_client/doc/pdoc/search/classes_4.html | 37 + ld_client/doc/pdoc/search/classes_4.js | 4 + ld_client/doc/pdoc/search/classes_5.html | 37 + ld_client/doc/pdoc/search/classes_5.js | 9 + ld_client/doc/pdoc/search/classes_6.html | 37 + ld_client/doc/pdoc/search/classes_6.js | 6 + ld_client/doc/pdoc/search/close.svg | 31 + ld_client/doc/pdoc/search/enums_0.html | 37 + ld_client/doc/pdoc/search/enums_0.js | 4 + ld_client/doc/pdoc/search/enums_1.html | 37 + ld_client/doc/pdoc/search/enums_1.js | 6 + ld_client/doc/pdoc/search/enumvalues_0.html | 37 + ld_client/doc/pdoc/search/enumvalues_0.js | 5 + ld_client/doc/pdoc/search/enumvalues_1.html | 37 + ld_client/doc/pdoc/search/enumvalues_1.js | 4 + ld_client/doc/pdoc/search/enumvalues_2.html | 37 + ld_client/doc/pdoc/search/enumvalues_2.js | 4 + ld_client/doc/pdoc/search/functions_0.html | 37 + ld_client/doc/pdoc/search/functions_0.js | 5 + ld_client/doc/pdoc/search/functions_1.html | 37 + ld_client/doc/pdoc/search/functions_1.js | 5 + ld_client/doc/pdoc/search/functions_2.html | 37 + ld_client/doc/pdoc/search/functions_2.js | 5 + ld_client/doc/pdoc/search/functions_3.html | 37 + ld_client/doc/pdoc/search/functions_3.js | 5 + ld_client/doc/pdoc/search/functions_4.html | 37 + ld_client/doc/pdoc/search/functions_4.js | 5 + ld_client/doc/pdoc/search/functions_5.html | 37 + ld_client/doc/pdoc/search/functions_5.js | 4 + ld_client/doc/pdoc/search/functions_6.html | 37 + ld_client/doc/pdoc/search/functions_6.js | 6 + ld_client/doc/pdoc/search/functions_7.html | 37 + ld_client/doc/pdoc/search/functions_7.js | 6 + ld_client/doc/pdoc/search/functions_8.html | 37 + ld_client/doc/pdoc/search/functions_8.js | 6 + ld_client/doc/pdoc/search/functions_9.html | 37 + ld_client/doc/pdoc/search/functions_9.js | 4 + ld_client/doc/pdoc/search/functions_a.html | 37 + ld_client/doc/pdoc/search/functions_a.js | 4 + ld_client/doc/pdoc/search/functions_b.html | 37 + ld_client/doc/pdoc/search/functions_b.js | 4 + ld_client/doc/pdoc/search/mag_sel.svg | 74 + ld_client/doc/pdoc/search/namespaces_0.html | 37 + ld_client/doc/pdoc/search/namespaces_0.js | 9 + ld_client/doc/pdoc/search/nomatches.html | 13 + ld_client/doc/pdoc/search/properties_0.html | 37 + ld_client/doc/pdoc/search/properties_0.js | 5 + ld_client/doc/pdoc/search/properties_1.html | 37 + ld_client/doc/pdoc/search/properties_1.js | 4 + ld_client/doc/pdoc/search/properties_2.html | 37 + ld_client/doc/pdoc/search/properties_2.js | 6 + ld_client/doc/pdoc/search/properties_3.html | 37 + ld_client/doc/pdoc/search/properties_3.js | 5 + ld_client/doc/pdoc/search/properties_4.html | 37 + ld_client/doc/pdoc/search/properties_4.js | 4 + ld_client/doc/pdoc/search/properties_5.html | 37 + ld_client/doc/pdoc/search/properties_5.js | 4 + ld_client/doc/pdoc/search/search.css | 263 +++ ld_client/doc/pdoc/search/search.js | 802 +++++++ ld_client/doc/pdoc/search/search_l.png | Bin 0 -> 567 bytes ld_client/doc/pdoc/search/search_m.png | Bin 0 -> 158 bytes ld_client/doc/pdoc/search/search_r.png | Bin 0 -> 553 bytes ld_client/doc/pdoc/search/searchdata.js | 36 + ld_client/doc/pdoc/search/variables_0.html | 37 + ld_client/doc/pdoc/search/variables_0.js | 4 + ld_client/doc/pdoc/search/variables_1.html | 37 + ld_client/doc/pdoc/search/variables_1.js | 4 + ld_client/doc/pdoc/search/variables_2.html | 37 + ld_client/doc/pdoc/search/variables_2.js | 4 + ld_client/doc/pdoc/search/variables_3.html | 37 + ld_client/doc/pdoc/search/variables_3.js | 4 + ld_client/doc/pdoc/search/variables_4.html | 37 + ld_client/doc/pdoc/search/variables_4.js | 4 + ld_client/doc/pdoc/splitbar.png | Bin 0 -> 314 bytes ld_client/doc/pdoc/sync_off.png | Bin 0 -> 853 bytes ld_client/doc/pdoc/sync_on.png | Bin 0 -> 845 bytes ld_client/doc/pdoc/tab_a.png | Bin 0 -> 142 bytes ld_client/doc/pdoc/tab_b.png | Bin 0 -> 169 bytes ld_client/doc/pdoc/tab_h.png | Bin 0 -> 177 bytes ld_client/doc/pdoc/tab_s.png | Bin 0 -> 184 bytes ld_client/doc/pdoc/tabs.css | 1 + 222 files changed, 14746 insertions(+) create mode 100644 ld_client/doc/pdoc/annotated.html create mode 100644 ld_client/doc/pdoc/annotated_dup.js create mode 100644 ld_client/doc/pdoc/bc_s.png create mode 100644 ld_client/doc/pdoc/bdwn.png create mode 100644 ld_client/doc/pdoc/class_file_logger-members.html create mode 100644 ld_client/doc/pdoc/class_file_logger.html create mode 100644 ld_client/doc/pdoc/class_file_logger.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js create mode 100644 ld_client/doc/pdoc/classes.html create mode 100644 ld_client/doc/pdoc/closed.png create mode 100644 ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html create mode 100644 ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html create mode 100644 ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html create mode 100644 ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html create mode 100644 ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html create mode 100644 ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html create mode 100644 ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html create mode 100644 ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html create mode 100644 ld_client/doc/pdoc/doc.png create mode 100644 ld_client/doc/pdoc/doxygen.css create mode 100644 ld_client/doc/pdoc/doxygen.svg create mode 100644 ld_client/doc/pdoc/dynsections.js create mode 100644 ld_client/doc/pdoc/folderclosed.png create mode 100644 ld_client/doc/pdoc/folderopen.png create mode 100644 ld_client/doc/pdoc/functions.html create mode 100644 ld_client/doc/pdoc/functions_func.html create mode 100644 ld_client/doc/pdoc/functions_prop.html create mode 100644 ld_client/doc/pdoc/functions_vars.html create mode 100644 ld_client/doc/pdoc/hierarchy.html create mode 100644 ld_client/doc/pdoc/hierarchy.js create mode 100644 ld_client/doc/pdoc/index.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js create mode 100644 ld_client/doc/pdoc/jquery.js create mode 100644 ld_client/doc/pdoc/menu.js create mode 100644 ld_client/doc/pdoc/menudata.js create mode 100644 ld_client/doc/pdoc/namespace_l_d_client.html create mode 100644 ld_client/doc/pdoc/namespace_l_d_client.js create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network.html create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network.js create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js create mode 100644 ld_client/doc/pdoc/namespacemembers.html create mode 100644 ld_client/doc/pdoc/namespacemembers_enum.html create mode 100644 ld_client/doc/pdoc/namespaces.html create mode 100644 ld_client/doc/pdoc/namespaces_dup.js create mode 100644 ld_client/doc/pdoc/nav_f.png create mode 100644 ld_client/doc/pdoc/nav_g.png create mode 100644 ld_client/doc/pdoc/nav_h.png create mode 100644 ld_client/doc/pdoc/navtree.css create mode 100644 ld_client/doc/pdoc/navtree.js create mode 100644 ld_client/doc/pdoc/navtreedata.js create mode 100644 ld_client/doc/pdoc/navtreeindex0.js create mode 100644 ld_client/doc/pdoc/open.png create mode 100644 ld_client/doc/pdoc/resize.js create mode 100644 ld_client/doc/pdoc/search/all_0.html create mode 100644 ld_client/doc/pdoc/search/all_0.js create mode 100644 ld_client/doc/pdoc/search/all_1.html create mode 100644 ld_client/doc/pdoc/search/all_1.js create mode 100644 ld_client/doc/pdoc/search/all_2.html create mode 100644 ld_client/doc/pdoc/search/all_2.js create mode 100644 ld_client/doc/pdoc/search/all_3.html create mode 100644 ld_client/doc/pdoc/search/all_3.js create mode 100644 ld_client/doc/pdoc/search/all_4.html create mode 100644 ld_client/doc/pdoc/search/all_4.js create mode 100644 ld_client/doc/pdoc/search/all_5.html create mode 100644 ld_client/doc/pdoc/search/all_5.js create mode 100644 ld_client/doc/pdoc/search/all_6.html create mode 100644 ld_client/doc/pdoc/search/all_6.js create mode 100644 ld_client/doc/pdoc/search/all_7.html create mode 100644 ld_client/doc/pdoc/search/all_7.js create mode 100644 ld_client/doc/pdoc/search/all_8.html create mode 100644 ld_client/doc/pdoc/search/all_8.js create mode 100644 ld_client/doc/pdoc/search/all_9.html create mode 100644 ld_client/doc/pdoc/search/all_9.js create mode 100644 ld_client/doc/pdoc/search/all_a.html create mode 100644 ld_client/doc/pdoc/search/all_a.js create mode 100644 ld_client/doc/pdoc/search/all_b.html create mode 100644 ld_client/doc/pdoc/search/all_b.js create mode 100644 ld_client/doc/pdoc/search/all_c.html create mode 100644 ld_client/doc/pdoc/search/all_c.js create mode 100644 ld_client/doc/pdoc/search/all_d.html create mode 100644 ld_client/doc/pdoc/search/all_d.js create mode 100644 ld_client/doc/pdoc/search/all_e.html create mode 100644 ld_client/doc/pdoc/search/all_e.js create mode 100644 ld_client/doc/pdoc/search/classes_0.html create mode 100644 ld_client/doc/pdoc/search/classes_0.js create mode 100644 ld_client/doc/pdoc/search/classes_1.html create mode 100644 ld_client/doc/pdoc/search/classes_1.js create mode 100644 ld_client/doc/pdoc/search/classes_2.html create mode 100644 ld_client/doc/pdoc/search/classes_2.js create mode 100644 ld_client/doc/pdoc/search/classes_3.html create mode 100644 ld_client/doc/pdoc/search/classes_3.js create mode 100644 ld_client/doc/pdoc/search/classes_4.html create mode 100644 ld_client/doc/pdoc/search/classes_4.js create mode 100644 ld_client/doc/pdoc/search/classes_5.html create mode 100644 ld_client/doc/pdoc/search/classes_5.js create mode 100644 ld_client/doc/pdoc/search/classes_6.html create mode 100644 ld_client/doc/pdoc/search/classes_6.js create mode 100644 ld_client/doc/pdoc/search/close.svg create mode 100644 ld_client/doc/pdoc/search/enums_0.html create mode 100644 ld_client/doc/pdoc/search/enums_0.js create mode 100644 ld_client/doc/pdoc/search/enums_1.html create mode 100644 ld_client/doc/pdoc/search/enums_1.js create mode 100644 ld_client/doc/pdoc/search/enumvalues_0.html create mode 100644 ld_client/doc/pdoc/search/enumvalues_0.js create mode 100644 ld_client/doc/pdoc/search/enumvalues_1.html create mode 100644 ld_client/doc/pdoc/search/enumvalues_1.js create mode 100644 ld_client/doc/pdoc/search/enumvalues_2.html create mode 100644 ld_client/doc/pdoc/search/enumvalues_2.js create mode 100644 ld_client/doc/pdoc/search/functions_0.html create mode 100644 ld_client/doc/pdoc/search/functions_0.js create mode 100644 ld_client/doc/pdoc/search/functions_1.html create mode 100644 ld_client/doc/pdoc/search/functions_1.js create mode 100644 ld_client/doc/pdoc/search/functions_2.html create mode 100644 ld_client/doc/pdoc/search/functions_2.js create mode 100644 ld_client/doc/pdoc/search/functions_3.html create mode 100644 ld_client/doc/pdoc/search/functions_3.js create mode 100644 ld_client/doc/pdoc/search/functions_4.html create mode 100644 ld_client/doc/pdoc/search/functions_4.js create mode 100644 ld_client/doc/pdoc/search/functions_5.html create mode 100644 ld_client/doc/pdoc/search/functions_5.js create mode 100644 ld_client/doc/pdoc/search/functions_6.html create mode 100644 ld_client/doc/pdoc/search/functions_6.js create mode 100644 ld_client/doc/pdoc/search/functions_7.html create mode 100644 ld_client/doc/pdoc/search/functions_7.js create mode 100644 ld_client/doc/pdoc/search/functions_8.html create mode 100644 ld_client/doc/pdoc/search/functions_8.js create mode 100644 ld_client/doc/pdoc/search/functions_9.html create mode 100644 ld_client/doc/pdoc/search/functions_9.js create mode 100644 ld_client/doc/pdoc/search/functions_a.html create mode 100644 ld_client/doc/pdoc/search/functions_a.js create mode 100644 ld_client/doc/pdoc/search/functions_b.html create mode 100644 ld_client/doc/pdoc/search/functions_b.js create mode 100644 ld_client/doc/pdoc/search/mag_sel.svg create mode 100644 ld_client/doc/pdoc/search/namespaces_0.html create mode 100644 ld_client/doc/pdoc/search/namespaces_0.js create mode 100644 ld_client/doc/pdoc/search/nomatches.html create mode 100644 ld_client/doc/pdoc/search/properties_0.html create mode 100644 ld_client/doc/pdoc/search/properties_0.js create mode 100644 ld_client/doc/pdoc/search/properties_1.html create mode 100644 ld_client/doc/pdoc/search/properties_1.js create mode 100644 ld_client/doc/pdoc/search/properties_2.html create mode 100644 ld_client/doc/pdoc/search/properties_2.js create mode 100644 ld_client/doc/pdoc/search/properties_3.html create mode 100644 ld_client/doc/pdoc/search/properties_3.js create mode 100644 ld_client/doc/pdoc/search/properties_4.html create mode 100644 ld_client/doc/pdoc/search/properties_4.js create mode 100644 ld_client/doc/pdoc/search/properties_5.html create mode 100644 ld_client/doc/pdoc/search/properties_5.js create mode 100644 ld_client/doc/pdoc/search/search.css create mode 100644 ld_client/doc/pdoc/search/search.js create mode 100644 ld_client/doc/pdoc/search/search_l.png create mode 100644 ld_client/doc/pdoc/search/search_m.png create mode 100644 ld_client/doc/pdoc/search/search_r.png create mode 100644 ld_client/doc/pdoc/search/searchdata.js create mode 100644 ld_client/doc/pdoc/search/variables_0.html create mode 100644 ld_client/doc/pdoc/search/variables_0.js create mode 100644 ld_client/doc/pdoc/search/variables_1.html create mode 100644 ld_client/doc/pdoc/search/variables_1.js create mode 100644 ld_client/doc/pdoc/search/variables_2.html create mode 100644 ld_client/doc/pdoc/search/variables_2.js create mode 100644 ld_client/doc/pdoc/search/variables_3.html create mode 100644 ld_client/doc/pdoc/search/variables_3.js create mode 100644 ld_client/doc/pdoc/search/variables_4.html create mode 100644 ld_client/doc/pdoc/search/variables_4.js create mode 100644 ld_client/doc/pdoc/splitbar.png create mode 100644 ld_client/doc/pdoc/sync_off.png create mode 100644 ld_client/doc/pdoc/sync_on.png create mode 100644 ld_client/doc/pdoc/tab_a.png create mode 100644 ld_client/doc/pdoc/tab_b.png create mode 100644 ld_client/doc/pdoc/tab_h.png create mode 100644 ld_client/doc/pdoc/tab_s.png create mode 100644 ld_client/doc/pdoc/tabs.css diff --git a/ld_client/doc/pdoc/annotated.html b/ld_client/doc/pdoc/annotated.html new file mode 100644 index 0000000..b2bd7ee --- /dev/null +++ b/ld_client/doc/pdoc/annotated.html @@ -0,0 +1,124 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Class List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('annotated.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">Class List</div></div> +</div><!--header--> +<div class="contents"> +<div class="textblock">Here are the classes, structs, unions and interfaces with brief descriptions:</div><div class="directory"> +<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span><span onclick="javascript:toggleLevel(4);">4</span>]</div><table class="directory"> +<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client.html" target="_self">LDClient</a></td><td class="desc"></td></tr> +<tr id="row_0_0_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_0_" class="arrow" onclick="toggleFolder('0_0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1detection.html" target="_self">detection</a></td><td class="desc"></td></tr> +<tr id="row_0_0_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" target="_self">IInfoFetcher</a></td><td class="desc">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </td></tr> +<tr id="row_0_0_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" target="_self">InfoFetcher</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </td></tr> +<tr id="row_0_0_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" target="_self">IProcessUtils</a></td><td class="desc">This interface defines the functionality of all methods that are used to work with processes (within this project). </td></tr> +<tr id="row_0_0_3_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html" target="_self">ProcessDetection</a></td><td class="desc">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </td></tr> +<tr id="row_0_0_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" target="_self">ProcessUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </td></tr> +<tr id="row_0_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_1_" class="arrow" onclick="toggleFolder('0_1_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network.html" target="_self">network</a></td><td class="desc"></td></tr> +<tr id="row_0_1_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span id="arr_0_1_0_" class="arrow" onclick="toggleFolder('0_1_0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network_1_1data.html" target="_self">data</a></td><td class="desc"></td></tr> +<tr id="row_0_1_0_0_"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html" target="_self">DebuggerInfo</a></td><td class="desc">This class holds all the information about a specific part of a debugger (head/body). </td></tr> +<tr id="row_0_1_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html" target="_self">Payload</a></td><td class="desc">This class represents a single payload that is sent to the server. </td></tr> +<tr id="row_0_1_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html" target="_self">ApiClient</a></td><td class="desc">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </td></tr> +<tr id="row_0_1_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html" target="_self">HttpClient</a></td><td class="desc">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </td></tr> +<tr id="row_0_1_3_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" target="_self">IApiClient</a></td><td class="desc">This interface defines the functionality of an API client which is used to send information (payloads) to the server. </td></tr> +<tr id="row_0_1_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" target="_self">IHttpClient</a></td><td class="desc">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </td></tr> +<tr id="row_0_2_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_2_" class="arrow" onclick="toggleFolder('0_2_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils.html" target="_self">utils</a></td><td class="desc"></td></tr> +<tr id="row_0_2_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span id="arr_0_2_0_" class="arrow" onclick="toggleFolder('0_2_0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html" target="_self">loggers</a></td><td class="desc"></td></tr> +<tr id="row_0_2_0_0_"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html" target="_self">ALogger</a></td><td class="desc">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </td></tr> +<tr id="row_0_2_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html" target="_self">ConsoleLogger</a></td><td class="desc"></td></tr> +<tr id="row_0_2_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html" target="_self">FileUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </td></tr> +<tr id="row_0_2_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" target="_self">IFileUtils</a></td><td class="desc">This interface defines IO operations. </td></tr> +<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_file_logger.html" target="_self">FileLogger</a></td><td class="desc"></td></tr> +</table> +</div><!-- directory --> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/annotated_dup.js b/ld_client/doc/pdoc/annotated_dup.js new file mode 100644 index 0000000..af9f396 --- /dev/null +++ b/ld_client/doc/pdoc/annotated_dup.js @@ -0,0 +1,31 @@ +var annotated_dup = +[ + [ "LDClient", "namespace_l_d_client.html", [ + [ "detection", "namespace_l_d_client_1_1detection.html", [ + [ "IInfoFetcher", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html", "interface_l_d_client_1_1detection_1_1_i_info_fetcher" ], + [ "InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html", "class_l_d_client_1_1detection_1_1_info_fetcher" ], + [ "IProcessUtils", "interface_l_d_client_1_1detection_1_1_i_process_utils.html", "interface_l_d_client_1_1detection_1_1_i_process_utils" ], + [ "ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html", "class_l_d_client_1_1detection_1_1_process_detection" ], + [ "ProcessUtils", "class_l_d_client_1_1detection_1_1_process_utils.html", "class_l_d_client_1_1detection_1_1_process_utils" ] + ] ], + [ "network", "namespace_l_d_client_1_1network.html", [ + [ "data", "namespace_l_d_client_1_1network_1_1data.html", [ + [ "DebuggerInfo", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html", "class_l_d_client_1_1network_1_1data_1_1_debugger_info" ], + [ "Payload", "class_l_d_client_1_1network_1_1data_1_1_payload.html", "class_l_d_client_1_1network_1_1data_1_1_payload" ] + ] ], + [ "ApiClient", "class_l_d_client_1_1network_1_1_api_client.html", "class_l_d_client_1_1network_1_1_api_client" ], + [ "HttpClient", "class_l_d_client_1_1network_1_1_http_client.html", "class_l_d_client_1_1network_1_1_http_client" ], + [ "IApiClient", "interface_l_d_client_1_1network_1_1_i_api_client.html", "interface_l_d_client_1_1network_1_1_i_api_client" ], + [ "IHttpClient", "interface_l_d_client_1_1network_1_1_i_http_client.html", "interface_l_d_client_1_1network_1_1_i_http_client" ] + ] ], + [ "utils", "namespace_l_d_client_1_1utils.html", [ + [ "loggers", "namespace_l_d_client_1_1utils_1_1loggers.html", [ + [ "ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger" ], + [ "ConsoleLogger", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger" ] + ] ], + [ "FileUtils", "class_l_d_client_1_1utils_1_1_file_utils.html", "class_l_d_client_1_1utils_1_1_file_utils" ], + [ "IFileUtils", "interface_l_d_client_1_1utils_1_1_i_file_utils.html", "interface_l_d_client_1_1utils_1_1_i_file_utils" ] + ] ] + ] ], + [ "FileLogger", "class_file_logger.html", "class_file_logger" ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/bc_s.png b/ld_client/doc/pdoc/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)<h;3K|Lk000e1NJLTq000O80015c1^@s65rAI}0007ONkl<ZcmeI5 z%WD%+6voe;xyj6=NhXt~4{e$zF*P<SZp4L@2Hd!iQY<tJD@e5{RU55hl&Talf{KWb zN*6A=C`Gqz5#NvcXzNOCOH(I9n<#?l<k5ws2omoMCgj%s3y1G=&gJ~>y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE<Gz)cj&*s5lRy$b&*W@2j<GZEpXZ$P|Z!4Q$_|`5gj> z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/bdwn.png b/ld_client/doc/pdoc/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C<wUB513~7 zF-Lk{?g8$ijf`2F^ip|Vw7EpzIJxiU`6~>2wk~_T<sM_r%les%%^JdHy*A#$ew5wb vr&wL1c8#4j*F5jfGT)c(PZrEb5O3m+yDrVre6KeTXbXd<tDnm{r-UW|3$!!q literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/class_file_logger-members.html b/ld_client/doc/pdoc/class_file_logger-members.html new file mode 100644 index 0000000..3ec38a0 --- /dev/null +++ b/ld_client/doc/pdoc/class_file_logger-members.html @@ -0,0 +1,103 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_file_logger.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">FileLogger Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_file_logger.html">FileLogger</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">CreateLog</a>(string message)</td><td class="entry"><a class="el" href="class_file_logger.html">FileLogger</a></td><td class="entry"><span class="mlabel">protected</span></td></tr> + <tr bgcolor="#f0f0f0" class="odd"><td class="entry"><b>ToString</b>() (defined in <a class="el" href="class_file_logger.html">FileLogger</a>)</td><td class="entry"><a class="el" href="class_file_logger.html">FileLogger</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_file_logger.html b/ld_client/doc/pdoc/class_file_logger.html new file mode 100644 index 0000000..a2ebfca --- /dev/null +++ b/ld_client/doc/pdoc/class_file_logger.html @@ -0,0 +1,154 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: FileLogger Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_file_logger.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="#pro-methods">Protected Member Functions</a> | +<a href="class_file_logger-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">FileLogger Class Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a81ffd2cce04042e6fadc3362ca5f1cf6"><td class="memItemLeft" align="right" valign="top"><a id="a81ffd2cce04042e6fadc3362ca5f1cf6" name="a81ffd2cce04042e6fadc3362ca5f1cf6"></a> +override string </td><td class="memItemRight" valign="bottom"><b>ToString</b> ()</td></tr> +<tr class="separator:a81ffd2cce04042e6fadc3362ca5f1cf6"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a> +Protected Member Functions</h2></td></tr> +<tr class="memitem:ad39844b2267623f858ab77e6f5433896"><td class="memItemLeft" align="right" valign="top">override void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">CreateLog</a> (string message)</td></tr> +<tr class="memdesc:ad39844b2267623f858ab77e6f5433896"><td class="mdescLeft"> </td><td class="mdescRight">Creates one entry in the rotating file. If the current log file is too big, it creates new log file. If there is too many log files it archives them. Deletes all archived files that are too old <a href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">More...</a><br /></td></tr> +<tr class="separator:ad39844b2267623f858ab77e6f5433896"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<h2 class="groupheader">Member Function Documentation</h2> +<a id="ad39844b2267623f858ab77e6f5433896" name="ad39844b2267623f858ab77e6f5433896"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ad39844b2267623f858ab77e6f5433896">◆ </a></span>CreateLog()</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">override void FileLogger.CreateLog </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>message</em></td><td>)</td> + <td></td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">protected</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Creates one entry in the rotating file. If the current log file is too big, it creates new log file. If there is too many log files it archives them. Deletes all archived files that are too old </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">message</td><td>Desired message to be logged<</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>utils/loggers/FileLogger.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="class_file_logger.html">FileLogger</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_file_logger.js b/ld_client/doc/pdoc/class_file_logger.js new file mode 100644 index 0000000..5aafedf --- /dev/null +++ b/ld_client/doc/pdoc/class_file_logger.js @@ -0,0 +1,4 @@ +var class_file_logger = +[ + [ "CreateLog", "class_file_logger.html#ad39844b2267623f858ab77e6f5433896", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html new file mode 100644 index 0000000..5dcc6d0 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html @@ -0,0 +1,107 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_info_fetcher.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.detection.InfoFetcher Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">BodySerialNumber</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">FetchDataAsync</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140">FileUtils</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">HeadSerialNumber</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">InfoFetcher</a>(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8">ProcessUtils</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html new file mode 100644 index 0000000..e719c11 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html @@ -0,0 +1,301 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.detection.InfoFetcher Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_info_fetcher.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="#pub-attribs">Public Attributes</a> | +<a href="#properties">Properties</a> | +<a href="class_l_d_client_1_1detection_1_1_info_fetcher-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.detection.InfoFetcher Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. + <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:abadca27b2740339ac6c1fd5c5e08bb26"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">InfoFetcher</a> (uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs)</td></tr> +<tr class="memdesc:abadca27b2740339ac6c1fd5c5e08bb26"><td class="mdescLeft"> </td><td class="mdescRight">Creates an instance of this class. <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">More...</a><br /></td></tr> +<tr class="separator:abadca27b2740339ac6c1fd5c5e08bb26"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a2192ceaf45e724814bdfde96fc0e544c"><td class="memItemLeft" align="right" valign="top">async Task< bool > </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">FetchDataAsync</a> ()</td></tr> +<tr class="memdesc:a2192ceaf45e724814bdfde96fc0e544c"><td class="mdescLeft"> </td><td class="mdescRight">Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers). <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">More...</a><br /></td></tr> +<tr class="separator:a2192ceaf45e724814bdfde96fc0e544c"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memItemLeft" align="right" valign="top">Task< bool > </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">FetchDataAsync</a> ()</td></tr> +<tr class="memdesc:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="mdescLeft"> </td><td class="mdescRight">Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers). <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">More...</a><br /></td></tr> +<tr class="separator:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a> +Public Attributes</h2></td></tr> +<tr class="memitem:a37f11db6d7bc81193b70015fc9192ed8"><td class="memItemLeft" align="right" valign="top"><a id="a37f11db6d7bc81193b70015fc9192ed8" name="a37f11db6d7bc81193b70015fc9192ed8"></a> +<a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a> </td><td class="memItemRight" valign="bottom"><b>ProcessUtils</b></td></tr> +<tr class="memdesc:a37f11db6d7bc81193b70015fc9192ed8"><td class="mdescLeft"> </td><td class="mdescRight">Instance of <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" title="This class implements the IProcessUtils interface. It implements methods that are used when dealing w...">ProcessUtils</a> which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application). <br /></td></tr> +<tr class="separator:a37f11db6d7bc81193b70015fc9192ed8"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:af30dbfb7559215ee29998f00ef5ea140"><td class="memItemLeft" align="right" valign="top"><a id="af30dbfb7559215ee29998f00ef5ea140" name="af30dbfb7559215ee29998f00ef5ea140"></a> +<a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a> </td><td class="memItemRight" valign="bottom"><b>FileUtils</b></td></tr> +<tr class="memdesc:af30dbfb7559215ee29998f00ef5ea140"><td class="mdescLeft"> </td><td class="mdescRight">Instance of FileUtils which encapsulates common functionality when it comes to dealing with files (limited by the needs of this application). <br /></td></tr> +<tr class="separator:af30dbfb7559215ee29998f00ef5ea140"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a> +Properties</h2></td></tr> +<tr class="memitem:a053ba7e01a8cfcbebf2325a864e98e2f"><td class="memItemLeft" align="right" valign="top">string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">HeadSerialNumber</a> = UndefinedSerialNumber<code> [get, set]</code></td></tr> +<tr class="memdesc:a053ba7e01a8cfcbebf2325a864e98e2f"><td class="mdescLeft"> </td><td class="mdescRight">Returns the head serial number of the debugger. <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">More...</a><br /></td></tr> +<tr class="separator:a053ba7e01a8cfcbebf2325a864e98e2f"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:af38c5cdb5dc206c65d5f018e0b30dd1d"><td class="memItemLeft" align="right" valign="top">string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">BodySerialNumber</a> = UndefinedSerialNumber<code> [get, set]</code></td></tr> +<tr class="memdesc:af38c5cdb5dc206c65d5f018e0b30dd1d"><td class="mdescLeft"> </td><td class="mdescRight">Returns the body serial number of the debugger. <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">More...</a><br /></td></tr> +<tr class="separator:af38c5cdb5dc206c65d5f018e0b30dd1d"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="inherit_header properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td colspan="2" onclick="javascript:toggleInherit('properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher')"><img src="closed.png" alt="-"/> Properties inherited from <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td></tr> +<tr class="memitem:a196620b51706ff95e86dce886bd3d3a0 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memItemLeft" align="right" valign="top">string </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">HeadSerialNumber</a><code> [get, set]</code></td></tr> +<tr class="memdesc:a196620b51706ff95e86dce886bd3d3a0 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="mdescLeft"> </td><td class="mdescRight">Returns the head serial number of the debugger. <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">More...</a><br /></td></tr> +<tr class="separator:a196620b51706ff95e86dce886bd3d3a0 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:afff68b22c92585ba9169cd558bcb66b9 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memItemLeft" align="right" valign="top">string </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">BodySerialNumber</a><code> [get, set]</code></td></tr> +<tr class="memdesc:afff68b22c92585ba9169cd558bcb66b9 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="mdescLeft"> </td><td class="mdescRight">Returns the body serial number of the debugger. <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">More...</a><br /></td></tr> +<tr class="separator:afff68b22c92585ba9169cd558bcb66b9 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </p> +</div><h2 class="groupheader">Constructor & Destructor Documentation</h2> +<a id="abadca27b2740339ac6c1fd5c5e08bb26" name="abadca27b2740339ac6c1fd5c5e08bb26"></a> +<h2 class="memtitle"><span class="permalink"><a href="#abadca27b2740339ac6c1fd5c5e08bb26">◆ </a></span>InfoFetcher()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">LDClient.detection.InfoFetcher.InfoFetcher </td> + <td>(</td> + <td class="paramtype">uint </td> + <td class="paramname"><em>maxAttempts</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">uint </td> + <td class="paramname"><em>waitPeriodMs</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">string </td> + <td class="paramname"><em>infoFilePath</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">string </td> + <td class="paramname"><em>f32RemExecutable</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">string[] </td> + <td class="paramname"><em>f32RemArguments</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">int </td> + <td class="paramname"><em>f32SuccessExitCode</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">int </td> + <td class="paramname"><em>f32WaitTimeoutMs</em> </td> + </tr> + <tr> + <td></td> + <td>)</td> + <td></td><td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates an instance of this class. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">maxAttempts</td><td>Maximum number of attempts to locate and parse the .txt file</td></tr> + <tr><td class="paramname">waitPeriodMs</td><td>Period (how often) the application tries to locate and parse the .txt file</td></tr> + <tr><td class="paramname">infoFilePath</td><td>Path to the .txt file which is generated from the debugger</td></tr> + <tr><td class="paramname">f32RemExecutable</td><td>Path to the t32rem.exe file which is used to send commands to the debugger</td></tr> + <tr><td class="paramname">f32RemArguments</td><td>Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</td></tr> + <tr><td class="paramname">f32SuccessExitCode</td><td>Status code indicating a successful termination of t32rem.exe</td></tr> + <tr><td class="paramname">f32WaitTimeoutMs</td><td>Timeout used when waiting for the t32rem.exe to finish</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<h2 class="groupheader">Member Function Documentation</h2> +<a id="a2192ceaf45e724814bdfde96fc0e544c" name="a2192ceaf45e724814bdfde96fc0e544c"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a2192ceaf45e724814bdfde96fc0e544c">◆ </a></span>FetchDataAsync()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">async Task< bool > LDClient.detection.InfoFetcher.FetchDataAsync </td> + <td>(</td> + <td class="paramname"></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers). </p> +<dl class="section return"><dt>Returns</dt><dd>True, if data was fetched successfully. False otherwise.</dd></dl> + +<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">LDClient.detection.IInfoFetcher</a>.</p> + +</div> +</div> +<h2 class="groupheader">Property Documentation</h2> +<a id="af38c5cdb5dc206c65d5f018e0b30dd1d" name="af38c5cdb5dc206c65d5f018e0b30dd1d"></a> +<h2 class="memtitle"><span class="permalink"><a href="#af38c5cdb5dc206c65d5f018e0b30dd1d">◆ </a></span>BodySerialNumber</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">string LDClient.detection.InfoFetcher.BodySerialNumber = UndefinedSerialNumber</td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Returns the body serial number of the debugger. </p> + +<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">LDClient.detection.IInfoFetcher</a>.</p> + +</div> +</div> +<a id="a053ba7e01a8cfcbebf2325a864e98e2f" name="a053ba7e01a8cfcbebf2325a864e98e2f"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a053ba7e01a8cfcbebf2325a864e98e2f">◆ </a></span>HeadSerialNumber</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">string LDClient.detection.InfoFetcher.HeadSerialNumber = UndefinedSerialNumber</td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Returns the head serial number of the debugger. </p> + +<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">LDClient.detection.IInfoFetcher</a>.</p> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>detection/InfoFetcher.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">InfoFetcher</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js new file mode 100644 index 0000000..d90f5da --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js @@ -0,0 +1,9 @@ +var class_l_d_client_1_1detection_1_1_info_fetcher = +[ + [ "InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26", null ], + [ "FetchDataAsync", "class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c", null ], + [ "FileUtils", "class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140", null ], + [ "ProcessUtils", "class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8", null ], + [ "BodySerialNumber", "class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d", null ], + [ "HeadSerialNumber", "class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html new file mode 100644 index 0000000..5e7b0eb --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html @@ -0,0 +1,104 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_detection.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.detection.ProcessDetection Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6">DetectionRunning</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">ProcessDetection</a>(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, IApiClient apiClient, IProcessUtils processUtils)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8">RunPeriodicDetection</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html new file mode 100644 index 0000000..7080b7a --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html @@ -0,0 +1,188 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.detection.ProcessDetection Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_detection.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="#pub-attribs">Public Attributes</a> | +<a href="class_l_d_client_1_1detection_1_1_process_detection-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.detection.ProcessDetection Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. + <a href="class_l_d_client_1_1detection_1_1_process_detection.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a586a1c6d9a48f2f7aa5389699bb4c679"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">ProcessDetection</a> (string processName, uint detectionPeriodMs, <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a> infoFetcher, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a> apiClient, <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a> processUtils)</td></tr> +<tr class="memdesc:a586a1c6d9a48f2f7aa5389699bb4c679"><td class="mdescLeft"> </td><td class="mdescRight">Creates an instance of this class. <a href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">More...</a><br /></td></tr> +<tr class="separator:a586a1c6d9a48f2f7aa5389699bb4c679"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:adc7f2823d21a1fbbddfe0328d05df3a8"><td class="memItemLeft" align="right" valign="top"><a id="adc7f2823d21a1fbbddfe0328d05df3a8" name="adc7f2823d21a1fbbddfe0328d05df3a8"></a> +async void </td><td class="memItemRight" valign="bottom"><b>RunPeriodicDetection</b> ()</td></tr> +<tr class="memdesc:adc7f2823d21a1fbbddfe0328d05df3a8"><td class="mdescLeft"> </td><td class="mdescRight">Periodically runs process detection. This method is instantiated as a thread from the main class (Program.cs). <br /></td></tr> +<tr class="separator:adc7f2823d21a1fbbddfe0328d05df3a8"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a> +Public Attributes</h2></td></tr> +<tr class="memitem:acb2ce395f8b608c48165ae01677aa2a6"><td class="memItemLeft" align="right" valign="top"><a id="acb2ce395f8b608c48165ae01677aa2a6" name="acb2ce395f8b608c48165ae01677aa2a6"></a> +bool </td><td class="memItemRight" valign="bottom"><b>DetectionRunning</b> = false</td></tr> +<tr class="memdesc:acb2ce395f8b608c48165ae01677aa2a6"><td class="mdescLeft"> </td><td class="mdescRight">Flag used to stop the thread (process detection). <br /></td></tr> +<tr class="separator:acb2ce395f8b608c48165ae01677aa2a6"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </p> +</div><h2 class="groupheader">Constructor & Destructor Documentation</h2> +<a id="a586a1c6d9a48f2f7aa5389699bb4c679" name="a586a1c6d9a48f2f7aa5389699bb4c679"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a586a1c6d9a48f2f7aa5389699bb4c679">◆ </a></span>ProcessDetection()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">LDClient.detection.ProcessDetection.ProcessDetection </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>processName</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">uint </td> + <td class="paramname"><em>detectionPeriodMs</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a> </td> + <td class="paramname"><em>infoFetcher</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a> </td> + <td class="paramname"><em>apiClient</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a> </td> + <td class="paramname"><em>processUtils</em> </td> + </tr> + <tr> + <td></td> + <td>)</td> + <td></td><td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates an instance of this class. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">processName</td><td>Name of the process the application detects</td></tr> + <tr><td class="paramname">detectionPeriodMs</td><td>How often the application check the current status of the process (cunning / not running)</td></tr> + <tr><td class="paramname">infoFetcher</td><td>Instance of <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" title="This class implements the IInfoFetcher interface which defines the functionality of an info fetcher.">InfoFetcher</a> used to fetch information from the debugger</td></tr> + <tr><td class="paramname">apiClient</td><td>Instance of API clients used for sending data off to the server</td></tr> + <tr><td class="paramname">processUtils</td><td>Instance of <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" title="This class implements the IProcessUtils interface. It implements methods that are used when dealing w...">ProcessUtils</a> which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>detection/ProcessDetection.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">ProcessDetection</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js new file mode 100644 index 0000000..1128cae --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js @@ -0,0 +1,6 @@ +var class_l_d_client_1_1detection_1_1_process_detection = +[ + [ "ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679", null ], + [ "RunPeriodicDetection", "class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8", null ], + [ "DetectionRunning", "class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html new file mode 100644 index 0000000..ab49597 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html @@ -0,0 +1,103 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.detection.ProcessUtils Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">LDClient.detection.ProcessUtils</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">ExecuteNewProcess</a>(string fileName, string argument, int timeout, int desiredExitCode)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">LDClient.detection.ProcessUtils</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">IsProcessRunning</a>(string name)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">LDClient.detection.ProcessUtils</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html new file mode 100644 index 0000000..5bbf1df --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html @@ -0,0 +1,210 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.detection.ProcessUtils Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="class_l_d_client_1_1detection_1_1_process_utils-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.detection.ProcessUtils Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. + <a href="class_l_d_client_1_1detection_1_1_process_utils.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a851a0af6188cf17614870a94ddb87fc4"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">IsProcessRunning</a> (string name)</td></tr> +<tr class="memdesc:a851a0af6188cf17614870a94ddb87fc4"><td class="mdescLeft"> </td><td class="mdescRight">Checks if a process is running or not. <a href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">More...</a><br /></td></tr> +<tr class="separator:a851a0af6188cf17614870a94ddb87fc4"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a863da05a6d25ead94a6eb0bd00f91557"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">ExecuteNewProcess</a> (string fileName, string argument, int timeout, int desiredExitCode)</td></tr> +<tr class="memdesc:a863da05a6d25ead94a6eb0bd00f91557"><td class="mdescLeft"> </td><td class="mdescRight">Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method. <a href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">More...</a><br /></td></tr> +<tr class="separator:a863da05a6d25ead94a6eb0bd00f91557"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">IsProcessRunning</a> (string name)</td></tr> +<tr class="memdesc:ad86c09b9bd71f7087ada92851b07e1a0"><td class="mdescLeft"> </td><td class="mdescRight">Checks if a process is running or not. <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">More...</a><br /></td></tr> +<tr class="separator:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ab7e48a228ebaf7dddc671e5af2325662"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">ExecuteNewProcess</a> (string fileName, string argument, int timeout, int desiredExitCode)</td></tr> +<tr class="memdesc:ab7e48a228ebaf7dddc671e5af2325662"><td class="mdescLeft"> </td><td class="mdescRight">Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method. <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">More...</a><br /></td></tr> +<tr class="separator:ab7e48a228ebaf7dddc671e5af2325662"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="a863da05a6d25ead94a6eb0bd00f91557" name="a863da05a6d25ead94a6eb0bd00f91557"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a863da05a6d25ead94a6eb0bd00f91557">◆ </a></span>ExecuteNewProcess()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">bool LDClient.detection.ProcessUtils.ExecuteNewProcess </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>fileName</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">string </td> + <td class="paramname"><em>argument</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">int </td> + <td class="paramname"><em>timeout</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">int </td> + <td class="paramname"><em>desiredExitCode</em> </td> + </tr> + <tr> + <td></td> + <td>)</td> + <td></td><td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">fileName</td><td>Path to the .exe file</td></tr> + <tr><td class="paramname">argument</td><td>Arguments passed into the .exe file</td></tr> + <tr><td class="paramname">timeout</td><td>Timeout used when waiting for the process to terminate</td></tr> + <tr><td class="paramname">desiredExitCode</td><td>Status code indicating a successful termination of the process.</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd>True, if the command was executed successfully. False otherwise.</dd></dl> + +<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">LDClient.detection.IProcessUtils</a>.</p> + +</div> +</div> +<a id="a851a0af6188cf17614870a94ddb87fc4" name="a851a0af6188cf17614870a94ddb87fc4"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a851a0af6188cf17614870a94ddb87fc4">◆ </a></span>IsProcessRunning()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">bool LDClient.detection.ProcessUtils.IsProcessRunning </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>name</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Checks if a process is running or not. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">name</td><td>Name of the process</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd>True, if the process is running. False otherwise.</dd></dl> + +<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">LDClient.detection.IProcessUtils</a>.</p> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>detection/ProcessUtils.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">ProcessUtils</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js new file mode 100644 index 0000000..9f2bdb9 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js @@ -0,0 +1,5 @@ +var class_l_d_client_1_1detection_1_1_process_utils = +[ + [ "ExecuteNewProcess", "class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557", null ], + [ "IsProcessRunning", "class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html new file mode 100644 index 0000000..08956ca --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html @@ -0,0 +1,106 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_api_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.network.ApiClient Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d">_client</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">ApiClient</a>(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1">ClientRunning</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">Run</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">SendPayloadAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html new file mode 100644 index 0000000..e8d1ec5 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html @@ -0,0 +1,264 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network.ApiClient Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_api_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="#pub-attribs">Public Attributes</a> | +<a href="class_l_d_client_1_1network_1_1_api_client-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.network.ApiClient Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. + <a href="class_l_d_client_1_1network_1_1_api_client.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a9dc8bd923651fcbac08b72ae6165aa73"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">ApiClient</a> (string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache)</td></tr> +<tr class="memdesc:a9dc8bd923651fcbac08b72ae6165aa73"><td class="mdescLeft"> </td><td class="mdescRight">Creates an instance of the class. <a href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">More...</a><br /></td></tr> +<tr class="separator:a9dc8bd923651fcbac08b72ae6165aa73"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a8e78939c5ab5b2f2f417ba280584cb55"><td class="memItemLeft" align="right" valign="top">async Task </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">SendPayloadAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr> +<tr class="memdesc:a8e78939c5ab5b2f2f417ba280584cb55"><td class="mdescLeft"> </td><td class="mdescRight">Sends a payload to the server (API). <a href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">More...</a><br /></td></tr> +<tr class="separator:a8e78939c5ab5b2f2f417ba280584cb55"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ade3b671e7561fbc4c560d3e3a7a79979"><td class="memItemLeft" align="right" valign="top">async void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">Run</a> ()</td></tr> +<tr class="memdesc:ade3b671e7561fbc4c560d3e3a7a79979"><td class="mdescLeft"> </td><td class="mdescRight">Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread. <a href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">More...</a><br /></td></tr> +<tr class="separator:ade3b671e7561fbc4c560d3e3a7a79979"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memItemLeft" align="right" valign="top">Task </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">SendPayloadAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr> +<tr class="memdesc:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="mdescLeft"> </td><td class="mdescRight">Sends a payload to the server (API). <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">More...</a><br /></td></tr> +<tr class="separator:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">Run</a> ()</td></tr> +<tr class="memdesc:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="mdescLeft"> </td><td class="mdescRight">Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread. <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">More...</a><br /></td></tr> +<tr class="separator:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a> +Public Attributes</h2></td></tr> +<tr class="memitem:a052df6039a9aed754761e3c62209f37d"><td class="memItemLeft" align="right" valign="top"><a id="a052df6039a9aed754761e3c62209f37d" name="a052df6039a9aed754761e3c62209f37d"></a> +<a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a> </td><td class="memItemRight" valign="bottom"><b>_client</b></td></tr> +<tr class="memdesc:a052df6039a9aed754761e3c62209f37d"><td class="mdescLeft"> </td><td class="mdescRight">Instance of an HTTP client the is used to send data off to the server <br /></td></tr> +<tr class="separator:a052df6039a9aed754761e3c62209f37d"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a5ea6642309925c666e39db7f3ac103c1"><td class="memItemLeft" align="right" valign="top"><a id="a5ea6642309925c666e39db7f3ac103c1" name="a5ea6642309925c666e39db7f3ac103c1"></a> +bool </td><td class="memItemRight" valign="bottom"><b>ClientRunning</b></td></tr> +<tr class="memdesc:a5ea6642309925c666e39db7f3ac103c1"><td class="mdescLeft"> </td><td class="mdescRight">Flag used to stop the client (periodical retrieval from the cache) <br /></td></tr> +<tr class="separator:a5ea6642309925c666e39db7f3ac103c1"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </p> +</div><h2 class="groupheader">Constructor & Destructor Documentation</h2> +<a id="a9dc8bd923651fcbac08b72ae6165aa73" name="a9dc8bd923651fcbac08b72ae6165aa73"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a9dc8bd923651fcbac08b72ae6165aa73">◆ </a></span>ApiClient()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">LDClient.network.ApiClient.ApiClient </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>url</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">uint </td> + <td class="paramname"><em>port</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">string </td> + <td class="paramname"><em>path</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">uint </td> + <td class="paramname"><em>retryPeriod</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">uint </td> + <td class="paramname"><em>maxEntries</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">uint </td> + <td class="paramname"><em>maxRetries</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">IPersistentQueue </td> + <td class="paramname"><em>cache</em> </td> + </tr> + <tr> + <td></td> + <td>)</td> + <td></td><td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates an instance of the class. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">url</td><td>IP address of the server (url in case a DNS server is being used)</td></tr> + <tr><td class="paramname">port</td><td>port that the API is running on</td></tr> + <tr><td class="paramname">path</td><td>path of the API e.g. /api/v1/lg-logs</td></tr> + <tr><td class="paramname">retryPeriod</td><td>number of milliseconds after which the class tries to resend failed payloads to the server</td></tr> + <tr><td class="paramname">maxEntries</td><td>maximum number of entries (payloads) that can be sent to the server within one period</td></tr> + <tr><td class="paramname">maxRetries</td><td>maximum number of failed payloads to be kept in the file-based cache</td></tr> + <tr><td class="paramname">cache</td><td>instance of a persistent cache for storing failed payloads</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<h2 class="groupheader">Member Function Documentation</h2> +<a id="ade3b671e7561fbc4c560d3e3a7a79979" name="ade3b671e7561fbc4c560d3e3a7a79979"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ade3b671e7561fbc4c560d3e3a7a79979">◆ </a></span>Run()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">async void LDClient.network.ApiClient.Run </td> + <td>(</td> + <td class="paramname"></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread. </p> + +<p>Implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">LDClient.network.IApiClient</a>.</p> + +</div> +</div> +<a id="a8e78939c5ab5b2f2f417ba280584cb55" name="a8e78939c5ab5b2f2f417ba280584cb55"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a8e78939c5ab5b2f2f417ba280584cb55">◆ </a></span>SendPayloadAsync()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">async Task LDClient.network.ApiClient.SendPayloadAsync </td> + <td>(</td> + <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> </td> + <td class="paramname"><em>payload</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Sends a payload to the server (API). </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">payload</td><td>instance of a payload to be sent off to the server</td></tr> + </table> + </dd> +</dl> + +<p>Implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">LDClient.network.IApiClient</a>.</p> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>network/ApiClient.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">ApiClient</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js new file mode 100644 index 0000000..6fde476 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js @@ -0,0 +1,8 @@ +var class_l_d_client_1_1network_1_1_api_client = +[ + [ "ApiClient", "class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73", null ], + [ "Run", "class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979", null ], + [ "SendPayloadAsync", "class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55", null ], + [ "_client", "class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d", null ], + [ "ClientRunning", "class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html new file mode 100644 index 0000000..09e6545 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html @@ -0,0 +1,103 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_http_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.network.HttpClient Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">LDClient.network.HttpClient</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">HttpClient</a>(string uri)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">LDClient.network.HttpClient</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">PostAsJsonAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">LDClient.network.HttpClient</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html new file mode 100644 index 0000000..f885623 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html @@ -0,0 +1,180 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network.HttpClient Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_http_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="class_l_d_client_1_1network_1_1_http_client-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.network.HttpClient Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. + <a href="class_l_d_client_1_1network_1_1_http_client.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a7ec70d89410863e423ea2bcabaedc9a3"><td class="memItemLeft" align="right" valign="top"> </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">HttpClient</a> (string uri)</td></tr> +<tr class="memdesc:a7ec70d89410863e423ea2bcabaedc9a3"><td class="mdescLeft"> </td><td class="mdescRight">Creates an instance of the class <a href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">More...</a><br /></td></tr> +<tr class="separator:a7ec70d89410863e423ea2bcabaedc9a3"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a553187973e0f43053af43bdae239ef4d"><td class="memItemLeft" align="right" valign="top">Task< HttpResponseMessage > </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">PostAsJsonAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr> +<tr class="memdesc:a553187973e0f43053af43bdae239ef4d"><td class="mdescLeft"> </td><td class="mdescRight">Asynchronically sends data in JSON format to the server. <a href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">More...</a><br /></td></tr> +<tr class="separator:a553187973e0f43053af43bdae239ef4d"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a241d7baceaf176b341c46844e235bd0f"><td class="memItemLeft" align="right" valign="top">Task< HttpResponseMessage > </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">PostAsJsonAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr> +<tr class="memdesc:a241d7baceaf176b341c46844e235bd0f"><td class="mdescLeft"> </td><td class="mdescRight">Asynchronically sends data in JSON format to the server. <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">More...</a><br /></td></tr> +<tr class="separator:a241d7baceaf176b341c46844e235bd0f"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </p> +</div><h2 class="groupheader">Constructor & Destructor Documentation</h2> +<a id="a7ec70d89410863e423ea2bcabaedc9a3" name="a7ec70d89410863e423ea2bcabaedc9a3"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a7ec70d89410863e423ea2bcabaedc9a3">◆ </a></span>HttpClient()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">LDClient.network.HttpClient.HttpClient </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>uri</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates an instance of the class </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">uri</td><td>URL to which the HTTP client will connect</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<h2 class="groupheader">Member Function Documentation</h2> +<a id="a553187973e0f43053af43bdae239ef4d" name="a553187973e0f43053af43bdae239ef4d"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a553187973e0f43053af43bdae239ef4d">◆ </a></span>PostAsJsonAsync()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">Task< HttpResponseMessage > LDClient.network.HttpClient.PostAsJsonAsync </td> + <td>(</td> + <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> </td> + <td class="paramname"><em>payload</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Asynchronically sends data in JSON format to the server. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">payload</td><td>Payload to be sent to the server</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +<p>Implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">LDClient.network.IHttpClient</a>.</p> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>network/HttpClient.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">HttpClient</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js new file mode 100644 index 0000000..42b38f6 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js @@ -0,0 +1,5 @@ +var class_l_d_client_1_1network_1_1_http_client = +[ + [ "HttpClient", "class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3", null ], + [ "PostAsJsonAsync", "class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html new file mode 100644 index 0000000..72fbec1 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html @@ -0,0 +1,102 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.network.data.DebuggerInfo Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">LDClient.network.data.DebuggerInfo</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb">SerialNumber</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">LDClient.network.data.DebuggerInfo</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html new file mode 100644 index 0000000..f51c123 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html @@ -0,0 +1,118 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network.data.DebuggerInfo Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#properties">Properties</a> | +<a href="class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.network.data.DebuggerInfo Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This class holds all the information about a specific part of a debugger (head/body). + <a href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a> +Properties</h2></td></tr> +<tr class="memitem:acb364e62b03d8eea272ad6bed3dc9cdb"><td class="memItemLeft" align="right" valign="top"><a id="acb364e62b03d8eea272ad6bed3dc9cdb" name="acb364e62b03d8eea272ad6bed3dc9cdb"></a> +string? </td><td class="memItemRight" valign="bottom"><b>SerialNumber</b><code> [get, set]</code></td></tr> +<tr class="memdesc:acb364e62b03d8eea272ad6bed3dc9cdb"><td class="mdescLeft"> </td><td class="mdescRight">Serial number of the part of a debugger. <br /></td></tr> +<tr class="separator:acb364e62b03d8eea272ad6bed3dc9cdb"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class holds all the information about a specific part of a debugger (head/body). </p> +</div><hr/>The documentation for this class was generated from the following file:<ul> +<li>network/data/DebuggerInfo.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html">data</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js new file mode 100644 index 0000000..ca56176 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js @@ -0,0 +1,4 @@ +var class_l_d_client_1_1network_1_1data_1_1_debugger_info = +[ + [ "SerialNumber", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html new file mode 100644 index 0000000..f7c9fd4 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html @@ -0,0 +1,110 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_payload.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.network.data.Payload Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208">BodyDevice</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5">HeadDevice</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72">HostName</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">ParseToJson</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056">ParseToJson</a>(Payload payload)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"><span class="mlabel">static</span></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481">Status</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297">TimeStamp</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">ToString</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65">UserName</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html new file mode 100644 index 0000000..617cfb5 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html @@ -0,0 +1,231 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network.data.Payload Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_payload.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="#pub-static-methods">Static Public Member Functions</a> | +<a href="#properties">Properties</a> | +<a href="class_l_d_client_1_1network_1_1data_1_1_payload-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.network.data.Payload Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This class represents a single payload that is sent to the server. + <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:ad81cd8c8c44f80a75d0fbea3aa8d0148"><td class="memItemLeft" align="right" valign="top">override string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">ToString</a> ()</td></tr> +<tr class="memdesc:ad81cd8c8c44f80a75d0fbea3aa8d0148"><td class="mdescLeft"> </td><td class="mdescRight">Returns a string representation of the payload. <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">More...</a><br /></td></tr> +<tr class="separator:ad81cd8c8c44f80a75d0fbea3aa8d0148"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:acd1a2d92945c91d22c262ce7b5a75d57"><td class="memItemLeft" align="right" valign="top">string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">ParseToJson</a> ()</td></tr> +<tr class="memdesc:acd1a2d92945c91d22c262ce7b5a75d57"><td class="mdescLeft"> </td><td class="mdescRight">Parses (converts) the payload into JSON format. <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">More...</a><br /></td></tr> +<tr class="separator:acd1a2d92945c91d22c262ce7b5a75d57"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-methods" name="pub-static-methods"></a> +Static Public Member Functions</h2></td></tr> +<tr class="memitem:a481fbe5952888d2dd7b6df0ff67ef056"><td class="memItemLeft" align="right" valign="top">static string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056">ParseToJson</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr> +<tr class="memdesc:a481fbe5952888d2dd7b6df0ff67ef056"><td class="mdescLeft"> </td><td class="mdescRight">Serializes a given payload into JSON format. <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056">More...</a><br /></td></tr> +<tr class="separator:a481fbe5952888d2dd7b6df0ff67ef056"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a> +Properties</h2></td></tr> +<tr class="memitem:ab1d3b30416e011f29b7e82f284495f65"><td class="memItemLeft" align="right" valign="top"><a id="ab1d3b30416e011f29b7e82f284495f65" name="ab1d3b30416e011f29b7e82f284495f65"></a> +string? </td><td class="memItemRight" valign="bottom"><b>UserName</b><code> [get, set]</code></td></tr> +<tr class="memdesc:ab1d3b30416e011f29b7e82f284495f65"><td class="mdescLeft"> </td><td class="mdescRight">Username of the currently logged user. <br /></td></tr> +<tr class="separator:ab1d3b30416e011f29b7e82f284495f65"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:acbcdcd13f4cfd6074cabcbe1f39e9b72"><td class="memItemLeft" align="right" valign="top"><a id="acbcdcd13f4cfd6074cabcbe1f39e9b72" name="acbcdcd13f4cfd6074cabcbe1f39e9b72"></a> +string? </td><td class="memItemRight" valign="bottom"><b>HostName</b><code> [get, set]</code></td></tr> +<tr class="memdesc:acbcdcd13f4cfd6074cabcbe1f39e9b72"><td class="mdescLeft"> </td><td class="mdescRight">Hostname of the pc. <br /></td></tr> +<tr class="separator:acbcdcd13f4cfd6074cabcbe1f39e9b72"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ad79e14f0c9936a6e6581d72fca767297"><td class="memItemLeft" align="right" valign="top"><a id="ad79e14f0c9936a6e6581d72fca767297" name="ad79e14f0c9936a6e6581d72fca767297"></a> +string? </td><td class="memItemRight" valign="bottom"><b>TimeStamp</b><code> [get, set]</code></td></tr> +<tr class="memdesc:ad79e14f0c9936a6e6581d72fca767297"><td class="mdescLeft"> </td><td class="mdescRight">Timestamp (when a debugger was plugged/unplugged). <br /></td></tr> +<tr class="separator:ad79e14f0c9936a6e6581d72fca767297"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ad8926696e666228bfb9164fcbf430da5"><td class="memItemLeft" align="right" valign="top"><a id="ad8926696e666228bfb9164fcbf430da5" name="ad8926696e666228bfb9164fcbf430da5"></a> +<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a>? </td><td class="memItemRight" valign="bottom"><b>HeadDevice</b><code> [get, set]</code></td></tr> +<tr class="memdesc:ad8926696e666228bfb9164fcbf430da5"><td class="mdescLeft"> </td><td class="mdescRight">Information about the head of the debugger. <br /></td></tr> +<tr class="separator:ad8926696e666228bfb9164fcbf430da5"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a82af1fdf887d86f81acfec3b51936208"><td class="memItemLeft" align="right" valign="top"><a id="a82af1fdf887d86f81acfec3b51936208" name="a82af1fdf887d86f81acfec3b51936208"></a> +<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a>? </td><td class="memItemRight" valign="bottom"><b>BodyDevice</b><code> [get, set]</code></td></tr> +<tr class="memdesc:a82af1fdf887d86f81acfec3b51936208"><td class="mdescLeft"> </td><td class="mdescRight">Information about the body of the debugger. <br /></td></tr> +<tr class="separator:a82af1fdf887d86f81acfec3b51936208"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a47489fcc58ebc325d36de38db4d4e481"><td class="memItemLeft" align="right" valign="top"><a id="a47489fcc58ebc325d36de38db4d4e481" name="a47489fcc58ebc325d36de38db4d4e481"></a> +<a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">ConnectionStatus</a> </td><td class="memItemRight" valign="bottom"><b>Status</b><code> [get, set]</code></td></tr> +<tr class="memdesc:a47489fcc58ebc325d36de38db4d4e481"><td class="mdescLeft"> </td><td class="mdescRight">Status of the debugger (connected/disconnected). <br /></td></tr> +<tr class="separator:a47489fcc58ebc325d36de38db4d4e481"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class represents a single payload that is sent to the server. </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="acd1a2d92945c91d22c262ce7b5a75d57" name="acd1a2d92945c91d22c262ce7b5a75d57"></a> +<h2 class="memtitle"><span class="permalink"><a href="#acd1a2d92945c91d22c262ce7b5a75d57">◆ </a></span>ParseToJson() <span class="overload">[1/2]</span></h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">string LDClient.network.data.Payload.ParseToJson </td> + <td>(</td> + <td class="paramname"></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Parses (converts) the payload into JSON format. </p> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +</div> +</div> +<a id="a481fbe5952888d2dd7b6df0ff67ef056" name="a481fbe5952888d2dd7b6df0ff67ef056"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a481fbe5952888d2dd7b6df0ff67ef056">◆ </a></span>ParseToJson() <span class="overload">[2/2]</span></h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">static string LDClient.network.data.Payload.ParseToJson </td> + <td>(</td> + <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> </td> + <td class="paramname"><em>payload</em></td><td>)</td> + <td></td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">static</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Serializes a given payload into JSON format. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">payload</td><td>payload to be serialized into JSON</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +</div> +</div> +<a id="ad81cd8c8c44f80a75d0fbea3aa8d0148" name="ad81cd8c8c44f80a75d0fbea3aa8d0148"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ad81cd8c8c44f80a75d0fbea3aa8d0148">◆ </a></span>ToString()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">override string LDClient.network.data.Payload.ToString </td> + <td>(</td> + <td class="paramname"></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Returns a string representation of the payload. </p> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>network/data/Payload.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html">data</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js new file mode 100644 index 0000000..f224ff5 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js @@ -0,0 +1,11 @@ +var class_l_d_client_1_1network_1_1data_1_1_payload = +[ + [ "ParseToJson", "class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57", null ], + [ "ToString", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148", null ], + [ "BodyDevice", "class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208", null ], + [ "HeadDevice", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5", null ], + [ "HostName", "class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72", null ], + [ "Status", "class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481", null ], + [ "TimeStamp", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297", null ], + [ "UserName", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html new file mode 100644 index 0000000..335832e --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html @@ -0,0 +1,102 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1_file_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.utils.FileUtils Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">LDClient.utils.FileUtils</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">ReadFileAllLines</a>(string file)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">LDClient.utils.FileUtils</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html new file mode 100644 index 0000000..1d00aa1 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html @@ -0,0 +1,150 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.utils.FileUtils Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1_file_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="class_l_d_client_1_1utils_1_1_file_utils-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.utils.FileUtils Class Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. + <a href="class_l_d_client_1_1utils_1_1_file_utils.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a411ef16d3be50fea59473b160d801737"><td class="memItemLeft" align="right" valign="top">string[] </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">ReadFileAllLines</a> (string file)</td></tr> +<tr class="memdesc:a411ef16d3be50fea59473b160d801737"><td class="mdescLeft"> </td><td class="mdescRight">Reads all lines of a files and returns them as a array. <a href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">More...</a><br /></td></tr> +<tr class="separator:a411ef16d3be50fea59473b160d801737"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ae4d668d0e5850831680c8793cecd89a3"><td class="memItemLeft" align="right" valign="top">string[] </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">ReadFileAllLines</a> (string file)</td></tr> +<tr class="memdesc:ae4d668d0e5850831680c8793cecd89a3"><td class="mdescLeft"> </td><td class="mdescRight">Reads all lines of a files and returns them as a array. <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">More...</a><br /></td></tr> +<tr class="separator:ae4d668d0e5850831680c8793cecd89a3"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="a411ef16d3be50fea59473b160d801737" name="a411ef16d3be50fea59473b160d801737"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a411ef16d3be50fea59473b160d801737">◆ </a></span>ReadFileAllLines()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">string[] LDClient.utils.FileUtils.ReadFileAllLines </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>file</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Reads all lines of a files and returns them as a array. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">file</td><td>path to the file</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd>all the lines of the file (as an array)</dd></dl> + +<p>Implements <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">LDClient.utils.IFileUtils</a>.</p> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>utils/FileUtils.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">FileUtils</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js new file mode 100644 index 0000000..5df8573 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js @@ -0,0 +1,4 @@ +var class_l_d_client_1_1utils_1_1_file_utils = +[ + [ "ReadFileAllLines", "class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html new file mode 100644 index 0000000..db6df3e --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html @@ -0,0 +1,113 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.utils.loggers.ALogger Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">ALogger</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a>(string message, LogType logType)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr> + <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>CreateLog</b>(string message) (defined in <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a>)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">pure virtual</span></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">Current</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">static</span></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">Dispose</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a>(Exception e)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">Flush</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a>(Exception? ex)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html new file mode 100644 index 0000000..09a6a5e --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html @@ -0,0 +1,395 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.utils.loggers.ALogger Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="#pro-methods">Protected Member Functions</a> | +<a href="#properties">Properties</a> | +<a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.utils.loggers.ALogger Class Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div></div> +</div><!--header--> +<div class="contents"> + +<p>This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern + <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:ac8f52ab4e431a47107d30db51615237e"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a> (string message)</td></tr> +<tr class="memdesc:ac8f52ab4e431a47107d30db51615237e"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log with Info identifier <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">More...</a><br /></td></tr> +<tr class="separator:ac8f52ab4e431a47107d30db51615237e"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a5c626205a03a7829c6dd195ee18d8e81"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a> (string message)</td></tr> +<tr class="memdesc:a5c626205a03a7829c6dd195ee18d8e81"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log with Debug identifier <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">More...</a><br /></td></tr> +<tr class="separator:a5c626205a03a7829c6dd195ee18d8e81"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a7f041d300e6d06dc58f969c4c0afd504"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a> (string message)</td></tr> +<tr class="memdesc:a7f041d300e6d06dc58f969c4c0afd504"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log with Error identifier <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">More...</a><br /></td></tr> +<tr class="separator:a7f041d300e6d06dc58f969c4c0afd504"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a8be19175b75b9e09ce307a251a0358f2"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a> (Exception e)</td></tr> +<tr class="memdesc:a8be19175b75b9e09ce307a251a0358f2"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log from the catched exception <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">More...</a><br /></td></tr> +<tr class="separator:a8be19175b75b9e09ce307a251a0358f2"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a08558ed797aa0cf2efbba7ff6c868453"><td class="memItemLeft" align="right" valign="top">override string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a> ()</td></tr> +<tr class="memdesc:a08558ed797aa0cf2efbba7ff6c868453"><td class="mdescLeft"> </td><td class="mdescRight">Creates new string info about current logger configuration <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">More...</a><br /></td></tr> +<tr class="separator:a08558ed797aa0cf2efbba7ff6c868453"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a8cb167cc304b1fb7fc581271f1465ca4"><td class="memItemLeft" align="right" valign="top"><a id="a8cb167cc304b1fb7fc581271f1465ca4" name="a8cb167cc304b1fb7fc581271f1465ca4"></a> +void </td><td class="memItemRight" valign="bottom"><b>Flush</b> ()</td></tr> +<tr class="memdesc:a8cb167cc304b1fb7fc581271f1465ca4"><td class="mdescLeft"> </td><td class="mdescRight">Waits for the logger to finish the logging <br /></td></tr> +<tr class="separator:a8cb167cc304b1fb7fc581271f1465ca4"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a60bb1691cc7cc543d94a34da86b91433"><td class="memItemLeft" align="right" valign="top"><a id="a60bb1691cc7cc543d94a34da86b91433" name="a60bb1691cc7cc543d94a34da86b91433"></a> +void </td><td class="memItemRight" valign="bottom"><b>Dispose</b> ()</td></tr> +<tr class="memdesc:a60bb1691cc7cc543d94a34da86b91433"><td class="mdescLeft"> </td><td class="mdescRight">Function stops the logger thread <br /></td></tr> +<tr class="separator:a60bb1691cc7cc543d94a34da86b91433"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a> +Protected Member Functions</h2></td></tr> +<tr class="memitem:a0a42ccc73ba8693a90da6a3a9bfca8f3"><td class="memItemLeft" align="right" valign="top"><a id="a0a42ccc73ba8693a90da6a3a9bfca8f3" name="a0a42ccc73ba8693a90da6a3a9bfca8f3"></a> + </td><td class="memItemRight" valign="bottom"><b>ALogger</b> ()</td></tr> +<tr class="memdesc:a0a42ccc73ba8693a90da6a3a9bfca8f3"><td class="mdescLeft"> </td><td class="mdescRight">Singleton constructor that initialized and starts the logger with arguments parsed by the config loader <br /></td></tr> +<tr class="separator:a0a42ccc73ba8693a90da6a3a9bfca8f3"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a0af186e371cd3325a1013bf219c8802e"><td class="memItemLeft" align="right" valign="top">abstract void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0af186e371cd3325a1013bf219c8802e">CreateLog</a> (string message)</td></tr> +<tr class="separator:a0af186e371cd3325a1013bf219c8802e"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a06814df4864ce7784647d15966eb1b4b"><td class="memItemLeft" align="right" valign="top">virtual string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a> (string message, <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a> logType)</td></tr> +<tr class="memdesc:a06814df4864ce7784647d15966eb1b4b"><td class="mdescLeft"> </td><td class="mdescRight">Composes the log with actual timestamp, log type and its main message <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">More...</a><br /></td></tr> +<tr class="separator:a06814df4864ce7784647d15966eb1b4b"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a6bcc70a878ba68230afcdcac45855eea"><td class="memItemLeft" align="right" valign="top">virtual string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a> (Exception? ex)</td></tr> +<tr class="memdesc:a6bcc70a878ba68230afcdcac45855eea"><td class="mdescLeft"> </td><td class="mdescRight">Function creates log from the catched exception <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">More...</a><br /></td></tr> +<tr class="separator:a6bcc70a878ba68230afcdcac45855eea"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a> +Properties</h2></td></tr> +<tr class="memitem:a614d0574928fa3f08452e753a263236f"><td class="memItemLeft" align="right" valign="top"><a id="a614d0574928fa3f08452e753a263236f" name="a614d0574928fa3f08452e753a263236f"></a> +static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a> </td><td class="memItemRight" valign="bottom"><b>Current</b><code> [get]</code></td></tr> +<tr class="memdesc:a614d0574928fa3f08452e753a263236f"><td class="mdescLeft"> </td><td class="mdescRight">Instance of the current logger type <br /></td></tr> +<tr class="separator:a614d0574928fa3f08452e753a263236f"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="a06814df4864ce7784647d15966eb1b4b" name="a06814df4864ce7784647d15966eb1b4b"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a06814df4864ce7784647d15966eb1b4b">◆ </a></span>ComposeLogRow()</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">virtual string LDClient.utils.loggers.ALogger.ComposeLogRow </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>message</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a> </td> + <td class="paramname"><em>logType</em> </td> + </tr> + <tr> + <td></td> + <td>)</td> + <td></td><td></td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">virtual</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Composes the log with actual timestamp, log type and its main message </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">message</td><td>main message of the log</td></tr> + <tr><td class="paramname">logType</td><td>Type of the logged message</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +</div> +</div> +<a id="a0af186e371cd3325a1013bf219c8802e" name="a0af186e371cd3325a1013bf219c8802e"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a0af186e371cd3325a1013bf219c8802e">◆ </a></span>CreateLog()</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">abstract void LDClient.utils.loggers.ALogger.CreateLog </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>message</em></td><td>)</td> + <td></td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">pure virtual</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">LDClient.utils.loggers.ConsoleLogger</a>.</p> + +</div> +</div> +<a id="a5c626205a03a7829c6dd195ee18d8e81" name="a5c626205a03a7829c6dd195ee18d8e81"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a5c626205a03a7829c6dd195ee18d8e81">◆ </a></span>Debug()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">void LDClient.utils.loggers.ALogger.Debug </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>message</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates new log with Debug identifier </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">message</td><td>Desired message to be logged</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<a id="a8be19175b75b9e09ce307a251a0358f2" name="a8be19175b75b9e09ce307a251a0358f2"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a8be19175b75b9e09ce307a251a0358f2">◆ </a></span>Error() <span class="overload">[1/2]</span></h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">void LDClient.utils.loggers.ALogger.Error </td> + <td>(</td> + <td class="paramtype">Exception </td> + <td class="paramname"><em>e</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates new log from the catched exception </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">e</td><td>catched exception tha should be logged</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<a id="a7f041d300e6d06dc58f969c4c0afd504" name="a7f041d300e6d06dc58f969c4c0afd504"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a7f041d300e6d06dc58f969c4c0afd504">◆ </a></span>Error() <span class="overload">[2/2]</span></h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">void LDClient.utils.loggers.ALogger.Error </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>message</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates new log with Error identifier </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">message</td><td>Desired message to be logged</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<a id="ac8f52ab4e431a47107d30db51615237e" name="ac8f52ab4e431a47107d30db51615237e"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ac8f52ab4e431a47107d30db51615237e">◆ </a></span>Info()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">void LDClient.utils.loggers.ALogger.Info </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>message</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates new log with Info identifier </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">message</td><td>Desired message to be logged</td></tr> + </table> + </dd> +</dl> + +</div> +</div> +<a id="a08558ed797aa0cf2efbba7ff6c868453" name="a08558ed797aa0cf2efbba7ff6c868453"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a08558ed797aa0cf2efbba7ff6c868453">◆ </a></span>ToString()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">override string LDClient.utils.loggers.ALogger.ToString </td> + <td>(</td> + <td class="paramname"></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Creates new string info about current logger configuration </p> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +</div> +</div> +<a id="a6bcc70a878ba68230afcdcac45855eea" name="a6bcc70a878ba68230afcdcac45855eea"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a6bcc70a878ba68230afcdcac45855eea">◆ </a></span>UnwrapExceptionMessages()</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">virtual string LDClient.utils.loggers.ALogger.UnwrapExceptionMessages </td> + <td>(</td> + <td class="paramtype">Exception? </td> + <td class="paramname"><em>ex</em></td><td>)</td> + <td></td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">virtual</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Function creates log from the catched exception </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">ex</td><td>catched exception tha should be logged</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>utils/loggers/ALogger.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">loggers</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js new file mode 100644 index 0000000..5a17264 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js @@ -0,0 +1,13 @@ +var class_l_d_client_1_1utils_1_1loggers_1_1_a_logger = +[ + [ "ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3", null ], + [ "ComposeLogRow", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b", null ], + [ "Debug", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81", null ], + [ "Dispose", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433", null ], + [ "Error", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2", null ], + [ "Error", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504", null ], + [ "Flush", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4", null ], + [ "Info", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e", null ], + [ "ToString", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453", null ], + [ "UnwrapExceptionMessages", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html new file mode 100644 index 0000000..010d1a1 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html @@ -0,0 +1,113 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.utils.loggers.ConsoleLogger Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">LDClient.utils.loggers.ConsoleLogger</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">ALogger</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a>(string message, LogType logType)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">CreateLog</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">LDClient.utils.loggers.ConsoleLogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">Current</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">static</span></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">Dispose</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a>(Exception e)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">Flush</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a>(Exception? ex)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html new file mode 100644 index 0000000..05a15b8 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html @@ -0,0 +1,194 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.utils.loggers.ConsoleLogger Class Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pro-methods">Protected Member Functions</a> | +<a href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.utils.loggers.ConsoleLogger Class Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a> +Protected Member Functions</h2></td></tr> +<tr class="memitem:aca7d10ea902e782733adaa53713f66b7"><td class="memItemLeft" align="right" valign="top">override void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">CreateLog</a> (string message)</td></tr> +<tr class="memdesc:aca7d10ea902e782733adaa53713f66b7"><td class="mdescLeft"> </td><td class="mdescRight">CreateLog function for the <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a> prints the desired message to the console <a href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">More...</a><br /></td></tr> +<tr class="separator:aca7d10ea902e782733adaa53713f66b7"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="inherit_header pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td colspan="2" onclick="javascript:toggleInherit('pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger')"><img src="closed.png" alt="-"/> Protected Member Functions inherited from <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td></tr> +<tr class="memitem:a0a42ccc73ba8693a90da6a3a9bfca8f3 inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a0a42ccc73ba8693a90da6a3a9bfca8f3" name="a0a42ccc73ba8693a90da6a3a9bfca8f3"></a> + </td><td class="memItemRight" valign="bottom"><b>ALogger</b> ()</td></tr> +<tr class="memdesc:a0a42ccc73ba8693a90da6a3a9bfca8f3 inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Singleton constructor that initialized and starts the logger with arguments parsed by the config loader <br /></td></tr> +<tr class="separator:a0a42ccc73ba8693a90da6a3a9bfca8f3 inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a0af186e371cd3325a1013bf219c8802e inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">abstract void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0af186e371cd3325a1013bf219c8802e">CreateLog</a> (string message)</td></tr> +<tr class="separator:a0af186e371cd3325a1013bf219c8802e inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a06814df4864ce7784647d15966eb1b4b inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">virtual string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a> (string message, <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a> logType)</td></tr> +<tr class="memdesc:a06814df4864ce7784647d15966eb1b4b inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Composes the log with actual timestamp, log type and its main message <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">More...</a><br /></td></tr> +<tr class="separator:a06814df4864ce7784647d15966eb1b4b inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a6bcc70a878ba68230afcdcac45855eea inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">virtual string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a> (Exception? ex)</td></tr> +<tr class="memdesc:a6bcc70a878ba68230afcdcac45855eea inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Function creates log from the catched exception <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">More...</a><br /></td></tr> +<tr class="separator:a6bcc70a878ba68230afcdcac45855eea inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="inherited" name="inherited"></a> +Additional Inherited Members</h2></td></tr> +<tr class="inherit_header pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger')"><img src="closed.png" alt="-"/> Public Member Functions inherited from <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td></tr> +<tr class="memitem:ac8f52ab4e431a47107d30db51615237e inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a> (string message)</td></tr> +<tr class="memdesc:ac8f52ab4e431a47107d30db51615237e inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log with Info identifier <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">More...</a><br /></td></tr> +<tr class="separator:ac8f52ab4e431a47107d30db51615237e inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a5c626205a03a7829c6dd195ee18d8e81 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a> (string message)</td></tr> +<tr class="memdesc:a5c626205a03a7829c6dd195ee18d8e81 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log with Debug identifier <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">More...</a><br /></td></tr> +<tr class="separator:a5c626205a03a7829c6dd195ee18d8e81 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a7f041d300e6d06dc58f969c4c0afd504 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a> (string message)</td></tr> +<tr class="memdesc:a7f041d300e6d06dc58f969c4c0afd504 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log with Error identifier <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">More...</a><br /></td></tr> +<tr class="separator:a7f041d300e6d06dc58f969c4c0afd504 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a8be19175b75b9e09ce307a251a0358f2 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a> (Exception e)</td></tr> +<tr class="memdesc:a8be19175b75b9e09ce307a251a0358f2 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Creates new log from the catched exception <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">More...</a><br /></td></tr> +<tr class="separator:a8be19175b75b9e09ce307a251a0358f2 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a08558ed797aa0cf2efbba7ff6c868453 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">override string </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a> ()</td></tr> +<tr class="memdesc:a08558ed797aa0cf2efbba7ff6c868453 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Creates new string info about current logger configuration <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">More...</a><br /></td></tr> +<tr class="separator:a08558ed797aa0cf2efbba7ff6c868453 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a8cb167cc304b1fb7fc581271f1465ca4 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a8cb167cc304b1fb7fc581271f1465ca4" name="a8cb167cc304b1fb7fc581271f1465ca4"></a> +void </td><td class="memItemRight" valign="bottom"><b>Flush</b> ()</td></tr> +<tr class="memdesc:a8cb167cc304b1fb7fc581271f1465ca4 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Waits for the logger to finish the logging <br /></td></tr> +<tr class="separator:a8cb167cc304b1fb7fc581271f1465ca4 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a60bb1691cc7cc543d94a34da86b91433 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a60bb1691cc7cc543d94a34da86b91433" name="a60bb1691cc7cc543d94a34da86b91433"></a> +void </td><td class="memItemRight" valign="bottom"><b>Dispose</b> ()</td></tr> +<tr class="memdesc:a60bb1691cc7cc543d94a34da86b91433 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Function stops the logger thread <br /></td></tr> +<tr class="separator:a60bb1691cc7cc543d94a34da86b91433 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="inherit_header properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td colspan="2" onclick="javascript:toggleInherit('properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger')"><img src="closed.png" alt="-"/> Properties inherited from <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td></tr> +<tr class="memitem:a614d0574928fa3f08452e753a263236f inherit properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a614d0574928fa3f08452e753a263236f" name="a614d0574928fa3f08452e753a263236f"></a> +static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a> </td><td class="memItemRight" valign="bottom"><b>Current</b><code> [get]</code></td></tr> +<tr class="memdesc:a614d0574928fa3f08452e753a263236f inherit properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft"> </td><td class="mdescRight">Instance of the current logger type <br /></td></tr> +<tr class="separator:a614d0574928fa3f08452e753a263236f inherit properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<h2 class="groupheader">Member Function Documentation</h2> +<a id="aca7d10ea902e782733adaa53713f66b7" name="aca7d10ea902e782733adaa53713f66b7"></a> +<h2 class="memtitle"><span class="permalink"><a href="#aca7d10ea902e782733adaa53713f66b7">◆ </a></span>CreateLog()</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">override void LDClient.utils.loggers.ConsoleLogger.CreateLog </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>message</em></td><td>)</td> + <td></td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">virtual</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>CreateLog function for the <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a> prints the desired message to the console </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">message</td><td>Desired message to be printed</td></tr> + </table> + </dd> +</dl> + +<p>Implements <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a>.</p> + +</div> +</div> +<hr/>The documentation for this class was generated from the following file:<ul> +<li>utils/loggers/ConsoleLogger.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">loggers</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js new file mode 100644 index 0000000..ba870f6 --- /dev/null +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js @@ -0,0 +1,4 @@ +var class_l_d_client_1_1utils_1_1loggers_1_1_console_logger = +[ + [ "CreateLog", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/classes.html b/ld_client/doc/pdoc/classes.html new file mode 100644 index 0000000..68fd64c --- /dev/null +++ b/ld_client/doc/pdoc/classes.html @@ -0,0 +1,122 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Class Index</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('classes.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">Class Index</div></div> +</div><!--header--> +<div class="contents"> +<div class="qindex"><a class="qindex" href="#letter_A">A</a> | <a class="qindex" href="#letter_C">C</a> | <a class="qindex" href="#letter_D">D</a> | <a class="qindex" href="#letter_F">F</a> | <a class="qindex" href="#letter_H">H</a> | <a class="qindex" href="#letter_I">I</a> | <a class="qindex" href="#letter_P">P</a></div> +<div class="classindex"> +<dl class="classindex even"> +<dt class="alphachar"><a id="letter_A" name="letter_A">A</a></dt> +<dd><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a> (<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">LDClient.utils.loggers</a>)</dd><dd><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">ApiClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd></dl> +<dl class="classindex odd"> +<dt class="alphachar"><a id="letter_C" name="letter_C">C</a></dt> +<dd><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a> (<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">LDClient.utils.loggers</a>)</dd></dl> +<dl class="classindex even"> +<dt class="alphachar"><a id="letter_D" name="letter_D">D</a></dt> +<dd><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a> (<a class="el" href="namespace_l_d_client_1_1network_1_1data.html">LDClient.network.data</a>)</dd></dl> +<dl class="classindex odd"> +<dt class="alphachar"><a id="letter_F" name="letter_F">F</a></dt> +<dd><a class="el" href="class_file_logger.html">FileLogger</a></dd><dd><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">FileUtils</a> (<a class="el" href="namespace_l_d_client_1_1utils.html">LDClient.utils</a>)</dd></dl> +<dl class="classindex even"> +<dt class="alphachar"><a id="letter_H" name="letter_H">H</a></dt> +<dd><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">HttpClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd></dl> +<dl class="classindex odd"> +<dt class="alphachar"><a id="letter_I" name="letter_I">I</a></dt> +<dd><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a> (<a class="el" href="namespace_l_d_client_1_1utils.html">LDClient.utils</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd><dd><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">InfoFetcher</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd></dl> +<dl class="classindex even"> +<dt class="alphachar"><a id="letter_P" name="letter_P">P</a></dt> +<dd><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> (<a class="el" href="namespace_l_d_client_1_1network_1_1data.html">LDClient.network.data</a>)</dd><dd><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">ProcessDetection</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd><dd><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">ProcessUtils</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd></dl> +</div> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/closed.png b/ld_client/doc/pdoc/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8<G4C~~x2bkCl7 zlF9slZh~6z%aUT|WfKm3{P*dDAfv<6>{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html b/ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html new file mode 100644 index 0000000..747f241 --- /dev/null +++ b/ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: network/data Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_08b4fbe3d60d6d41472a6a22c750d4c7.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">data Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_c901c14b65aa229498a52b725b3d4a2c.html">network</a></li><li class="navelem"><a class="el" href="dir_08b4fbe3d60d6d41472a6a22c750d4c7.html">data</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html b/ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html new file mode 100644 index 0000000..779f3da --- /dev/null +++ b/ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: obj Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_43724e81dd40e09f32417973865cdd64.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">obj Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_43724e81dd40e09f32417973865cdd64.html">obj</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html b/ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html new file mode 100644 index 0000000..b05309c --- /dev/null +++ b/ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: obj/Debug/net6.0 Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_7212c827820ef56532d3599ed27e3aff.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">net6.0 Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_43724e81dd40e09f32417973865cdd64.html">obj</a></li><li class="navelem"><a class="el" href="dir_a71c3b2ad23b9ff58220dd012d201987.html">Debug</a></li><li class="navelem"><a class="el" href="dir_7212c827820ef56532d3599ed27e3aff.html">net6.0</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html b/ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html new file mode 100644 index 0000000..9c95957 --- /dev/null +++ b/ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: utils/loggers Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_754926843367c7eee8b48719e3f14adf.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">loggers Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html">utils</a></li><li class="navelem"><a class="el" href="dir_754926843367c7eee8b48719e3f14adf.html">loggers</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html b/ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html new file mode 100644 index 0000000..3703383 --- /dev/null +++ b/ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html @@ -0,0 +1,105 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: obj/Debug Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_a71c3b2ad23b9ff58220dd012d201987.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">Debug Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_7212c827820ef56532d3599ed27e3aff.html">net6.0</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_43724e81dd40e09f32417973865cdd64.html">obj</a></li><li class="navelem"><a class="el" href="dir_a71c3b2ad23b9ff58220dd012d201987.html">Debug</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html b/ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html new file mode 100644 index 0000000..58822f4 --- /dev/null +++ b/ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: detection Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">detection Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html">detection</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html b/ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html new file mode 100644 index 0000000..ae982de --- /dev/null +++ b/ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html @@ -0,0 +1,105 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: network Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_c901c14b65aa229498a52b725b3d4a2c.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">network Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_08b4fbe3d60d6d41472a6a22c750d4c7.html">data</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_c901c14b65aa229498a52b725b3d4a2c.html">network</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html b/ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html new file mode 100644 index 0000000..fb7a76a --- /dev/null +++ b/ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html @@ -0,0 +1,105 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: utils Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">utils Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_754926843367c7eee8b48719e3f14adf.html">loggers</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html">utils</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/doc.png b/ld_client/doc/pdoc/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV<G0u}v<P)<h;3K|Lk000e1NJLTq000;O000&U1^@s6+I?Jz00089Nkl<ZcmeI5 zO;1x>7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$))<VZ%w8AHp|fq%mP;4ffy zZ-fC6h(S;T@^On$pg;?)``rZ-=s7qr4DR5hE4!!NdDmX=TJJeiSGimUI5QXkXNfZ> zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!n<GayH9yHg8K} z>w*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXR<pt)Tx_l7FX`b+T&0J~3Ac zDisC2f48s?Pz6U1j(Y#7FGXj244=p1VQ-4TfmZrD8|c58q%jdB67*815?3si0IJ}q zK#I#XHom~r+!`&75xy*K>bTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41N<zz(9MkMF~u!W-n>Azrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3<FfbmLT1ma;4wB2Ka6K c|6iFu0IFBSu=gW%4*&oF07*qoM6N<$f>OR*Hvj+t literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/doxygen.css b/ld_client/doc/pdoc/doxygen.css new file mode 100644 index 0000000..2010785 --- /dev/null +++ b/ld_client/doc/pdoc/doxygen.css @@ -0,0 +1,1841 @@ +/* The standard CSS for doxygen 1.9.4 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +th p.starttd, th p.intertd, th p.endtd { + font-size: 100%; + font-weight: 700; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.navtab { + border-right: 1px solid #A3B4D7; + padding-right: 15px; + text-align: right; + line-height: 110%; +} + +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} +td.navtabHL { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; + width: 100%; + line-height: 140%; + font-size: 130%; + color: #A0A0A0; +} + +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} + +.alphachar a{ + color: black; +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; +} + +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.odd { + background-color: #F8F9FC; +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +.contents a.qindexHL:visited { + color: #FFFFFF; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +a.code.hl_class { /* style for links to class names in code snippets */ } +a.code.hl_struct { /* style for links to struct names in code snippets */ } +a.code.hl_union { /* style for links to union names in code snippets */ } +a.code.hl_interface { /* style for links to interface names in code snippets */ } +a.code.hl_protocol { /* style for links to protocol names in code snippets */ } +a.code.hl_category { /* style for links to category names in code snippets */ } +a.code.hl_exception { /* style for links to exception names in code snippets */ } +a.code.hl_service { /* style for links to service names in code snippets */ } +a.code.hl_singleton { /* style for links to singleton names in code snippets */ } +a.code.hl_concept { /* style for links to concept names in code snippets */ } +a.code.hl_namespace { /* style for links to namespace names in code snippets */ } +a.code.hl_package { /* style for links to package names in code snippets */ } +a.code.hl_define { /* style for links to macro names in code snippets */ } +a.code.hl_function { /* style for links to function names in code snippets */ } +a.code.hl_variable { /* style for links to variable names in code snippets */ } +a.code.hl_typedef { /* style for links to typedef names in code snippets */ } +a.code.hl_enumvalue { /* style for links to enum value names in code snippets */ } +a.code.hl_enumeration { /* style for links to enumeration names in code snippets */ } +a.code.hl_signal { /* style for links to Qt signal names in code snippets */ } +a.code.hl_slot { /* style for links to Qt slot names in code snippets */ } +a.code.hl_friend { /* style for links to friend names in code snippets */ } +a.code.hl_dcop { /* style for links to KDE3 DCOP names in code snippets */ } +a.code.hl_property { /* style for links to property names in code snippets */ } +a.code.hl_event { /* style for links to event names in code snippets */ } +a.code.hl_sequence { /* style for links to sequence names in code snippets */ } +a.code.hl_dictionary { /* style for links to dictionary names in code snippets */ } + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: visible; +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + margin-right: 9px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #FFFFFF; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +.compoundTemplParams { + color: #4665A2; + font-size: 80%; + line-height: 120%; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight, .memTemplItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectrow +{ + height: 56px; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; + padding-left: 0.5em; +} + +#projectname +{ + font: 200% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 90% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; + text-align:right; + width:52px; +} + +dl.citelist dd { + margin:2px 0 2px 72px; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + +span.obfuscator { + display: none; +} + +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + /*white-space: nowrap;*/ + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +.DocNodeRTL { + text-align: right; + direction: rtl; +} + +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +code.JavaDocCode { + direction:ltr; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} +/* @end */ + +u { + text-decoration: underline; +} + diff --git a/ld_client/doc/pdoc/doxygen.svg b/ld_client/doc/pdoc/doxygen.svg new file mode 100644 index 0000000..d42dad5 --- /dev/null +++ b/ld_client/doc/pdoc/doxygen.svg @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg version="1.1" viewBox="0 0 104 31" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <linearGradient id="a"> + <stop stop-color="#5373B4" offset="0"/> + <stop stop-color="#7C95C6" offset="1"/> + </linearGradient> + <linearGradient id="d" x1="31.474" x2="31.474" y1="24.821" y2="26.773" gradientUnits="userSpaceOnUse" xlink:href="#a"/> + <linearGradient id="c" x1="31.474" x2="31.474" y1="24.821" y2="26.773" gradientTransform="matrix(.6816 0 0 1.0248 72.391 -.91809)" gradientUnits="userSpaceOnUse" xlink:href="#a"/> + <linearGradient id="b" x1="56.295" x2="56.295" y1="24.622" y2="26.574" gradientUnits="userSpaceOnUse" xlink:href="#a"/> + <linearGradient id="e" x1="49.067" x2="48.956" y1="19.719" y2="9.5227" gradientTransform="matrix(.97968 0 0 1.0207 -.25579 -.25579)" gradientUnits="userSpaceOnUse"> + <stop stop-color="#C0CCE3" offset="0"/> + <stop stop-color="#EEF1F7" offset="1"/> + </linearGradient> + <filter id="f" x="-.010676" y="-.045304" width="1.0214" height="1.0906" color-interpolation-filters="sRGB"> + <feGaussianBlur stdDeviation="0.45293203"/> + </filter> + </defs> + <g> + <path transform="translate(-2.5759 -27.848)" d="m13.609 32.203v6.8633h-0.05078c-0.40533-0.66867-0.96254-1.1715-1.6719-1.5059-0.69244-0.35193-1.4282-0.52734-2.2051-0.52734-0.96267 0-1.807 0.2027-2.5332 0.60742-0.72622 0.38713-1.3344 0.90556-1.8242 1.5566-0.47289 0.65108-0.83456 1.4092-1.0879 2.2715-0.23644 0.84464-0.35547 1.7236-0.35547 2.6387 0 0.95022 0.11902 1.8643 0.35547 2.7441 0.25333 0.87983 0.615 1.6633 1.0879 2.3496 0.48978 0.66867 1.1065 1.2066 1.8496 1.6113 0.74311 0.38713 1.6044 0.58008 2.584 0.58008 0.86133 0 1.6311-0.15787 2.3066-0.47461 0.69244-0.33434 1.2497-0.87227 1.6719-1.6113h0.05078v1.7422h3.4199v-18.846zm12.875 4.8301c-1.0302 0-1.9596 0.17541-2.7871 0.52734-0.82756 0.33434-1.5358 0.81965-2.127 1.4531-0.59111 0.61588-1.0483 1.3721-1.3691 2.2695-0.32089 0.87983-0.48047 1.866-0.48047 2.957s0.15958 2.0752 0.48047 2.9551c0.32089 0.87983 0.77803 1.6361 1.3691 2.2695 0.59111 0.61588 1.2994 1.0914 2.127 1.4258 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.0302 0 1.9596-0.16762 2.7871-0.50195 0.84444-0.33434 1.5612-0.8099 2.1523-1.4258 0.59111-0.63348 1.0483-1.3897 1.3691-2.2695 0.32089-0.87983 0.48047-1.8641 0.48047-2.9551s-0.15958-2.0772-0.48047-2.957c-0.32089-0.89743-0.77803-1.6536-1.3691-2.2695-0.59111-0.63348-1.3079-1.1188-2.1523-1.4531-0.82756-0.35193-1.7569-0.52734-2.7871-0.52734zm41.715 0c-0.912 0-1.7223 0.18516-2.4316 0.55469-0.69244 0.36953-1.2752 0.87043-1.748 1.5039-0.47289 0.61588-0.83651 1.337-1.0898 2.1641-0.23645 0.80944-0.35352 1.6553-0.35352 2.5352 0 0.93262 0.10007 1.8214 0.30273 2.666 0.21956 0.82704 0.55767 1.556 1.0137 2.1895 0.456 0.61588 1.0387 1.109 1.748 1.4785 0.70933 0.35193 1.5536 0.5293 2.5332 0.5293 0.79378 0 1.5446-0.16762 2.2539-0.50195 0.72622-0.35193 1.2834-0.88986 1.6719-1.6113h0.05078v1.7949c0.01689 0.96782-0.21071 1.7689-0.68359 2.4023-0.456 0.63348-1.1898 0.95117-2.2031 0.95117-0.64178 0-1.2075-0.14228-1.6973-0.42383-0.48978-0.26395-0.81939-0.74731-0.98828-1.4512h-3.5723c0.05067 0.77425 0.25276 1.435 0.60742 1.9805 0.37156 0.56309 0.8287 1.0192 1.3691 1.3711 0.55733 0.35193 1.1656 0.60726 1.8242 0.76562 0.67556 0.17597 1.3328 0.26562 1.9746 0.26562 1.5031 0 2.7025-0.21245 3.5977-0.63477 0.89511-0.42232 1.5798-0.94076 2.0527-1.5566 0.47289-0.59829 0.777-1.2493 0.91211-1.9531 0.152-0.70386 0.22656-1.3295 0.22656-1.875v-12.775h-3.4199v1.8223h-0.05078c-0.43911-0.79185-0.98782-1.3551-1.6465-1.6895-0.64178-0.33434-1.3926-0.50195-2.2539-0.50195zm16.523 0c-0.99644 0-1.9088 0.18516-2.7363 0.55469-0.81067 0.36953-1.5124 0.88018-2.1035 1.5312-0.59111 0.63348-1.0463 1.3897-1.3672 2.2695s-0.48047 1.831-0.48047 2.8516c0 1.0558 0.15108 2.0225 0.45508 2.9023 0.32089 0.87983 0.76758 1.6361 1.3418 2.2695 0.57422 0.63348 1.276 1.1266 2.1035 1.4785 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.4862 0 2.7517-0.35277 3.7988-1.0566 1.0471-0.70387 1.8254-1.8733 2.332-3.5098h-3.168c-0.11822 0.42232-0.43934 0.82772-0.96289 1.2148-0.52355 0.36953-1.1468 0.55274-1.873 0.55273-1.0133 0-1.7916-0.27286-2.332-0.81836-0.54044-0.5455-0.83605-1.4245-0.88672-2.6387h9.4492c0.06756-1.0558-0.01551-2.0673-0.25195-3.0352-0.23644-0.96782-0.62557-1.8293-1.166-2.5859-0.52356-0.75666-1.1998-1.355-2.0273-1.7949-0.82756-0.45751-1.7974-0.6875-2.9121-0.6875zm16.189 0c-0.76 0-1.5023 0.18516-2.2285 0.55469-0.72622 0.35193-1.3174 0.92299-1.7734 1.7148h-0.07617v-1.9004h-3.4199v13.646h3.5977v-7.1523c0-1.3901 0.21909-2.3841 0.6582-2.9824 0.43911-0.61588 1.1494-0.92383 2.1289-0.92383 0.86133 0 1.4611 0.28066 1.7988 0.84375 0.33777 0.5455 0.50586 1.3816 0.50586 2.5078v7.707h3.5976v-8.3926c0-0.84464-0.0765-1.6106-0.22851-2.2969-0.13511-0.70387-0.37971-1.2925-0.73438-1.7676-0.35466-0.49271-0.84386-0.87277-1.4688-1.1367-0.608-0.28155-1.3948-0.42188-2.3574-0.42188zm-66.063 0.36914 4.3066 6.4668-4.7129 7.1797h4.0293l2.7363-4.3027 2.7344 4.3027h4.1055l-4.8398-7.2578 4.3066-6.3887h-3.9766l-2.2793 3.5645-2.3066-3.5645zm13.275 0 4.584 12.803c0.10133 0.26395 0.15234 0.54461 0.15234 0.84375 0 0.40472-0.11707 0.77504-0.35352 1.1094-0.21956 0.33434-0.56617 0.52729-1.0391 0.58008-0.35467 0.0176-0.70979 0.0098-1.0645-0.02539-0.35467-0.03519-0.70128-0.07028-1.0391-0.10547v3.0879c0.37156 0.03519 0.73518 0.06051 1.0898 0.07813 0.37156 0.03519 0.74368 0.05273 1.1152 0.05273 1.2329 0 2.1943-0.23778 2.8867-0.71289 0.69244-0.47511 1.2326-1.2664 1.6211-2.375l5.4727-15.336h-3.7246l-2.8613 9.3438h-0.05078l-2.9648-9.3438zm-37.48 2.4551c0.59111 0 1.0823 0.12279 1.4707 0.36914 0.38844 0.24635 0.6991 0.57184 0.93555 0.97656 0.25333 0.38713 0.43187 0.84515 0.5332 1.373 0.10133 0.5103 0.15234 1.0482 0.15234 1.6113 0 0.56309-0.05101 1.1069-0.15234 1.6348-0.10133 0.5279-0.27137 1.0035-0.50781 1.4258-0.23644 0.40472-0.5556 0.73021-0.96094 0.97656-0.38844 0.24635-0.87959 0.36914-1.4707 0.36914-0.55733 0-1.038-0.12279-1.4434-0.36914-0.38844-0.26395-0.71806-0.59723-0.98828-1.002-0.25333-0.42232-0.43842-0.89788-0.55664-1.4258s-0.17773-1.0561-0.17773-1.584c-1e-7 -0.56309 0.05101-1.0991 0.15234-1.6094 0.11822-0.5279 0.29481-0.99567 0.53125-1.4004 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.24635 0.90303-0.36914 1.4941-0.36914zm15.84 0c0.608 0 1.1142 0.13253 1.5195 0.39648 0.42222 0.24635 0.75184 0.57184 0.98828 0.97656 0.25333 0.40472 0.42992 0.87054 0.53125 1.3984 0.10133 0.5279 0.15234 1.0658 0.15234 1.6113 0 0.5455-0.05101 1.0815-0.15234 1.6094-0.10134 0.5103-0.27792 0.97612-0.53125 1.3984-0.23644 0.40472-0.56606 0.73021-0.98828 0.97656-0.40533 0.24635-0.91153 0.36914-1.5195 0.36914-0.608 0-1.1142-0.12279-1.5195-0.36914s-0.73495-0.57184-0.98828-0.97656c-0.23644-0.42232-0.40648-0.88814-0.50781-1.3984-0.10133-0.5279-0.15234-1.0639-0.15234-1.6094 0-0.5455 0.05101-1.0834 0.15234-1.6113 0.10133-0.5279 0.27137-0.99371 0.50781-1.3984 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.26395 0.91153-0.39648 1.5195-0.39648zm42.602 0c0.59111 0 1.0803 0.11499 1.4688 0.34375 0.38844 0.22876 0.70105 0.5367 0.9375 0.92383 0.23644 0.38713 0.40648 0.8354 0.50781 1.3457 0.10133 0.49271 0.15039 1.0209 0.15039 1.584 0 0.4927-0.06606 0.96827-0.20117 1.4258-0.11822 0.43992-0.30526 0.83557-0.55859 1.1875-0.25333 0.35193-0.57445 0.63259-0.96289 0.84375-0.38844 0.21116-0.83513 0.31836-1.3418 0.31836-0.55733 0-1.021-0.12474-1.3926-0.37109-0.37156-0.24635-0.67566-0.56209-0.91211-0.94922-0.21956-0.38713-0.38109-0.81786-0.48242-1.293-0.08444-0.49271-0.12695-0.98581-0.12695-1.4785 0-0.5103 0.05101-0.99366 0.15234-1.4512 0.11822-0.47511 0.29676-0.89025 0.5332-1.2422 0.25333-0.36953 0.55744-0.65993 0.91211-0.87109 0.37156-0.21116 0.80974-0.31641 1.3164-0.31641zm15.535 0c0.87822 0 1.529 0.24753 1.9512 0.74023 0.43911 0.49271 0.74322 1.2138 0.91211 2.1641h-5.8535c0.01689-0.26395 0.0679-0.5641 0.15234-0.89844 0.10133-0.33434 0.26287-0.65008 0.48242-0.94922 0.23644-0.29914 0.54055-0.54667 0.91211-0.74023 0.38845-0.21116 0.86914-0.31641 1.4434-0.31641z" filter="url(#f)" opacity=".3" stroke="#969696" xlink:href="#path141"/> + <path d="m0.97202 24.161 43.605-0.0019 0.0508 3.3061-43.6 0.04174z" fill="url(#d)" stroke="#000" stroke-width=".5"/> + <path d="m10.283 3.5547v6.8633h-0.05078c-0.40533-0.66867-0.96254-1.1715-1.6719-1.5059-0.69244-0.35193-1.4282-0.52734-2.2051-0.52734-0.96267 0-1.807 0.2027-2.5332 0.60742-0.72622 0.38713-1.3344 0.90556-1.8242 1.5566-0.47289 0.65108-0.83456 1.4092-1.0879 2.2715-0.23644 0.84464-0.35547 1.7236-0.35547 2.6387 0 0.95022 0.11902 1.8643 0.35547 2.7441 0.25333 0.87983 0.615 1.6633 1.0879 2.3496 0.48978 0.66867 1.1065 1.2066 1.8496 1.6113 0.74311 0.38713 1.6044 0.58008 2.584 0.58008 0.86133 0 1.6311-0.15787 2.3066-0.47461 0.69244-0.33434 1.2497-0.87227 1.6719-1.6113h0.05078v1.7422h3.4199v-18.846zm12.875 4.8301c-1.0302 0-1.9596 0.17541-2.7871 0.52734-0.82756 0.33434-1.5358 0.81965-2.127 1.4531-0.59111 0.61588-1.0483 1.3721-1.3691 2.2695-0.32089 0.87983-0.48047 1.866-0.48047 2.957s0.15958 2.0752 0.48047 2.9551c0.32089 0.87983 0.77803 1.6361 1.3691 2.2695 0.59111 0.61588 1.2994 1.0914 2.127 1.4258 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.0302 0 1.9596-0.16762 2.7871-0.50195 0.84444-0.33434 1.5612-0.8099 2.1523-1.4258 0.59111-0.63348 1.0483-1.3897 1.3691-2.2695 0.32089-0.87983 0.48047-1.8641 0.48047-2.9551s-0.15958-2.0772-0.48047-2.957c-0.32089-0.89743-0.77803-1.6536-1.3691-2.2695-0.59111-0.63348-1.3079-1.1188-2.1523-1.4531-0.82756-0.35193-1.7569-0.52734-2.7871-0.52734zm41.715 0c-0.912 0-1.7223 0.18516-2.4316 0.55469-0.69244 0.36953-1.2752 0.87043-1.748 1.5039-0.47289 0.61588-0.83651 1.337-1.0898 2.1641-0.23644 0.80944-0.35352 1.6553-0.35352 2.5352 0 0.93262 0.10007 1.8214 0.30273 2.666 0.21956 0.82704 0.55767 1.556 1.0137 2.1895 0.456 0.61588 1.0387 1.109 1.748 1.4785 0.70933 0.35193 1.5536 0.5293 2.5332 0.5293 0.79378 0 1.5446-0.16762 2.2539-0.50195 0.72622-0.35193 1.2834-0.88986 1.6719-1.6113h0.05078v1.7949c0.01689 0.96782-0.21071 1.7689-0.68359 2.4023-0.456 0.63348-1.1898 0.95117-2.2031 0.95117-0.64178 0-1.2075-0.14228-1.6973-0.42383-0.48978-0.26395-0.81939-0.74731-0.98828-1.4512h-3.5723c0.05067 0.77425 0.25276 1.435 0.60742 1.9805 0.37156 0.56309 0.8287 1.0192 1.3691 1.3711 0.55733 0.35193 1.1656 0.60726 1.8242 0.76562 0.67556 0.17597 1.3328 0.26562 1.9746 0.26562 1.5031 0 2.7025-0.21245 3.5977-0.63477 0.89511-0.42232 1.5798-0.94076 2.0527-1.5566 0.47289-0.59829 0.777-1.2493 0.91211-1.9531 0.152-0.70386 0.22656-1.3295 0.22656-1.875v-12.775h-3.4199v1.8223h-0.05078c-0.43911-0.79185-0.98782-1.3551-1.6465-1.6895-0.64178-0.33434-1.3926-0.50195-2.2539-0.50195zm16.523 0c-0.99644 0-1.9088 0.18516-2.7363 0.55469-0.81067 0.36953-1.5124 0.88017-2.1035 1.5312-0.59111 0.63348-1.0463 1.3897-1.3672 2.2695s-0.48047 1.831-0.48047 2.8516c0 1.0558 0.15108 2.0225 0.45508 2.9023 0.32089 0.87983 0.76758 1.6361 1.3418 2.2695 0.57422 0.63348 1.276 1.1266 2.1035 1.4785 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.4862 0 2.7517-0.35278 3.7988-1.0566 1.0471-0.70386 1.8254-1.8733 2.332-3.5098h-3.168c-0.11822 0.42232-0.43934 0.82772-0.96289 1.2148-0.52355 0.36953-1.1468 0.55274-1.873 0.55273-1.0133 0-1.7916-0.27286-2.332-0.81836-0.54044-0.5455-0.83605-1.4245-0.88672-2.6387h9.4492c0.06756-1.0558-0.01551-2.0673-0.25195-3.0352-0.23644-0.96782-0.62557-1.8293-1.166-2.5859-0.52356-0.75666-1.1998-1.355-2.0273-1.7949-0.82756-0.45751-1.7974-0.6875-2.9121-0.6875zm16.189 0c-0.76 0-1.5023 0.18516-2.2285 0.55469-0.72622 0.35193-1.3174 0.923-1.7734 1.7148h-0.07617v-1.9004h-3.4199v13.646h3.5977v-7.1523c0-1.3901 0.21909-2.3841 0.6582-2.9824 0.43911-0.61588 1.1494-0.92383 2.1289-0.92383 0.86133 0 1.461 0.28066 1.7988 0.84375 0.33778 0.5455 0.50586 1.3816 0.50586 2.5078v7.707h3.5977v-8.3926c0-0.84464-0.0765-1.6106-0.22852-2.2969-0.13511-0.70387-0.3797-1.2925-0.73437-1.7676-0.35466-0.49271-0.84386-0.87277-1.4688-1.1367-0.608-0.28155-1.3948-0.42188-2.3574-0.42188zm-66.062 0.36914 4.3066 6.4668-4.7129 7.1797h4.0293l2.7363-4.3027 2.7344 4.3027h4.1055l-4.8398-7.2578 4.3066-6.3887h-3.9766l-2.2793 3.5645-2.3066-3.5645zm13.275 0 4.584 12.803c0.10133 0.26395 0.15234 0.54461 0.15234 0.84375 0 0.40472-0.11707 0.77504-0.35352 1.1094-0.21956 0.33434-0.56617 0.52729-1.0391 0.58008-0.35467 0.0176-0.70979 0.0098-1.0645-0.02539-0.35467-0.03519-0.70128-0.07027-1.0391-0.10547v3.0879c0.37156 0.03519 0.73518 0.06052 1.0898 0.07813 0.37156 0.03519 0.74368 0.05273 1.1152 0.05273 1.2329 0 2.1943-0.23778 2.8867-0.71289 0.69244-0.47511 1.2326-1.2664 1.6211-2.375l5.4727-15.336h-3.7246l-2.8613 9.3437h-0.05078l-2.9648-9.3437zm-37.48 2.4551c0.59111 0 1.0823 0.12279 1.4707 0.36914s0.6991 0.57184 0.93555 0.97656c0.25333 0.38713 0.43187 0.84515 0.5332 1.373 0.10133 0.5103 0.15234 1.0482 0.15234 1.6113 0 0.56309-0.05101 1.1069-0.15234 1.6348-0.10133 0.5279-0.27137 1.0035-0.50781 1.4258-0.23644 0.40472-0.5556 0.73021-0.96094 0.97656-0.38844 0.24635-0.87959 0.36914-1.4707 0.36914-0.55733 0-1.038-0.12279-1.4434-0.36914-0.38844-0.26395-0.71806-0.59723-0.98828-1.002-0.25333-0.42232-0.43842-0.89788-0.55664-1.4258s-0.17773-1.0561-0.17773-1.584c-1e-7 -0.56309 0.05101-1.0991 0.15234-1.6094 0.11822-0.5279 0.29481-0.99567 0.53125-1.4004 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.24635 0.90303-0.36914 1.4941-0.36914zm15.84 0c0.608 0 1.1142 0.13254 1.5195 0.39648 0.42222 0.24635 0.75184 0.57184 0.98828 0.97656 0.25333 0.40472 0.42992 0.87054 0.53125 1.3984 0.10133 0.5279 0.15234 1.0658 0.15234 1.6113 0 0.5455-0.05101 1.0815-0.15234 1.6094-0.10133 0.5103-0.27792 0.97612-0.53125 1.3984-0.23644 0.40472-0.56606 0.73021-0.98828 0.97656-0.40533 0.24635-0.91153 0.36914-1.5195 0.36914-0.608 0-1.1142-0.12279-1.5195-0.36914s-0.73495-0.57184-0.98828-0.97656c-0.23644-0.42232-0.40648-0.88813-0.50781-1.3984-0.10133-0.5279-0.15234-1.0639-0.15234-1.6094 0-0.5455 0.05101-1.0834 0.15234-1.6113 0.10133-0.5279 0.27137-0.99371 0.50781-1.3984 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.26395 0.91153-0.39648 1.5195-0.39648zm42.602 0c0.59111 0 1.0803 0.11499 1.4688 0.34375 0.38844 0.22876 0.70106 0.5367 0.9375 0.92383 0.23644 0.38713 0.40648 0.8354 0.50781 1.3457 0.10133 0.49271 0.15039 1.0209 0.15039 1.584 0 0.49271-0.06606 0.96827-0.20117 1.4258-0.11822 0.43992-0.30526 0.83557-0.55859 1.1875-0.25333 0.35193-0.57445 0.63259-0.96289 0.84375-0.38844 0.21116-0.83513 0.31836-1.3418 0.31836-0.55733 0-1.021-0.12474-1.3926-0.37109-0.37156-0.24635-0.67566-0.56209-0.91211-0.94922-0.21956-0.38713-0.38109-0.81786-0.48242-1.293-0.08444-0.49271-0.12695-0.98581-0.12695-1.4785 0-0.5103 0.05101-0.99366 0.15234-1.4512 0.11822-0.47511 0.29676-0.89026 0.5332-1.2422 0.25333-0.36953 0.55744-0.65993 0.91211-0.87109 0.37156-0.21116 0.80974-0.31641 1.3164-0.31641zm15.535 0c0.87822 0 1.529 0.24753 1.9512 0.74024 0.43911 0.49271 0.74322 1.2138 0.91211 2.1641h-5.8535c0.01689-0.26395 0.0679-0.5641 0.15234-0.89844 0.10133-0.33434 0.26287-0.65008 0.48242-0.94922 0.23644-0.29914 0.54055-0.54667 0.91211-0.74023 0.38845-0.21116 0.86914-0.31641 1.4434-0.31641z" fill="url(#e)" stroke="#4665A2" stroke-width=".7"/> + <path d="m52.988 27.291c0.99602-1.0359 1.3944-1.8725 1.7928-3.1076l3.8247-0.03984c0.3113 1.6096 0.82413 2.5137 1.6335 3.1474z" fill="url(#b)" stroke="#000" stroke-width=".5"/> + <path d="m73.89 24.04 28.885-0.2011-0.12476 3.3879-31.033 0.16229c1.2621-1.0234 1.9665-2.2859 2.2724-3.3491z" fill="url(#c)" stroke="#000" stroke-width=".41788"/> + </g> +</svg> diff --git a/ld_client/doc/pdoc/dynsections.js b/ld_client/doc/pdoc/dynsections.js new file mode 100644 index 0000000..3174bd7 --- /dev/null +++ b/ld_client/doc/pdoc/dynsections.js @@ -0,0 +1,121 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l<level+1) { + i.removeClass('iconfopen iconfclosed').addClass('iconfopen'); + a.html('▼'); + $(this).show(); + } else if (l==level+1) { + i.removeClass('iconfclosed iconfopen').addClass('iconfclosed'); + a.html('►'); + $(this).show(); + } else { + $(this).hide(); + } + }); + updateStripes(); +} + +function toggleFolder(id) +{ + // the clicked row + var currentRow = $('#row_'+id); + + // all rows after the clicked row + var rows = currentRow.nextAll("tr"); + + var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub + + // only match elements AFTER this one (can't hide elements before) + var childRows = rows.filter(function() { return this.id.match(re); }); + + // first row is visible we are HIDING + if (childRows.filter(':first').is(':visible')===true) { + // replace down arrow by right arrow for current row + var currentRowSpans = currentRow.find("span"); + currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed"); + currentRowSpans.filter(".arrow").html('►'); + rows.filter("[id^=row_"+id+"]").hide(); // hide all children + } else { // we are SHOWING + // replace right arrow by down arrow for current row + var currentRowSpans = currentRow.find("span"); + currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen"); + currentRowSpans.filter(".arrow").html('▼'); + // replace down arrows by right arrows for child rows + var childRowsSpans = childRows.find("span"); + childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed"); + childRowsSpans.filter(".arrow").html('►'); + childRows.show(); //show all children + } + updateStripes(); +} + + +function toggleInherit(id) +{ + var rows = $('tr.inherit.'+id); + var img = $('tr.inherit_header.'+id+' img'); + var src = $(img).attr('src'); + if (rows.filter(':first').is(':visible')===true) { + rows.css('display','none'); + $(img).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + rows.css('display','table-row'); // using show() causes jump in firefox + $(img).attr('src',src.substring(0,src.length-10)+'open.png'); + } +} +/* @license-end */ diff --git a/ld_client/doc/pdoc/folderclosed.png b/ld_client/doc/pdoc/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)<h;3K|Lk000e1NJLTq000;O000&U1^@s6+I?Jz0006nNkl<ZcmeHQ zO;6N77=GINb=Z(>a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM<n!c> zlFX`g{k$X}yIe%$N)cn1LNu=q<K5OS7CNKPk1f&9-+dXiicCfAy8a*|m;2$mAHWmO zXHGi+kV1-pHt+rM<gA>9_CS)*<?(PP8<}W6a5(^^keLBRMb50K&dQM@pmn94ZU=xQ zQX)TlxfVQ_9);_LB~VUu;v|U_-?p*(;VWJ|=^7%ZGN6sBL~)dHv|OyK(wPKdmH>>A zsX_mM4<gjHpqc8Q=uo450T?4i;CdW;`z|<XAntIp>L@`(cSNQKMFc$RtYbx{79<Tw zWXi-A43v#7I@t_Ijx7TKV2n(H{k|uniNrjlLmWw}y*t^*R9a-QX?;6B==9%$de=Kk z*QYpi761&SjtX%clomR5cK>#j-J7hk*>*+ZZhM4Hw?<fJyv$}=71o`ou(^pUn-ky6 z->I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000<MNUMnLSTaR CZX#j; literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/folderopen.png b/ld_client/doc/pdoc/folderopen.png new file mode 100644 index 0000000000000000000000000000000000000000..d6c7f676a3b3ef8c2c307d319dff3c6a604eb227 GIT binary patch literal 597 zcmV-b0;>IqP)<h;3K|Lk000e1NJLTq000;O000&U1^@s6+I?Jz0006UNkl<ZcmeHQ zKX21e5dS%8nlx#!9XpK>X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgY<a!3GSVHw98r3tc|WLmCr=#k@b07--d0B^h;_*7huEOe@B5HbiIMnQNV2X-w6 zOrIHW*Nh!-3RJ{NFA7|xb7mLqy*mtQR%uj&==!8@USn{@{Ji@c`@7F#U6jIrqNF?z zhGG8IoU)VO(*u}!lcNr&IgdJw?)fXgkFy?t@!%{)3!Y}PHt9|Ph>gTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/functions.html b/ld_client/doc/pdoc/functions.html new file mode 100644 index 0000000..e5d185c --- /dev/null +++ b/ld_client/doc/pdoc/functions.html @@ -0,0 +1,189 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Class Members</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('functions.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="contents"> +<div class="textblock">Here is a list of all documented class members with links to the class documentation for each member:</div> + +<h3><a id="index__5F" name="index__5F"></a>- _ -</h3><ul> +<li>_client : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d">LDClient.network.ApiClient</a></li> +</ul> + + +<h3><a id="index_a" name="index_a"></a>- a -</h3><ul> +<li>ALogger() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">LDClient.utils.loggers.ALogger</a></li> +<li>ApiClient() : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">LDClient.network.ApiClient</a></li> +</ul> + + +<h3><a id="index_b" name="index_b"></a>- b -</h3><ul> +<li>BodyDevice : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208">LDClient.network.data.Payload</a></li> +<li>BodySerialNumber : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">LDClient.detection.InfoFetcher</a></li> +</ul> + + +<h3><a id="index_c" name="index_c"></a>- c -</h3><ul> +<li>ClientRunning : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1">LDClient.network.ApiClient</a></li> +<li>ComposeLogRow() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">LDClient.utils.loggers.ALogger</a></li> +<li>CreateLog() : <a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">FileLogger</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">LDClient.utils.loggers.ConsoleLogger</a></li> +<li>Current : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">LDClient.utils.loggers.ALogger</a></li> +</ul> + + +<h3><a id="index_d" name="index_d"></a>- d -</h3><ul> +<li>Debug() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">LDClient.utils.loggers.ALogger</a></li> +<li>DetectionRunning : <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6">LDClient.detection.ProcessDetection</a></li> +<li>Dispose() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">LDClient.utils.loggers.ALogger</a></li> +</ul> + + +<h3><a id="index_e" name="index_e"></a>- e -</h3><ul> +<li>Error() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">LDClient.utils.loggers.ALogger</a></li> +<li>ExecuteNewProcess() : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">LDClient.detection.ProcessUtils</a></li> +</ul> + + +<h3><a id="index_f" name="index_f"></a>- f -</h3><ul> +<li>FetchDataAsync() : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">LDClient.detection.InfoFetcher</a></li> +<li>FileUtils : <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140">LDClient.detection.InfoFetcher</a></li> +<li>Flush() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">LDClient.utils.loggers.ALogger</a></li> +</ul> + + +<h3><a id="index_h" name="index_h"></a>- h -</h3><ul> +<li>HeadDevice : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5">LDClient.network.data.Payload</a></li> +<li>HeadSerialNumber : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">LDClient.detection.InfoFetcher</a></li> +<li>HostName : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72">LDClient.network.data.Payload</a></li> +<li>HttpClient() : <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">LDClient.network.HttpClient</a></li> +</ul> + + +<h3><a id="index_i" name="index_i"></a>- i -</h3><ul> +<li>Info() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">LDClient.utils.loggers.ALogger</a></li> +<li>InfoFetcher() : <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">LDClient.detection.InfoFetcher</a></li> +<li>IsProcessRunning() : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">LDClient.detection.ProcessUtils</a></li> +</ul> + + +<h3><a id="index_p" name="index_p"></a>- p -</h3><ul> +<li>ParseToJson() : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">LDClient.network.data.Payload</a></li> +<li>PostAsJsonAsync() : <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">LDClient.network.HttpClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">LDClient.network.IHttpClient</a></li> +<li>ProcessDetection() : <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">LDClient.detection.ProcessDetection</a></li> +<li>ProcessUtils : <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8">LDClient.detection.InfoFetcher</a></li> +</ul> + + +<h3><a id="index_r" name="index_r"></a>- r -</h3><ul> +<li>ReadFileAllLines() : <a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">LDClient.utils.FileUtils</a>, <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">LDClient.utils.IFileUtils</a></li> +<li>Run() : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">LDClient.network.IApiClient</a></li> +<li>RunPeriodicDetection() : <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8">LDClient.detection.ProcessDetection</a></li> +</ul> + + +<h3><a id="index_s" name="index_s"></a>- s -</h3><ul> +<li>SendPayloadAsync() : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">LDClient.network.IApiClient</a></li> +<li>SerialNumber : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb">LDClient.network.data.DebuggerInfo</a></li> +<li>Status : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481">LDClient.network.data.Payload</a></li> +</ul> + + +<h3><a id="index_t" name="index_t"></a>- t -</h3><ul> +<li>TimeStamp : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297">LDClient.network.data.Payload</a></li> +<li>ToString() : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">LDClient.network.data.Payload</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">LDClient.utils.loggers.ALogger</a></li> +</ul> + + +<h3><a id="index_u" name="index_u"></a>- u -</h3><ul> +<li>UnwrapExceptionMessages() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">LDClient.utils.loggers.ALogger</a></li> +<li>UserName : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65">LDClient.network.data.Payload</a></li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/functions_func.html b/ld_client/doc/pdoc/functions_func.html new file mode 100644 index 0000000..044f868 --- /dev/null +++ b/ld_client/doc/pdoc/functions_func.html @@ -0,0 +1,166 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Class Members - Functions</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('functions_func.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="contents"> +  + +<h3><a id="index_a" name="index_a"></a>- a -</h3><ul> +<li>ALogger() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">LDClient.utils.loggers.ALogger</a></li> +<li>ApiClient() : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">LDClient.network.ApiClient</a></li> +</ul> + + +<h3><a id="index_c" name="index_c"></a>- c -</h3><ul> +<li>ComposeLogRow() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">LDClient.utils.loggers.ALogger</a></li> +<li>CreateLog() : <a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">FileLogger</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">LDClient.utils.loggers.ConsoleLogger</a></li> +</ul> + + +<h3><a id="index_d" name="index_d"></a>- d -</h3><ul> +<li>Debug() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">LDClient.utils.loggers.ALogger</a></li> +<li>Dispose() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">LDClient.utils.loggers.ALogger</a></li> +</ul> + + +<h3><a id="index_e" name="index_e"></a>- e -</h3><ul> +<li>Error() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">LDClient.utils.loggers.ALogger</a></li> +<li>ExecuteNewProcess() : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">LDClient.detection.ProcessUtils</a></li> +</ul> + + +<h3><a id="index_f" name="index_f"></a>- f -</h3><ul> +<li>FetchDataAsync() : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">LDClient.detection.InfoFetcher</a></li> +<li>Flush() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">LDClient.utils.loggers.ALogger</a></li> +</ul> + + +<h3><a id="index_h" name="index_h"></a>- h -</h3><ul> +<li>HttpClient() : <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">LDClient.network.HttpClient</a></li> +</ul> + + +<h3><a id="index_i" name="index_i"></a>- i -</h3><ul> +<li>Info() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">LDClient.utils.loggers.ALogger</a></li> +<li>InfoFetcher() : <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">LDClient.detection.InfoFetcher</a></li> +<li>IsProcessRunning() : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">LDClient.detection.ProcessUtils</a></li> +</ul> + + +<h3><a id="index_p" name="index_p"></a>- p -</h3><ul> +<li>ParseToJson() : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">LDClient.network.data.Payload</a></li> +<li>PostAsJsonAsync() : <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">LDClient.network.HttpClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">LDClient.network.IHttpClient</a></li> +<li>ProcessDetection() : <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">LDClient.detection.ProcessDetection</a></li> +</ul> + + +<h3><a id="index_r" name="index_r"></a>- r -</h3><ul> +<li>ReadFileAllLines() : <a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">LDClient.utils.FileUtils</a>, <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">LDClient.utils.IFileUtils</a></li> +<li>Run() : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">LDClient.network.IApiClient</a></li> +<li>RunPeriodicDetection() : <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8">LDClient.detection.ProcessDetection</a></li> +</ul> + + +<h3><a id="index_s" name="index_s"></a>- s -</h3><ul> +<li>SendPayloadAsync() : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">LDClient.network.IApiClient</a></li> +</ul> + + +<h3><a id="index_t" name="index_t"></a>- t -</h3><ul> +<li>ToString() : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">LDClient.network.data.Payload</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">LDClient.utils.loggers.ALogger</a></li> +</ul> + + +<h3><a id="index_u" name="index_u"></a>- u -</h3><ul> +<li>UnwrapExceptionMessages() : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">LDClient.utils.loggers.ALogger</a></li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/functions_prop.html b/ld_client/doc/pdoc/functions_prop.html new file mode 100644 index 0000000..e899b21 --- /dev/null +++ b/ld_client/doc/pdoc/functions_prop.html @@ -0,0 +1,107 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Class Members - Properties</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('functions_prop.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="contents"> + <ul> +<li>BodyDevice : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208">LDClient.network.data.Payload</a></li> +<li>BodySerialNumber : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">LDClient.detection.InfoFetcher</a></li> +<li>Current : <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">LDClient.utils.loggers.ALogger</a></li> +<li>HeadDevice : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5">LDClient.network.data.Payload</a></li> +<li>HeadSerialNumber : <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">LDClient.detection.InfoFetcher</a></li> +<li>HostName : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72">LDClient.network.data.Payload</a></li> +<li>SerialNumber : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb">LDClient.network.data.DebuggerInfo</a></li> +<li>Status : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481">LDClient.network.data.Payload</a></li> +<li>TimeStamp : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297">LDClient.network.data.Payload</a></li> +<li>UserName : <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65">LDClient.network.data.Payload</a></li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/functions_vars.html b/ld_client/doc/pdoc/functions_vars.html new file mode 100644 index 0000000..77d1832 --- /dev/null +++ b/ld_client/doc/pdoc/functions_vars.html @@ -0,0 +1,102 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Class Members - Variables</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('functions_vars.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="contents"> + <ul> +<li>_client : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d">LDClient.network.ApiClient</a></li> +<li>ClientRunning : <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1">LDClient.network.ApiClient</a></li> +<li>DetectionRunning : <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6">LDClient.detection.ProcessDetection</a></li> +<li>FileUtils : <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140">LDClient.detection.InfoFetcher</a></li> +<li>ProcessUtils : <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8">LDClient.detection.InfoFetcher</a></li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/hierarchy.html b/ld_client/doc/pdoc/hierarchy.html new file mode 100644 index 0000000..9a563d1 --- /dev/null +++ b/ld_client/doc/pdoc/hierarchy.html @@ -0,0 +1,120 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Class Hierarchy</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('hierarchy.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">Class Hierarchy</div></div> +</div><!--header--> +<div class="contents"> +<div class="textblock">This inheritance list is sorted roughly, but not completely, alphabetically:</div><div class="directory"> +<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span>]</div><table class="directory"> +<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">▼</span><span class="icona"><span class="icon">C</span></span><b>ALogger</b></td><td class="desc"></td></tr> +<tr id="row_0_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_file_logger.html" target="_self">FileLogger</a></td><td class="desc"></td></tr> +<tr id="row_1_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html" target="_self">LDClient.network.data.DebuggerInfo</a></td><td class="desc">This class holds all the information about a specific part of a debugger (head/body). </td></tr> +<tr id="row_2_"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_2_" class="arrow" onclick="toggleFolder('2_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" target="_self">LDClient.network.IApiClient</a></td><td class="desc">This interface defines the functionality of an API client which is used to send information (payloads) to the server. </td></tr> +<tr id="row_2_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html" target="_self">LDClient.network.ApiClient</a></td><td class="desc">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </td></tr> +<tr id="row_3_"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_3_" class="arrow" onclick="toggleFolder('3_')">▼</span><span class="icona"><span class="icon">C</span></span><b>IDisposable</b></td><td class="desc"></td></tr> +<tr id="row_3_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_3_0_" class="arrow" onclick="toggleFolder('3_0_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html" target="_self">LDClient.utils.loggers.ALogger</a></td><td class="desc">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </td></tr> +<tr id="row_3_0_0_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html" target="_self">LDClient.utils.loggers.ConsoleLogger</a></td><td class="desc"></td></tr> +<tr id="row_4_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_4_" class="arrow" onclick="toggleFolder('4_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" target="_self">LDClient.utils.IFileUtils</a></td><td class="desc">This interface defines IO operations. </td></tr> +<tr id="row_4_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html" target="_self">LDClient.utils.FileUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </td></tr> +<tr id="row_5_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_5_" class="arrow" onclick="toggleFolder('5_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" target="_self">LDClient.network.IHttpClient</a></td><td class="desc">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </td></tr> +<tr id="row_5_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html" target="_self">LDClient.network.HttpClient</a></td><td class="desc">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </td></tr> +<tr id="row_6_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_6_" class="arrow" onclick="toggleFolder('6_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" target="_self">LDClient.detection.IInfoFetcher</a></td><td class="desc">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </td></tr> +<tr id="row_6_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" target="_self">LDClient.detection.InfoFetcher</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </td></tr> +<tr id="row_7_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_7_" class="arrow" onclick="toggleFolder('7_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" target="_self">LDClient.detection.IProcessUtils</a></td><td class="desc">This interface defines the functionality of all methods that are used to work with processes (within this project). </td></tr> +<tr id="row_7_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" target="_self">LDClient.detection.ProcessUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </td></tr> +<tr id="row_8_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html" target="_self">LDClient.network.data.Payload</a></td><td class="desc">This class represents a single payload that is sent to the server. </td></tr> +<tr id="row_9_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html" target="_self">LDClient.detection.ProcessDetection</a></td><td class="desc">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </td></tr> +</table> +</div><!-- directory --> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/hierarchy.js b/ld_client/doc/pdoc/hierarchy.js new file mode 100644 index 0000000..9ffe682 --- /dev/null +++ b/ld_client/doc/pdoc/hierarchy.js @@ -0,0 +1,29 @@ +var hierarchy = +[ + [ "ALogger", null, [ + [ "FileLogger", "class_file_logger.html", null ] + ] ], + [ "LDClient.network.data.DebuggerInfo", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html", null ], + [ "LDClient.network.IApiClient", "interface_l_d_client_1_1network_1_1_i_api_client.html", [ + [ "LDClient.network.ApiClient", "class_l_d_client_1_1network_1_1_api_client.html", null ] + ] ], + [ "IDisposable", null, [ + [ "LDClient.utils.loggers.ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html", [ + [ "LDClient.utils.loggers.ConsoleLogger", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html", null ] + ] ] + ] ], + [ "LDClient.utils.IFileUtils", "interface_l_d_client_1_1utils_1_1_i_file_utils.html", [ + [ "LDClient.utils.FileUtils", "class_l_d_client_1_1utils_1_1_file_utils.html", null ] + ] ], + [ "LDClient.network.IHttpClient", "interface_l_d_client_1_1network_1_1_i_http_client.html", [ + [ "LDClient.network.HttpClient", "class_l_d_client_1_1network_1_1_http_client.html", null ] + ] ], + [ "LDClient.detection.IInfoFetcher", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html", [ + [ "LDClient.detection.InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html", null ] + ] ], + [ "LDClient.detection.IProcessUtils", "interface_l_d_client_1_1detection_1_1_i_process_utils.html", [ + [ "LDClient.detection.ProcessUtils", "class_l_d_client_1_1detection_1_1_process_utils.html", null ] + ] ], + [ "LDClient.network.data.Payload", "class_l_d_client_1_1network_1_1data_1_1_payload.html", null ], + [ "LDClient.detection.ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/index.html b/ld_client/doc/pdoc/index.html new file mode 100644 index 0000000..c018938 --- /dev/null +++ b/ld_client/doc/pdoc/index.html @@ -0,0 +1,98 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Main Page</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('index.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient Documentation</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html new file mode 100644 index 0000000..c5ee33f --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html @@ -0,0 +1,104 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.detection.IInfoFetcher Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">BodySerialNumber</a></td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">FetchDataAsync</a>()</td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td><td class="entry"></td></tr> + <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">HeadSerialNumber</a></td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html new file mode 100644 index 0000000..30955ae --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html @@ -0,0 +1,203 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.detection.IInfoFetcher Interface Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="#properties">Properties</a> | +<a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.detection.IInfoFetcher Interface Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. + <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memItemLeft" align="right" valign="top">Task< bool > </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">FetchDataAsync</a> ()</td></tr> +<tr class="memdesc:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="mdescLeft"> </td><td class="mdescRight">Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers). <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">More...</a><br /></td></tr> +<tr class="separator:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a> +Properties</h2></td></tr> +<tr class="memitem:a196620b51706ff95e86dce886bd3d3a0"><td class="memItemLeft" align="right" valign="top">string </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">HeadSerialNumber</a><code> [get, set]</code></td></tr> +<tr class="memdesc:a196620b51706ff95e86dce886bd3d3a0"><td class="mdescLeft"> </td><td class="mdescRight">Returns the head serial number of the debugger. <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">More...</a><br /></td></tr> +<tr class="separator:a196620b51706ff95e86dce886bd3d3a0"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:afff68b22c92585ba9169cd558bcb66b9"><td class="memItemLeft" align="right" valign="top">string </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">BodySerialNumber</a><code> [get, set]</code></td></tr> +<tr class="memdesc:afff68b22c92585ba9169cd558bcb66b9"><td class="mdescLeft"> </td><td class="mdescRight">Returns the body serial number of the debugger. <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">More...</a><br /></td></tr> +<tr class="separator:afff68b22c92585ba9169cd558bcb66b9"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="a115b4d4fb74bd4eb09d8eeb4716793f9" name="a115b4d4fb74bd4eb09d8eeb4716793f9"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a115b4d4fb74bd4eb09d8eeb4716793f9">◆ </a></span>FetchDataAsync()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">Task< bool > LDClient.detection.IInfoFetcher.FetchDataAsync </td> + <td>(</td> + <td class="paramname"></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers). </p> +<dl class="section return"><dt>Returns</dt><dd>True, if data was fetched successfully. False otherwise.</dd></dl> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">LDClient.detection.InfoFetcher</a>.</p> + +</div> +</div> +<h2 class="groupheader">Property Documentation</h2> +<a id="afff68b22c92585ba9169cd558bcb66b9" name="afff68b22c92585ba9169cd558bcb66b9"></a> +<h2 class="memtitle"><span class="permalink"><a href="#afff68b22c92585ba9169cd558bcb66b9">◆ </a></span>BodySerialNumber</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">string LDClient.detection.IInfoFetcher.BodySerialNumber</td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Returns the body serial number of the debugger. </p> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">LDClient.detection.InfoFetcher</a>.</p> + +</div> +</div> +<a id="a196620b51706ff95e86dce886bd3d3a0" name="a196620b51706ff95e86dce886bd3d3a0"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a196620b51706ff95e86dce886bd3d3a0">◆ </a></span>HeadSerialNumber</h2> + +<div class="memitem"> +<div class="memproto"> +<table class="mlabels"> + <tr> + <td class="mlabels-left"> + <table class="memname"> + <tr> + <td class="memname">string LDClient.detection.IInfoFetcher.HeadSerialNumber</td> + </tr> + </table> + </td> + <td class="mlabels-right"> +<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span> </td> + </tr> +</table> +</div><div class="memdoc"> + +<p>Returns the head serial number of the debugger. </p> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">LDClient.detection.InfoFetcher</a>.</p> + +</div> +</div> +<hr/>The documentation for this interface was generated from the following file:<ul> +<li>detection/IInfoFetcher.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js new file mode 100644 index 0000000..5838d30 --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js @@ -0,0 +1,6 @@ +var interface_l_d_client_1_1detection_1_1_i_info_fetcher = +[ + [ "FetchDataAsync", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9", null ], + [ "BodySerialNumber", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9", null ], + [ "HeadSerialNumber", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html new file mode 100644 index 0000000..8058f80 --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html @@ -0,0 +1,103 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_process_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.detection.IProcessUtils Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">LDClient.detection.IProcessUtils</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">ExecuteNewProcess</a>(string fileName, string argument, int timeout, int desiredExitCode)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">LDClient.detection.IProcessUtils</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">IsProcessRunning</a>(string name)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">LDClient.detection.IProcessUtils</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html new file mode 100644 index 0000000..24e7373 --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html @@ -0,0 +1,204 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.detection.IProcessUtils Interface Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_process_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="interface_l_d_client_1_1detection_1_1_i_process_utils-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.detection.IProcessUtils Interface Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This interface defines the functionality of all methods that are used to work with processes (within this project). + <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">IsProcessRunning</a> (string name)</td></tr> +<tr class="memdesc:ad86c09b9bd71f7087ada92851b07e1a0"><td class="mdescLeft"> </td><td class="mdescRight">Checks if a process is running or not. <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">More...</a><br /></td></tr> +<tr class="separator:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ab7e48a228ebaf7dddc671e5af2325662"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">ExecuteNewProcess</a> (string fileName, string argument, int timeout, int desiredExitCode)</td></tr> +<tr class="memdesc:ab7e48a228ebaf7dddc671e5af2325662"><td class="mdescLeft"> </td><td class="mdescRight">Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method. <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">More...</a><br /></td></tr> +<tr class="separator:ab7e48a228ebaf7dddc671e5af2325662"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This interface defines the functionality of all methods that are used to work with processes (within this project). </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="ab7e48a228ebaf7dddc671e5af2325662" name="ab7e48a228ebaf7dddc671e5af2325662"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ab7e48a228ebaf7dddc671e5af2325662">◆ </a></span>ExecuteNewProcess()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">bool LDClient.detection.IProcessUtils.ExecuteNewProcess </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>fileName</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">string </td> + <td class="paramname"><em>argument</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">int </td> + <td class="paramname"><em>timeout</em>, </td> + </tr> + <tr> + <td class="paramkey"></td> + <td></td> + <td class="paramtype">int </td> + <td class="paramname"><em>desiredExitCode</em> </td> + </tr> + <tr> + <td></td> + <td>)</td> + <td></td><td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">fileName</td><td>Path to the .exe file</td></tr> + <tr><td class="paramname">argument</td><td>Arguments passed into the .exe file</td></tr> + <tr><td class="paramname">timeout</td><td>Timeout used when waiting for the process to terminate</td></tr> + <tr><td class="paramname">desiredExitCode</td><td>Status code indicating a successful termination of the process.</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd>True, if the command was executed successfully. False otherwise.</dd></dl> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">LDClient.detection.ProcessUtils</a>.</p> + +</div> +</div> +<a id="ad86c09b9bd71f7087ada92851b07e1a0" name="ad86c09b9bd71f7087ada92851b07e1a0"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ad86c09b9bd71f7087ada92851b07e1a0">◆ </a></span>IsProcessRunning()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">bool LDClient.detection.IProcessUtils.IsProcessRunning </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>name</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Checks if a process is running or not. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">name</td><td>Name of the process</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd>True, if the process is running. False otherwise.</dd></dl> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">LDClient.detection.ProcessUtils</a>.</p> + +</div> +</div> +<hr/>The documentation for this interface was generated from the following file:<ul> +<li>detection/IProcessUtils.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js new file mode 100644 index 0000000..481e8ab --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js @@ -0,0 +1,5 @@ +var interface_l_d_client_1_1detection_1_1_i_process_utils = +[ + [ "ExecuteNewProcess", "interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662", null ], + [ "IsProcessRunning", "interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html new file mode 100644 index 0000000..dab2bcc --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html @@ -0,0 +1,103 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_api_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.network.IApiClient Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">LDClient.network.IApiClient</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">Run</a>()</td><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">LDClient.network.IApiClient</a></td><td class="entry"></td></tr> + <tr class="odd"><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">SendPayloadAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">LDClient.network.IApiClient</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html new file mode 100644 index 0000000..e333b90 --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html @@ -0,0 +1,170 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network.IApiClient Interface Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_api_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="interface_l_d_client_1_1network_1_1_i_api_client-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.network.IApiClient Interface Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This interface defines the functionality of an API client which is used to send information (payloads) to the server. + <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memItemLeft" align="right" valign="top">Task </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">SendPayloadAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr> +<tr class="memdesc:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="mdescLeft"> </td><td class="mdescRight">Sends a payload to the server (API). <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">More...</a><br /></td></tr> +<tr class="separator:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">Run</a> ()</td></tr> +<tr class="memdesc:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="mdescLeft"> </td><td class="mdescRight">Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread. <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">More...</a><br /></td></tr> +<tr class="separator:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This interface defines the functionality of an API client which is used to send information (payloads) to the server. </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="ab668a6e4e3f1d219c38f5e323d8735cb" name="ab668a6e4e3f1d219c38f5e323d8735cb"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ab668a6e4e3f1d219c38f5e323d8735cb">◆ </a></span>Run()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">void LDClient.network.IApiClient.Run </td> + <td>(</td> + <td class="paramname"></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread. </p> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">LDClient.network.ApiClient</a>.</p> + +</div> +</div> +<a id="a8edc6823e4fb6f476a88af2da18e3b7f" name="a8edc6823e4fb6f476a88af2da18e3b7f"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a8edc6823e4fb6f476a88af2da18e3b7f">◆ </a></span>SendPayloadAsync()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">Task LDClient.network.IApiClient.SendPayloadAsync </td> + <td>(</td> + <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> </td> + <td class="paramname"><em>payload</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Sends a payload to the server (API). </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">payload</td><td>instance of a payload to be sent off to the server</td></tr> + </table> + </dd> +</dl> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">LDClient.network.ApiClient</a>.</p> + +</div> +</div> +<hr/>The documentation for this interface was generated from the following file:<ul> +<li>network/IApiClient.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js new file mode 100644 index 0000000..2cb6345 --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js @@ -0,0 +1,5 @@ +var interface_l_d_client_1_1network_1_1_i_api_client = +[ + [ "Run", "interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb", null ], + [ "SendPayloadAsync", "interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html new file mode 100644 index 0000000..57a319d --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html @@ -0,0 +1,102 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_http_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.network.IHttpClient Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">LDClient.network.IHttpClient</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">PostAsJsonAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">LDClient.network.IHttpClient</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html new file mode 100644 index 0000000..c09212a --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html @@ -0,0 +1,147 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network.IHttpClient Interface Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_http_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="interface_l_d_client_1_1network_1_1_i_http_client-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.network.IHttpClient Interface Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. + <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:a241d7baceaf176b341c46844e235bd0f"><td class="memItemLeft" align="right" valign="top">Task< HttpResponseMessage > </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">PostAsJsonAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr> +<tr class="memdesc:a241d7baceaf176b341c46844e235bd0f"><td class="mdescLeft"> </td><td class="mdescRight">Asynchronically sends data in JSON format to the server. <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">More...</a><br /></td></tr> +<tr class="separator:a241d7baceaf176b341c46844e235bd0f"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="a241d7baceaf176b341c46844e235bd0f" name="a241d7baceaf176b341c46844e235bd0f"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a241d7baceaf176b341c46844e235bd0f">◆ </a></span>PostAsJsonAsync()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">Task< HttpResponseMessage > LDClient.network.IHttpClient.PostAsJsonAsync </td> + <td>(</td> + <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> </td> + <td class="paramname"><em>payload</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Asynchronically sends data in JSON format to the server. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">payload</td><td>Payload to be sent to the server</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd></dd></dl> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">LDClient.network.HttpClient</a>.</p> + +</div> +</div> +<hr/>The documentation for this interface was generated from the following file:<ul> +<li>network/IHttpClient.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js new file mode 100644 index 0000000..3786abf --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js @@ -0,0 +1,4 @@ +var interface_l_d_client_1_1network_1_1_i_http_client = +[ + [ "PostAsJsonAsync", "interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html new file mode 100644 index 0000000..1938d06 --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html @@ -0,0 +1,102 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Member List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1utils_1_1_i_file_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient.utils.IFileUtils Member List</div></div> +</div><!--header--> +<div class="contents"> + +<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">LDClient.utils.IFileUtils</a>, including all inherited members.</p> +<table class="directory"> + <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">ReadFileAllLines</a>(string file)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">LDClient.utils.IFileUtils</a></td><td class="entry"></td></tr> +</table></div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html new file mode 100644 index 0000000..dd550a8 --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html @@ -0,0 +1,147 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.utils.IFileUtils Interface Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('interface_l_d_client_1_1utils_1_1_i_file_utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#pub-methods">Public Member Functions</a> | +<a href="interface_l_d_client_1_1utils_1_1_i_file_utils-members.html">List of all members</a> </div> + <div class="headertitle"><div class="title">LDClient.utils.IFileUtils Interface Reference</div></div> +</div><!--header--> +<div class="contents"> + +<p>This interface defines IO operations. + <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#details">More...</a></p> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a> +Public Member Functions</h2></td></tr> +<tr class="memitem:ae4d668d0e5850831680c8793cecd89a3"><td class="memItemLeft" align="right" valign="top">string[] </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">ReadFileAllLines</a> (string file)</td></tr> +<tr class="memdesc:ae4d668d0e5850831680c8793cecd89a3"><td class="mdescLeft"> </td><td class="mdescRight">Reads all lines of a files and returns them as a array. <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">More...</a><br /></td></tr> +<tr class="separator:ae4d668d0e5850831680c8793cecd89a3"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> +<div class="textblock"><p >This interface defines IO operations. </p> +</div><h2 class="groupheader">Member Function Documentation</h2> +<a id="ae4d668d0e5850831680c8793cecd89a3" name="ae4d668d0e5850831680c8793cecd89a3"></a> +<h2 class="memtitle"><span class="permalink"><a href="#ae4d668d0e5850831680c8793cecd89a3">◆ </a></span>ReadFileAllLines()</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">string[] LDClient.utils.IFileUtils.ReadFileAllLines </td> + <td>(</td> + <td class="paramtype">string </td> + <td class="paramname"><em>file</em></td><td>)</td> + <td></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>Reads all lines of a files and returns them as a array. </p> +<dl class="params"><dt>Parameters</dt><dd> + <table class="params"> + <tr><td class="paramname">file</td><td>path to the file</td></tr> + </table> + </dd> +</dl> +<dl class="section return"><dt>Returns</dt><dd>all the lines of the file (as an array)</dd></dl> + +<p>Implemented in <a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">LDClient.utils.FileUtils</a>.</p> + +</div> +</div> +<hr/>The documentation for this interface was generated from the following file:<ul> +<li>utils/IFileUtils.cs</li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js new file mode 100644 index 0000000..a033d8b --- /dev/null +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js @@ -0,0 +1,4 @@ +var interface_l_d_client_1_1utils_1_1_i_file_utils = +[ + [ "ReadFileAllLines", "interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3", null ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/jquery.js b/ld_client/doc/pdoc/jquery.js new file mode 100644 index 0000000..c9ed3d9 --- /dev/null +++ b/ld_client/doc/pdoc/jquery.js @@ -0,0 +1,35 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(j).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var D,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ee(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,we)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Se(this,e,Ce),!1},trigger:function(){return Se(this,e),!0},_default:function(){return!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return Ee(this,e,t,n,r)},one:function(e,t,n,r){return Ee(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){S.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,Ne=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),De)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(Ne,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Me=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ie=new RegExp(ne.join("|"),"i");function We(e,t,n){var r,i,o,a,s=e.style;return(n=n||Re(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Pe.test(a)&&Ie.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Fe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var Be=["Webkit","Moz","ms"],$e=E.createElement("div").style,_e={};function ze(e){var t=S.cssProps[e]||_e[e];return t||(e in $e?e:_e[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Be.length;while(n--)if((e=Be[n]+t)in $e)return e}(e)||e)}var Ue=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ve={position:"absolute",visibility:"hidden",display:"block"},Ge={letterSpacing:"0",fontWeight:"400"};function Ye(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Qe(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Je(e,t,n){var r=Re(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=We(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Qe(e,t,n||(i?"border":"content"),o,r,a)+"px"}function Ke(e,t,n,r,i){return new Ke.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=We(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Xe.test(t),l=e.style;if(u||(t=ze(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Xe.test(t)||(t=ze(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=We(e,t,r)),"normal"===i&&t in Ge&&(i=Ge[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ue.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,u,n):Me(e,Ve,function(){return Je(e,u,n)})},set:function(e,t,n){var r,i=Re(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Qe(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Qe(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Ye(0,t,s)}}}),S.cssHooks.marginLeft=Fe(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(We(e,"marginLeft"))||e.getBoundingClientRect().left-Me(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Ye)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Re(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=Ke).prototype={constructor:Ke,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=Ke.propHooks[this.prop];return e&&e.get?e.get(this):Ke.propHooks._default.get(this)},run:function(e){var t,n=Ke.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ke.propHooks._default.set(this),this}}).init.prototype=Ke.prototype,(Ke.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[ze(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=Ke.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=Ke.prototype.init,S.fx.step={};var Ze,et,tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){et&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(ot):C.setTimeout(ot,S.fx.interval),S.fx.tick())}function at(){return C.setTimeout(function(){Ze=void 0}),Ze=Date.now()}function st(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ut(e,t,n){for(var r,i=(lt.tweeners[t]||[]).concat(lt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function lt(o,e,t){var n,a,r=0,i=lt.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=Ze||at(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:Ze||at(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=lt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ut,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(lt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],lt.tweeners[n]=lt.tweeners[n]||[],lt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],rt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ut(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?lt.prefilters.unshift(e):lt.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=lt(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&it.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(st(r,!0),e,t,n)}}),S.each({slideDown:st("show"),slideUp:st("hide"),slideToggle:st("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(Ze=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),Ze=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){et||(et=!0,ot())},S.fx.stop=function(){et=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},tt=E.createElement("input"),nt=E.createElement("select").appendChild(E.createElement("option")),tt.type="checkbox",y.checkOn=""!==tt.value,y.optSelected=nt.selected,(tt=E.createElement("input")).value="t",tt.type="radio",y.radioValue="t"===tt.value;var ct,ft=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=ft[t]||S.find.attr;ft[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=ft[o],ft[o]=r,r=null!=a(e,t,n)?o:null,ft[o]=i),r}});var pt=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;function ht(e){return(e.match(P)||[]).join(" ")}function gt(e){return e.getAttribute&&e.getAttribute("class")||""}function vt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):pt.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,gt(this)))});if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,gt(this)))});if(!arguments.length)return this.attr("class","");if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,gt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=vt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=gt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+ht(gt(n))+" ").indexOf(t))return!0;return!1}});var yt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(yt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:ht(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var mt=/^(?:focusinfocus|focusoutblur)$/,xt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!mt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,mt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,xt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,xt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var bt=C.location,wt={guid:Date.now()},Tt=/\?/;S.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||S.error("Invalid XML: "+(n?S.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var Ct=/\[\]$/,Et=/\r?\n/g,St=/^(?:submit|button|image|reset|file)$/i,kt=/^(?:input|select|textarea|keygen)/i;function At(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||Ct.test(n)?i(n,t):At(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)At(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)At(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&kt.test(this.nodeName)&&!St.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(Et,"\r\n")}}):{name:t.name,value:n.replace(Et,"\r\n")}}).get()}});var Nt=/%20/g,jt=/#.*$/,Dt=/([?&])_=[^&]*/,qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Lt=/^(?:GET|HEAD)$/,Ht=/^\/\//,Ot={},Pt={},Rt="*/".concat("*"),Mt=E.createElement("a");function It(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Wt(t,i,o,a){var s={},u=t===Pt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Ft(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Mt.href=bt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:bt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(bt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Rt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ft(Ft(e,S.ajaxSettings),t):Ft(S.ajaxSettings,e)},ajaxPrefilter:It(Ot),ajaxTransport:It(Pt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=qt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||bt.href)+"").replace(Ht,bt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Mt.protocol+"//"+Mt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Wt(Ot,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Lt.test(v.type),f=v.url.replace(jt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Nt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Tt.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Dt,"$1"),o=(Tt.test(f)?"&":"?")+"_="+wt.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+Rt+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Wt(Pt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&S.inArray("json",v.dataTypes)<0&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Bt={0:200,1223:204},$t=S.ajaxSettings.xhr();y.cors=!!$t&&"withCredentials"in $t,y.ajax=$t=!!$t,S.ajaxTransport(function(i){var o,a;if(y.cors||$t&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Bt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=ht(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Xt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Xt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Vt=C.jQuery,Gt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Gt),e&&C.jQuery===S&&(C.jQuery=Vt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S}); +/*! jQuery UI - v1.12.1 - 2019-01-27 +* http://jqueryui.com +* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/resizable.js, widgets/mouse.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}t.ui=t.ui||{},t.ui.version="1.12.1";var i=0,s=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,n,o=s.call(arguments,1),a=0,r=o.length;r>a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType,o=!s&&!n;return{element:i,isWindow:s,isDocument:n,offset:o?t(e).offset():{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(n){if(!n||!n.of)return d.apply(this,arguments);n=t.extend({},n);var u,p,f,m,g,_,v=t(n.of),b=t.position.getWithinInfo(n.within),y=t.position.getScrollInfo(b),w=(n.collision||"flip").split(" "),x={};return _=s(v),v[0].preventDefault&&(n.at="left top"),p=_.width,f=_.height,m=_.offset,g=t.extend({},m),t.each(["my","at"],function(){var t,e,i=(n[this]||"").split(" ");1===i.length&&(i=r.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=r.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),x[this]=[t?t[0]:0,e?e[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===n.at[0]?g.left+=p:"center"===n.at[0]&&(g.left+=p/2),"bottom"===n.at[1]?g.top+=f:"center"===n.at[1]&&(g.top+=f/2),u=e(x.at,p,f),g.left+=u[0],g.top+=u[1],this.each(function(){var s,r,h=t(this),l=h.outerWidth(),c=h.outerHeight(),d=i(this,"marginLeft"),_=i(this,"marginTop"),k=l+d+i(this,"marginRight")+y.width,C=c+_+i(this,"marginBottom")+y.height,D=t.extend({},g),T=e(x.my,h.outerWidth(),h.outerHeight());"right"===n.my[0]?D.left-=l:"center"===n.my[0]&&(D.left-=l/2),"bottom"===n.my[1]?D.top-=c:"center"===n.my[1]&&(D.top-=c/2),D.left+=T[0],D.top+=T[1],s={marginLeft:d,marginTop:_},t.each(["left","top"],function(e,i){t.ui.position[w[e]]&&t.ui.position[w[e]][i](D,{targetWidth:p,targetHeight:f,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:k,collisionHeight:C,offset:[u[0]+T[0],u[1]+T[1]],my:n.my,at:n.at,within:b,elem:h})}),n.using&&(r=function(t){var e=m.left-D.left,i=e+p-l,s=m.top-D.top,r=s+f-c,u={target:{element:v,left:m.left,top:m.top,width:p,height:f},element:{element:h,left:D.left,top:D.top,width:l,height:c},horizontal:0>i?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("<div>"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler â—‹ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1<b.axis.length;u&&(d/=2);b.offset=h(b.offset);b.over=h(b.over);return this.each(function(){function k(a){var k=$.extend({},b,{queue:!0,duration:d,complete:a&&function(){a.call(q,e,b)}});r.animate(f,k)}if(null!==a){var l=n(this),q=l?this.contentWindow||window:this,r=$(q),e=a,f={},t;switch(typeof e){case "number":case "string":if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(e)){e= h(e);break}e=l?$(e):$(e,q);case "object":if(e.length===0)return;if(e.is||e.style)t=(e=$(e)).offset()}var v=$.isFunction(b.offset)&&b.offset(q,e)||b.offset;$.each(b.axis.split(""),function(a,c){var d="x"===c?"Left":"Top",m=d.toLowerCase(),g="scroll"+d,h=r[g](),n=p.max(q,c);t?(f[g]=t[m]+(l?0:h-r.offset()[m]),b.margin&&(f[g]-=parseInt(e.css("margin"+d),10)||0,f[g]-=parseInt(e.css("border"+d+"Width"),10)||0),f[g]+=v[m]||0,b.over[m]&&(f[g]+=e["x"===c?"width":"height"]()*b.over[m])):(d=e[m],f[g]=d.slice&& "%"===d.slice(-1)?parseFloat(d)/100*n:d);b.limit&&/^\d+$/.test(f[g])&&(f[g]=0>=f[g]?0:Math.min(f[g],n));!a&&1<b.axis.length&&(h===f[g]?f={}:u&&(k(b.onAfterFirst),f={}))});k(b.onAfter)}})};p.max=function(a,d){var b="x"===d?"Width":"Height",h="scroll"+b;if(!n(a))return a[h]-$(a)[b.toLowerCase()]();var b="client"+b,k=a.ownerDocument||a.document,l=k.documentElement,k=k.body;return Math.max(l[h],k[h])-Math.min(l[b],k[b])};$.Tween.propHooks.scrollLeft=$.Tween.propHooks.scrollTop={get:function(a){return $(a.elem)[a.prop]()}, set:function(a){var d=this.get(a);if(a.options.interrupt&&a._last&&a._last!==d)return $(a.elem).stop();var b=Math.round(a.now);d!==b&&($(a.elem)[a.prop](b),a._last=this.get(a))}};return p}); +/*! + PowerTip v1.3.1 (2018-04-15) + https://stevenbenner.github.io/jquery-powertip/ + Copyright (c) 2018 Steven Benner (http://stevenbenner.com/). + Released under MIT license. + https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt +*/ +(function(root,factory){if(typeof define==="function"&&define.amd){define(["jquery"],factory)}else if(typeof module==="object"&&module.exports){module.exports=factory(require("jquery"))}else{factory(root.jQuery)}})(this,function($){var $document=$(document),$window=$(window),$body=$("body");var DATA_DISPLAYCONTROLLER="displayController",DATA_HASACTIVEHOVER="hasActiveHover",DATA_FORCEDOPEN="forcedOpen",DATA_HASMOUSEMOVE="hasMouseMove",DATA_MOUSEONTOTIP="mouseOnToPopup",DATA_ORIGINALTITLE="originalTitle",DATA_POWERTIP="powertip",DATA_POWERTIPJQ="powertipjq",DATA_POWERTIPTARGET="powertiptarget",EVENT_NAMESPACE=".powertip",RAD2DEG=180/Math.PI,MOUSE_EVENTS=["click","dblclick","mousedown","mouseup","mousemove","mouseover","mouseout","mouseenter","mouseleave","contextmenu"];var session={tooltips:null,isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,closeDelayTimeout:null,mouseTrackingActive:false,delayInProgress:false,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0};var Collision={none:0,top:1,bottom:2,left:4,right:8};$.fn.powerTip=function(opts,arg){var targetElements=this,options,tipController;if(!targetElements.length){return targetElements}if($.type(opts)==="string"&&$.powerTip[opts]){return $.powerTip[opts].call(targetElements,targetElements,arg)}options=$.extend({},$.fn.powerTip.defaults,opts);tipController=new TooltipController(options);initTracking();targetElements.each(function elementSetup(){var $this=$(this),dataPowertip=$this.data(DATA_POWERTIP),dataElem=$this.data(DATA_POWERTIPJQ),dataTarget=$this.data(DATA_POWERTIPTARGET),title=$this.attr("title");if(!dataPowertip&&!dataTarget&&!dataElem&&title){$this.data(DATA_POWERTIP,title);$this.data(DATA_ORIGINALTITLE,title);$this.removeAttr("title")}$this.data(DATA_DISPLAYCONTROLLER,new DisplayController($this,options,tipController))});if(!options.manual){$.each(options.openEvents,function(idx,evt){if($.inArray(evt,options.closeEvents)>-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference<options.intentSensitivity){cancelClose();closeAnyDelayed();tipController.showTip(element)}else{session.previousX=session.currentX;session.previousY=session.currentY;openTooltip()}}function cancelTimer(stopClose){hoverTimer=clearTimeout(hoverTimer);if(session.closeDelayTimeout&&myCloseDelay===session.closeDelayTimeout||stopClose){cancelClose()}}function cancelClose(){session.closeDelayTimeout=clearTimeout(session.closeDelayTimeout);session.delayInProgress=false}function closeAnyDelayed(){if(session.delayInProgress&&session.activeHover&&!session.activeHover.is(element)){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide(true)}}function repositionTooltip(){tipController.resetPosition(element)}this.show=openTooltip;this.hide=closeTooltip;this.cancel=cancelTimer;this.resetPosition=repositionTooltip}function PlacementCalculator(){function computePlacementCoords(element,placement,tipWidth,tipHeight,offset){var placementBase=placement.split("-")[0],coords=new CSSCoordinates,position;if(isSvgElement(element)){position=getSvgPlacement(element,placementBase)}else{position=getHtmlPlacement(element,placementBase)}switch(placement){case"n":coords.set("left",position.left-tipWidth/2);coords.set("bottom",session.windowHeight-position.top+offset);break;case"e":coords.set("left",position.left+offset);coords.set("top",position.top-tipHeight/2);break;case"s":coords.set("left",position.left-tipWidth/2);coords.set("top",position.top+offset);break;case"w":coords.set("top",position.top-tipHeight/2);coords.set("right",session.windowWidth-position.left+offset);break;case"nw":coords.set("bottom",session.windowHeight-position.top+offset);coords.set("right",session.windowWidth-position.left-20);break;case"nw-alt":coords.set("left",position.left);coords.set("bottom",session.windowHeight-position.top+offset);break;case"ne":coords.set("left",position.left-20);coords.set("bottom",session.windowHeight-position.top+offset);break;case"ne-alt":coords.set("bottom",session.windowHeight-position.top+offset);coords.set("right",session.windowWidth-position.left);break;case"sw":coords.set("top",position.top+offset);coords.set("right",session.windowWidth-position.left-20);break;case"sw-alt":coords.set("left",position.left);coords.set("top",position.top+offset);break;case"se":coords.set("left",position.left-20);coords.set("top",position.top+offset);break;case"se-alt":coords.set("top",position.top+offset);coords.set("right",session.windowWidth-position.left);break}return coords}function getHtmlPlacement(element,placement){var objectOffset=element.offset(),objectWidth=element.outerWidth(),objectHeight=element.outerHeight(),left,top;switch(placement){case"n":left=objectOffset.left+objectWidth/2;top=objectOffset.top;break;case"e":left=objectOffset.left+objectWidth;top=objectOffset.top+objectHeight/2;break;case"s":left=objectOffset.left+objectWidth/2;top=objectOffset.top+objectHeight;break;case"w":left=objectOffset.left;top=objectOffset.top+objectHeight/2;break;case"nw":left=objectOffset.left;top=objectOffset.top;break;case"ne":left=objectOffset.left+objectWidth;top=objectOffset.top;break;case"sw":left=objectOffset.left;top=objectOffset.top+objectHeight;break;case"se":left=objectOffset.left+objectWidth;top=objectOffset.top+objectHeight;break}return{top:top,left:left}}function getSvgPlacement(element,placement){var svgElement=element.closest("svg")[0],domElement=element[0],point=svgElement.createSVGPoint(),boundingBox=domElement.getBBox(),matrix=domElement.getScreenCTM(),halfWidth=boundingBox.width/2,halfHeight=boundingBox.height/2,placements=[],placementKeys=["nw","n","ne","e","se","s","sw","w"],coords,rotation,steps,x;function pushPlacement(){placements.push(point.matrixTransform(matrix))}point.x=boundingBox.x;point.y=boundingBox.y;pushPlacement();point.x+=halfWidth;pushPlacement();point.x+=halfWidth;pushPlacement();point.y+=halfHeight;pushPlacement();point.y+=halfHeight;pushPlacement();point.x-=halfWidth;pushPlacement();point.x-=halfWidth;pushPlacement();point.y-=halfHeight;pushPlacement();if(placements[0].y!==placements[1].y||placements[0].x!==placements[7].x){rotation=Math.atan2(matrix.b,matrix.a)*RAD2DEG;steps=Math.ceil((rotation%360-22.5)/45);if(steps<1){steps+=8}while(steps--){placementKeys.push(placementKeys.shift())}}for(x=0;x<placements.length;x++){if(placementKeys[x]===placement){coords=placements[x];break}}return{top:coords.y+session.scrollTop,left:coords.x+session.scrollLeft}}this.compute=computePlacementCoords}function TooltipController(options){var placementCalculator=new PlacementCalculator,tipElement=$("#"+options.popupId);if(tipElement.length===0){tipElement=$("<div/>",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.top<viewportTop||Math.abs(coords.bottom-session.windowHeight)-elementHeight<viewportTop){collisions|=Collision.top}if(coords.top+elementHeight>viewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.left<viewportLeft||coords.right+elementWidth>viewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right<viewportLeft){collisions|=Collision.right}return collisions}function countFlags(value){var count=0;while(value){value&=value-1;count++}return count}return $.powerTip});/*! + * jQuery UI Touch Punch 0.2.3 + * + * Copyright 2011–2014, Dave Furfero + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Depends: + * jquery.ui.widget.js + * jquery.ui.mouse.js + */ +!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("<span/>").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('<div class="sm-jquery-disable-overlay"/>').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0],$('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y<o.upEnd)&&a.eq(o.up?1:0).show(),o.y==n)mouse&&a.eq(o.up?0:1).hide(),this.menuScrollStop(t);else if(!e){this.opts.scrollAccelerate&&o.step<this.opts.scrollStep&&(o.step+=.2);var h=this;this.scrollTimeout=requestAnimationFrame(function(){h.menuScroll(t)})}},menuScrollMousewheel:function(t,e){if(this.getClosestMenu(e.target)==t[0]){e=e.originalEvent;var i=(e.wheelDelta||-e.detail)>0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/ld_client/doc/pdoc/menu.js b/ld_client/doc/pdoc/menu.js new file mode 100644 index 0000000..818b859 --- /dev/null +++ b/ld_client/doc/pdoc/menu.js @@ -0,0 +1,135 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+='<ul>'; + for (var i in data.children) { + var url; + var link; + link = data.children[i].url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + } else { + url = relPath+link; + } + result+='<li><a href="'+url+'">'+ + data.children[i].text+'</a>'+ + makeTree(data.children[i],relPath)+'</li>'; + } + result+='</ul>'; + } + return result; + } + var searchBox; + if (searchEnabled) { + if (serverSide) { + searchBox='<div id="MSearchBox" class="MSearchBoxInactive">'+ + '<div class="left">'+ + '<form id="FSearchBox" action="'+relPath+searchPage+ + '" method="get"><img id="MSearchSelect" src="'+ + relPath+'search/mag.svg" alt=""/>'+ + '<input type="text" id="MSearchField" name="query" value="'+search+ + '" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)"'+ + ' onblur="searchBox.OnSearchFieldFocus(false)">'+ + '</form>'+ + '</div>'+ + '<div class="right"></div>'+ + '</div>'; + } else { + searchBox='<div id="MSearchBox" class="MSearchBoxInactive">'+ + '<span class="left">'+ + '<img id="MSearchSelect" src="'+relPath+ + 'search/mag_sel.svg" onmouseover="return searchBox.OnSearchSelectShow()"'+ + ' onmouseout="return searchBox.OnSearchSelectHide()" alt=""/>'+ + '<input type="text" id="MSearchField" value="'+search+ + '" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" '+ + 'onblur="searchBox.OnSearchFieldFocus(false)" '+ + 'onkeyup="searchBox.OnSearchFieldChange(event)"/>'+ + '</span>'+ + '<span class="right"><a id="MSearchClose" '+ + 'href="javascript:searchBox.CloseResultsWindow()">'+ + '<img id="MSearchCloseImg" border="0" src="'+relPath+ + 'search/close.svg" alt=""/></a>' + '</span>' + '</div>'; + } + } + + $('#main-nav').before('<div class="sm sm-dox"><input id="main-menu-state" type="checkbox"/>'+ + '<label class="main-menu-btn" for="main-menu-state">'+ + '<span class="main-menu-btn-icon"></span> '+ + 'Toggle main menu visibility</label>'+ + '<span id="searchBoxPos1" style="position:absolute;right:8px;top:8px;height:36px;"></span>'+ + '</div>'); + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchBox) { + $('#main-menu').append('<li id="searchBoxPos2" style="float:right"></li>'); + } + var $mainMenuState = $('#main-menu-state'); + var prevWidth = 0; + if ($mainMenuState.length) { + function initResizableIfExists() { + if (typeof initResizable==='function') initResizable(); + } + // animate mobile menu + $mainMenuState.change(function(e) { + var $menu = $('#main-menu'); + var options = { duration: 250, step: initResizableIfExists }; + if (this.checked) { + options['complete'] = function() { $menu.css('display', 'block') }; + $menu.hide().slideDown(options); + } else { + options['complete'] = function() { $menu.css('display', 'none') }; + $menu.show().slideUp(options); + } + }); + // set default menu visibility + function resetState() { + var $menu = $('#main-menu'); + var $mainMenuState = $('#main-menu-state'); + var newWidth = $(window).outerWidth(); + if (newWidth!=prevWidth) { + if ($(window).outerWidth()<768) { + $mainMenuState.prop('checked',false); $menu.hide(); + $('#searchBoxPos1').html(searchBox); + $('#searchBoxPos2').hide(); + } else { + $menu.show(); + $('#searchBoxPos1').empty(); + $('#searchBoxPos2').html(searchBox); + $('#searchBoxPos2').show(); + } + prevWidth = newWidth; + } + } + $(window).ready(function() { resetState(); initResizableIfExists(); }); + $(window).resize(resetState); + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/ld_client/doc/pdoc/menudata.js b/ld_client/doc/pdoc/menudata.js new file mode 100644 index 0000000..bdd6830 --- /dev/null +++ b/ld_client/doc/pdoc/menudata.js @@ -0,0 +1,66 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Packages",url:"namespaces.html",children:[ +{text:"Package List",url:"namespaces.html"}, +{text:"Package Members",url:"namespacemembers.html",children:[ +{text:"All",url:"namespacemembers.html"}, +{text:"Enumerations",url:"namespacemembers_enum.html"}]}]}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Hierarchy",url:"hierarchy.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"_",url:"functions.html#index__5F"}, +{text:"a",url:"functions.html#index_a"}, +{text:"b",url:"functions.html#index_b"}, +{text:"c",url:"functions.html#index_c"}, +{text:"d",url:"functions.html#index_d"}, +{text:"e",url:"functions.html#index_e"}, +{text:"f",url:"functions.html#index_f"}, +{text:"h",url:"functions.html#index_h"}, +{text:"i",url:"functions.html#index_i"}, +{text:"p",url:"functions.html#index_p"}, +{text:"r",url:"functions.html#index_r"}, +{text:"s",url:"functions.html#index_s"}, +{text:"t",url:"functions.html#index_t"}, +{text:"u",url:"functions.html#index_u"}]}, +{text:"Functions",url:"functions_func.html",children:[ +{text:"a",url:"functions_func.html#index_a"}, +{text:"c",url:"functions_func.html#index_c"}, +{text:"d",url:"functions_func.html#index_d"}, +{text:"e",url:"functions_func.html#index_e"}, +{text:"f",url:"functions_func.html#index_f"}, +{text:"h",url:"functions_func.html#index_h"}, +{text:"i",url:"functions_func.html#index_i"}, +{text:"p",url:"functions_func.html#index_p"}, +{text:"r",url:"functions_func.html#index_r"}, +{text:"s",url:"functions_func.html#index_s"}, +{text:"t",url:"functions_func.html#index_t"}, +{text:"u",url:"functions_func.html#index_u"}]}, +{text:"Variables",url:"functions_vars.html"}, +{text:"Properties",url:"functions_prop.html"}]}]}]} diff --git a/ld_client/doc/pdoc/namespace_l_d_client.html b/ld_client/doc/pdoc/namespace_l_d_client.html new file mode 100644 index 0000000..c14ee5f --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient Namespace Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespace_l_d_client.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient Namespace Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespace_l_d_client.js b/ld_client/doc/pdoc/namespace_l_d_client.js new file mode 100644 index 0000000..5099a19 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client.js @@ -0,0 +1,6 @@ +var namespace_l_d_client = +[ + [ "detection", "namespace_l_d_client_1_1detection.html", "namespace_l_d_client_1_1detection" ], + [ "network", "namespace_l_d_client_1_1network.html", "namespace_l_d_client_1_1network" ], + [ "utils", "namespace_l_d_client_1_1utils.html", "namespace_l_d_client_1_1utils" ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html new file mode 100644 index 0000000..8e858c2 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html @@ -0,0 +1,126 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.detection Namespace Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespace_l_d_client_1_1detection.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#nested-classes">Classes</a> </div> + <div class="headertitle"><div class="title">LDClient.detection Namespace Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a> +Classes</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><b>DebuggerInfoParser</b></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class parses the .txt file generated from the debugger. Its primary interest is to find two serial numbers (head + body). <br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface  </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">InfoFetcher</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface  </td><td class="memItemRight" valign="bottom"><b>IProcessDetection</b></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This interface defines the functionality of a process detector. A process detector is used to determine whether a user is currently using a debugger or not. <br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface  </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This interface defines the functionality of all methods that are used to work with processes (within this project). <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">ProcessDetection</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. <a href="class_l_d_client_1_1detection_1_1_process_detection.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">ProcessUtils</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. <a href="class_l_d_client_1_1detection_1_1_process_utils.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js new file mode 100644 index 0000000..de070af --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js @@ -0,0 +1,8 @@ +var namespace_l_d_client_1_1detection = +[ + [ "IInfoFetcher", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html", "interface_l_d_client_1_1detection_1_1_i_info_fetcher" ], + [ "InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html", "class_l_d_client_1_1detection_1_1_info_fetcher" ], + [ "IProcessUtils", "interface_l_d_client_1_1detection_1_1_i_process_utils.html", "interface_l_d_client_1_1detection_1_1_i_process_utils" ], + [ "ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html", "class_l_d_client_1_1detection_1_1_process_detection" ], + [ "ProcessUtils", "class_l_d_client_1_1detection_1_1_process_utils.html", "class_l_d_client_1_1detection_1_1_process_utils" ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.html new file mode 100644 index 0000000..a166f36 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.html @@ -0,0 +1,117 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network Namespace Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespace_l_d_client_1_1network.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#nested-classes">Classes</a> </div> + <div class="headertitle"><div class="title">LDClient.network Namespace Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a> +Classes</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">ApiClient</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. <a href="class_l_d_client_1_1network_1_1_api_client.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">HttpClient</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. <a href="class_l_d_client_1_1network_1_1_http_client.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface  </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This interface defines the functionality of an API client which is used to send information (payloads) to the server. <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface  </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.js new file mode 100644 index 0000000..95e41ff --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.js @@ -0,0 +1,8 @@ +var namespace_l_d_client_1_1network = +[ + [ "data", "namespace_l_d_client_1_1network_1_1data.html", "namespace_l_d_client_1_1network_1_1data" ], + [ "ApiClient", "class_l_d_client_1_1network_1_1_api_client.html", "class_l_d_client_1_1network_1_1_api_client" ], + [ "HttpClient", "class_l_d_client_1_1network_1_1_http_client.html", "class_l_d_client_1_1network_1_1_http_client" ], + [ "IApiClient", "interface_l_d_client_1_1network_1_1_i_api_client.html", "interface_l_d_client_1_1network_1_1_i_api_client" ], + [ "IHttpClient", "interface_l_d_client_1_1network_1_1_i_http_client.html", "interface_l_d_client_1_1network_1_1_i_http_client" ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html new file mode 100644 index 0000000..38e4cf2 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html @@ -0,0 +1,143 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.network.data Namespace Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespace_l_d_client_1_1network_1_1data.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#nested-classes">Classes</a> | +<a href="#enum-members">Enumerations</a> </div> + <div class="headertitle"><div class="title">LDClient.network.data Namespace Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a> +Classes</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class holds all the information about a specific part of a debugger (head/body). <a href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class represents a single payload that is sent to the server. <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="enum-members" name="enum-members"></a> +Enumerations</h2></td></tr> +<tr class="memitem:a0c6d481eff113dd190f5a162b6464e60"><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">ConnectionStatus</a> { <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7">Connected</a> +, <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0">Disconnected</a> + }</td></tr> +<tr class="memdesc:a0c6d481eff113dd190f5a162b6464e60"><td class="mdescLeft"> </td><td class="mdescRight">This enumeration defines different states in which a debugger can be. <a href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">More...</a><br /></td></tr> +<tr class="separator:a0c6d481eff113dd190f5a162b6464e60"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<h2 class="groupheader">Enumeration Type Documentation</h2> +<a id="a0c6d481eff113dd190f5a162b6464e60" name="a0c6d481eff113dd190f5a162b6464e60"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a0c6d481eff113dd190f5a162b6464e60">◆ </a></span>ConnectionStatus</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">enum <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">LDClient.network.data.ConnectionStatus</a></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>This enumeration defines different states in which a debugger can be. </p> +<table class="fieldtable"> +<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7" name="a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7"></a>Connected </td><td class="fielddoc"><p >Debugger is connected </p> +</td></tr> +<tr><td class="fieldname"><a id="a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0" name="a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0"></a>Disconnected </td><td class="fielddoc"><p >Debugger is disconnected </p> +</td></tr> +</table> + +</div> +</div> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html">data</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js new file mode 100644 index 0000000..3bba0dc --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js @@ -0,0 +1,9 @@ +var namespace_l_d_client_1_1network_1_1data = +[ + [ "DebuggerInfo", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html", "class_l_d_client_1_1network_1_1data_1_1_debugger_info" ], + [ "Payload", "class_l_d_client_1_1network_1_1data_1_1_payload.html", "class_l_d_client_1_1network_1_1data_1_1_payload" ], + [ "ConnectionStatus", "namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60", [ + [ "Connected", "namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7", null ], + [ "Disconnected", "namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0", null ] + ] ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html new file mode 100644 index 0000000..4505713 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html @@ -0,0 +1,114 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.utils Namespace Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespace_l_d_client_1_1utils.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#nested-classes">Classes</a> </div> + <div class="headertitle"><div class="title">LDClient.utils Namespace Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a> +Classes</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><b>ConfigLoader</b></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class loads up the configuration file (appsettingss.json). <br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">FileUtils</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. <a href="class_l_d_client_1_1utils_1_1_file_utils.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface  </td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This interface defines IO operations. <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js new file mode 100644 index 0000000..8cfd3d6 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js @@ -0,0 +1,6 @@ +var namespace_l_d_client_1_1utils = +[ + [ "loggers", "namespace_l_d_client_1_1utils_1_1loggers.html", "namespace_l_d_client_1_1utils_1_1loggers" ], + [ "FileUtils", "class_l_d_client_1_1utils_1_1_file_utils.html", "class_l_d_client_1_1utils_1_1_file_utils" ], + [ "IFileUtils", "interface_l_d_client_1_1utils_1_1_i_file_utils.html", "interface_l_d_client_1_1utils_1_1_i_file_utils" ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html new file mode 100644 index 0000000..f600f48 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html @@ -0,0 +1,154 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: LDClient.utils.loggers Namespace Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespace_l_d_client_1_1utils_1_1loggers.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="summary"> +<a href="#nested-classes">Classes</a> | +<a href="#enum-members">Enumerations</a> </div> + <div class="headertitle"><div class="title">LDClient.utils.loggers Namespace Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a> +Classes</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a></td></tr> +<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#details">More...</a><br /></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table><table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="enum-members" name="enum-members"></a> +Enumerations</h2></td></tr> +<tr class="memitem:a8a6f0dbee11cb125ee34af8fcc8bc345"><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LogFlow</a> { <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f">Console</a> = 0 +, <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e">File</a> + }</td></tr> +<tr class="memdesc:a8a6f0dbee11cb125ee34af8fcc8bc345"><td class="mdescLeft"> </td><td class="mdescRight">This enum specifies all possible types of loggers <a href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">More...</a><br /></td></tr> +<tr class="separator:a8a6f0dbee11cb125ee34af8fcc8bc345"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:afeef5648c4f78e32623be5fa2b27f37c"><td class="memItemLeft" align="right" valign="top"><a id="afeef5648c4f78e32623be5fa2b27f37c" name="afeef5648c4f78e32623be5fa2b27f37c"></a>enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a> { <b>Info</b> = 0 +, <b>Debug</b> +, <b>Error</b> + }</td></tr> +<tr class="memdesc:afeef5648c4f78e32623be5fa2b27f37c"><td class="mdescLeft"> </td><td class="mdescRight">Types of all possible logs <br /></td></tr> +<tr class="separator:afeef5648c4f78e32623be5fa2b27f37c"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:a98b0cc04a019c9d28b7a9bd5737f944d"><td class="memItemLeft" align="right" valign="top"><a id="a98b0cc04a019c9d28b7a9bd5737f944d" name="a98b0cc04a019c9d28b7a9bd5737f944d"></a>enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d">LogVerbosity</a> { <b>None</b> = 0 +, <b>Exceptions</b> +, <b>Full</b> + }</td></tr> +<tr class="memdesc:a98b0cc04a019c9d28b7a9bd5737f944d"><td class="mdescLeft"> </td><td class="mdescRight">Enum specifies the verbosity of the log messages <br /></td></tr> +<tr class="separator:a98b0cc04a019c9d28b7a9bd5737f944d"><td class="memSeparator" colspan="2"> </td></tr> +</table> +<h2 class="groupheader">Enumeration Type Documentation</h2> +<a id="a8a6f0dbee11cb125ee34af8fcc8bc345" name="a8a6f0dbee11cb125ee34af8fcc8bc345"></a> +<h2 class="memtitle"><span class="permalink"><a href="#a8a6f0dbee11cb125ee34af8fcc8bc345">◆ </a></span>LogFlow</h2> + +<div class="memitem"> +<div class="memproto"> + <table class="memname"> + <tr> + <td class="memname">enum <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LDClient.utils.loggers.LogFlow</a></td> + </tr> + </table> +</div><div class="memdoc"> + +<p>This enum specifies all possible types of loggers </p> +<table class="fieldtable"> +<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f" name="a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f"></a>Console </td><td class="fielddoc"><p >Console logger </p> +</td></tr> +<tr><td class="fieldname"><a id="a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e" name="a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e"></a>File </td><td class="fielddoc"><p >Rotating file logger </p> +</td></tr> +</table> + +</div> +</div> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">loggers</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js new file mode 100644 index 0000000..d3a32a7 --- /dev/null +++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js @@ -0,0 +1,19 @@ +var namespace_l_d_client_1_1utils_1_1loggers = +[ + [ "ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger" ], + [ "ConsoleLogger", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger" ], + [ "LogFlow", "namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345", [ + [ "Console", "namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f", null ], + [ "File", "namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e", null ] + ] ], + [ "LogType", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c", [ + [ "Info", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca4059b0251f66a18cb56f544728796875", null ], + [ "Debug", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37caa603905470e2a5b8c13e96b579ef0dba", null ], + [ "Error", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca902b0d55fddef6f8d651fe1035b7d4bd", null ] + ] ], + [ "LogVerbosity", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d", [ + [ "None", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944da6adf97f83acf6453d4a6a4b1070f3754", null ], + [ "Exceptions", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dad5f1381c5f97f928df4ef8d18c2a27c0", null ], + [ "Full", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dabbd47109890259c0127154db1af26c75", null ] + ] ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/namespacemembers.html b/ld_client/doc/pdoc/namespacemembers.html new file mode 100644 index 0000000..09b0c35 --- /dev/null +++ b/ld_client/doc/pdoc/namespacemembers.html @@ -0,0 +1,101 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Package Members</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespacemembers.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="contents"> +<div class="textblock">Here is a list of all documented namespace members with links to the namespaces they belong to:</div><ul> +<li>ConnectionStatus : <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">LDClient.network.data</a></li> +<li>LogFlow : <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LDClient.utils.loggers</a></li> +<li>LogType : <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LDClient.utils.loggers</a></li> +<li>LogVerbosity : <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d">LDClient.utils.loggers</a></li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespacemembers_enum.html b/ld_client/doc/pdoc/namespacemembers_enum.html new file mode 100644 index 0000000..bfff096 --- /dev/null +++ b/ld_client/doc/pdoc/namespacemembers_enum.html @@ -0,0 +1,101 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Package Members</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespacemembers_enum.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="contents"> + <ul> +<li>ConnectionStatus : <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">LDClient.network.data</a></li> +<li>LogFlow : <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LDClient.utils.loggers</a></li> +<li>LogType : <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LDClient.utils.loggers</a></li> +<li>LogVerbosity : <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d">LDClient.utils.loggers</a></li> +</ul> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespaces.html b/ld_client/doc/pdoc/namespaces.html new file mode 100644 index 0000000..9fa0abd --- /dev/null +++ b/ld_client/doc/pdoc/namespaces.html @@ -0,0 +1,123 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: Package List</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('namespaces.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">Package List</div></div> +</div><!--header--> +<div class="contents"> +<div class="textblock">Here are the packages with brief descriptions (if available):</div><div class="directory"> +<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span><span onclick="javascript:toggleLevel(4);">4</span>]</div><table class="directory"> +<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client.html" target="_self">LDClient</a></td><td class="desc"></td></tr> +<tr id="row_0_0_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_0_" class="arrow" onclick="toggleFolder('0_0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1detection.html" target="_self">detection</a></td><td class="desc"></td></tr> +<tr id="row_0_0_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" target="_self">IInfoFetcher</a></td><td class="desc">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </td></tr> +<tr id="row_0_0_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" target="_self">InfoFetcher</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </td></tr> +<tr id="row_0_0_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" target="_self">IProcessUtils</a></td><td class="desc">This interface defines the functionality of all methods that are used to work with processes (within this project). </td></tr> +<tr id="row_0_0_3_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html" target="_self">ProcessDetection</a></td><td class="desc">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </td></tr> +<tr id="row_0_0_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" target="_self">ProcessUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </td></tr> +<tr id="row_0_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_1_" class="arrow" onclick="toggleFolder('0_1_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network.html" target="_self">network</a></td><td class="desc"></td></tr> +<tr id="row_0_1_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span id="arr_0_1_0_" class="arrow" onclick="toggleFolder('0_1_0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network_1_1data.html" target="_self">data</a></td><td class="desc"></td></tr> +<tr id="row_0_1_0_0_"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html" target="_self">DebuggerInfo</a></td><td class="desc">This class holds all the information about a specific part of a debugger (head/body). </td></tr> +<tr id="row_0_1_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html" target="_self">Payload</a></td><td class="desc">This class represents a single payload that is sent to the server. </td></tr> +<tr id="row_0_1_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html" target="_self">ApiClient</a></td><td class="desc">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </td></tr> +<tr id="row_0_1_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html" target="_self">HttpClient</a></td><td class="desc">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </td></tr> +<tr id="row_0_1_3_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" target="_self">IApiClient</a></td><td class="desc">This interface defines the functionality of an API client which is used to send information (payloads) to the server. </td></tr> +<tr id="row_0_1_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" target="_self">IHttpClient</a></td><td class="desc">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </td></tr> +<tr id="row_0_2_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_0_2_" class="arrow" onclick="toggleFolder('0_2_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils.html" target="_self">utils</a></td><td class="desc"></td></tr> +<tr id="row_0_2_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span id="arr_0_2_0_" class="arrow" onclick="toggleFolder('0_2_0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html" target="_self">loggers</a></td><td class="desc"></td></tr> +<tr id="row_0_2_0_0_"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html" target="_self">ALogger</a></td><td class="desc">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </td></tr> +<tr id="row_0_2_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html" target="_self">ConsoleLogger</a></td><td class="desc"></td></tr> +<tr id="row_0_2_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html" target="_self">FileUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </td></tr> +<tr id="row_0_2_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" target="_self">IFileUtils</a></td><td class="desc">This interface defines IO operations. </td></tr> +</table> +</div><!-- directory --> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/namespaces_dup.js b/ld_client/doc/pdoc/namespaces_dup.js new file mode 100644 index 0000000..dc23a9c --- /dev/null +++ b/ld_client/doc/pdoc/namespaces_dup.js @@ -0,0 +1,4 @@ +var namespaces_dup = +[ + [ "LDClient", "namespace_l_d_client.html", "namespace_l_d_client" ] +]; \ No newline at end of file diff --git a/ld_client/doc/pdoc/nav_f.png b/ld_client/doc/pdoc/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_<lqdB{jiFDSaaN3W^xbJMH7CDK7=Q3_$6tQ&<~Cp4L6ZEndC`8;cO zrss?`_g+2sGU&M|cu~La_w1Rnf~7w`e!jQgteDwDLg6kW!`DinT@0SCelF{r5}E+Y CM>z8U literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/nav_g.png b/ld_client/doc/pdoc/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!K<?EJwDd;c`qumW{3c)I$ztaD0e0syCC7$E=v literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/nav_h.png b/ld_client/doc/pdoc/nav_h.png new file mode 100644 index 0000000000000000000000000000000000000000..33389b101d9cd9b4c98ad286b5d9c46a6671f650 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!2~3AUOE6t22D>F$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&v<Kx}xDV3h>FVdQ&MBb@0HFXL<NyEw literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/navtree.css b/ld_client/doc/pdoc/navtree.css new file mode 100644 index 0000000..d8a311a --- /dev/null +++ b/ld_client/doc/pdoc/navtree.css @@ -0,0 +1,147 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:#fff; +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + background-color: #FAFAFF; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: 250px; + overflow : hidden; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background-image:url("splitbar.png"); + background-size:100%; + background-repeat:repeat-y; + background-attachment: scroll; + cursor:ew-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/ld_client/doc/pdoc/navtree.js b/ld_client/doc/pdoc/navtree.js new file mode 100644 index 0000000..2798368 --- /dev/null +++ b/ld_client/doc/pdoc/navtree.js @@ -0,0 +1,549 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var navTreeSubIndices = new Array(); +var arrowDown = '▼'; +var arrowRight = '►'; + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("span"); + imgNode.className = 'arrow'; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.innerHTML=arrowRight; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.innerHTML=arrowRight; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + } else { + var span = document.createElement("span"); + span.className = 'arrow'; + span.style.width = 16*(level+1)+'px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('memtitle') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',100,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).slideDown("fast"); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + var topOffset=5; + if (typeof page_layout!=='undefined' && page_layout==1) { + topOffset+=$('#top').outerHeight(); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + topOffset+=25; + } + $('#nav-sync').css('top',topOffset+'px'); + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+1<o.breadcrumbs.length) { + showNode(o,n,index+1,hash); + } else { + if (typeof(n.childrenData)==='string') { + var varName = n.childrenData; + getScript(n.relpath+varName,function(){ + n.childrenData = getData(varName); + node.expanded=false; + showNode(o,node,index,hash); // retry with child node expanded + },true); + } else { + var rootBase = stripPath(o.toroot.replace(/\..+$/, '')); + if (rootBase=="index" || rootBase=="pages" || rootBase=="search") { + expandNode(o, n, true, true); + } + selectAndHighlight(hash,n); + } + } + } + } else { + selectAndHighlight(hash); + } +} + +function removeToInsertLater(element) { + var parentNode = element.parentNode; + var nextSibling = element.nextSibling; + parentNode.removeChild(element); + return function() { + if (nextSibling) { + parentNode.insertBefore(element, nextSibling); + } else { + parentNode.appendChild(element); + } + }; +} + +function getNode(o, po) +{ + var insertFunction = removeToInsertLater(po.li); + po.childrenVisited = true; + var l = po.childrenData.length-1; + for (var i in po.childrenData) { + var nodeData = po.childrenData[i]; + po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2], + i==l); + } + insertFunction(); +} + +function gotoNode(o,subIndex,root,hash,relpath) +{ + var nti = navTreeSubIndices[subIndex][root+hash]; + o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]); + if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index + navTo(o,NAVTREE[0][1],"",relpath); + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + } + if (o.breadcrumbs) { + o.breadcrumbs.unshift(0); // add 0 for root node + showNode(o, o.node, 0, hash); + } +} + +function navTo(o,root,hash,relpath) +{ + var link = cachedLink(); + if (link) { + var parts = link.split('#'); + root = parts[0]; + if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>'); +} + +function showSyncOn(n,relpath) +{ + n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>'); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +var loadTriggered = false; +var readyTriggered = false; +var loadObject,loadToRoot,loadUrl,loadRelPath; + +$(window).on('load',function(){ + if (readyTriggered) { // ready first + navTo(loadObject,loadToRoot,loadUrl,loadRelPath); + showRoot(); + } + loadTriggered=true; +}); + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("span"); + o.node.plus_img.className = 'arrow'; + o.node.plus_img.innerHTML = arrowRight; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + if (loadTriggered) { // load before ready + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + } else { // ready before load + loadObject = o; + loadToRoot = toroot; + loadUrl = hashUrl(); + loadRelPath = relpath; + readyTriggered=true; + } + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]'); + } + if (a==null || !$(a).parent().parent().hasClass('selected')){ + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + } + var link=stripPath2(pathName()); + navTo(o,link,hashUrl(),relpath); + } else if (!animationInProgress) { + $('#doc-content').scrollTop(0); + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + navTo(o,toroot,hashUrl(),relpath); + } + }) +} +/* @license-end */ diff --git a/ld_client/doc/pdoc/navtreedata.js b/ld_client/doc/pdoc/navtreedata.js new file mode 100644 index 0000000..16cc445 --- /dev/null +++ b/ld_client/doc/pdoc/navtreedata.js @@ -0,0 +1,55 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ +var NAVTREE = +[ + [ "LDClient", "index.html", [ + [ "Packages", "namespaces.html", [ + [ "Package List", "namespaces.html", "namespaces_dup" ], + [ "Package Members", "namespacemembers.html", [ + [ "All", "namespacemembers.html", null ], + [ "Enumerations", "namespacemembers_enum.html", null ] + ] ] + ] ], + [ "Classes", "annotated.html", [ + [ "Class List", "annotated.html", "annotated_dup" ], + [ "Class Index", "classes.html", null ], + [ "Class Hierarchy", "hierarchy.html", "hierarchy" ], + [ "Class Members", "functions.html", [ + [ "All", "functions.html", null ], + [ "Functions", "functions_func.html", null ], + [ "Variables", "functions_vars.html", null ], + [ "Properties", "functions_prop.html", null ] + ] ] + ] ] + ] ] +]; + +var NAVTREEINDEX = +[ +"annotated.html" +]; + +var SYNCONMSG = 'click to disable panel synchronisation'; +var SYNCOFFMSG = 'click to enable panel synchronisation'; \ No newline at end of file diff --git a/ld_client/doc/pdoc/navtreeindex0.js b/ld_client/doc/pdoc/navtreeindex0.js new file mode 100644 index 0000000..b8626c9 --- /dev/null +++ b/ld_client/doc/pdoc/navtreeindex0.js @@ -0,0 +1,163 @@ +var NAVTREEINDEX0 = +{ +"annotated.html":[1,0], +"class_file_logger.html":[1,0,1], +"class_file_logger.html#ad39844b2267623f858ab77e6f5433896":[1,0,1,0], +"class_l_d_client_1_1detection_1_1_info_fetcher.html":[0,0,0,0,1], +"class_l_d_client_1_1detection_1_1_info_fetcher.html":[1,0,0,0,1], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f":[0,0,0,0,1,5], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f":[1,0,0,0,1,5], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c":[1,0,0,0,1,1], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c":[0,0,0,0,1,1], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8":[0,0,0,0,1,3], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8":[1,0,0,0,1,3], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26":[1,0,0,0,1,0], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26":[0,0,0,0,1,0], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140":[1,0,0,0,1,2], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140":[0,0,0,0,1,2], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d":[1,0,0,0,1,4], +"class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d":[0,0,0,0,1,4], +"class_l_d_client_1_1detection_1_1_process_detection.html":[0,0,0,0,3], +"class_l_d_client_1_1detection_1_1_process_detection.html":[1,0,0,0,3], +"class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679":[0,0,0,0,3,0], +"class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679":[1,0,0,0,3,0], +"class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6":[0,0,0,0,3,2], +"class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6":[1,0,0,0,3,2], +"class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8":[0,0,0,0,3,1], +"class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8":[1,0,0,0,3,1], +"class_l_d_client_1_1detection_1_1_process_utils.html":[0,0,0,0,4], +"class_l_d_client_1_1detection_1_1_process_utils.html":[1,0,0,0,4], +"class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4":[0,0,0,0,4,1], +"class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4":[1,0,0,0,4,1], +"class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557":[1,0,0,0,4,0], +"class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557":[0,0,0,0,4,0], +"class_l_d_client_1_1network_1_1_api_client.html":[1,0,0,1,1], +"class_l_d_client_1_1network_1_1_api_client.html":[0,0,0,1,1], +"class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d":[1,0,0,1,1,3], +"class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d":[0,0,0,1,1,3], +"class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1":[1,0,0,1,1,4], +"class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1":[0,0,0,1,1,4], +"class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55":[1,0,0,1,1,2], +"class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55":[0,0,0,1,1,2], +"class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73":[1,0,0,1,1,0], +"class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73":[0,0,0,1,1,0], +"class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979":[1,0,0,1,1,1], +"class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979":[0,0,0,1,1,1], +"class_l_d_client_1_1network_1_1_http_client.html":[1,0,0,1,2], +"class_l_d_client_1_1network_1_1_http_client.html":[0,0,0,1,2], +"class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d":[1,0,0,1,2,1], +"class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d":[0,0,0,1,2,1], +"class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3":[0,0,0,1,2,0], +"class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3":[1,0,0,1,2,0], +"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html":[1,0,0,1,0,0], +"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html":[0,0,0,1,0,0], +"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb":[1,0,0,1,0,0,0], +"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb":[0,0,0,1,0,0,0], +"class_l_d_client_1_1network_1_1data_1_1_payload.html":[0,0,0,1,0,1], +"class_l_d_client_1_1network_1_1data_1_1_payload.html":[1,0,0,1,0,1], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481":[1,0,0,1,0,1,5], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481":[0,0,0,1,0,1,5], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208":[1,0,0,1,0,1,2], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208":[0,0,0,1,0,1,2], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65":[1,0,0,1,0,1,7], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65":[0,0,0,1,0,1,7], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72":[1,0,0,1,0,1,4], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72":[0,0,0,1,0,1,4], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57":[0,0,0,1,0,1,0], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57":[1,0,0,1,0,1,0], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297":[1,0,0,1,0,1,6], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297":[0,0,0,1,0,1,6], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148":[1,0,0,1,0,1,1], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148":[0,0,0,1,0,1,1], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5":[1,0,0,1,0,1,3], +"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5":[0,0,0,1,0,1,3], +"class_l_d_client_1_1utils_1_1_file_utils.html":[0,0,0,2,1], +"class_l_d_client_1_1utils_1_1_file_utils.html":[1,0,0,2,1], +"class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737":[0,0,0,2,1,0], +"class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737":[1,0,0,2,1,0], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html":[0,0,0,2,0,0], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html":[1,0,0,2,0,0], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b":[0,0,0,2,0,0,1], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b":[1,0,0,2,0,0,1], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453":[0,0,0,2,0,0,8], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453":[1,0,0,2,0,0,8], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3":[0,0,0,2,0,0,0], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3":[1,0,0,2,0,0,0], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81":[0,0,0,2,0,0,2], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81":[1,0,0,2,0,0,2], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433":[0,0,0,2,0,0,3], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433":[1,0,0,2,0,0,3], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea":[0,0,0,2,0,0,9], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea":[1,0,0,2,0,0,9], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504":[1,0,0,2,0,0,5], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504":[0,0,0,2,0,0,5], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2":[1,0,0,2,0,0,4], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2":[0,0,0,2,0,0,4], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4":[1,0,0,2,0,0,6], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4":[0,0,0,2,0,0,6], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e":[0,0,0,2,0,0,7], +"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e":[1,0,0,2,0,0,7], +"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html":[0,0,0,2,0,1], +"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html":[1,0,0,2,0,1], +"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7":[0,0,0,2,0,1,0], +"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7":[1,0,0,2,0,1,0], +"classes.html":[1,1], +"functions.html":[1,3,0], +"functions_func.html":[1,3,1], +"functions_prop.html":[1,3,3], +"functions_vars.html":[1,3,2], +"hierarchy.html":[1,2], +"index.html":[], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html":[0,0,0,0,0], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html":[1,0,0,0,0], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9":[1,0,0,0,0,0], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9":[0,0,0,0,0,0], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0":[1,0,0,0,0,2], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0":[0,0,0,0,0,2], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9":[1,0,0,0,0,1], +"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9":[0,0,0,0,0,1], +"interface_l_d_client_1_1detection_1_1_i_process_utils.html":[1,0,0,0,2], +"interface_l_d_client_1_1detection_1_1_i_process_utils.html":[0,0,0,0,2], +"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662":[0,0,0,0,2,0], +"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662":[1,0,0,0,2,0], +"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0":[0,0,0,0,2,1], +"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0":[1,0,0,0,2,1], +"interface_l_d_client_1_1network_1_1_i_api_client.html":[1,0,0,1,3], +"interface_l_d_client_1_1network_1_1_i_api_client.html":[0,0,0,1,3], +"interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f":[1,0,0,1,3,1], +"interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f":[0,0,0,1,3,1], +"interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb":[0,0,0,1,3,0], +"interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb":[1,0,0,1,3,0], +"interface_l_d_client_1_1network_1_1_i_http_client.html":[1,0,0,1,4], +"interface_l_d_client_1_1network_1_1_i_http_client.html":[0,0,0,1,4], +"interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f":[1,0,0,1,4,0], +"interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f":[0,0,0,1,4,0], +"interface_l_d_client_1_1utils_1_1_i_file_utils.html":[0,0,0,2,2], +"interface_l_d_client_1_1utils_1_1_i_file_utils.html":[1,0,0,2,2], +"interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3":[0,0,0,2,2,0], +"interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3":[1,0,0,2,2,0], +"namespace_l_d_client.html":[0,0,0], +"namespace_l_d_client_1_1detection.html":[0,0,0,0], +"namespace_l_d_client_1_1network.html":[0,0,0,1], +"namespace_l_d_client_1_1network_1_1data.html":[0,0,0,1,0], +"namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60":[0,0,0,1,0,2], +"namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7":[0,0,0,1,0,2,0], +"namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0":[0,0,0,1,0,2,1], +"namespace_l_d_client_1_1utils.html":[0,0,0,2], +"namespace_l_d_client_1_1utils_1_1loggers.html":[0,0,0,2,0], +"namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345":[0,0,0,2,0,2], +"namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e":[0,0,0,2,0,2,1], +"namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f":[0,0,0,2,0,2,0], +"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d":[0,0,0,2,0,4], +"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944da6adf97f83acf6453d4a6a4b1070f3754":[0,0,0,2,0,4,0], +"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dabbd47109890259c0127154db1af26c75":[0,0,0,2,0,4,2], +"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dad5f1381c5f97f928df4ef8d18c2a27c0":[0,0,0,2,0,4,1], +"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c":[0,0,0,2,0,3], +"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca4059b0251f66a18cb56f544728796875":[0,0,0,2,0,3,0], +"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca902b0d55fddef6f8d651fe1035b7d4bd":[0,0,0,2,0,3,2], +"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37caa603905470e2a5b8c13e96b579ef0dba":[0,0,0,2,0,3,1], +"namespacemembers.html":[0,1,0], +"namespacemembers_enum.html":[0,1,1], +"namespaces.html":[0,0], +"pages.html":[] +}; diff --git a/ld_client/doc/pdoc/open.png b/ld_client/doc/pdoc/open.png new file mode 100644 index 0000000000000000000000000000000000000000..30f75c7efe2dd0c9e956e35b69777a02751f048b GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM<Rdl=8h W@EqZ{ytxBt8iS{+pUXO@geCxcDJg#d literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/resize.js b/ld_client/doc/pdoc/resize.js new file mode 100644 index 0000000..7fe30d1 --- /dev/null +++ b/ld_client/doc/pdoc/resize.js @@ -0,0 +1,150 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function initResizable() +{ + var cookie_namespace = 'doxygen'; + var sidenav,navtree,content,header,collapsed,collapsedWidth=0,barWidth=6,desktop_vp=768,titleHeight; + + function readCookie(cookie) + { + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) { + var index = document.cookie.indexOf(myCookie); + if (index != -1) { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + return 0; + } + + function writeCookie(cookie, val, expiration) + { + if (val==undefined) return; + if (expiration == null) { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + } + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; SameSite=Lax; expires=" + expiration+"; path=/"; + } + + function resizeWidth() + { + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + writeCookie('width',sidenavWidth-barWidth, null); + } + + function restoreWidth(navWidth) + { + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + sidenav.css({width:navWidth + "px"}); + } + + function resizeHeight() + { + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height(); + var contentHeight,navtreeHeight,sideNavHeight; + if (typeof page_layout==='undefined' || page_layout==0) { /* DISABLE_INDEX=NO */ + contentHeight = windowHeight - headerHeight - footerHeight; + navtreeHeight = contentHeight; + sideNavHeight = contentHeight; + } else if (page_layout==1) { /* DISABLE_INDEX=YES */ + contentHeight = windowHeight - footerHeight; + navtreeHeight = windowHeight - headerHeight; + sideNavHeight = windowHeight; + } + content.css({height:contentHeight + "px"}); + navtree.css({height:navtreeHeight + "px"}); + sidenav.css({height:sideNavHeight + "px"}); + var width=$(window).width(); + if (width!=collapsedWidth) { + if (width<desktop_vp && collapsedWidth>=desktop_vp) { + if (!collapsed) { + collapseExpand(); + } + } else if (width>desktop_vp && collapsedWidth<desktop_vp) { + if (collapsed) { + collapseExpand(); + } + } + collapsedWidth=width; + } + if (location.hash.slice(1)) { + (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView(); + } + } + + function collapseExpand() + { + if (sidenav.width()>0) { + restoreWidth(0); + collapsed=true; + } + else { + var width = readCookie('width'); + if (width>200 && width<$(window).width()) { restoreWidth(width); } else { restoreWidth(200); } + collapsed=false; + } + } + + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(sidenav).resizable({ minWidth: 0 }); + $(window).resize(function() { resizeHeight(); }); + var device = navigator.userAgent.toLowerCase(); + var touch_device = device.match(/(iphone|ipod|ipad|android)/); + if (touch_device) { /* wider split bar for touch only devices */ + $(sidenav).css({ paddingRight:'20px' }); + $('.ui-resizable-e').css({ width:'20px' }); + $('#nav-sync').css({ right:'34px' }); + barWidth=20; + } + var width = readCookie('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + $(".ui-resizable-handle").dblclick(collapseExpand); + $(window).on('load',resizeHeight); +} +/* @license-end */ diff --git a/ld_client/doc/pdoc/search/all_0.html b/ld_client/doc/pdoc/search/all_0.html new file mode 100644 index 0000000..bb9e364 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_0.js b/ld_client/doc/pdoc/search/all_0.js new file mode 100644 index 0000000..3d59743 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['_5fclient_0',['_client',['../class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d',1,'LDClient::network::ApiClient']]] +]; diff --git a/ld_client/doc/pdoc/search/all_1.html b/ld_client/doc/pdoc/search/all_1.html new file mode 100644 index 0000000..8989416 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_1.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_1.js b/ld_client/doc/pdoc/search/all_1.js new file mode 100644 index 0000000..bd62760 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['alogger_0',['ALogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3',1,'LDClient.utils.loggers.ALogger.ALogger()'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',1,'LDClient.utils.loggers.ALogger']]], + ['apiclient_1',['ApiClient',['../class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73',1,'LDClient.network.ApiClient.ApiClient()'],['../class_l_d_client_1_1network_1_1_api_client.html',1,'LDClient.network.ApiClient']]] +]; diff --git a/ld_client/doc/pdoc/search/all_2.html b/ld_client/doc/pdoc/search/all_2.html new file mode 100644 index 0000000..98e648c --- /dev/null +++ b/ld_client/doc/pdoc/search/all_2.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_2.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_2.js b/ld_client/doc/pdoc/search/all_2.js new file mode 100644 index 0000000..4ff2bab --- /dev/null +++ b/ld_client/doc/pdoc/search/all_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['bodydevice_0',['BodyDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208',1,'LDClient::network::data::Payload']]], + ['bodyserialnumber_1',['BodySerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9',1,'LDClient.detection.IInfoFetcher.BodySerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d',1,'LDClient.detection.InfoFetcher.BodySerialNumber()']]] +]; diff --git a/ld_client/doc/pdoc/search/all_3.html b/ld_client/doc/pdoc/search/all_3.html new file mode 100644 index 0000000..f4e8da7 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_3.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_3.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_3.js b/ld_client/doc/pdoc/search/all_3.js new file mode 100644 index 0000000..fd4c764 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_3.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['clientrunning_0',['ClientRunning',['../class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1',1,'LDClient::network::ApiClient']]], + ['composelogrow_1',['ComposeLogRow',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b',1,'LDClient::utils::loggers::ALogger']]], + ['connected_2',['Connected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7',1,'LDClient::network::data']]], + ['connectionstatus_3',['ConnectionStatus',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60',1,'LDClient::network::data']]], + ['console_4',['Console',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f',1,'LDClient::utils::loggers']]], + ['consolelogger_5',['ConsoleLogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',1,'LDClient::utils::loggers']]], + ['createlog_6',['CreateLog',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7',1,'LDClient.utils.loggers.ConsoleLogger.CreateLog()'],['../class_file_logger.html#ad39844b2267623f858ab77e6f5433896',1,'FileLogger.CreateLog()']]], + ['current_7',['Current',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f',1,'LDClient::utils::loggers::ALogger']]] +]; diff --git a/ld_client/doc/pdoc/search/all_4.html b/ld_client/doc/pdoc/search/all_4.html new file mode 100644 index 0000000..678d3a2 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_4.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_4.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_4.js b/ld_client/doc/pdoc/search/all_4.js new file mode 100644 index 0000000..626ce5a --- /dev/null +++ b/ld_client/doc/pdoc/search/all_4.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['debug_0',['Debug',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81',1,'LDClient::utils::loggers::ALogger']]], + ['debuggerinfo_1',['DebuggerInfo',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',1,'LDClient::network::data']]], + ['detectionrunning_2',['DetectionRunning',['../class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6',1,'LDClient::detection::ProcessDetection']]], + ['disconnected_3',['Disconnected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0',1,'LDClient::network::data']]], + ['dispose_4',['Dispose',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433',1,'LDClient::utils::loggers::ALogger']]] +]; diff --git a/ld_client/doc/pdoc/search/all_5.html b/ld_client/doc/pdoc/search/all_5.html new file mode 100644 index 0000000..aa9af78 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_5.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_5.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_5.js b/ld_client/doc/pdoc/search/all_5.js new file mode 100644 index 0000000..018d2dc --- /dev/null +++ b/ld_client/doc/pdoc/search/all_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['error_0',['Error',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504',1,'LDClient.utils.loggers.ALogger.Error(string message)'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2',1,'LDClient.utils.loggers.ALogger.Error(Exception e)']]], + ['executenewprocess_1',['ExecuteNewProcess',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662',1,'LDClient.detection.IProcessUtils.ExecuteNewProcess()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557',1,'LDClient.detection.ProcessUtils.ExecuteNewProcess()']]] +]; diff --git a/ld_client/doc/pdoc/search/all_6.html b/ld_client/doc/pdoc/search/all_6.html new file mode 100644 index 0000000..d3026a7 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_6.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_6.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_6.js b/ld_client/doc/pdoc/search/all_6.js new file mode 100644 index 0000000..c4d01bd --- /dev/null +++ b/ld_client/doc/pdoc/search/all_6.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['fetchdataasync_0',['FetchDataAsync',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9',1,'LDClient.detection.IInfoFetcher.FetchDataAsync()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c',1,'LDClient.detection.InfoFetcher.FetchDataAsync()']]], + ['file_1',['File',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e',1,'LDClient::utils::loggers']]], + ['filelogger_2',['FileLogger',['../class_file_logger.html',1,'']]], + ['fileutils_3',['FileUtils',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140',1,'LDClient.detection.InfoFetcher.FileUtils()'],['../class_l_d_client_1_1utils_1_1_file_utils.html',1,'LDClient.utils.FileUtils']]], + ['flush_4',['Flush',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4',1,'LDClient::utils::loggers::ALogger']]] +]; diff --git a/ld_client/doc/pdoc/search/all_7.html b/ld_client/doc/pdoc/search/all_7.html new file mode 100644 index 0000000..b2ee042 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_7.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_7.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_7.js b/ld_client/doc/pdoc/search/all_7.js new file mode 100644 index 0000000..59c5ac4 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_7.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['headdevice_0',['HeadDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5',1,'LDClient::network::data::Payload']]], + ['headserialnumber_1',['HeadSerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0',1,'LDClient.detection.IInfoFetcher.HeadSerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f',1,'LDClient.detection.InfoFetcher.HeadSerialNumber()']]], + ['hostname_2',['HostName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72',1,'LDClient::network::data::Payload']]], + ['httpclient_3',['HttpClient',['../class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3',1,'LDClient.network.HttpClient.HttpClient()'],['../class_l_d_client_1_1network_1_1_http_client.html',1,'LDClient.network.HttpClient']]] +]; diff --git a/ld_client/doc/pdoc/search/all_8.html b/ld_client/doc/pdoc/search/all_8.html new file mode 100644 index 0000000..40a0b3f --- /dev/null +++ b/ld_client/doc/pdoc/search/all_8.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_8.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_8.js b/ld_client/doc/pdoc/search/all_8.js new file mode 100644 index 0000000..0752101 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_8.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['iapiclient_0',['IApiClient',['../interface_l_d_client_1_1network_1_1_i_api_client.html',1,'LDClient::network']]], + ['ifileutils_1',['IFileUtils',['../interface_l_d_client_1_1utils_1_1_i_file_utils.html',1,'LDClient::utils']]], + ['ihttpclient_2',['IHttpClient',['../interface_l_d_client_1_1network_1_1_i_http_client.html',1,'LDClient::network']]], + ['iinfofetcher_3',['IInfoFetcher',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',1,'LDClient::detection']]], + ['info_4',['Info',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e',1,'LDClient::utils::loggers::ALogger']]], + ['infofetcher_5',['InfoFetcher',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26',1,'LDClient.detection.InfoFetcher.InfoFetcher()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html',1,'LDClient.detection.InfoFetcher']]], + ['iprocessutils_6',['IProcessUtils',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html',1,'LDClient::detection']]], + ['isprocessrunning_7',['IsProcessRunning',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0',1,'LDClient.detection.IProcessUtils.IsProcessRunning()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4',1,'LDClient.detection.ProcessUtils.IsProcessRunning()']]] +]; diff --git a/ld_client/doc/pdoc/search/all_9.html b/ld_client/doc/pdoc/search/all_9.html new file mode 100644 index 0000000..7c49144 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_9.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_9.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_9.js b/ld_client/doc/pdoc/search/all_9.js new file mode 100644 index 0000000..5f15c1c --- /dev/null +++ b/ld_client/doc/pdoc/search/all_9.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['data_0',['data',['../namespace_l_d_client_1_1network_1_1data.html',1,'LDClient::network']]], + ['detection_1',['detection',['../namespace_l_d_client_1_1detection.html',1,'LDClient']]], + ['ldclient_2',['LDClient',['../namespace_l_d_client.html',1,'']]], + ['logflow_3',['LogFlow',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345',1,'LDClient::utils::loggers']]], + ['loggers_4',['loggers',['../namespace_l_d_client_1_1utils_1_1loggers.html',1,'LDClient::utils']]], + ['logtype_5',['LogType',['../namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c',1,'LDClient::utils::loggers']]], + ['logverbosity_6',['LogVerbosity',['../namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d',1,'LDClient::utils::loggers']]], + ['network_7',['network',['../namespace_l_d_client_1_1network.html',1,'LDClient']]], + ['utils_8',['utils',['../namespace_l_d_client_1_1utils.html',1,'LDClient']]] +]; diff --git a/ld_client/doc/pdoc/search/all_a.html b/ld_client/doc/pdoc/search/all_a.html new file mode 100644 index 0000000..fc9d79c --- /dev/null +++ b/ld_client/doc/pdoc/search/all_a.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_a.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_a.js b/ld_client/doc/pdoc/search/all_a.js new file mode 100644 index 0000000..1fe257c --- /dev/null +++ b/ld_client/doc/pdoc/search/all_a.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['parsetojson_0',['ParseToJson',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57',1,'LDClient.network.data.Payload.ParseToJson()'],['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056',1,'LDClient.network.data.Payload.ParseToJson(Payload payload)']]], + ['payload_1',['Payload',['../class_l_d_client_1_1network_1_1data_1_1_payload.html',1,'LDClient::network::data']]], + ['postasjsonasync_2',['PostAsJsonAsync',['../class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d',1,'LDClient.network.HttpClient.PostAsJsonAsync()'],['../interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f',1,'LDClient.network.IHttpClient.PostAsJsonAsync()']]], + ['processdetection_3',['ProcessDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html',1,'LDClient.detection.ProcessDetection'],['../class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679',1,'LDClient.detection.ProcessDetection.ProcessDetection()']]], + ['processutils_4',['ProcessUtils',['../class_l_d_client_1_1detection_1_1_process_utils.html',1,'LDClient.detection.ProcessUtils'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8',1,'LDClient.detection.InfoFetcher.ProcessUtils()']]] +]; diff --git a/ld_client/doc/pdoc/search/all_b.html b/ld_client/doc/pdoc/search/all_b.html new file mode 100644 index 0000000..dafb1fa --- /dev/null +++ b/ld_client/doc/pdoc/search/all_b.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_b.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_b.js b/ld_client/doc/pdoc/search/all_b.js new file mode 100644 index 0000000..fc6db8c --- /dev/null +++ b/ld_client/doc/pdoc/search/all_b.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['readfilealllines_0',['ReadFileAllLines',['../class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737',1,'LDClient.utils.FileUtils.ReadFileAllLines()'],['../interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3',1,'LDClient.utils.IFileUtils.ReadFileAllLines()']]], + ['run_1',['Run',['../class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979',1,'LDClient.network.ApiClient.Run()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb',1,'LDClient.network.IApiClient.Run()']]], + ['runperiodicdetection_2',['RunPeriodicDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8',1,'LDClient::detection::ProcessDetection']]] +]; diff --git a/ld_client/doc/pdoc/search/all_c.html b/ld_client/doc/pdoc/search/all_c.html new file mode 100644 index 0000000..9df619d --- /dev/null +++ b/ld_client/doc/pdoc/search/all_c.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_c.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_c.js b/ld_client/doc/pdoc/search/all_c.js new file mode 100644 index 0000000..0787247 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['sendpayloadasync_0',['SendPayloadAsync',['../class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55',1,'LDClient.network.ApiClient.SendPayloadAsync()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f',1,'LDClient.network.IApiClient.SendPayloadAsync()']]], + ['serialnumber_1',['SerialNumber',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb',1,'LDClient::network::data::DebuggerInfo']]], + ['status_2',['Status',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481',1,'LDClient::network::data::Payload']]] +]; diff --git a/ld_client/doc/pdoc/search/all_d.html b/ld_client/doc/pdoc/search/all_d.html new file mode 100644 index 0000000..95d8eec --- /dev/null +++ b/ld_client/doc/pdoc/search/all_d.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_d.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_d.js b/ld_client/doc/pdoc/search/all_d.js new file mode 100644 index 0000000..2d8b980 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_d.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['timestamp_0',['TimeStamp',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297',1,'LDClient::network::data::Payload']]], + ['tostring_1',['ToString',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148',1,'LDClient.network.data.Payload.ToString()'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453',1,'LDClient.utils.loggers.ALogger.ToString()']]] +]; diff --git a/ld_client/doc/pdoc/search/all_e.html b/ld_client/doc/pdoc/search/all_e.html new file mode 100644 index 0000000..a54e120 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_e.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="all_e.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/all_e.js b/ld_client/doc/pdoc/search/all_e.js new file mode 100644 index 0000000..94ddcc3 --- /dev/null +++ b/ld_client/doc/pdoc/search/all_e.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['unwrapexceptionmessages_0',['UnwrapExceptionMessages',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea',1,'LDClient::utils::loggers::ALogger']]], + ['username_1',['UserName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65',1,'LDClient::network::data::Payload']]] +]; diff --git a/ld_client/doc/pdoc/search/classes_0.html b/ld_client/doc/pdoc/search/classes_0.html new file mode 100644 index 0000000..9d4f871 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="classes_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/classes_0.js b/ld_client/doc/pdoc/search/classes_0.js new file mode 100644 index 0000000..c2bc89b --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['alogger_0',['ALogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',1,'LDClient::utils::loggers']]], + ['apiclient_1',['ApiClient',['../class_l_d_client_1_1network_1_1_api_client.html',1,'LDClient::network']]] +]; diff --git a/ld_client/doc/pdoc/search/classes_1.html b/ld_client/doc/pdoc/search/classes_1.html new file mode 100644 index 0000000..0557f9f --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="classes_1.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/classes_1.js b/ld_client/doc/pdoc/search/classes_1.js new file mode 100644 index 0000000..24f6506 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['consolelogger_0',['ConsoleLogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',1,'LDClient::utils::loggers']]] +]; diff --git a/ld_client/doc/pdoc/search/classes_2.html b/ld_client/doc/pdoc/search/classes_2.html new file mode 100644 index 0000000..fa20861 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_2.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="classes_2.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/classes_2.js b/ld_client/doc/pdoc/search/classes_2.js new file mode 100644 index 0000000..3d9e4e9 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['debuggerinfo_0',['DebuggerInfo',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',1,'LDClient::network::data']]] +]; diff --git a/ld_client/doc/pdoc/search/classes_3.html b/ld_client/doc/pdoc/search/classes_3.html new file mode 100644 index 0000000..98fbc87 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_3.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="classes_3.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/classes_3.js b/ld_client/doc/pdoc/search/classes_3.js new file mode 100644 index 0000000..230c4a7 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['filelogger_0',['FileLogger',['../class_file_logger.html',1,'']]], + ['fileutils_1',['FileUtils',['../class_l_d_client_1_1utils_1_1_file_utils.html',1,'LDClient::utils']]] +]; diff --git a/ld_client/doc/pdoc/search/classes_4.html b/ld_client/doc/pdoc/search/classes_4.html new file mode 100644 index 0000000..3b6c51e --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_4.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="classes_4.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/classes_4.js b/ld_client/doc/pdoc/search/classes_4.js new file mode 100644 index 0000000..7de16de --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['httpclient_0',['HttpClient',['../class_l_d_client_1_1network_1_1_http_client.html',1,'LDClient::network']]] +]; diff --git a/ld_client/doc/pdoc/search/classes_5.html b/ld_client/doc/pdoc/search/classes_5.html new file mode 100644 index 0000000..51c2b30 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_5.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="classes_5.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/classes_5.js b/ld_client/doc/pdoc/search/classes_5.js new file mode 100644 index 0000000..80f4a0d --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_5.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['iapiclient_0',['IApiClient',['../interface_l_d_client_1_1network_1_1_i_api_client.html',1,'LDClient::network']]], + ['ifileutils_1',['IFileUtils',['../interface_l_d_client_1_1utils_1_1_i_file_utils.html',1,'LDClient::utils']]], + ['ihttpclient_2',['IHttpClient',['../interface_l_d_client_1_1network_1_1_i_http_client.html',1,'LDClient::network']]], + ['iinfofetcher_3',['IInfoFetcher',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',1,'LDClient::detection']]], + ['infofetcher_4',['InfoFetcher',['../class_l_d_client_1_1detection_1_1_info_fetcher.html',1,'LDClient::detection']]], + ['iprocessutils_5',['IProcessUtils',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html',1,'LDClient::detection']]] +]; diff --git a/ld_client/doc/pdoc/search/classes_6.html b/ld_client/doc/pdoc/search/classes_6.html new file mode 100644 index 0000000..431fb05 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_6.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="classes_6.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/classes_6.js b/ld_client/doc/pdoc/search/classes_6.js new file mode 100644 index 0000000..72a3395 --- /dev/null +++ b/ld_client/doc/pdoc/search/classes_6.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['payload_0',['Payload',['../class_l_d_client_1_1network_1_1data_1_1_payload.html',1,'LDClient::network::data']]], + ['processdetection_1',['ProcessDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html',1,'LDClient::detection']]], + ['processutils_2',['ProcessUtils',['../class_l_d_client_1_1detection_1_1_process_utils.html',1,'LDClient::detection']]] +]; diff --git a/ld_client/doc/pdoc/search/close.svg b/ld_client/doc/pdoc/search/close.svg new file mode 100644 index 0000000..a933eea --- /dev/null +++ b/ld_client/doc/pdoc/search/close.svg @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 11 11" + height="11" + width="11" + id="svg2" + version="1.1"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6" /> + <path + id="path12" + d="M 5.5 0.5 A 5 5 0 0 0 0.5 5.5 A 5 5 0 0 0 5.5 10.5 A 5 5 0 0 0 10.5 5.5 A 5 5 0 0 0 5.5 0.5 z M 3.5820312 3 A 0.58291923 0.58291923 0 0 1 4 3.1757812 L 5.5 4.6757812 L 7 3.1757812 A 0.58291923 0.58291923 0 0 1 7.4003906 3 A 0.58291923 0.58291923 0 0 1 7.8242188 4 L 6.3242188 5.5 L 7.8242188 7 A 0.58291923 0.58291923 0 1 1 7 7.8242188 L 5.5 6.3242188 L 4 7.8242188 A 0.58291923 0.58291923 0 1 1 3.1757812 7 L 4.6757812 5.5 L 3.1757812 4 A 0.58291923 0.58291923 0 0 1 3.5820312 3 z " + style="stroke-width:1.09870648;fill:#bababa;fill-opacity:1" /> +</svg> diff --git a/ld_client/doc/pdoc/search/enums_0.html b/ld_client/doc/pdoc/search/enums_0.html new file mode 100644 index 0000000..ec25efd --- /dev/null +++ b/ld_client/doc/pdoc/search/enums_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="enums_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/enums_0.js b/ld_client/doc/pdoc/search/enums_0.js new file mode 100644 index 0000000..cf8256f --- /dev/null +++ b/ld_client/doc/pdoc/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['connectionstatus_0',['ConnectionStatus',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60',1,'LDClient::network::data']]] +]; diff --git a/ld_client/doc/pdoc/search/enums_1.html b/ld_client/doc/pdoc/search/enums_1.html new file mode 100644 index 0000000..cc99a33 --- /dev/null +++ b/ld_client/doc/pdoc/search/enums_1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="enums_1.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/enums_1.js b/ld_client/doc/pdoc/search/enums_1.js new file mode 100644 index 0000000..98425df --- /dev/null +++ b/ld_client/doc/pdoc/search/enums_1.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['logflow_0',['LogFlow',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345',1,'LDClient::utils::loggers']]], + ['logtype_1',['LogType',['../namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c',1,'LDClient::utils::loggers']]], + ['logverbosity_2',['LogVerbosity',['../namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d',1,'LDClient::utils::loggers']]] +]; diff --git a/ld_client/doc/pdoc/search/enumvalues_0.html b/ld_client/doc/pdoc/search/enumvalues_0.html new file mode 100644 index 0000000..71e9b7c --- /dev/null +++ b/ld_client/doc/pdoc/search/enumvalues_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="enumvalues_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/enumvalues_0.js b/ld_client/doc/pdoc/search/enumvalues_0.js new file mode 100644 index 0000000..3830bdb --- /dev/null +++ b/ld_client/doc/pdoc/search/enumvalues_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['connected_0',['Connected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7',1,'LDClient::network::data']]], + ['console_1',['Console',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f',1,'LDClient::utils::loggers']]] +]; diff --git a/ld_client/doc/pdoc/search/enumvalues_1.html b/ld_client/doc/pdoc/search/enumvalues_1.html new file mode 100644 index 0000000..595aa8c --- /dev/null +++ b/ld_client/doc/pdoc/search/enumvalues_1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="enumvalues_1.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/enumvalues_1.js b/ld_client/doc/pdoc/search/enumvalues_1.js new file mode 100644 index 0000000..ae0f7a4 --- /dev/null +++ b/ld_client/doc/pdoc/search/enumvalues_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['disconnected_0',['Disconnected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0',1,'LDClient::network::data']]] +]; diff --git a/ld_client/doc/pdoc/search/enumvalues_2.html b/ld_client/doc/pdoc/search/enumvalues_2.html new file mode 100644 index 0000000..5343504 --- /dev/null +++ b/ld_client/doc/pdoc/search/enumvalues_2.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="enumvalues_2.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/enumvalues_2.js b/ld_client/doc/pdoc/search/enumvalues_2.js new file mode 100644 index 0000000..a5f557f --- /dev/null +++ b/ld_client/doc/pdoc/search/enumvalues_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['file_0',['File',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e',1,'LDClient::utils::loggers']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_0.html b/ld_client/doc/pdoc/search/functions_0.html new file mode 100644 index 0000000..3b739c7 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_0.js b/ld_client/doc/pdoc/search/functions_0.js new file mode 100644 index 0000000..356c8b6 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['alogger_0',['ALogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3',1,'LDClient::utils::loggers::ALogger']]], + ['apiclient_1',['ApiClient',['../class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73',1,'LDClient::network::ApiClient']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_1.html b/ld_client/doc/pdoc/search/functions_1.html new file mode 100644 index 0000000..2cef5e3 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_1.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_1.js b/ld_client/doc/pdoc/search/functions_1.js new file mode 100644 index 0000000..f94987c --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['composelogrow_0',['ComposeLogRow',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b',1,'LDClient::utils::loggers::ALogger']]], + ['createlog_1',['CreateLog',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7',1,'LDClient.utils.loggers.ConsoleLogger.CreateLog()'],['../class_file_logger.html#ad39844b2267623f858ab77e6f5433896',1,'FileLogger.CreateLog()']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_2.html b/ld_client/doc/pdoc/search/functions_2.html new file mode 100644 index 0000000..3308c65 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_2.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_2.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_2.js b/ld_client/doc/pdoc/search/functions_2.js new file mode 100644 index 0000000..8fdccce --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['debug_0',['Debug',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81',1,'LDClient::utils::loggers::ALogger']]], + ['dispose_1',['Dispose',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433',1,'LDClient::utils::loggers::ALogger']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_3.html b/ld_client/doc/pdoc/search/functions_3.html new file mode 100644 index 0000000..43ac697 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_3.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_3.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_3.js b/ld_client/doc/pdoc/search/functions_3.js new file mode 100644 index 0000000..018d2dc --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['error_0',['Error',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504',1,'LDClient.utils.loggers.ALogger.Error(string message)'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2',1,'LDClient.utils.loggers.ALogger.Error(Exception e)']]], + ['executenewprocess_1',['ExecuteNewProcess',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662',1,'LDClient.detection.IProcessUtils.ExecuteNewProcess()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557',1,'LDClient.detection.ProcessUtils.ExecuteNewProcess()']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_4.html b/ld_client/doc/pdoc/search/functions_4.html new file mode 100644 index 0000000..d12c2df --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_4.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_4.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_4.js b/ld_client/doc/pdoc/search/functions_4.js new file mode 100644 index 0000000..77b0446 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_4.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['fetchdataasync_0',['FetchDataAsync',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9',1,'LDClient.detection.IInfoFetcher.FetchDataAsync()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c',1,'LDClient.detection.InfoFetcher.FetchDataAsync()']]], + ['flush_1',['Flush',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4',1,'LDClient::utils::loggers::ALogger']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_5.html b/ld_client/doc/pdoc/search/functions_5.html new file mode 100644 index 0000000..7266236 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_5.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_5.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_5.js b/ld_client/doc/pdoc/search/functions_5.js new file mode 100644 index 0000000..a4088a6 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['httpclient_0',['HttpClient',['../class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3',1,'LDClient::network::HttpClient']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_6.html b/ld_client/doc/pdoc/search/functions_6.html new file mode 100644 index 0000000..7f9fc45 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_6.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_6.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_6.js b/ld_client/doc/pdoc/search/functions_6.js new file mode 100644 index 0000000..cf45353 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_6.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['info_0',['Info',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e',1,'LDClient::utils::loggers::ALogger']]], + ['infofetcher_1',['InfoFetcher',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26',1,'LDClient::detection::InfoFetcher']]], + ['isprocessrunning_2',['IsProcessRunning',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0',1,'LDClient.detection.IProcessUtils.IsProcessRunning()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4',1,'LDClient.detection.ProcessUtils.IsProcessRunning()']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_7.html b/ld_client/doc/pdoc/search/functions_7.html new file mode 100644 index 0000000..ad0f88b --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_7.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_7.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_7.js b/ld_client/doc/pdoc/search/functions_7.js new file mode 100644 index 0000000..689681a --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_7.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['parsetojson_0',['ParseToJson',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57',1,'LDClient.network.data.Payload.ParseToJson()'],['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056',1,'LDClient.network.data.Payload.ParseToJson(Payload payload)']]], + ['postasjsonasync_1',['PostAsJsonAsync',['../class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d',1,'LDClient.network.HttpClient.PostAsJsonAsync()'],['../interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f',1,'LDClient.network.IHttpClient.PostAsJsonAsync()']]], + ['processdetection_2',['ProcessDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679',1,'LDClient::detection::ProcessDetection']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_8.html b/ld_client/doc/pdoc/search/functions_8.html new file mode 100644 index 0000000..ea7fa74 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_8.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_8.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_8.js b/ld_client/doc/pdoc/search/functions_8.js new file mode 100644 index 0000000..fc6db8c --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_8.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['readfilealllines_0',['ReadFileAllLines',['../class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737',1,'LDClient.utils.FileUtils.ReadFileAllLines()'],['../interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3',1,'LDClient.utils.IFileUtils.ReadFileAllLines()']]], + ['run_1',['Run',['../class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979',1,'LDClient.network.ApiClient.Run()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb',1,'LDClient.network.IApiClient.Run()']]], + ['runperiodicdetection_2',['RunPeriodicDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8',1,'LDClient::detection::ProcessDetection']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_9.html b/ld_client/doc/pdoc/search/functions_9.html new file mode 100644 index 0000000..d831dc7 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_9.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_9.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_9.js b/ld_client/doc/pdoc/search/functions_9.js new file mode 100644 index 0000000..358fa79 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['sendpayloadasync_0',['SendPayloadAsync',['../class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55',1,'LDClient.network.ApiClient.SendPayloadAsync()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f',1,'LDClient.network.IApiClient.SendPayloadAsync()']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_a.html b/ld_client/doc/pdoc/search/functions_a.html new file mode 100644 index 0000000..7018fc6 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_a.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_a.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_a.js b/ld_client/doc/pdoc/search/functions_a.js new file mode 100644 index 0000000..1a5397b --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['tostring_0',['ToString',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148',1,'LDClient.network.data.Payload.ToString()'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453',1,'LDClient.utils.loggers.ALogger.ToString()']]] +]; diff --git a/ld_client/doc/pdoc/search/functions_b.html b/ld_client/doc/pdoc/search/functions_b.html new file mode 100644 index 0000000..c0660b0 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_b.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="functions_b.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/functions_b.js b/ld_client/doc/pdoc/search/functions_b.js new file mode 100644 index 0000000..b788fa0 --- /dev/null +++ b/ld_client/doc/pdoc/search/functions_b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['unwrapexceptionmessages_0',['UnwrapExceptionMessages',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea',1,'LDClient::utils::loggers::ALogger']]] +]; diff --git a/ld_client/doc/pdoc/search/mag_sel.svg b/ld_client/doc/pdoc/search/mag_sel.svg new file mode 100644 index 0000000..03626f6 --- /dev/null +++ b/ld_client/doc/pdoc/search/mag_sel.svg @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg2" + width="20" + height="19" + viewBox="0 0 20 19" + sodipodi:docname="mag_sel.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="2096" + id="namedview4" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:zoom="32" + inkscape:cx="5.9792688" + inkscape:cy="1.1436277" + inkscape:window-x="1920" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg2" /> + <circle + style="fill:#000000;fill-opacity:0;stroke:#656565;stroke-width:1.4;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + id="path4611" + cx="5.5" + cy="8.5" + r="3.5" /> + <path + style="fill:#656565;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 11,7 13.5,10 16,7 Z" + id="path4609" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccc" /> + <path + style="fill:none;stroke:#656565;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 8.1085854,11.109059 2.7823556,2.782356" + id="path4630" + inkscape:connector-curvature="0" /> +</svg> diff --git a/ld_client/doc/pdoc/search/namespaces_0.html b/ld_client/doc/pdoc/search/namespaces_0.html new file mode 100644 index 0000000..b2d68fe --- /dev/null +++ b/ld_client/doc/pdoc/search/namespaces_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="namespaces_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/namespaces_0.js b/ld_client/doc/pdoc/search/namespaces_0.js new file mode 100644 index 0000000..7472a95 --- /dev/null +++ b/ld_client/doc/pdoc/search/namespaces_0.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['data_0',['data',['../namespace_l_d_client_1_1network_1_1data.html',1,'LDClient::network']]], + ['detection_1',['detection',['../namespace_l_d_client_1_1detection.html',1,'LDClient']]], + ['ldclient_2',['LDClient',['../namespace_l_d_client.html',1,'']]], + ['loggers_3',['loggers',['../namespace_l_d_client_1_1utils_1_1loggers.html',1,'LDClient::utils']]], + ['network_4',['network',['../namespace_l_d_client_1_1network.html',1,'LDClient']]], + ['utils_5',['utils',['../namespace_l_d_client_1_1utils.html',1,'LDClient']]] +]; diff --git a/ld_client/doc/pdoc/search/nomatches.html b/ld_client/doc/pdoc/search/nomatches.html new file mode 100644 index 0000000..2b9360b --- /dev/null +++ b/ld_client/doc/pdoc/search/nomatches.html @@ -0,0 +1,13 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="NoMatches">No Matches</div> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/properties_0.html b/ld_client/doc/pdoc/search/properties_0.html new file mode 100644 index 0000000..e1b4f60 --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="properties_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/properties_0.js b/ld_client/doc/pdoc/search/properties_0.js new file mode 100644 index 0000000..4ff2bab --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['bodydevice_0',['BodyDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208',1,'LDClient::network::data::Payload']]], + ['bodyserialnumber_1',['BodySerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9',1,'LDClient.detection.IInfoFetcher.BodySerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d',1,'LDClient.detection.InfoFetcher.BodySerialNumber()']]] +]; diff --git a/ld_client/doc/pdoc/search/properties_1.html b/ld_client/doc/pdoc/search/properties_1.html new file mode 100644 index 0000000..dab619c --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="properties_1.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/properties_1.js b/ld_client/doc/pdoc/search/properties_1.js new file mode 100644 index 0000000..a3e1d85 --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['current_0',['Current',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f',1,'LDClient::utils::loggers::ALogger']]] +]; diff --git a/ld_client/doc/pdoc/search/properties_2.html b/ld_client/doc/pdoc/search/properties_2.html new file mode 100644 index 0000000..4492167 --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_2.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="properties_2.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/properties_2.js b/ld_client/doc/pdoc/search/properties_2.js new file mode 100644 index 0000000..e8a4bfa --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_2.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['headdevice_0',['HeadDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5',1,'LDClient::network::data::Payload']]], + ['headserialnumber_1',['HeadSerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0',1,'LDClient.detection.IInfoFetcher.HeadSerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f',1,'LDClient.detection.InfoFetcher.HeadSerialNumber()']]], + ['hostname_2',['HostName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72',1,'LDClient::network::data::Payload']]] +]; diff --git a/ld_client/doc/pdoc/search/properties_3.html b/ld_client/doc/pdoc/search/properties_3.html new file mode 100644 index 0000000..2d5a4bb --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_3.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="properties_3.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/properties_3.js b/ld_client/doc/pdoc/search/properties_3.js new file mode 100644 index 0000000..b8f186b --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['serialnumber_0',['SerialNumber',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb',1,'LDClient::network::data::DebuggerInfo']]], + ['status_1',['Status',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481',1,'LDClient::network::data::Payload']]] +]; diff --git a/ld_client/doc/pdoc/search/properties_4.html b/ld_client/doc/pdoc/search/properties_4.html new file mode 100644 index 0000000..cc95ce5 --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_4.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="properties_4.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/properties_4.js b/ld_client/doc/pdoc/search/properties_4.js new file mode 100644 index 0000000..c46006b --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['timestamp_0',['TimeStamp',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297',1,'LDClient::network::data::Payload']]] +]; diff --git a/ld_client/doc/pdoc/search/properties_5.html b/ld_client/doc/pdoc/search/properties_5.html new file mode 100644 index 0000000..94489a0 --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_5.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="properties_5.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/properties_5.js b/ld_client/doc/pdoc/search/properties_5.js new file mode 100644 index 0000000..4f0807e --- /dev/null +++ b/ld_client/doc/pdoc/search/properties_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['username_0',['UserName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65',1,'LDClient::network::data::Payload']]] +]; diff --git a/ld_client/doc/pdoc/search/search.css b/ld_client/doc/pdoc/search/search.css new file mode 100644 index 0000000..648a792 --- /dev/null +++ b/ld_client/doc/pdoc/search/search.css @@ -0,0 +1,263 @@ +/*---------------- Search Box */ + +#MSearchBox { + white-space : nowrap; + background: white; + border-radius: 0.65em; + box-shadow: inset 0.5px 0.5px 3px 0px #555; + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + height: 19px; + padding: 0 0 0 0.3em; + margin: 0; +} + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: #909090; + outline: none; + font-family: Arial, Verdana, sans-serif; + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + height: 1.4em; + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +#main-menu > li:last-child { + /* This <li> object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; + z-index:10000; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: Arial, Verdana, sans-serif; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: Arial, Verdana, sans-serif; +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/ld_client/doc/pdoc/search/search.js b/ld_client/doc/pdoc/search/search.js new file mode 100644 index 0000000..607f4e1 --- /dev/null +++ b/ld_client/doc/pdoc/search/search.js @@ -0,0 +1,802 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i<search.length;i++) + { + var c = search.charAt(i); + var cn = c.charCodeAt(0); + if (c.match(/[a-z0-9\u0080-\uFFFF]/)) + { + result+=c; + } + else if (cn<16) + { + result+="_0"+cn.toString(16); + } + else + { + result+="_"+cn.toString(16); + } + } + return result; +} + +function getXPos(item) +{ + var x = 0; + if (item.offsetWidth) + { + while (item && item!=document.body) + { + x += item.offsetLeft; + item = item.offsetParent; + } + } + return x; +} + +function getYPos(item) +{ + var y = 0; + if (item.offsetWidth) + { + while (item && item!=document.body) + { + y += item.offsetTop; + item = item.offsetParent; + } + } + return y; +} + +/* A class handling everything associated with the search panel. + + Parameters: + name - The name of the global variable that will be + storing this instance. Is needed to be able to set timeouts. + resultPath - path to use for external files +*/ +function SearchBox(name, resultsPath, label, extension) +{ + if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); } + if (!extension || extension == "") { extension = ".html"; } + + // ---------- Instance variables + this.name = name; + this.resultsPath = resultsPath; + this.keyTimeout = 0; + this.keyTimeoutLength = 500; + this.closeSelectionTimeout = 300; + this.lastSearchValue = ""; + this.lastResultsPage = ""; + this.hideTimeout = 0; + this.searchIndex = 0; + this.searchActive = false; + this.searchLabel = label; + this.extension = extension; + + // ----------- DOM Elements + + this.DOMSearchField = function() + { return document.getElementById("MSearchField"); } + + this.DOMSearchSelect = function() + { return document.getElementById("MSearchSelect"); } + + this.DOMSearchSelectWindow = function() + { return document.getElementById("MSearchSelectWindow"); } + + this.DOMPopupSearchResults = function() + { return document.getElementById("MSearchResults"); } + + this.DOMPopupSearchResultsWindow = function() + { return document.getElementById("MSearchResultsWindow"); } + + this.DOMSearchClose = function() + { return document.getElementById("MSearchClose"); } + + this.DOMSearchBox = function() + { return document.getElementById("MSearchBox"); } + + // ------------ Event Handlers + + // Called when focus is added or removed from the search field. + this.OnSearchFieldFocus = function(isActive) + { + this.Activate(isActive); + } + + this.OnSearchSelectShow = function() + { + var searchSelectWindow = this.DOMSearchSelectWindow(); + var searchField = this.DOMSearchSelect(); + + var left = getXPos(searchField); + var top = getYPos(searchField); + top += searchField.offsetHeight; + + // show search selection popup + searchSelectWindow.style.display='block'; + searchSelectWindow.style.left = left + 'px'; + searchSelectWindow.style.top = top + 'px'; + + // stop selection hide timer + if (this.hideTimeout) + { + clearTimeout(this.hideTimeout); + this.hideTimeout=0; + } + return false; // to avoid "image drag" default event + } + + this.OnSearchSelectHide = function() + { + this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()", + this.closeSelectionTimeout); + } + + // Called when the content of the search field is changed. + this.OnSearchFieldChange = function(evt) + { + if (this.keyTimeout) // kill running timer + { + clearTimeout(this.keyTimeout); + this.keyTimeout = 0; + } + + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 || e.keyCode==13) + { + if (e.shiftKey==1) + { + this.OnSearchSelectShow(); + var win=this.DOMSearchSelectWindow(); + for (i=0;i<win.childNodes.length;i++) + { + var child = win.childNodes[i]; // get span within a + if (child.className=='SelectItem') + { + child.focus(); + return; + } + } + return; + } + else + { + window.frames.MSearchResults.postMessage("take_focus", "*"); + } + } + else if (e.keyCode==27) // Escape out of the search field + { + this.DOMSearchField().blur(); + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.lastSearchValue = ''; + this.Activate(false); + return; + } + + // strip whitespaces + var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); + + if (searchValue != this.lastSearchValue) // search value has changed + { + if (searchValue != "") // non-empty search + { + // set timer for search update + this.keyTimeout = setTimeout(this.name + '.Search()', + this.keyTimeoutLength); + } + else // empty search field + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.lastSearchValue = ''; + } + } + } + + this.SelectItemCount = function(id) + { + var count=0; + var win=this.DOMSearchSelectWindow(); + for (i=0;i<win.childNodes.length;i++) + { + var child = win.childNodes[i]; // get span within a + if (child.className=='SelectItem') + { + count++; + } + } + return count; + } + + this.SelectItemSet = function(id) + { + var i,j=0; + var win=this.DOMSearchSelectWindow(); + for (i=0;i<win.childNodes.length;i++) + { + var child = win.childNodes[i]; // get span within a + if (child.className=='SelectItem') + { + var node = child.firstChild; + if (j==id) + { + node.innerHTML='•'; + } + else + { + node.innerHTML=' '; + } + j++; + } + } + } + + // Called when an search filter selection is made. + // set item with index id as the active item + this.OnSelectItem = function(id) + { + this.searchIndex = id; + this.SelectItemSet(id); + var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); + if (searchValue!="" && this.searchActive) // something was found -> do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down + { + this.searchIndex++; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==38 && this.searchIndex>0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches' + this.extension; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline-block'; + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var width = 400; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of <Search()>. + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e<searchData.length; e++) + { + var id = searchData[e][0]; + var srResult = document.createElement('div'); + srResult.setAttribute('id','SR_'+id); + setClassAttr(srResult,'SRResult'); + var srEntry = document.createElement('div'); + setClassAttr(srEntry,'SREntry'); + var srLink = document.createElement('a'); + srLink.setAttribute('id','Item'+e); + setKeyActions(srLink,'return searchResults.Nav(event,'+e+')'); + setClassAttr(srLink,'SRSymbol'); + srLink.innerHTML = searchData[e][1][0]; + srEntry.appendChild(srLink); + if (searchData[e][1].length==2) // single result + { + srLink.setAttribute('href',searchData[e][1][1][0]); + srLink.setAttribute('onclick','parent.searchBox.CloseResultsWindow()'); + if (searchData[e][1][1][1]) + { + srLink.setAttribute('target','_parent'); + } + else + { + srLink.setAttribute('target','_blank'); + } + var srScope = document.createElement('span'); + setClassAttr(srScope,'SRScope'); + srScope.innerHTML = searchData[e][1][1][2]; + srEntry.appendChild(srScope); + } + else // multiple results + { + srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")'); + var srChildren = document.createElement('div'); + setClassAttr(srChildren,'SRChildren'); + for (var c=0; c<searchData[e][1].length-1; c++) + { + var srChild = document.createElement('a'); + srChild.setAttribute('id','Item'+e+'_c'+c); + setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')'); + setClassAttr(srChild,'SRScope'); + srChild.setAttribute('href',searchData[e][1][c+1][0]); + srChild.setAttribute('onclick','parent.searchBox.CloseResultsWindow()'); + if (searchData[e][1][c+1][1]) + { + srChild.setAttribute('target','_parent'); + } + else + { + srChild.setAttribute('target','_blank'); + } + srChild.innerHTML = searchData[e][1][c+1][2]; + srChildren.appendChild(srChild); + } + srEntry.appendChild(srChildren); + } + srResult.appendChild(srEntry); + results.appendChild(srResult); + } +} + +function init_search() +{ + var results = document.getElementById("MSearchSelectWindow"); + for (var key in indexSectionLabels) + { + var link = document.createElement('a'); + link.setAttribute('class','SelectItem'); + link.setAttribute('onclick','searchBox.OnSelectItem('+key+')'); + link.href='javascript:void(0)'; + link.innerHTML='<span class="SelectionMark"> </span>'+indexSectionLabels[key]; + results.appendChild(link); + } + searchBox.OnSelectItem(0); +} +/* @license-end */ diff --git a/ld_client/doc/pdoc/search/search_l.png b/ld_client/doc/pdoc/search/search_l.png new file mode 100644 index 0000000000000000000000000000000000000000..fd5f7daa41a4c79b4ae9bea5aa7bdfb94e14084b GIT binary patch literal 567 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz6!2%?$TA$hhDVB6cUq=Rpjs4tz5?O(Kg=CK) zUj~NU84L`?eGCi_EEpJ?t}-xGu`@87+QPtK?83kxQ`TapwHK(CDaqU2h2ejD|C#+j z9%q3^WHAE+w=f7ZGR&GI0Tg5}@$_|Nf5gMiEhFgvHvB#V1EZFwi(`n!`QAxqy_^C? z+`jj!^>(R!W8j_r#qQ#gnr4kAxdU#F0+OBry<A_XEfSiTFv~GuLE}}0iFF6&H>$Z+ z_0PMi;P|#{d%mw(dnw=jM%@$onTJa%@6Nm3`;2S#nwtVFJI#`U@2Q@@JCCctagvF- z8H=anvo~dTmJ2<pSnM=aYQ7mur_Vc=KQ;l29JyWDZCN~fev0|+o3}F2P%CNIx5trL z8gA}<cc1qPiOH&eRG9J7<ifc}f%_b|eRo%1h+kMg?QxbQD_=Y#XWHp4|L@3Yv6bBq zd~oOD{y#VJ78Z8RC_Y*B*FLF4Y09bOg^5e_I(Ak>YA%wA6IHRv%{vxvUm|R)kgZeo zmX%Zb;mpflGZdXCTAgit`||AFzkI#z&(3d4(htA?U2FOL4WF6wY&TB#n3n*I4+hl| z*NBpo#FA92<f2p{#b9J$XrXIpq-$UvVrXb(WMO4!u5DmoWniFd?|d6YLvDUbW?Cg~ V4KYc-(}5ZoJYD@<);T3K0RU@P%k2OF literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/search/search_m.png b/ld_client/doc/pdoc/search/search_m.png new file mode 100644 index 0000000000000000000000000000000000000000..b429a16ba641960da1e52e5da85dc80fd82635c8 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Em0U}M~ynTTbOS+@4BLl;=8&~`zjDUQ}64!{5 z;QX|b^2DN42FH~Aq*MjZ+{E<Mpwz^a%EFVWHb6xNo-U3d6}OUf^!3vd5)y3c{#bPU z`teb@<JbTH_7jql7?`61bOfX$^6u_pUBbY`!?2W{-=^-N>vEu822WQ%mvv4FO#qs` BFGc_W literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/search/search_r.png b/ld_client/doc/pdoc/search/search_r.png new file mode 100644 index 0000000000000000000000000000000000000000..1af5d21ee13e070d7600f1c4657fde843b953a69 GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9c!2%@BXHTsJQY`6?zK#qG8~eHcB(ehe3dtTp zz6=bxGZ+|(`xqD=STHa&U1eaXVrO7DwS|Gf*oA>XrmV$GYcEhOQ<As43&a2R{xkc5 zJkA1-$YKTtZeb8+WSBKa0w~B{;_2(k{)mU2TSn0TZTNi#21XfA7sn8d^R1H{y_o_< z+~hsAIakGYPy5?E?QfIV-)Ulw-A&uvc6(^?XfA18cvfYFtH_Fg-3MA$nhAz1;G4nQ z)c5(>T(QLuS{~ooZ2P@v=Xc@RKW@Irliv8_;wroU0*)0O?temdsA~70jrdux+`@W7 z-N(<(C)L?hOO?KV{>8(jC{h<AlVfGFV&cS)C3al`J({hH{AZi%%{daMX%zO!rQPhj zO4O~O1uR{5ym@yvujLfdunGzN6vJTAIO%M=m#VrSQ@h&By8@n<o)p=ZT$+AnU5ifM z=cKe}PAc7}R+@<xE&raDXZb+)aQF4y<?OdioGN6^Ufq9RRdf1xc5a~x>pKsws)#Fh zvsO>IB+gb@b+rGWaO&!a9Z{!U+fV*s7TS>fdt&j$L%^U@Epd$~Nl7e8wMs5Z1yT$~ z28I^8hDN#u<{^fLRz?<9hUVG^237_Jy7tbuQ8eV{r(~v8;?@w8^gA7>fx*+&&t;uc GLK6VEQpiUD literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/search/searchdata.js b/ld_client/doc/pdoc/search/searchdata.js new file mode 100644 index 0000000..d2dc55d --- /dev/null +++ b/ld_client/doc/pdoc/search/searchdata.js @@ -0,0 +1,36 @@ +var indexSectionsWithContent = +{ + 0: "_abcdefhilprstu", + 1: "acdfhip", + 2: "l", + 3: "acdefhiprstu", + 4: "_cdfp", + 5: "cl", + 6: "cdf", + 7: "bchstu" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "namespaces", + 3: "functions", + 4: "variables", + 5: "enums", + 6: "enumvalues", + 7: "properties" +}; + +var indexSectionLabels = +{ + 0: "All", + 1: "Classes", + 2: "Namespaces", + 3: "Functions", + 4: "Variables", + 5: "Enumerations", + 6: "Enumerator", + 7: "Properties" +}; + diff --git a/ld_client/doc/pdoc/search/variables_0.html b/ld_client/doc/pdoc/search/variables_0.html new file mode 100644 index 0000000..fd893a6 --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_0.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="variables_0.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/variables_0.js b/ld_client/doc/pdoc/search/variables_0.js new file mode 100644 index 0000000..3d59743 --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['_5fclient_0',['_client',['../class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d',1,'LDClient::network::ApiClient']]] +]; diff --git a/ld_client/doc/pdoc/search/variables_1.html b/ld_client/doc/pdoc/search/variables_1.html new file mode 100644 index 0000000..5f8e440 --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="variables_1.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/variables_1.js b/ld_client/doc/pdoc/search/variables_1.js new file mode 100644 index 0000000..2214017 --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['clientrunning_0',['ClientRunning',['../class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1',1,'LDClient::network::ApiClient']]] +]; diff --git a/ld_client/doc/pdoc/search/variables_2.html b/ld_client/doc/pdoc/search/variables_2.html new file mode 100644 index 0000000..77a7f48 --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_2.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="variables_2.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/variables_2.js b/ld_client/doc/pdoc/search/variables_2.js new file mode 100644 index 0000000..657a0dd --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['detectionrunning_0',['DetectionRunning',['../class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6',1,'LDClient::detection::ProcessDetection']]] +]; diff --git a/ld_client/doc/pdoc/search/variables_3.html b/ld_client/doc/pdoc/search/variables_3.html new file mode 100644 index 0000000..3ee62ba --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_3.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="variables_3.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/variables_3.js b/ld_client/doc/pdoc/search/variables_3.js new file mode 100644 index 0000000..faeaae4 --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['fileutils_0',['FileUtils',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140',1,'LDClient::detection::InfoFetcher']]] +]; diff --git a/ld_client/doc/pdoc/search/variables_4.html b/ld_client/doc/pdoc/search/variables_4.html new file mode 100644 index 0000000..640713f --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_4.html @@ -0,0 +1,37 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="variables_4.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">Loading...</div> +<div id="SRResults"></div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +createResults(); +/* @license-end */ +</script> +<div class="SRStatus" id="Searching">Searching...</div> +<div class="SRStatus" id="NoMatches">No Matches</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +window.addEventListener("message", function(event) { + if (event.data == "take_focus") { + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); + } +}); +/* @license-end */ +</script> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/search/variables_4.js b/ld_client/doc/pdoc/search/variables_4.js new file mode 100644 index 0000000..626a4f2 --- /dev/null +++ b/ld_client/doc/pdoc/search/variables_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['processutils_0',['ProcessUtils',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8',1,'LDClient::detection::InfoFetcher']]] +]; diff --git a/ld_client/doc/pdoc/splitbar.png b/ld_client/doc/pdoc/splitbar.png new file mode 100644 index 0000000000000000000000000000000000000000..fe895f2c58179b471a22d8320b39a4bd7312ec8e GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jW<lVxsx`Ym~nPnqw$O~`M84{XS6<Mm0<Zit<Tk``D^RashfFq{wG<# zZG2vRxL<$IhkFMSBd@N1`uRtp)t>rYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|E<fHWtM%;-WUJ&>EGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/sync_off.png b/ld_client/doc/pdoc/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0009VNkl<ZcmeI* zOK4PA7{KxW<S|JmGnqI|rb(KahDirA+8B+gVk8A)%pe9yF;+3L5iKZG7xuBS&@L(k z33MTXOIxMHjirbWgs8M;qhM?(_-v^nS(KzU#%Ih_`hB-^XYSm&39)2*I6vmhow@fr z=iKj{vvuv-e;!~uA+biR6pf-n<cdGVuox5<#BBg4c>oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO<q-Bsh$IuZaopT|9E z-75alp&U9s%(|8uI^NA(#AD;nc=%{ivdZX(QFJ7~-yf%_Adjk`W@NhjJTyZ8*;|!n z9=K#TJuZz+={YZ#>8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sT<tBHx6XfOFDx2(ijpMiR>xLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/sync_on.png b/ld_client/doc/pdoc/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0009NNkl<ZcmeI* zUr1D09KiAKIOC-Ar)j4&EoU~y1|7@QCTmeCsMH~fFw#|0OWK8m>Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I<ojWskx{8*sm){4kXJ+p2oO6HY zoL5W7@h*VL_(ZL!7GaSmtl}SWU-XD;q7T4~4ZuW>_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F<o_Z}1zllSWC8!Z+rkFN>={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$M<u9&-IHqnYs=DL+lbi3lG2ysF!p!_2H=p zj-g89hmThki^;JHknVE4V`@zS$(ZbTd?1=dsrXLRiJbUBq7weAmVjEk@rP>j4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/tab_a.png b/ld_client/doc/pdoc/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/tab_b.png b/ld_client/doc/pdoc/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn<f<Rf3mJ=+uzfrOMlc%s`x4TZtnrR|B~W{ zyZP0m7vvtXV80W5^J2vvp97)4WrPK1-P<H^B$Ll|TGvzm;+92|BpdT89$b1Qf7x5g UZ&RH}7SL`6Pgg&ebxsLQ0A}n&iU0rr literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/tab_h.png b/ld_client/doc/pdoc/tab_h.png new file mode 100644 index 0000000000000000000000000000000000000000..fd5cb705488e60fcf30f56fcc951dee74f3b095b GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QWc&qjv*C{Z}0jF9dr<AdpNI7 zaOs_6=O($9b?lc?Qk=SJVv5%FA{O^TY1^*qJ@<p}E}!uH_1eoPJ&tpVl={bg{Skd2 zp1FO|;|R90%G3WYZM5AU=A4%H?3qaQhHt%H9G|xYJ)ff*|MmI*zD3`*Z|LP?7d&26 cn!ZiLK0QM$CeyB_80ZEDPgg&ebxsLQ0C?O;!~g&Q literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/tab_s.png b/ld_client/doc/pdoc/tab_s.png new file mode 100644 index 0000000000000000000000000000000000000000..ab478c95b67371d700a20869f7de1ddd73522d50 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QuUrLjv*C{Z|^p8HaRdjTwH7) zC?wLlL}}I{)n%R&r+1}IGmDnq;&J#%V6)9VsYhS`O^BVBQlxOUep0c$RENLq#g8A$ z)z7%K_bI&n@J+X_=x}fJoEKed-$<>=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/ld_client/doc/pdoc/tabs.css b/ld_client/doc/pdoc/tabs.css new file mode 100644 index 0000000..00d1c60 --- /dev/null +++ b/ld_client/doc/pdoc/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:#666;-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file -- GitLab From f09385a359d71f272b995ccb103422706ae0d8ed Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 8 May 2022 12:48:17 +0200 Subject: [PATCH 53/67] re #9712 Added configuration properties of the t32 api --- ld_client/LDClient/LDClient.csproj | 15 ++++++----- ld_client/LDClient/appsettings.json | 33 +++++++++++++++++++++--- ld_client/LDClient/utils/ConfigLoader.cs | 21 +++++++++++---- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj index c575ea0..a63b79f 100644 --- a/ld_client/LDClient/LDClient.csproj +++ b/ld_client/LDClient/LDClient.csproj @@ -7,21 +7,24 @@ <Nullable>enable</Nullable> </PropertyGroup> - <ItemGroup> + <PropertyGroup Condition=" '$(OS)' == 'Windows_NT' "> + <DefineConstants>_WINDOWS</DefineConstants> + </PropertyGroup> + + <ItemGroup> <None Remove="appsettings.json" /> + <None Remove="t32api64.dll" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="appsettings.json"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </EmbeddedResource> + <EmbeddedResource Include="lib\t32api64.dll"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </EmbeddedResource> </ItemGroup> - <ItemGroup> - <Reference Include="t32apinet"> - <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath> - </Reference> - </ItemGroup> <ItemGroup> <PackageReference Include="DiskQueue" Version="1.5.0" /> diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index 3a3a702..ba3cadb 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -26,18 +26,43 @@ "CacheFileName": "cache" }, "DebuggerDetection": { - "F32RemArguments": [ + "T32RemArguments": [ "localhost port=20000 printer.filetype ASCIIE", "localhost port=20000 printer.open C:\\app\\result.txt", "localhost port=20000 WinPrint.version.hardware", "localhost port=20000 printer.close " ], - "F32RemExecutable": "c:\\app\\tools\\T32\\bin\\windows64\\t32rem.exe", + "T32ApiAddress": "localhost", + "T32ApiPort": "20000", + "T32ApiPacketLen": "1024", + "T32ApiCommands": [ + "AREA.Create TWOWIRE", + "AREA.Select TWOWIRE", + "AREA.clear TWOWIRE", + + "WinPOS 1. 1. 50. 3. 0. 0. MYAREA", + "Print \"TwoWire:\"", + "Print.cable.twowire()", + "Area.View TWOWIRE", + + "PRinTer.FileType ASCIIE", + "PRinTer.OPEN C:\\app\\result.txt", + "WinPrint.license.list", + "screen.wait", + "WinPrint.Area.View TWOWIRE", + "WinPrint.version.hardware", + "Printer.CLOSE", + + "Area.delete TWOWIRE", + + "enddo" + ], + "T32RemExecutable": "c:\\app\\tools\\T32\\bin\\windows64\\t32rem.exe", "T32ProcessName": "t32mtc", "T32InfoLocation": "C:\\app\\result.txt", "DetectionPeriod": 5000, - "FetchInfoMaxAttempts": 5, - "FetchInfoAttemptPeriod": 1000, + "FetchInfoMaxAttempts": 15, + "FetchInfoAttemptPeriod": 4000, "T32RemSuccessExitCode": 0, "T32RemWaitTimeoutMs": 2000 } diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index 6dc3cf7..f585cce 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -38,8 +38,14 @@ namespace LDClient.utils { /// </summary> private const string DdSection = "DebuggerDetection"; + + public string[] T32ApiCommands { get; private set; } = null!; + public string T32ApiAddress { get; private set; } = null!; + public string T32ApiPort { get; private set; } = null!; + public string T32ApiPacketLen { get; private set; } = null!; + #region Logger - + /// <summary> /// Maximum size of the log file (it will start to rotate when this limit is reached). /// </summary> @@ -135,7 +141,7 @@ namespace LDClient.utils { /// <summary> /// Path to the t32rem.exe which is used to send commands to a debugger. /// </summary> - public string F32RemExecutable { get; private set; } = null!; + public string T32RemExecutable { get; private set; } = null!; /// <summary> /// How many times the application attempts to check if there @@ -151,7 +157,7 @@ namespace LDClient.utils { /// <summary> /// Arguments (commands) sent to the t32rem.exe file. /// </summary> - public string[] F32RemArguments { get; private set; } = null!; + public string[] T32RemArguments { get; private set; } = null!; /// <summary> /// Status code indication successful execution of the t32rem.exe file. @@ -251,12 +257,17 @@ namespace LDClient.utils { T32ProcessName = debugger["T32ProcessName"]; T32InfoLocation = debugger["T32InfoLocation"]; DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]); - F32RemExecutable = debugger["F32RemExecutable"]; + T32RemExecutable = debugger["T32RemExecutable"]; FetchInfoMaxAttempts = uint.Parse(debugger["FetchInfoMaxAttempts"]); FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]); T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]); T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]); - F32RemArguments = configuration.GetSection($"{DdSection}:F32RemArguments").GetChildren().Select(key => key.Value).ToArray(); + T32RemArguments = configuration.GetSection($"{DdSection}:T32RemArguments").GetChildren().Select(key => key.Value).ToArray(); + T32ApiCommands = configuration.GetSection($"{DdSection}:T32ApiCommands").GetChildren().Select(key => key.Value).ToArray(); + T32ApiAddress = debugger["T32ApiAddress"]; + T32ApiPort = debugger["T32ApiPort"]; + T32ApiPacketLen = debugger["T32ApiPacketLen"]; + } catch (Exception e) { Console.WriteLine(e); Environment.Exit(ErrorExitCode); -- GitLab From 68087f99f168fb52dded94470ac3d67d582e31eb Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 8 May 2022 12:49:38 +0200 Subject: [PATCH 54/67] re #9712 restructuring of info fetcher --- ld_client/LDClient/detection/AInfoFetcher.cs | 130 +++++++++++++ ld_client/LDClient/detection/IT32Utils.cs | 15 ++ ld_client/LDClient/detection/InfoFetcher.cs | 186 ------------------- 3 files changed, 145 insertions(+), 186 deletions(-) create mode 100644 ld_client/LDClient/detection/AInfoFetcher.cs create mode 100644 ld_client/LDClient/detection/IT32Utils.cs delete mode 100644 ld_client/LDClient/detection/InfoFetcher.cs diff --git a/ld_client/LDClient/detection/AInfoFetcher.cs b/ld_client/LDClient/detection/AInfoFetcher.cs new file mode 100644 index 0000000..c41f581 --- /dev/null +++ b/ld_client/LDClient/detection/AInfoFetcher.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using LDClient.utils; + +namespace LDClient.detection; + +/// <summary> +/// This abstract class implements the common functions of the IInfoFetcher interface +/// which defines the functionality of an info fetcher. +/// </summary> +public abstract class AInfoFetcher : IInfoFetcher { + + /// <summary> + /// Default value of a serial number (undefined). + /// </summary> + private const string UndefinedSerialNumber = "number"; + + /// <summary> + /// Returns the head serial number of the debugger. + /// </summary> + public string HeadSerialNumber { get; set; } = UndefinedSerialNumber; + + /// <summary> + /// Returns the body serial number of the debugger. + /// </summary> + public string BodySerialNumber { get; set; } = UndefinedSerialNumber; + + /// <summary> + /// Instance of FileUtils which encapsulates common functionality + /// when it comes to dealing with files (limited by the needs of this application). + /// </summary> + public IFileUtils FileUtils; + + /// <summary> + /// Maximum number of attempts to locate and parse the .txt file. + /// </summary> + protected readonly uint _maxAttempts; + + /// <summary> + /// Period (how often) the application tries to locate and parse the .txt file. + /// </summary> + protected readonly uint _waitPeriodMs; + + /// <summary> + /// Path to the .txt file which is generated from the debugger. + /// </summary> + protected readonly string _infoFilePath; + + /// <summary> + /// Abstract constructor of this class + /// </summary> + /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param> + /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param> + /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param> + + protected AInfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath) { + this.FileUtils = new FileUtils(); + this._maxAttempts = maxAttempts; + this._waitPeriodMs = waitPeriodMs; + this._infoFilePath = infoFilePath; + } + + /// <summary> + /// Abstract definition of the data fetching function + /// Function should send the commands to the debugger. + /// </summary> + /// <returns>true on success</returns> + protected abstract bool FetchData(); + + /// <summary> + /// Fetches data from the debugger. It sends the commands defined + /// in the appsettings.json file to the debugger and tries to + /// parse the .txt (contains the serial numbers). + /// </summary> + /// <returns>True, if data was fetched successfully. False otherwise.</returns> + public async Task<bool> FetchDataAsync() { + Program.DefaultLogger.Info("Fetching data from the debugger."); + // Send the commands to the debugger. + var success = FetchData(); + + // Make sure that all commands were sent and executed successfully. + if (!success) { + Program.DefaultLogger.Error("Failed to fetch data from the debugger."); + return false; + } + // Periodically try to parse the .txt file. + for (var i = 0; i < _maxAttempts; i++) { + Program.DefaultLogger.Info($"{i}. attempt to parse the info file."); + // Try to parse .txt file. + if (RetrieveDebuggerInfo(_infoFilePath)) { + Program.DefaultLogger.Info($"Info file has been parsed successfully."); + return true; + } + // Wait for a specified number of milliseconds. + await Task.Delay((int)_waitPeriodMs); + } + Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created."); + return false; + } + + /// <summary> + /// Tries to retrieve information from the debugger. + /// </summary> + /// <param name="filePath">path to the .txt file that contains all information</param> + /// <returns>True if the information was retrieved successfully. False, otherwise.</returns> + + protected bool RetrieveDebuggerInfo(string filePath) { + try { + // Read the content of the .txt file. + var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n"); + + // Parse it (try to find the serial numbers) + var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent); + + // Store the serial numbers into class variables (properties) + HeadSerialNumber = headSerialNumber; + BodySerialNumber = bodySerialNumber; + + // Finally, delete the file. + //File.Delete(filePath); + } catch (Exception exception) { + Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}"); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/IT32Utils.cs b/ld_client/LDClient/detection/IT32Utils.cs new file mode 100644 index 0000000..5904691 --- /dev/null +++ b/ld_client/LDClient/detection/IT32Utils.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.detection { + public interface IT32Utils { + + public bool InitConnection(); + public bool ExecuteCommands(); + public bool CloseConnection(); + + } +} diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs deleted file mode 100644 index 7854ea6..0000000 --- a/ld_client/LDClient/detection/InfoFetcher.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System.Diagnostics; -using LDClient.utils; -using LDClient.utils.loggers; - -namespace LDClient.detection { - - /// <summary> - /// This class implements the IInfoFetcher interface - /// which defines the functionality of an info fetcher. - /// </summary> - public class InfoFetcher : IInfoFetcher { - - /// <summary> - /// Default value of a serial number (undefined). - /// </summary> - private const string UndefinedSerialNumber = "number"; - - /// <summary> - /// Path to the t32rem.exe file which is used to send commands to the debugger. - /// </summary> - private readonly string _f32RemExecutable; - - /// <summary> - /// Arguments (commands) sent to the debugger in order to generate a .txt file - /// containing all the desired information. - /// </summary> - private readonly string[] _f32RemArguments; - - /// <summary> - /// Status code indicating a successful termination of t32rem.exe - /// </summary> - private readonly int _f32SuccessExitCode; - - /// <summary> - /// Timeout used when waiting for the t32rem.exe to finish. - /// </summary> - private readonly int _f32WaitTimeoutMs; - - /// <summary> - /// Maximum number of attempts to locate and parse the .txt file. - /// </summary> - private readonly uint _maxAttempts; - - /// <summary> - /// Period (how often) the application tries to locate and parse the .txt file. - /// </summary> - private readonly uint _waitPeriodMs; - - /// <summary> - /// Path to the .txt file which is generated from the debugger. - /// </summary> - private readonly string _infoFilePath; - - /// <summary> - /// Instance of ProcessUtils which encapsulates common functionality - /// when it comes to dealing with processes (limited by the needs of this application). - /// </summary> - public IProcessUtils ProcessUtils; - - /// <summary> - /// Instance of FileUtils which encapsulates common functionality - /// when it comes to dealing with files (limited by the needs of this application). - /// </summary> - public IFileUtils FileUtils; - - /// <summary> - /// Returns the head serial number of the debugger. - /// </summary> - public string HeadSerialNumber { get; set; } = UndefinedSerialNumber; - - /// <summary> - /// Returns the body serial number of the debugger. - /// </summary> - public string BodySerialNumber { get; set; } = UndefinedSerialNumber; - - /// <summary> - /// Creates an instance of this class. - /// </summary> - /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param> - /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param> - /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param> - /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param> - /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param> - /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param> - /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param> - public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, - string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) { - // Store the parameters into the class variables. - _maxAttempts = maxAttempts; - _waitPeriodMs = waitPeriodMs; - _infoFilePath = infoFilePath; - _f32RemExecutable = f32RemExecutable; - _f32RemArguments = f32RemArguments; - _f32SuccessExitCode = f32SuccessExitCode; - _f32WaitTimeoutMs = f32WaitTimeoutMs; - - // Create an instance of ProcessUtils. - ProcessUtils = new ProcessUtils(); - - // Create an instance of FileUtils. - FileUtils = new FileUtils(); - } - - /// <summary> - /// Fetches data from the debugger. It sends the commands defined - /// in the appsettings.json file to the debugger and tries to - /// parse the .txt (contains the serial numbers). - /// </summary> - /// <returns>True, if data was fetched successfully. False otherwise.</returns> - public async Task<bool> FetchDataAsync() { - Program.DefaultLogger.Info("Fetching data from the debugger."); - - // Send the commands to the debugger. - var success = SendRetrieveInfoCommands(_f32RemExecutable, _f32RemArguments, _f32SuccessExitCode, _f32WaitTimeoutMs); - - // Make sure that all commands were sent and executed successfully. - if (!success) { - Program.DefaultLogger.Error("Failed to fetch data from the debugger."); - return false; - } - - // Periodically try to parse the .txt file. - for (var i = 0; i < _maxAttempts; i++) { - Program.DefaultLogger.Info($"{i}. attempt to parse the info file."); - - // Try to parse .txt file. - if (RetrieveDebuggerInfo(_infoFilePath)) { - Program.DefaultLogger.Info($"Info file has been parsed successfully."); - return true; - } - // Wait for a specified number of milliseconds. - await Task.Delay((int)_waitPeriodMs); - } - Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created."); - return false; - } - - /// <summary> - /// Tries to retrieve information from the debugger. - /// </summary> - /// <param name="filePath">path to the .txt file that contains all information</param> - /// <returns>True if the information was retrieved successfully. False, otherwise.</returns> - private bool RetrieveDebuggerInfo(string filePath) { - try { - // Read the content of the .txt file. - var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n"); - - // Parse it (try to find the serial numbers) - var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent); - - // Store the serial numbers into class variables (properties) - HeadSerialNumber = headSerialNumber; - BodySerialNumber = bodySerialNumber; - - // Finally, delete the file. - File.Delete(filePath); - } catch (Exception exception) { - Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}"); - return false; - } - return true; - } - - /// <summary> - /// Sends commands to the debugger. - /// </summary> - /// <param name="executableFile">Path to the t32rem.exe file</param> - /// <param name="arguments">Arguments sent to the debugger through t32rem.exe (one argument is one command)</param> - /// <param name="desiredExitCode">Status code indicating successful termination of t32rem.exe</param> - /// <param name="waitTimeoutMs">Timeout used when waiting for t32rem.exe to finish</param> - /// <returns>True if all the commands were executed successfully. False, otherwise.</returns> - private bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int desiredExitCode, int waitTimeoutMs) { - if (arguments == null) { - Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given"); - return false; - } - // Execute one all arguments (commands) one by one. - foreach (var argument in arguments) { - if (!ProcessUtils.ExecuteNewProcess(executableFile, argument, waitTimeoutMs, desiredExitCode)) { - return false; - } - } - return true; - } - } -} \ No newline at end of file -- GitLab From 6cde905ffbe816a629dfad1019221d2657874270 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 8 May 2022 12:50:38 +0200 Subject: [PATCH 55/67] re #9712 Added t32 api fetcher --- ld_client/LDClient/detection/T32ApiFetcher.cs | 103 ++++++++++++++++++ ld_client/LDClient/detection/T32RemFetcher.cs | 72 ++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 ld_client/LDClient/detection/T32ApiFetcher.cs create mode 100644 ld_client/LDClient/detection/T32RemFetcher.cs diff --git a/ld_client/LDClient/detection/T32ApiFetcher.cs b/ld_client/LDClient/detection/T32ApiFetcher.cs new file mode 100644 index 0000000..50a5deb --- /dev/null +++ b/ld_client/LDClient/detection/T32ApiFetcher.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace LDClient.detection { + + public class T32ApiFetcher : AInfoFetcher, IT32Utils { +#if _WINDOWS + private const string T32DllLibrary = "./lib/t32api64.dll"; +#else + private const string T32DllLibrary = "./lib/t32api64.so"; +#endif + + private readonly string _t32Address; + private readonly string _t32Port; + private readonly string _t32PacketLength; + private readonly string[] _commands; + + public T32ApiFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string t32Address, + string t32Port, string t32PacketLength, string[] commands) : base(maxAttempts, waitPeriodMs, infoFilePath) { + this._t32Address = t32Address; + this._t32Port = t32Port; + this._t32PacketLength = t32PacketLength; + this._commands = commands; + } + + + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Config(string s1, string s2); + + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Init(); + + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Attach(int dev); + + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Cmd(string command); + + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Exit(); + + public bool InitConnection() { + Program.DefaultLogger.Debug("Trace32 connection initialization"); + var config1 = T32_Config("NODE=", _t32Address); + var config2 = T32_Config("PORT=", _t32Port); + var config3 = T32_Config("PACKLEN=", _t32PacketLength); + + if (config1 != 0 || config2 != 0 || config3 != 0) { + Program.DefaultLogger.Error("Trace32 API connection configuration failed."); + return false; + } + var init = T32_Init(); + if (init != 0) { + Program.DefaultLogger.Error("Trace32 API connection init failed."); + return false; + } + + var attach = T32_Attach(1); + if (attach != 0) { + Program.DefaultLogger.Error("Trace32 API connection attach failed."); + } + + Program.DefaultLogger.Info("Trace32 connection established"); + return true; + } + + public bool ExecuteCommands() { + Program.DefaultLogger.Info("Trace32 API commands execution."); + foreach (var command in _commands) { + Program.DefaultLogger.Debug($"Executing Trace32 command '{command}'."); + var ret = T32_Cmd(command); + if (ret != 0) { + Program.DefaultLogger.Error($"Execution of command '{command}' failed. Return code {ret}."); + return false; + } + } + Program.DefaultLogger.Info("All Trace32 commands executed successfully."); + return true; + } + + public bool CloseConnection() { + Program.DefaultLogger.Debug("Trace32 connection exit"); + return T32_Exit() == 0; + } + + protected override bool FetchData() { + var connected = false; + for (var i = 0; i < _maxAttempts; i++) { + connected = InitConnection(); + if (connected) { + break; + } + Thread.Sleep((int)_waitPeriodMs); + + } + return connected && ExecuteCommands() && CloseConnection(); + } + } +} diff --git a/ld_client/LDClient/detection/T32RemFetcher.cs b/ld_client/LDClient/detection/T32RemFetcher.cs new file mode 100644 index 0000000..30dbeb0 --- /dev/null +++ b/ld_client/LDClient/detection/T32RemFetcher.cs @@ -0,0 +1,72 @@ +using System.Diagnostics; +using LDClient.utils; +using LDClient.utils.loggers; + +namespace LDClient.detection { + + public class T32RemFetcher : AInfoFetcher{ + + /// <summary> + /// Path to the t32rem.exe file which is used to send commands to the debugger. + /// </summary> + private readonly string _f32RemExecutable; + + /// <summary> + /// Arguments (commands) sent to the debugger in order to generate a .txt file + /// containing all the desired information. + /// </summary> + private readonly string[] _f32RemArguments; + + /// <summary> + /// Status code indicating a successful termination of t32rem.exe + /// </summary> + private readonly int _f32SuccessExitCode; + + + /// <summary> + /// Timeout used when waiting for the t32rem.exe to finish. + /// </summary> + private readonly int _f32WaitTimeoutMs; + + /// <summary> + /// Instance of ProcessUtils which encapsulates common functionality + /// when it comes to dealing with processes (limited by the needs of this application). + /// </summary> + public IProcessUtils ProcessUtils; + + /// <summary> + /// Creates an instance of this class. + /// </summary> + /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param> + /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param> + /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param> + /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param> + /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param> + /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param> + /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param> + + public T32RemFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, + string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) : base(maxAttempts, waitPeriodMs, infoFilePath) { + _f32RemExecutable = f32RemExecutable; + _f32RemArguments = f32RemArguments; + _f32SuccessExitCode = f32SuccessExitCode; + _f32WaitTimeoutMs = f32WaitTimeoutMs; + ProcessUtils = new ProcessUtils(); + + } + + protected override bool FetchData() { + if (_f32RemArguments == null) { + Program.DefaultLogger.Error($"Failed to run {_f32RemExecutable} - no parameters were given"); + return false; + } + // Execute one all arguments (commands) one by one. + foreach (var argument in _f32RemArguments) { + if (!ProcessUtils.ExecuteNewProcess(_f32RemExecutable, argument, _f32WaitTimeoutMs, _f32SuccessExitCode)) { + return false; + } + } + return true; + } + } +} \ No newline at end of file -- GitLab From d49f4d79d28ae98f65c8a4bcaa354e2b6d181f23 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 8 May 2022 12:52:57 +0200 Subject: [PATCH 56/67] re #9712 main new info fetcher redefinition --- ld_client/LDClient/Program.cs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 98a61b2..04c6099 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -33,20 +33,37 @@ internal static class Program { /// Instance of an API client. /// </summary> private static IApiClient? DefaultApiClient { get; set; } - + + /* + + It is possible to use previous info fetching method + /// <summary> /// Instance of an info fetcher. /// </summary> - private static readonly InfoFetcher InfoFetcher = new( + private static readonly IInfoFetcher InfoFetcher = new( Config.FetchInfoMaxAttempts, Config.FetchInfoAttemptPeriod, Config.T32InfoLocation, - Config.F32RemExecutable, - Config.F32RemArguments, + Config.T32RemExecutable, + Config.T32RemArguments, Config.T32RemSuccessExitCode, Config.T32RemWaitTimeoutMs ); - + */ + /// <summary> + /// Instance of an info fetcher + /// </summary> + private static readonly IInfoFetcher InfoFetcher = new T32ApiFetcher( + Config.FetchInfoMaxAttempts, + Config.FetchInfoAttemptPeriod, + Config.T32InfoLocation, + Config.T32ApiAddress, + Config.T32ApiPort, + Config.T32ApiPacketLen, + Config.T32ApiCommands + ); + /// <summary> /// The main entry pint of the application. /// </summary> -- GitLab From e6a01bd8a1f18450fab43c329b955876f4aea7d6 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 8 May 2022 13:25:41 +0200 Subject: [PATCH 57/67] re #9712 Added documentation of the newly implemented methods + refactoring --- ld_client/LDClient/detection/AInfoFetcher.cs | 7 +- .../LDClient/detection/DebuggerInfoParser.cs | 59 ++-- ld_client/LDClient/detection/IInfoFetcher.cs | 49 ++- .../LDClient/detection/IProcessDetection.cs | 25 +- ld_client/LDClient/detection/IProcessUtils.cs | 51 ++- ld_client/LDClient/detection/IT32Utils.cs | 38 ++- .../LDClient/detection/ProcessDetection.cs | 304 +++++++++--------- ld_client/LDClient/detection/ProcessUtils.cs | 94 +++--- ld_client/LDClient/detection/T32ApiFetcher.cs | 232 ++++++++----- ld_client/LDClient/detection/T32RemFetcher.cs | 111 ++++--- ld_client/LDClient/utils/ConfigLoader.cs | 26 +- 11 files changed, 530 insertions(+), 466 deletions(-) diff --git a/ld_client/LDClient/detection/AInfoFetcher.cs b/ld_client/LDClient/detection/AInfoFetcher.cs index c41f581..bdacb4a 100644 --- a/ld_client/LDClient/detection/AInfoFetcher.cs +++ b/ld_client/LDClient/detection/AInfoFetcher.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using LDClient.utils; +using LDClient.utils; namespace LDClient.detection; diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs index 27b80c6..a4cdee7 100644 --- a/ld_client/LDClient/detection/DebuggerInfoParser.cs +++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs @@ -1,41 +1,40 @@ using System.Text.RegularExpressions; -namespace LDClient.detection { +namespace LDClient.detection; + +/// <summary> +/// This class parses the .txt file generated from the debugger. +/// Its primary interest is to find two serial numbers (head + body). +/// </summary> +public static class DebuggerInfoParser { /// <summary> - /// This class parses the .txt file generated from the debugger. - /// Its primary interest is to find two serial numbers (head + body). + /// Number of serial numbers expected to be in the .txt file (number of matches - regex). /// </summary> - public static class DebuggerInfoParser { - - /// <summary> - /// Number of serial numbers expected to be in the .txt file (number of matches - regex). - /// </summary> - private const int ExpectedNumberOfMatches = 2; + private const int ExpectedNumberOfMatches = 2; - /// <summary> - /// Regular expression used to find the serial numbers. - /// </summary> - private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)"); + /// <summary> + /// Regular expression used to find the serial numbers. + /// </summary> + private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)"); - /// <summary> - /// Takes the content of a .txt file and tries to find the two serial numbers (head and body). - /// If it succeed, it will return the two numbers. - /// </summary> - /// <param name="dataTxt">the content of a .txt file (generated from the debugger)</param> - /// <returns>two serial numbers (head and body) of the debugger</returns> - /// <exception cref="ArgumentException">throws an exception if it fails to find the serial numbers</exception> - public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) { - // Find all matches in the content of the file that satisfy the regular expression. - var matches = SerialNumberRegex.Matches(dataTxt); + /// <summary> + /// Takes the content of a .txt file and tries to find the two serial numbers (head and body). + /// If it succeed, it will return the two numbers. + /// </summary> + /// <param name="dataTxt">the content of a .txt file (generated from the debugger)</param> + /// <returns>two serial numbers (head and body) of the debugger</returns> + /// <exception cref="ArgumentException">throws an exception if it fails to find the serial numbers</exception> + public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) { + // Find all matches in the content of the file that satisfy the regular expression. + var matches = SerialNumberRegex.Matches(dataTxt); - // Make sure an exact number of matches has been found. - if (matches.Count != ExpectedNumberOfMatches) { - throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})"); - } - - // Return the two serial numbers (head and body). - return (matches[1].ToString().Trim(), matches[0].ToString().Trim()); + // Make sure an exact number of matches has been found. + if (matches.Count != ExpectedNumberOfMatches) { + throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})"); } + + // Return the two serial numbers (head and body). + return (matches[1].ToString().Trim(), matches[0].ToString().Trim()); } } \ No newline at end of file diff --git a/ld_client/LDClient/detection/IInfoFetcher.cs b/ld_client/LDClient/detection/IInfoFetcher.cs index f8c47a3..c5e871f 100644 --- a/ld_client/LDClient/detection/IInfoFetcher.cs +++ b/ld_client/LDClient/detection/IInfoFetcher.cs @@ -1,33 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace LDClient.detection; + +/// <summary> +/// This interface defines the functionality of an info fetcher which +/// takes care of sending commands to the debugger. +/// </summary> +public interface IInfoFetcher { -namespace LDClient.detection { - /// <summary> - /// This interface defines the functionality of an info fetcher which - /// takes care of sending commands to the debugger. + /// Returns the head serial number of the debugger. /// </summary> - public interface IInfoFetcher { - - /// <summary> - /// Returns the head serial number of the debugger. - /// </summary> - public string HeadSerialNumber { get; set; } + public string HeadSerialNumber { get; set; } - /// <summary> - /// Returns the body serial number of the debugger. - /// </summary> - public string BodySerialNumber { get; set; } + /// <summary> + /// Returns the body serial number of the debugger. + /// </summary> + public string BodySerialNumber { get; set; } - /// <summary> - /// Fetches data from the debugger. It sends the commands defined - /// in the appsettings.json file to the debugger and tries to - /// parse the .txt (contains the serial numbers). - /// </summary> - /// <returns>True, if data was fetched successfully. False otherwise.</returns> - public Task<bool> FetchDataAsync(); - } -} + /// <summary> + /// Fetches data from the debugger. It sends the commands defined + /// in the appsettings.json file to the debugger and tries to + /// parse the .txt (contains the serial numbers). + /// </summary> + /// <returns>True, if data was fetched successfully. False otherwise.</returns> + public Task<bool> FetchDataAsync(); +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/IProcessDetection.cs b/ld_client/LDClient/detection/IProcessDetection.cs index 27383f5..03a2398 100644 --- a/ld_client/LDClient/detection/IProcessDetection.cs +++ b/ld_client/LDClient/detection/IProcessDetection.cs @@ -1,16 +1,15 @@ -namespace LDClient.detection { - +namespace LDClient.detection; + +/// <summary> +/// This interface defines the functionality of a process detector. +/// A process detector is used to determine whether a user is currently +/// using a debugger or not. +/// </summary> +internal interface IProcessDetection { + /// <summary> - /// This interface defines the functionality of a process detector. - /// A process detector is used to determine whether a user is currently - /// using a debugger or not. + /// Periodically runs process detection. This method is instantiated + /// as a thread from the main class (Program.cs). /// </summary> - internal interface IProcessDetection { - - /// <summary> - /// Periodically runs process detection. This method is instantiated - /// as a thread from the main class (Program.cs). - /// </summary> - public void RunPeriodicDetection(); - } + public void RunPeriodicDetection(); } \ No newline at end of file diff --git a/ld_client/LDClient/detection/IProcessUtils.cs b/ld_client/LDClient/detection/IProcessUtils.cs index d55a663..6759e14 100644 --- a/ld_client/LDClient/detection/IProcessUtils.cs +++ b/ld_client/LDClient/detection/IProcessUtils.cs @@ -1,33 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace LDClient.detection; -namespace LDClient.detection { - +/// <summary> +/// This interface defines the functionality of all methods that +/// are used to work with processes (within this project). +/// </summary> +public interface IProcessUtils { + /// <summary> - /// This interface defines the functionality of all methods that - /// are used to work with processes (within this project). + /// Checks if a process is running or not. /// </summary> - public interface IProcessUtils { - - /// <summary> - /// Checks if a process is running or not. - /// </summary> - /// <param name="name">Name of the process</param> - /// <returns>True, if the process is running. False otherwise.</returns> - public bool IsProcessRunning(string name); + /// <param name="name">Name of the process</param> + /// <returns>True, if the process is running. False otherwise.</returns> + public bool IsProcessRunning(string name); - /// <summary> - /// Executes a new process (t32rem.exe) with arguments which are passed in - /// as a parameter of the method. - /// </summary> - /// <param name="fileName">Path to the .exe file</param> - /// <param name="argument">Arguments passed into the .exe file</param> - /// <param name="timeout">Timeout used when waiting for the process to terminate</param> - /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param> - /// <returns>True, if the command was executed successfully. False otherwise.</returns> - public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode); - } -} + /// <summary> + /// Executes a new process (t32rem.exe) with arguments which are passed in + /// as a parameter of the method. + /// </summary> + /// <param name="fileName">Path to the .exe file</param> + /// <param name="argument">Arguments passed into the .exe file</param> + /// <param name="timeout">Timeout used when waiting for the process to terminate</param> + /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param> + /// <returns>True, if the command was executed successfully. False otherwise.</returns> + public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode); +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/IT32Utils.cs b/ld_client/LDClient/detection/IT32Utils.cs index 5904691..f33fb29 100644 --- a/ld_client/LDClient/detection/IT32Utils.cs +++ b/ld_client/LDClient/detection/IT32Utils.cs @@ -1,15 +1,29 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace LDClient.detection; -namespace LDClient.detection { - public interface IT32Utils { - public bool InitConnection(); - public bool ExecuteCommands(); - public bool CloseConnection(); +/// <summary> +/// This interface defines the main functionality of an trace32 API +/// which is mainly used to send commands to the debugger. +/// </summary> +public interface IT32Utils { + + /// <summary> + /// This method initialized the connection with the trace32 application API. + /// It setups the standard connection configuration a tries to connect to the API + /// </summary> + /// <returns>true on success</returns> + public bool InitConnection(); - } -} + /// <summary> + /// Method executes all passed commands though the trace32 API + /// </summary> + /// <returns>true on success</returns> + public bool ExecuteCommands(); + + /// <summary> + /// This method closes the connection with the trace32 application api + /// </summary> + /// <returns>true on success</returns> + public bool CloseConnection(); + +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs index 4bde0fd..af47b38 100644 --- a/ld_client/LDClient/detection/ProcessDetection.cs +++ b/ld_client/LDClient/detection/ProcessDetection.cs @@ -1,185 +1,183 @@ -using System.Diagnostics; -using LDClient.network; +using LDClient.network; using LDClient.network.data; -namespace LDClient.detection { +namespace LDClient.detection; + +/// <summary> +/// This class takes care of process detection. When t32mtc (process) +/// is detected, it means that the debugger is currently being used. +/// The class keeps track of the current state of a debugger. +/// </summary> +public sealed class ProcessDetection : IProcessDetection { /// <summary> - /// This class takes care of process detection. When t32mtc (process) - /// is detected, it means that the debugger is currently being used. - /// The class keeps track of the current state of a debugger. + /// Datetime format used when sending payloads to the server. /// </summary> - public sealed class ProcessDetection : IProcessDetection { - - /// <summary> - /// Datetime format used when sending payloads to the server. - /// </summary> - private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss"; + private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss"; - /// <summary> - /// Name of the process the application detects. - /// </summary> - private readonly string _processName; + /// <summary> + /// Name of the process the application detects. + /// </summary> + private readonly string _processName; - /// <summary> - /// How often the application check the current status of the process (cunning / not running). - /// </summary> - private readonly uint _detectionPeriodMs; + /// <summary> + /// How often the application check the current status of the process (cunning / not running). + /// </summary> + private readonly uint _detectionPeriodMs; - /// <summary> - /// Instance of InfoFetcher used to fetch information from the debugger - /// (when the process is detected). - /// </summary> - private readonly IInfoFetcher _infoFetcher; + /// <summary> + /// Instance of InfoFetcher used to fetch information from the debugger + /// (when the process is detected). + /// </summary> + private readonly IInfoFetcher _infoFetcher; - /// <summary> - /// Instance of API clients used for sending data off to the server. - /// </summary> - private readonly IApiClient _apiClient; + /// <summary> + /// Instance of API clients used for sending data off to the server. + /// </summary> + private readonly IApiClient _apiClient; - /// <summary> - /// Instance of ProcessUtils which encapsulates common functionality - /// when it comes to dealing with processes (limited by the needs of this application). - /// </summary> - private readonly IProcessUtils _processUtils; + /// <summary> + /// Instance of ProcessUtils which encapsulates common functionality + /// when it comes to dealing with processes (limited by the needs of this application). + /// </summary> + private readonly IProcessUtils _processUtils; - /// <summary> - /// Flag indicating whether the process is currently running or not. - /// </summary> - private bool _processIsActive; + /// <summary> + /// Flag indicating whether the process is currently running or not. + /// </summary> + private bool _processIsActive; - /// <summary> - /// Flag if the application failed to retrieve data when the process was detected. - /// </summary> - private bool _failedToRetrieveData; + /// <summary> + /// Flag if the application failed to retrieve data when the process was detected. + /// </summary> + private bool _failedToRetrieveData; - /// <summary> - /// Last payload that was sent to the server. - /// </summary> - private Payload? _lastConnectedPayload; + /// <summary> + /// Last payload that was sent to the server. + /// </summary> + private Payload? _lastConnectedPayload; - /// <summary> - /// Flag used to stop the thread (process detection). - /// </summary> - public bool DetectionRunning = false; + /// <summary> + /// Flag used to stop the thread (process detection). + /// </summary> + public bool DetectionRunning = false; - /// <summary> - /// Creates an instance of this class. - /// </summary> - /// <param name="processName">Name of the process the application detects</param> - /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param> - /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param> - /// <param name="apiClient">Instance of API clients used for sending data off to the server</param> - /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param> - public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, - IApiClient apiClient, IProcessUtils processUtils) { - _processName = processName; - _detectionPeriodMs = detectionPeriodMs; - _infoFetcher = infoFetcher; - _apiClient = apiClient; - _failedToRetrieveData = false; - _processUtils = processUtils; - } + /// <summary> + /// Creates an instance of this class. + /// </summary> + /// <param name="processName">Name of the process the application detects</param> + /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param> + /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param> + /// <param name="apiClient">Instance of API clients used for sending data off to the server</param> + /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param> + public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, + IApiClient apiClient, IProcessUtils processUtils) { + _processName = processName; + _detectionPeriodMs = detectionPeriodMs; + _infoFetcher = infoFetcher; + _apiClient = apiClient; + _failedToRetrieveData = false; + _processUtils = processUtils; + } - /// <summary> - /// Retrieves data from the debugger. - /// </summary> - /// <returns>True, if the data was fetched successfully. False, otherwise.</returns> - private async Task<bool> RetrieveDataFromDebugger() { - // Try to fetch data from the debugger. - var success = await _infoFetcher.FetchDataAsync(); + /// <summary> + /// Retrieves data from the debugger. + /// </summary> + /// <returns>True, if the data was fetched successfully. False, otherwise.</returns> + private async Task<bool> RetrieveDataFromDebugger() { + // Try to fetch data from the debugger. + var success = await _infoFetcher.FetchDataAsync(); - // If the data was fetched successfully, send a payload off to the server. - if (success) { - _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, - _infoFetcher.BodySerialNumber, DatetimeFormat); - } - return success; + // If the data was fetched successfully, send a payload off to the server. + if (success) { + _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, + _infoFetcher.BodySerialNumber, DatetimeFormat); } + return success; + } - /// <summary> - /// Sends a payload to the server when a debugger gets disconnected. - /// </summary> - private async Task DebuggerDisconnected() { - // Make sure the debugger was connected in the first place. - if (_lastConnectedPayload is not null) { - // Update the status and timestamp of the last payload - // (the serial numbers remain the same). - _lastConnectedPayload.Status = ConnectionStatus.Disconnected; - _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat); + /// <summary> + /// Sends a payload to the server when a debugger gets disconnected. + /// </summary> + private async Task DebuggerDisconnected() { + // Make sure the debugger was connected in the first place. + if (_lastConnectedPayload is not null) { + // Update the status and timestamp of the last payload + // (the serial numbers remain the same). + _lastConnectedPayload.Status = ConnectionStatus.Disconnected; + _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat); - // Send the data to the server. - await _apiClient.SendPayloadAsync(_lastConnectedPayload); + // Send the data to the server. + await _apiClient.SendPayloadAsync(_lastConnectedPayload); - // Clear the last payload. - _lastConnectedPayload = null; - } + // Clear the last payload. + _lastConnectedPayload = null; } + } - /// <summary> - /// Checks if the t32mtc process is running or not. - /// </summary> - private async Task DetectProcessAsync() { - // Check if the process is running. - var processExists = _processUtils.IsProcessRunning(_processName); + /// <summary> + /// Checks if the t32mtc process is running or not. + /// </summary> + private async Task DetectProcessAsync() { + // Check if the process is running. + var processExists = _processUtils.IsProcessRunning(_processName); - // Check if the process was not running but now it is (flip flop ON). - if (processExists && !_processIsActive) { - Program.DefaultLogger.Info($"Process started: {_processName}"); - if (!_failedToRetrieveData) { - _failedToRetrieveData = !await RetrieveDataFromDebugger(); - } - } - // Check if the process was running but now it is not (fli flop OFF). - else if (!processExists && _processIsActive) { - Program.DefaultLogger.Info($"Process stopped: {_processName}"); - _failedToRetrieveData = false; - await DebuggerDisconnected(); + // Check if the process was not running but now it is (flip flop ON). + if (processExists && !_processIsActive) { + Program.DefaultLogger.Info($"Process started: {_processName}"); + if (!_failedToRetrieveData) { + _failedToRetrieveData = !await RetrieveDataFromDebugger(); } - - // Keep track of the current state of the debugger. - _processIsActive = processExists; + } + // Check if the process was running but now it is not (fli flop OFF). + else if (!processExists && _processIsActive) { + Program.DefaultLogger.Info($"Process stopped: {_processName}"); + _failedToRetrieveData = false; + await DebuggerDisconnected(); } - /// <summary> - /// Creates a payload and sends it to the server. - /// </summary> - /// <param name="headSerialNumber">serial number of the head of the debugger</param> - /// <param name="bodySerialNumber">serial number of the body of the debugger</param> - /// <param name="datetimeFormat">datetime format (timestamp)</param> - /// <returns>the newly-created payload</returns> - private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) { - // Create a new payload. - Payload payload = new() { - UserName = Environment.UserName, - HostName = Environment.MachineName, - TimeStamp = DateTime.Now.ToString(datetimeFormat), - HeadDevice = new DebuggerInfo { - SerialNumber = headSerialNumber - }, - BodyDevice = new DebuggerInfo { - SerialNumber = bodySerialNumber - }, - Status = ConnectionStatus.Connected - }; + // Keep track of the current state of the debugger. + _processIsActive = processExists; + } + + /// <summary> + /// Creates a payload and sends it to the server. + /// </summary> + /// <param name="headSerialNumber">serial number of the head of the debugger</param> + /// <param name="bodySerialNumber">serial number of the body of the debugger</param> + /// <param name="datetimeFormat">datetime format (timestamp)</param> + /// <returns>the newly-created payload</returns> + private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) { + // Create a new payload. + Payload payload = new() { + UserName = Environment.UserName, + HostName = Environment.MachineName, + TimeStamp = DateTime.Now.ToString(datetimeFormat), + HeadDevice = new DebuggerInfo { + SerialNumber = headSerialNumber + }, + BodyDevice = new DebuggerInfo { + SerialNumber = bodySerialNumber + }, + Status = ConnectionStatus.Connected + }; - // Send it to the server and return it. - await _apiClient.SendPayloadAsync(payload); - return payload; - } + // Send it to the server and return it. + await _apiClient.SendPayloadAsync(payload); + return payload; + } - /// <summary> - /// Periodically runs process detection. This method is instantiated - /// as a thread from the main class (Program.cs). - /// </summary> - public async void RunPeriodicDetection() { - Program.DefaultLogger.Info("Process periodic detector has started"); - DetectionRunning = true; + /// <summary> + /// Periodically runs process detection. This method is instantiated + /// as a thread from the main class (Program.cs). + /// </summary> + public async void RunPeriodicDetection() { + Program.DefaultLogger.Info("Process periodic detector has started"); + DetectionRunning = true; - while (DetectionRunning) { - await DetectProcessAsync(); - Thread.Sleep((int) _detectionPeriodMs); - } + while (DetectionRunning) { + await DetectProcessAsync(); + Thread.Sleep((int) _detectionPeriodMs); } } -} +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/ProcessUtils.cs b/ld_client/LDClient/detection/ProcessUtils.cs index 5c448e7..af52955 100644 --- a/ld_client/LDClient/detection/ProcessUtils.cs +++ b/ld_client/LDClient/detection/ProcessUtils.cs @@ -1,60 +1,54 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Diagnostics; + +namespace LDClient.detection; + +/// <summary> +/// This class implements the IProcessUtils interface. +/// It implements methods that are used when dealing with processes. +/// </summary> +public class ProcessUtils : IProcessUtils { -namespace LDClient.detection { - /// <summary> - /// This class implements the IProcessUtils interface. - /// It implements methods that are used when dealing with processes. + /// Checks if a process is running or not. /// </summary> - public class ProcessUtils : IProcessUtils { - - /// <summary> - /// Checks if a process is running or not. - /// </summary> - /// <param name="name">Name of the process</param> - /// <returns>True, if the process is running. False otherwise.</returns> - public bool IsProcessRunning(string name) { - return Process.GetProcessesByName(name).Length > 0; - } + /// <param name="name">Name of the process</param> + /// <returns>True, if the process is running. False otherwise.</returns> + public bool IsProcessRunning(string name) { + return Process.GetProcessesByName(name).Length > 0; + } - /// <summary> - /// Executes a new process (t32rem.exe) with arguments which are passed in - /// as a parameter of the method. - /// </summary> - /// <param name="fileName">Path to the .exe file</param> - /// <param name="argument">Arguments passed into the .exe file</param> - /// <param name="timeout">Timeout used when waiting for the process to terminate</param> - /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param> - /// <returns>True, if the command was executed successfully. False otherwise.</returns> - public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) { - // Create a new process. - var t32RemProcess = new Process(); - t32RemProcess.StartInfo.FileName = fileName; - t32RemProcess.StartInfo.Arguments = argument; + /// <summary> + /// Executes a new process (t32rem.exe) with arguments which are passed in + /// as a parameter of the method. + /// </summary> + /// <param name="fileName">Path to the .exe file</param> + /// <param name="argument">Arguments passed into the .exe file</param> + /// <param name="timeout">Timeout used when waiting for the process to terminate</param> + /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param> + /// <returns>True, if the command was executed successfully. False otherwise.</returns> + public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) { + // Create a new process. + var t32RemProcess = new Process(); + t32RemProcess.StartInfo.FileName = fileName; + t32RemProcess.StartInfo.Arguments = argument; - try { - // Execute the process and wait until it terminates or until the timeout is up. - t32RemProcess.Start(); - if (!t32RemProcess.WaitForExit(timeout)) { - Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms"); - return false; - } + try { + // Execute the process and wait until it terminates or until the timeout is up. + t32RemProcess.Start(); + if (!t32RemProcess.WaitForExit(timeout)) { + Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms"); + return false; + } - // Check if the process terminated successfully. - if (t32RemProcess.ExitCode != desiredExitCode) { - Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}"); - return false; - } - } catch (Exception exception) { - Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}"); + // Check if the process terminated successfully. + if (t32RemProcess.ExitCode != desiredExitCode) { + Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}"); return false; } - return true; + } catch (Exception exception) { + Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}"); + return false; } + return true; } -} +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/T32ApiFetcher.cs b/ld_client/LDClient/detection/T32ApiFetcher.cs index 50a5deb..893e95e 100644 --- a/ld_client/LDClient/detection/T32ApiFetcher.cs +++ b/ld_client/LDClient/detection/T32ApiFetcher.cs @@ -1,103 +1,167 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; +using System.Runtime.InteropServices; -namespace LDClient.detection { +namespace LDClient.detection; - public class T32ApiFetcher : AInfoFetcher, IT32Utils { +public class T32ApiFetcher : AInfoFetcher, IT32Utils { #if _WINDOWS - private const string T32DllLibrary = "./lib/t32api64.dll"; + /// <summary> + /// Path to the Trace32 API library + /// </summary> + private const string T32DllLibrary = "./lib/t32api64.dll"; #else private const string T32DllLibrary = "./lib/t32api64.so"; #endif + /// <summary> + /// Address of the listening t32 application + /// </summary> + private readonly string _t32Address; + + /// <summary> + /// Port of the listening t32 application + /// </summary> + private readonly string _t32Port; + + /// <summary> + /// Size of the packets send/received from t32 application + /// </summary> + private readonly string _t32PacketLength; + + /// <summary> + /// List of commands to be executed by though the t32 api + /// </summary> + private readonly string[] _commands; + + /// <summary> + /// + /// </summary> + /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param> + /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param> + /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param> + /// <param name="t32Address">Address of the listening t32 application</param> + /// <param name="t32Port">Port of the listening t32 application</param> + /// <param name="t32PacketLength"> Size of the packets send/received from t32 application </param> + /// <param name="commands"> List of commands to be executed by though the t32 api</param> + public T32ApiFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string t32Address, + string t32Port, string t32PacketLength, string[] commands) : base(maxAttempts, waitPeriodMs, infoFilePath) { + this._t32Address = t32Address; + this._t32Port = t32Port; + this._t32PacketLength = t32PacketLength; + this._commands = commands; + } - private readonly string _t32Address; - private readonly string _t32Port; - private readonly string _t32PacketLength; - private readonly string[] _commands; - - public T32ApiFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string t32Address, - string t32Port, string t32PacketLength, string[] commands) : base(maxAttempts, waitPeriodMs, infoFilePath) { - this._t32Address = t32Address; - this._t32Port = t32Port; - this._t32PacketLength = t32PacketLength; - this._commands = commands; - } - - - [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] - private static extern int T32_Config(string s1, string s2); - - [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] - private static extern int T32_Init(); - [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] - private static extern int T32_Attach(int dev); + /// <summary> + /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf + /// </summary> + /// <param name="s1"></param> + /// <param name="s2"></param> + /// <returns>return code</returns> + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Config(string s1, string s2); + + /// <summary> + /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf + /// </summary> + /// <returns>Return code</returns> + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Init(); + + /// <summary> + /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf + /// </summary> + /// <param name="dev"></param> + /// <returns>Return code</returns> + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Attach(int dev); + + /// <summary> + /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf + /// </summary> + /// <param name="command"></param> + /// <returns>Return code</returns> + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Cmd(string command); + + /// <summary> + /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf + /// </summary> + /// <returns>Return code</returns> + [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] + private static extern int T32_Exit(); + + + /// <summary> + /// This method initialized the connection with the trace32 application API. + /// It setups the standard connection configuration a tries to connect to the API + /// </summary> + /// <returns>true on success</returns> + public bool InitConnection() { + Program.DefaultLogger.Debug("Trace32 connection initialization"); + var config1 = T32_Config("NODE=", _t32Address); + var config2 = T32_Config("PORT=", _t32Port); + var config3 = T32_Config("PACKLEN=", _t32PacketLength); + + if (config1 != 0 || config2 != 0 || config3 != 0) { + Program.DefaultLogger.Error("Trace32 API connection configuration failed."); + return false; + } + var init = T32_Init(); + if (init != 0) { + Program.DefaultLogger.Error("Trace32 API connection init failed."); + return false; + } - [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] - private static extern int T32_Cmd(string command); + var attach = T32_Attach(1); + if (attach != 0) { + Program.DefaultLogger.Error("Trace32 API connection attach failed."); + } - [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)] - private static extern int T32_Exit(); - - public bool InitConnection() { - Program.DefaultLogger.Debug("Trace32 connection initialization"); - var config1 = T32_Config("NODE=", _t32Address); - var config2 = T32_Config("PORT=", _t32Port); - var config3 = T32_Config("PACKLEN=", _t32PacketLength); + Program.DefaultLogger.Info("Trace32 connection established"); + return true; + } - if (config1 != 0 || config2 != 0 || config3 != 0) { - Program.DefaultLogger.Error("Trace32 API connection configuration failed."); - return false; - } - var init = T32_Init(); - if (init != 0) { - Program.DefaultLogger.Error("Trace32 API connection init failed."); + /// <summary> + /// Method executes all passed commands though the trace32 API + /// </summary> + /// <returns>true on success</returns> + public bool ExecuteCommands() { + Program.DefaultLogger.Info("Trace32 API commands execution."); + foreach (var command in _commands) { + Program.DefaultLogger.Debug($"Executing Trace32 command '{command}'."); + var ret = T32_Cmd(command); + if (ret != 0) { + Program.DefaultLogger.Error($"Execution of command '{command}' failed. Return code {ret}."); return false; } - - var attach = T32_Attach(1); - if (attach != 0) { - Program.DefaultLogger.Error("Trace32 API connection attach failed."); - } - - Program.DefaultLogger.Info("Trace32 connection established"); - return true; - } - - public bool ExecuteCommands() { - Program.DefaultLogger.Info("Trace32 API commands execution."); - foreach (var command in _commands) { - Program.DefaultLogger.Debug($"Executing Trace32 command '{command}'."); - var ret = T32_Cmd(command); - if (ret != 0) { - Program.DefaultLogger.Error($"Execution of command '{command}' failed. Return code {ret}."); - return false; - } - } - Program.DefaultLogger.Info("All Trace32 commands executed successfully."); - return true; - } - - public bool CloseConnection() { - Program.DefaultLogger.Debug("Trace32 connection exit"); - return T32_Exit() == 0; } + Program.DefaultLogger.Info("All Trace32 commands executed successfully."); + return true; + } - protected override bool FetchData() { - var connected = false; - for (var i = 0; i < _maxAttempts; i++) { - connected = InitConnection(); - if (connected) { - break; - } - Thread.Sleep((int)_waitPeriodMs); + /// <summary> + /// This method closes the connection with the trace32 application api + /// </summary> + /// <returns>true on success</returns> + public bool CloseConnection() { + Program.DefaultLogger.Debug("Trace32 connection exit"); + return T32_Exit() == 0; + } + /// <summary> + /// Method tries to fetch the data from the trace32 application. + /// Upon connection fail it tries again for specified number of times + /// </summary> + /// <returns>true on success</returns> + protected override bool FetchData() { + var connected = false; + for (var i = 0; i < _maxAttempts; i++) { + connected = InitConnection(); + if (connected) { + break; } - return connected && ExecuteCommands() && CloseConnection(); + Thread.Sleep((int)_waitPeriodMs); + } + return connected && ExecuteCommands() && CloseConnection(); } -} +} \ No newline at end of file diff --git a/ld_client/LDClient/detection/T32RemFetcher.cs b/ld_client/LDClient/detection/T32RemFetcher.cs index 30dbeb0..91bda8c 100644 --- a/ld_client/LDClient/detection/T32RemFetcher.cs +++ b/ld_client/LDClient/detection/T32RemFetcher.cs @@ -1,72 +1,71 @@ -using System.Diagnostics; -using LDClient.utils; -using LDClient.utils.loggers; +namespace LDClient.detection; -namespace LDClient.detection { +public class T32RemFetcher : AInfoFetcher{ - public class T32RemFetcher : AInfoFetcher{ + /// <summary> + /// Path to the t32rem.exe file which is used to send commands to the debugger. + /// </summary> + private readonly string _f32RemExecutable; - /// <summary> - /// Path to the t32rem.exe file which is used to send commands to the debugger. - /// </summary> - private readonly string _f32RemExecutable; + /// <summary> + /// Arguments (commands) sent to the debugger in order to generate a .txt file + /// containing all the desired information. + /// </summary> + private readonly string[] _f32RemArguments; - /// <summary> - /// Arguments (commands) sent to the debugger in order to generate a .txt file - /// containing all the desired information. - /// </summary> - private readonly string[] _f32RemArguments; + /// <summary> + /// Status code indicating a successful termination of t32rem.exe + /// </summary> + private readonly int _f32SuccessExitCode; - /// <summary> - /// Status code indicating a successful termination of t32rem.exe - /// </summary> - private readonly int _f32SuccessExitCode; + /// <summary> + /// Timeout used when waiting for the t32rem.exe to finish. + /// </summary> + private readonly int _f32WaitTimeoutMs; - /// <summary> - /// Timeout used when waiting for the t32rem.exe to finish. - /// </summary> - private readonly int _f32WaitTimeoutMs; + /// <summary> + /// Instance of ProcessUtils which encapsulates common functionality + /// when it comes to dealing with processes (limited by the needs of this application). + /// </summary> + public IProcessUtils ProcessUtils; - /// <summary> - /// Instance of ProcessUtils which encapsulates common functionality - /// when it comes to dealing with processes (limited by the needs of this application). - /// </summary> - public IProcessUtils ProcessUtils; + /// <summary> + /// Creates an instance of this class. + /// </summary> + /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param> + /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param> + /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param> + /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param> + /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param> + /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param> + /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param> + public T32RemFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, + string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) : base(maxAttempts, waitPeriodMs, infoFilePath) { + _f32RemExecutable = f32RemExecutable; + _f32RemArguments = f32RemArguments; + _f32SuccessExitCode = f32SuccessExitCode; + _f32WaitTimeoutMs = f32WaitTimeoutMs; + ProcessUtils = new ProcessUtils(); - /// <summary> - /// Creates an instance of this class. - /// </summary> - /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param> - /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param> - /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param> - /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param> - /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param> - /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param> - /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param> - - public T32RemFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, - string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) : base(maxAttempts, waitPeriodMs, infoFilePath) { - _f32RemExecutable = f32RemExecutable; - _f32RemArguments = f32RemArguments; - _f32SuccessExitCode = f32SuccessExitCode; - _f32WaitTimeoutMs = f32WaitTimeoutMs; - ProcessUtils = new ProcessUtils(); + } + /// <summary> + /// Method tries to fetch the data from the trace32 application + /// via defined executable + /// </summary> + /// <returns>true upon success</returns> + protected override bool FetchData() { + if (_f32RemArguments == null) { + Program.DefaultLogger.Error($"Failed to run {_f32RemExecutable} - no parameters were given"); + return false; } - - protected override bool FetchData() { - if (_f32RemArguments == null) { - Program.DefaultLogger.Error($"Failed to run {_f32RemExecutable} - no parameters were given"); + // Execute one all arguments (commands) one by one. + foreach (var argument in _f32RemArguments) { + if (!ProcessUtils.ExecuteNewProcess(_f32RemExecutable, argument, _f32WaitTimeoutMs, _f32SuccessExitCode)) { return false; } - // Execute one all arguments (commands) one by one. - foreach (var argument in _f32RemArguments) { - if (!ProcessUtils.ExecuteNewProcess(_f32RemExecutable, argument, _f32WaitTimeoutMs, _f32SuccessExitCode)) { - return false; - } - } - return true; } + return true; } } \ No newline at end of file diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index f585cce..3544c46 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -39,11 +39,6 @@ namespace LDClient.utils { private const string DdSection = "DebuggerDetection"; - public string[] T32ApiCommands { get; private set; } = null!; - public string T32ApiAddress { get; private set; } = null!; - public string T32ApiPort { get; private set; } = null!; - public string T32ApiPacketLen { get; private set; } = null!; - #region Logger /// <summary> @@ -169,6 +164,27 @@ namespace LDClient.utils { /// </summary> public int T32RemWaitTimeoutMs { get; private set; } + + /// <summary> + /// List of commands to be executed by though the t32 api + /// </summary> + public string[] T32ApiCommands { get; private set; } = null!; + + /// <summary> + /// Address of the listening t32 application + /// </summary> + public string T32ApiAddress { get; private set; } = null!; + + /// <summary> + /// Port of the listening t32 application + /// </summary> + public string T32ApiPort { get; private set; } = null!; + + /// <summary> + /// Size of the packets send/received from t32 application + /// </summary> + public string T32ApiPacketLen { get; private set; } = null!; + #endregion /// <summary> -- GitLab From 964ced30f4baafd27de935cc441139370c5e176b Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 8 May 2022 13:27:01 +0200 Subject: [PATCH 58/67] re #9712 added tr32api dll --- ld_client/LDClient/lib/t32api64.dll | Bin 0 -> 250368 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ld_client/LDClient/lib/t32api64.dll diff --git a/ld_client/LDClient/lib/t32api64.dll b/ld_client/LDClient/lib/t32api64.dll new file mode 100644 index 0000000000000000000000000000000000000000..45bed3b6a273e38e05df808560dcd9002e0e8ba5 GIT binary patch literal 250368 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 aT!~a-?3Dz&MQ6X%*)d$;Uw{7TBJls)N99QX literal 0 HcmV?d00001 -- GitLab From 98bc5e43b474cf0d2971ff40ed90eab24b37444b Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Sun, 8 May 2022 13:32:03 +0200 Subject: [PATCH 59/67] re #9712 html doc generation --- ld_client/doc/pdoc/class_file_logger.html | 2 +- ..._client_1_1detection_1_1_info_fetcher.html | 2 +- ...nt_1_1detection_1_1_process_detection.html | 2 +- ...client_1_1detection_1_1_process_utils.html | 2 +- ..._l_d_client_1_1network_1_1_api_client.html | 2 +- ...l_d_client_1_1network_1_1_http_client.html | 2 +- ..._1_1network_1_1data_1_1_debugger_info.html | 2 +- ...client_1_1network_1_1data_1_1_payload.html | 2 +- ...ss_l_d_client_1_1utils_1_1_file_utils.html | 2 +- ...ient_1_1utils_1_1loggers_1_1_a_logger.html | 2 +- ..._1utils_1_1loggers_1_1_console_logger.html | 2 +- .../dir_082f6a8deca2b2d1a7c77b6edd561a50.html | 99 ++++++++++++++++ .../dir_3829590d4bc1496e3a509b2e3d199db3.html | 105 +++++++++++++++++ .../dir_3ff60c654341cc744f8b6bad46bdfd33.html | 99 ++++++++++++++++ .../dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html | 99 ++++++++++++++++ .../dir_706db108f1db495156020bde23f92570.html | 105 +++++++++++++++++ .../dir_760ce4e5796d28b3d0dd6e7840ecfe13.html | 99 ++++++++++++++++ .../dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html | 105 +++++++++++++++++ .../dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html | 109 ++++++++++++++++++ .../dir_d13acb3f48e6aaa83bf47a5658d35ef4.html | 99 ++++++++++++++++ .../dir_e995fcc46e5f182c24bd6fe0d90a742c.html | 99 ++++++++++++++++ .../dir_eba1acdda5df661dbf6e514468df4101.html | 105 +++++++++++++++++ .../dir_ebc798c9b1f11074fd71688d371864c0.html | 99 ++++++++++++++++ ...lient_1_1detection_1_1_i_info_fetcher.html | 2 +- ...ient_1_1detection_1_1_i_process_utils.html | 2 +- ..._d_client_1_1network_1_1_i_api_client.html | 2 +- ...d_client_1_1network_1_1_i_http_client.html | 2 +- ..._l_d_client_1_1utils_1_1_i_file_utils.html | 2 +- 28 files changed, 1238 insertions(+), 16 deletions(-) create mode 100644 ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html create mode 100644 ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html create mode 100644 ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html create mode 100644 ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html create mode 100644 ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html create mode 100644 ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html create mode 100644 ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html create mode 100644 ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html create mode 100644 ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html create mode 100644 ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html create mode 100644 ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html create mode 100644 ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html diff --git a/ld_client/doc/pdoc/class_file_logger.html b/ld_client/doc/pdoc/class_file_logger.html index a2ebfca..2de3c64 100644 --- a/ld_client/doc/pdoc/class_file_logger.html +++ b/ld_client/doc/pdoc/class_file_logger.html @@ -139,7 +139,7 @@ Protected Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>utils/loggers/FileLogger.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers/FileLogger.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html index e719c11..d7ddd2e 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html @@ -286,7 +286,7 @@ Properties</h2></td></tr> </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>detection/InfoFetcher.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/InfoFetcher.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html index 7080b7a..107a82d 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html @@ -173,7 +173,7 @@ bool </td><td class="memItemRight" valign="bottom"><b>DetectionRunning</b> </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>detection/ProcessDetection.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/ProcessDetection.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html index 5bbf1df..dfeadef 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html @@ -195,7 +195,7 @@ Public Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>detection/ProcessUtils.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/ProcessUtils.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html index e8d1ec5..a3e8d6d 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html @@ -249,7 +249,7 @@ bool </td><td class="memItemRight" valign="bottom"><b>ClientRunning</b></td </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>network/ApiClient.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/network/ApiClient.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html index f885623..90e28a1 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html @@ -165,7 +165,7 @@ Public Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>network/HttpClient.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/network/HttpClient.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html index f51c123..dd3362f 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html @@ -103,7 +103,7 @@ string? </td><td class="memItemRight" valign="bottom"><b>SerialNumber</b><c <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> <div class="textblock"><p >This class holds all the information about a specific part of a debugger (head/body). </p> </div><hr/>The documentation for this class was generated from the following file:<ul> -<li>network/data/DebuggerInfo.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/network/data/DebuggerInfo.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html index 617cfb5..cf69e4d 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html @@ -216,7 +216,7 @@ string? </td><td class="memItemRight" valign="bottom"><b>TimeStamp</b><code </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>network/data/Payload.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/network/data/Payload.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html index 1d00aa1..fc1bb9e 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html @@ -135,7 +135,7 @@ Public Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>utils/FileUtils.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/FileUtils.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html index 09a6a5e..b592e10 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html @@ -380,7 +380,7 @@ static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.htm </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>utils/loggers/ALogger.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers/ALogger.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html index 05a15b8..dbc5fbe 100644 --- a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html +++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html @@ -179,7 +179,7 @@ static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.htm </div> </div> <hr/>The documentation for this class was generated from the following file:<ul> -<li>utils/loggers/ConsoleLogger.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers/ConsoleLogger.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html b/ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html new file mode 100644 index 0000000..d3e9b32 --- /dev/null +++ b/ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/obj Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_082f6a8deca2b2d1a7c77b6edd561a50.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">obj Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_082f6a8deca2b2d1a7c77b6edd561a50.html">obj</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html b/ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html new file mode 100644 index 0000000..3df66b7 --- /dev/null +++ b/ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html @@ -0,0 +1,105 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_3829590d4bc1496e3a509b2e3d199db3.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">ld_client Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html b/ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html new file mode 100644 index 0000000..f95438a --- /dev/null +++ b/ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_3ff60c654341cc744f8b6bad46bdfd33.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">loggers Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html">utils</a></li><li class="navelem"><a class="el" href="dir_3ff60c654341cc744f8b6bad46bdfd33.html">loggers</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html b/ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html new file mode 100644 index 0000000..920ca6f --- /dev/null +++ b/ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/detection Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">detection Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html">detection</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html b/ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html new file mode 100644 index 0000000..d1ce16c --- /dev/null +++ b/ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html @@ -0,0 +1,105 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/network Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_706db108f1db495156020bde23f92570.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">network Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_760ce4e5796d28b3d0dd6e7840ecfe13.html">data</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_706db108f1db495156020bde23f92570.html">network</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html b/ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html new file mode 100644 index 0000000..3f7f15d --- /dev/null +++ b/ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/network/data Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_760ce4e5796d28b3d0dd6e7840ecfe13.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">data Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_706db108f1db495156020bde23f92570.html">network</a></li><li class="navelem"><a class="el" href="dir_760ce4e5796d28b3d0dd6e7840ecfe13.html">data</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html b/ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html new file mode 100644 index 0000000..a03de9b --- /dev/null +++ b/ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html @@ -0,0 +1,105 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/utils Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">utils Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_3ff60c654341cc744f8b6bad46bdfd33.html">loggers</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html">utils</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html b/ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html new file mode 100644 index 0000000..896e32e --- /dev/null +++ b/ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html @@ -0,0 +1,109 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">LDClient Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html">detection</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_706db108f1db495156020bde23f92570.html">network</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html">utils</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html b/ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html new file mode 100644 index 0000000..9b27610 --- /dev/null +++ b/ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_d13acb3f48e6aaa83bf47a5658d35ef4.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">review Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html b/ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html new file mode 100644 index 0000000..e050ea2 --- /dev/null +++ b/ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_e995fcc46e5f182c24bd6fe0d90a742c.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">aswi2022bug-thugs Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html b/ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html new file mode 100644 index 0000000..997200a --- /dev/null +++ b/ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html @@ -0,0 +1,105 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/obj/Debug Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_eba1acdda5df661dbf6e514468df4101.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">Debug Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +<table class="memberdecls"> +<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a> +Directories</h2></td></tr> +<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory  </td><td class="memItemRight" valign="bottom"><a class="el" href="dir_ebc798c9b1f11074fd71688d371864c0.html">net6.0</a></td></tr> +<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> +</table> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_082f6a8deca2b2d1a7c77b6edd561a50.html">obj</a></li><li class="navelem"><a class="el" href="dir_eba1acdda5df661dbf6e514468df4101.html">Debug</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html b/ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html new file mode 100644 index 0000000..90e0b7c --- /dev/null +++ b/ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html @@ -0,0 +1,99 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=11"/> +<meta name="generator" content="Doxygen 1.9.4"/> +<meta name="viewport" content="width=device-width, initial-scale=1"/> +<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/obj/Debug/net6.0 Directory Reference</title> +<link href="tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="jquery.js"></script> +<script type="text/javascript" src="dynsections.js"></script> +<link href="navtree.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="resize.js"></script> +<script type="text/javascript" src="navtreedata.js"></script> +<script type="text/javascript" src="navtree.js"></script> +<link href="search/search.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="search/searchdata.js"></script> +<script type="text/javascript" src="search/search.js"></script> +<link href="doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr id="projectrow"> + <td id="projectalign"> + <div id="projectname">LDClient<span id="projectnumber"> v.1</span> + </div> + <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div> + </td> + </tr> + </tbody> +</table> +</div> +<!-- end header part --> +<!-- Generated by Doxygen 1.9.4 --> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +var searchBox = new SearchBox("searchBox", "search",'Search','.html'); +/* @license-end */ +</script> +<script type="text/javascript" src="menudata.js"></script> +<script type="text/javascript" src="menu.js"></script> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(function() { + initMenu('',true,false,'search.php','Search'); + $(document).ready(function() { init_search(); }); +}); +/* @license-end */ +</script> +<div id="main-nav"></div> +</div><!-- top --> +<div id="side-nav" class="ui-resizable side-nav-resizable"> + <div id="nav-tree"> + <div id="nav-tree-contents"> + <div id="nav-sync" class="sync"></div> + </div> + </div> + <div id="splitbar" style="-moz-user-select:none;" + class="ui-resizable-handle"> + </div> +</div> +<script type="text/javascript"> +/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */ +$(document).ready(function(){initNavTree('dir_ebc798c9b1f11074fd71688d371864c0.html',''); initResizable(); }); +/* @license-end */ +</script> +<div id="doc-content"> +<!-- window showing the filter options --> +<div id="MSearchSelectWindow" + onmouseover="return searchBox.OnSearchSelectShow()" + onmouseout="return searchBox.OnSearchSelectHide()" + onkeydown="return searchBox.OnSearchSelectKey(event)"> +</div> + +<!-- iframe showing the search results (closed by default) --> +<div id="MSearchResultsWindow"> +<iframe src="javascript:void(0)" frameborder="0" + name="MSearchResults" id="MSearchResults"> +</iframe> +</div> + +<div class="header"> + <div class="headertitle"><div class="title">net6.0 Directory Reference</div></div> +</div><!--header--> +<div class="contents"> +</div><!-- contents --> +</div><!-- doc-content --> +<!-- start footer part --> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_082f6a8deca2b2d1a7c77b6edd561a50.html">obj</a></li><li class="navelem"><a class="el" href="dir_eba1acdda5df661dbf6e514468df4101.html">Debug</a></li><li class="navelem"><a class="el" href="dir_ebc798c9b1f11074fd71688d371864c0.html">net6.0</a></li> + <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li> + </ul> +</div> +</body> +</html> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html index 30955ae..754f8c0 100644 --- a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html @@ -188,7 +188,7 @@ Properties</h2></td></tr> </div> </div> <hr/>The documentation for this interface was generated from the following file:<ul> -<li>detection/IInfoFetcher.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/IInfoFetcher.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html index 24e7373..9a8ab40 100644 --- a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html @@ -189,7 +189,7 @@ Public Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this interface was generated from the following file:<ul> -<li>detection/IProcessUtils.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/IProcessUtils.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html index e333b90..ee2637d 100644 --- a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html @@ -155,7 +155,7 @@ Public Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this interface was generated from the following file:<ul> -<li>network/IApiClient.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/network/IApiClient.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html index c09212a..7eb4cbd 100644 --- a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html @@ -132,7 +132,7 @@ Public Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this interface was generated from the following file:<ul> -<li>network/IHttpClient.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/network/IHttpClient.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html index dd550a8..bbec061 100644 --- a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html +++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html @@ -132,7 +132,7 @@ Public Member Functions</h2></td></tr> </div> </div> <hr/>The documentation for this interface was generated from the following file:<ul> -<li>utils/IFileUtils.cs</li> +<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/IFileUtils.cs</li> </ul> </div><!-- contents --> </div><!-- doc-content --> -- GitLab From 2c9a5fda113e0b63aa67b92d228b5b6cdb40edd2 Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Sat, 14 May 2022 10:30:19 +0200 Subject: [PATCH 60/67] re #9845 Added an outer loop for information retrieval --- ld_client/LDClient/Program.cs | 4 ++- ld_client/LDClient/appsettings.json | 4 ++- .../LDClient/detection/ProcessDetection.cs | 33 ++++++++++++++----- ld_client/LDClient/utils/ConfigLoader.cs | 14 +++++++- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs index 04c6099..1fb5d96 100644 --- a/ld_client/LDClient/Program.cs +++ b/ld_client/LDClient/Program.cs @@ -92,7 +92,9 @@ internal static class Program { Config.DetectionPeriod, InfoFetcher, DefaultApiClient, - new ProcessUtils() + new ProcessUtils(), + Config.FetchInfoSuperiorMaxAttempts, + Config.FetchInfoSuperiorAttemptPeriod ); // Create and start a new thread that periodically diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json index ba3cadb..e07c78c 100644 --- a/ld_client/LDClient/appsettings.json +++ b/ld_client/LDClient/appsettings.json @@ -64,6 +64,8 @@ "FetchInfoMaxAttempts": 15, "FetchInfoAttemptPeriod": 4000, "T32RemSuccessExitCode": 0, - "T32RemWaitTimeoutMs": 2000 + "T32RemWaitTimeoutMs": 2000, + "FetchInfoSuperiorMaxAttempts": 5, + "FetchInfoSuperiorAttemptPeriod": 1000 } } \ No newline at end of file diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs index af47b38..043361e 100644 --- a/ld_client/LDClient/detection/ProcessDetection.cs +++ b/ld_client/LDClient/detection/ProcessDetection.cs @@ -61,6 +61,16 @@ public sealed class ProcessDetection : IProcessDetection { /// Flag used to stop the thread (process detection). /// </summary> public bool DetectionRunning = false; + + /// <summary> + /// Superior number of attempts to fetch the information (outer loop). + /// </summary> + private uint _fetchInfoSuperiorMaxAttempts; + + /// <summary> + /// Period of the superior (outer) loop to fetch the data. + /// </summary> + private uint _fetchInfoSuperiorAttemptPeriod; /// <summary> /// Creates an instance of this class. @@ -71,13 +81,15 @@ public sealed class ProcessDetection : IProcessDetection { /// <param name="apiClient">Instance of API clients used for sending data off to the server</param> /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param> public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, - IApiClient apiClient, IProcessUtils processUtils) { + IApiClient apiClient, IProcessUtils processUtils, uint fetchInfoSuperiorMaxAttempts, uint fetchInfoSuperiorAttemptPeriod) { _processName = processName; _detectionPeriodMs = detectionPeriodMs; _infoFetcher = infoFetcher; _apiClient = apiClient; _failedToRetrieveData = false; _processUtils = processUtils; + _fetchInfoSuperiorMaxAttempts = fetchInfoSuperiorMaxAttempts; + _fetchInfoSuperiorAttemptPeriod = fetchInfoSuperiorAttemptPeriod; } /// <summary> @@ -86,14 +98,19 @@ public sealed class ProcessDetection : IProcessDetection { /// <returns>True, if the data was fetched successfully. False, otherwise.</returns> private async Task<bool> RetrieveDataFromDebugger() { // Try to fetch data from the debugger. - var success = await _infoFetcher.FetchDataAsync(); - - // If the data was fetched successfully, send a payload off to the server. - if (success) { - _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, - _infoFetcher.BodySerialNumber, DatetimeFormat); + + for (var i = 0; i < _fetchInfoSuperiorMaxAttempts; i++) { + var success = await _infoFetcher.FetchDataAsync(); + + // If the data was fetched successfully, send a payload off to the server. + if (success) { + _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, + _infoFetcher.BodySerialNumber, DatetimeFormat); + return true; + } + await Task.Delay((int)_fetchInfoSuperiorAttemptPeriod); } - return success; + return false; } /// <summary> diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs index 3544c46..6093f45 100644 --- a/ld_client/LDClient/utils/ConfigLoader.cs +++ b/ld_client/LDClient/utils/ConfigLoader.cs @@ -185,6 +185,16 @@ namespace LDClient.utils { /// </summary> public string T32ApiPacketLen { get; private set; } = null!; + /// <summary> + /// Superior number of attempts to fetch the information (outer loop). + /// </summary> + public uint FetchInfoSuperiorMaxAttempts { get; private set; } + + /// <summary> + /// Period of the superior (outer) loop to fetch the data. + /// </summary> + public uint FetchInfoSuperiorAttemptPeriod { get; private set; } + #endregion /// <summary> @@ -283,7 +293,9 @@ namespace LDClient.utils { T32ApiAddress = debugger["T32ApiAddress"]; T32ApiPort = debugger["T32ApiPort"]; T32ApiPacketLen = debugger["T32ApiPacketLen"]; - + FetchInfoSuperiorMaxAttempts = uint.Parse(debugger["FetchInfoSuperiorMaxAttempts"]); + FetchInfoSuperiorAttemptPeriod = uint.Parse(debugger["FetchInfoSuperiorAttemptPeriod"]); + } catch (Exception e) { Console.WriteLine(e); Environment.Exit(ErrorExitCode); -- GitLab From 0728c021a2c66439583488eee61b84d702a9627a Mon Sep 17 00:00:00 2001 From: silhavyj <jakub.sil@seznam.cz> Date: Sat, 14 May 2022 10:36:52 +0200 Subject: [PATCH 61/67] re #9845 Fixed some bugs in InfoFetcherTests.cs and ProcessDetectionTests.cs --- ld_client/LDClientTests/detection/InfoFetcherTests.cs | 8 ++++---- .../LDClientTests/detection/ProcessDetectionTests.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ld_client/LDClientTests/detection/InfoFetcherTests.cs b/ld_client/LDClientTests/detection/InfoFetcherTests.cs index 03c62a9..3285226 100644 --- a/ld_client/LDClientTests/detection/InfoFetcherTests.cs +++ b/ld_client/LDClientTests/detection/InfoFetcherTests.cs @@ -48,7 +48,7 @@ internal class InfoFetcherTests { Returns(DebuggerInfoParserTests.CorrectFileContent.Split("\n")); - var result = await _defaultFetcher.FetchDataAsync(); + bool result = await _defaultFetcher.FetchDataAsync(); Assert.IsTrue(result); _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), @@ -70,7 +70,7 @@ internal class InfoFetcherTests { Returns(new []{""}); - var result = await _defaultFetcher.FetchDataAsync(); + bool result = await _defaultFetcher.FetchDataAsync(); Assert.IsFalse(result); @@ -86,7 +86,7 @@ internal class InfoFetcherTests { _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())). Returns(new[] { "" }); - var result = await _fetcherWithoutPars.FetchDataAsync(); + bool result = await _fetcherWithoutPars.FetchDataAsync(); Assert.IsFalse(result); _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), @@ -102,7 +102,7 @@ internal class InfoFetcherTests { It.IsAny<int>(), It.IsAny<int>())).Returns(true); _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).Throws(new FileNotFoundException()); - var result = await _defaultFetcher.FetchDataAsync(); + bool result = await _defaultFetcher.FetchDataAsync(); Assert.IsFalse(result); _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(), diff --git a/ld_client/LDClientTests/detection/ProcessDetectionTests.cs b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs index 6c6a2da..c0200db 100644 --- a/ld_client/LDClientTests/detection/ProcessDetectionTests.cs +++ b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs @@ -33,7 +33,7 @@ public class ProcessDetectionTests { _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict); - _processDetection = new ProcessDetection("process", 50, _mockInfoFetcher.Object, _mockApiClient.Object, _mockProcessUtils.Object); + _processDetection = new ProcessDetection("process", 50, _mockInfoFetcher.Object, _mockApiClient.Object, _mockProcessUtils.Object, 1, 0); } -- GitLab From 35168e5f93569072cba4fad064febc3917a673ff Mon Sep 17 00:00:00 2001 From: "zemanm98@students.zcu.cz" <Farnhait123*> Date: Sat, 14 May 2022 16:16:40 +0200 Subject: [PATCH 62/67] Fixed minor issues. View on keyman devices changed. Changed database for new keyman x license connection. --- server/sql_app/api/devices_web.py | 115 ++++++--- server/sql_app/api/licenses_web.py | 16 +- server/sql_app/api/pcs_web.py | 29 --- server/sql_app/api/teams_web.py | 29 ++- server/sql_app/crud.py | 233 ++++++++++++++---- server/sql_app/main.py | 2 +- server/sql_app/models.py | 17 +- server/sql_app/schemas.py | 18 +- .../templates/body-devices/body_devices.html | 9 +- .../body-devices/body_devices_normal.html | 9 +- server/templates/devices/devicelicense.html | 33 ++- server/templates/devices/devices.html | 107 +++++--- server/templates/devices/devices_normal.html | 69 ++++-- server/templates/ld-logs/ldlogs.html | 9 +- server/templates/ld-logs/ldlogs_normal.html | 9 +- server/templates/licenses/license_create.html | 2 + server/templates/licenses/licenses.html | 15 +- .../templates/licenses/licenses_normal.html | 9 +- server/templates/pcs/pcs.html | 19 +- server/templates/pcs/pcs_normal.html | 17 +- server/templates/teams/team_change.html | 15 ++ server/templates/teams/teams.html | 15 +- server/templates/teams/teams_normal.html | 13 +- server/templates/usb-logs/logs.html | 11 +- server/templates/usb-logs/logs_normal.html | 11 +- server/templates/users/users.html | 7 +- 26 files changed, 557 insertions(+), 281 deletions(-) create mode 100644 server/templates/teams/team_change.html diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py index 0d82a6b..73fdf61 100644 --- a/server/sql_app/api/devices_web.py +++ b/server/sql_app/api/devices_web.py @@ -8,7 +8,7 @@ from fastapi_jwt_auth import AuthJWT from pydantic import BaseModel from sqlalchemy.orm import Session from sql_app.api.auth import fake_users_db -from sql_app import crud, models +from sql_app import crud, models, schemas from ..database import SessionLocal, engine models.Base.metadata.create_all(bind=engine) @@ -38,23 +38,31 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() + device_dict = [] devices = crud.get_devices(db, skip=skip, limit=limit) - statuses = [] - # adding state for each device in list - for i in range(0, len(devices)): - statuses.append(devices[i].logs[len(devices[i].logs) - 1].status) + teams = crud.get_teams(db, skip=skip, limit=limit) + # adding dictionary entry with all inforamtions needed in template + for dev in devices: + if len(dev.licenses) > 0: + for lic in dev.licenses: + device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]}) + else: + device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) if current_user == "admin": - return templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, + "licenses": licenses, "devs": devices, + "teams": teams, "user": current_user}) else: current_user = "guest" - return templates.TemplateResponse("devices_normal.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, + "licenses": licenses, "user": current_user}) @device_web.post("/devices-web", response_class=HTMLResponse) -async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form("all"), +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + keyman_id: str = Form("all"), lic_name: str = Form("all"), + lic_id: str = Form("all"), team: str = Form("all"), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ Endpoint used for filtering devices by license. returns html template with only @@ -62,28 +70,29 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() - devices = crud.get_devices(db, skip=skip, limit=limit) - def_devices = [] + device_dict = [] + devices_f = crud.get_filtered_devices(db, keyman_id, lic_name, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_devices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + # adding dictionary entry with all inforamtions needed in template for dev in devices: - for l in dev.licenses: - if dev not in def_devices and l.licenses.name == lic: - def_devices.append(dev) - # if input was default all - if lic == "all": - def_devices = devices - statuses = [] - for i in range(0, len(def_devices)): - statuses.append(def_devices[i].logs[len(def_devices[i].logs) - 1].status) + if len(dev.licenses) > 0: + for lic in dev.licenses: + device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]}) + else: + device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) if current_user == "admin": - return templates.TemplateResponse("devices.html", - {"request": request, "devs": len(def_devices), "devices": def_devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, + "licenses": licenses, "devs": devices, + "teams": teams, "user": current_user}) else: current_user = "guest" - return templates.TemplateResponse("devices_normal.html", - {"request": request, "devs": len(def_devices), "devices": def_devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, + "licenses": licenses, "user": current_user}) @device_web.get("/device-license/{device_id}", response_class=HTMLResponse) @@ -98,19 +107,21 @@ async def connect_dev_lic(request: Request, device_id: int, db: Session = Depend return RedirectResponse(url=f"/logs-web", status_code=303) device = crud.get_device(db, device_id) dev_licenses = crud.get_device_licenses(db, device_id) - lic_names = [] + lic_ids = [] dev_lics = [] for dev_lic in dev_licenses: dev_lics.append(dev_lic.licenses) for dev_lic in dev_licenses: - lic_names.append(dev_lic.licenses.name) + lic_ids.append(dev_lic.licenses.license_id) licenses = crud.get_licenses(db, 0, 100) lic_left = [] for lic in licenses: - if lic.name not in lic_names and lic not in lic_left: + if lic.license_id not in lic_ids and lic not in lic_left: lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) return templates.TemplateResponse("devicelicense.html", - {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics}) + {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics, + "teams": teams}) @device_web.post("/devices-web/{device_id}") @@ -141,3 +152,45 @@ async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = De return RedirectResponse(url=f"/logs-web", status_code=303) crud.delete_device_license(db, device_id, int(lic_del)) return RedirectResponse(url=f"/devices-web", status_code=303) + +@device_web.post("/devices-web-team/{device_id}") +async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses + table and redirects to devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device(db, device_id, team_con) + return RedirectResponse(url=f"/devices-web", status_code=303) + +@device_web.post("/devices-web-inv/{device_id}") +async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses + table and redirects to devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device_inv(db, device_id, dev_inv) + return RedirectResponse(url=f"/devices-web", status_code=303) + +@device_web.post("/devices-web-comment/{device_id}") +async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses + table and redirects to devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device_com(db, device_id, dev_com) + return RedirectResponse(url=f"/devices-web", status_code=303) diff --git a/server/sql_app/api/licenses_web.py b/server/sql_app/api/licenses_web.py index f402a1b..3d9bdf5 100644 --- a/server/sql_app/api/licenses_web.py +++ b/server/sql_app/api/licenses_web.py @@ -1,5 +1,5 @@ from typing import List - +from typing import Optional from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form from sqlalchemy.orm import Session from datetime import date @@ -60,8 +60,8 @@ async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, d "user": current_user}) @licenses_web.post("/licenses-web") -def create_license(name: str = Form(...), expdate: date = Form(...), db: Session = Depends(get_db), - Authorize: AuthJWT = Depends()): +def create_license(name: str = Form(...), lic_id: str = Form(...), expdate: Optional[date] = Form(None), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ Endpoint called from create license form. Creates new license and redirects to devices-web endpoint """ @@ -70,11 +70,11 @@ def create_license(name: str = Form(...), expdate: date = Form(...), db: Session if current_user != "admin": return RedirectResponse(url=f"/logs-web", status_code=303) licenses = crud.get_licenses(db, 0, 100) - licenses_names = [] + licenses_ids = [] for l in licenses: - licenses_names.append(l.name) - if name not in licenses_names: - db_license = crud.create_license(db, name, expdate) + licenses_ids.append(l.license_id) + if lic_id not in licenses_ids: + db_license = crud.create_license(db, name, lic_id, expdate) if db_license is None: print("something went wrong") - return RedirectResponse(url=f"/devices-web", status_code=303) + return RedirectResponse(url=f"/licenses-web", status_code=303) diff --git a/server/sql_app/api/pcs_web.py b/server/sql_app/api/pcs_web.py index 2779e46..39dfac5 100644 --- a/server/sql_app/api/pcs_web.py +++ b/server/sql_app/api/pcs_web.py @@ -42,32 +42,3 @@ async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Sessio current_user = "guest" return templates.TemplateResponse("pcs_normal.html", {"request": request, "pcs": pcs, "user": current_user}) - -@pcs_web.get("/pc-team/{pc_id}", response_class=HTMLResponse) -async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db), - Authorize: AuthJWT = Depends()): - """ - Returns template with Form for connecting pc with team - """ - Authorize.jwt_optional() - current_user = Authorize.get_jwt_subject() - if current_user != "admin": - return RedirectResponse(url=f"/logs-web", status_code=303) - pc = crud.get_pc(db, pc_id) - teams = crud.get_teams(db, 0, 100) - return templates.TemplateResponse("pcteam.html", - {"request": request, "pc": pc, "teams": teams}) - - -@pcs_web.post("/pcs-web/{pc_id}") -async def connect_post(pc_id: int, team: str = Form(...), db: Session = Depends(get_db), - Authorize: AuthJWT = Depends()): - """ - Endpoint called from within form for connecting pc with team. Updates certain pc with new team. - """ - Authorize.jwt_optional() - current_user = Authorize.get_jwt_subject() - if current_user != "admin": - return RedirectResponse(url=f"/logs-web", status_code=303) - old_pc = crud.update_pc(db, pc_id, team) - return RedirectResponse(url=f"/pcs-web", status_code=303) diff --git a/server/sql_app/api/teams_web.py b/server/sql_app/api/teams_web.py index 616c1c7..15c44b7 100644 --- a/server/sql_app/api/teams_web.py +++ b/server/sql_app/api/teams_web.py @@ -59,7 +59,7 @@ async def team_create_web(request: Request, Authorize: AuthJWT = Depends()): @teams_web.post("/teams-web-con") def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from within form for creating new team. Creates new team and returns all teams in database + Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() @@ -74,3 +74,30 @@ def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: if team is None: print("something went wrong") return RedirectResponse(url=f"/teams-web", status_code=303) + + +@teams_web.get("/team-change/{team_id}", response_class=HTMLResponse) +async def team_change_web(request: Request, team_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with form for changing teams name + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + team = crud.get_team(db, team_id) + return templates.TemplateResponse("team_change.html", {"request": request, "team": team}) + +@teams_web.post("/teams-change-process/{team_id}") +async def team_change_process(team_id: int, db:Session = Depends(get_db), name: str = Form(...), + Authorize: AuthJWT = Depends()): + """ + Changes teams name to a new one given by user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + team = crud.change_team(db, team_id, name) + return RedirectResponse(url=f"/teams-web", status_code=303) \ No newline at end of file diff --git a/server/sql_app/crud.py b/server/sql_app/crud.py index f2b3a9b..d20873b 100644 --- a/server/sql_app/crud.py +++ b/server/sql_app/crud.py @@ -19,21 +19,37 @@ def get_devices(db: Session, skip: int = 0, limit: int = 100): return db.query(models.Device).offset(skip).limit(limit).all() -def find_device(db: Session, device: schemas.DeviceBase): +def find_device(db: Session, device: schemas.DeviceTemp): """ - finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object + finds one device with serial_number same as in given DeviceBase object """ - return db.query(models.Device).filter(and_(models.Device.product_id == device.product_id, - models.Device.vendor_id == device.vendor_id, - models.Device.serial_number == device.serial_number)).first() + return db.query(models.Device).filter(and_(models.Device.serial_number == device.serial_number)).first() -def create_device(db: Session, device: schemas.DeviceBase): +def find_device_by_serial(db: Session, ser: str): + """ + finds one device with serial_number same as in given DeviceBase object + """ + return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first() + +def get_devices_with_ids(db: Session, ids: []): + """ + returns all devices with given ids + """ + return db.query(models.Device).filter(models.Device.id.in_(ids)).all() + +def get_devices_by_team(db: Session, team: int): + """ + returns all devices with same team + """ + return db.query(models.Device).filter(models.Device.team_id == team).all() + +def create_device(db: Session, device: schemas.DeviceTemp): """ creates new device with data from given DeviceBase object """ db_device = models.Device(vendor_id=device.vendor_id, product_id=device.product_id, - serial_number=device.serial_number, assigned=False) + serial_number=device.serial_number, inventory_number="", comment="") db.add(db_device) db.commit() db.refresh(db_device) @@ -58,14 +74,18 @@ def find_license(db: Session, name: str): """ finds one license by given string name """ - return db.query(models.License).filter(models.License.name == name).first() + return db.query(models.License).filter(models.License.license_id == name).first() + +def get_licenses_by_name(db: Session, name: str): + return db.query(models.License).filter(models.License.name == name).all() -def create_license(db: Session, name: str, expdate: date): + +def create_license(db: Session, name: str, lic_id: str, expdate: date): """ creates new license with given name and expiration date """ - db_license = models.License(name=name, expiration_date=expdate) + db_license = models.License(name=name, license_id=lic_id, expiration_date=expdate) db.add(db_license) db.commit() db.refresh(db_license) @@ -79,9 +99,16 @@ def get_license_devices(db: Session, license_id: int): return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id == license_id).all() +def find_devicelicenses_by_licid_array(db: Session, lcs: []): + """ + Finds all device_licenses with license_id in given id array + """ + return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id.in_(lcs)).all() + + def get_device_licenses(db: Session, device_id: int): """ - returns all entries in devices_licenses table with given license_id + returns all entries in devices_licenses table with given device_id """ return db.query(models.DeviceLicense).filter(models.DeviceLicense.device_id == device_id).all() @@ -174,19 +201,61 @@ def get_pc(db: Session, pc_id: int): return db.query(models.PC).filter(models.PC.id == pc_id).first() -def update_pc(db: Session, pc_id: int, team: str): +def update_device(db: Session, device_id: int, team: str): """ Updates team of one specific pc """ - old_pc = get_pc(db, pc_id) + old_dev = get_device(db, device_id) team = get_team(db, int(team)) - new = {'id': old_pc.id, 'username': old_pc.username, 'hostname': old_pc.hostname, 'assigned': True, - 'team_id': team.id} + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_device_inv(db: Session, device_id: int, inv: str): + """ + Updates inventory number of one specific pc + """ + old_dev = get_device(db, device_id) + if old_dev.team_id != None: + team = get_team(db, int(old_dev.team_id)) + teamid = team.id + else: + teamid = None + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': inv, + 'comment': old_dev.comment, 'team_id': teamid} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_device_com(db: Session, device_id: int, comm: str): + """ + Updates team of one specific pc + """ + old_dev = get_device(db, device_id) + if old_dev.team_id != None: + team = get_team(db, int(old_dev.team_id)) + teamid = team.id + else: + teamid = None + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': teamid} for key, value in new.items(): - setattr(old_pc, key, value) + setattr(old_dev, key, value) db.commit() - db.refresh(old_pc) - return old_pc + db.refresh(old_dev) + return old_dev + def change_role(db: Session, usr_id: int, role: str): """ @@ -237,18 +306,11 @@ def find_pcs(db: Session, pcs: []): return db.query(models.PC).filter(models.PC.id.in_(pcs)).all() -def get_pcs_by_team(db: Session, team_id: int): - """ - returns all pcs in given team by team id - """ - return db.query(models.PC).filter(models.PC.team_id == team_id).all() - - def create_pc(db: Session, user: str, host: str): """ creates new pc with given username and hostname """ - db_pc = models.PC(username=user, hostname=host, assigned=False) + db_pc = models.PC(username=user, hostname=host) db.add(db_pc) db.commit() db.refresh(db_pc) @@ -287,6 +349,19 @@ def create_team(db: Session, name: str): return db_team +def change_team(db: Session, team_id: int, name: str): + """ + Updates name of one specific team + """ + old_team = get_team(db, team_id) + new = {'id': old_team.id, 'name': name} + for key, value in new.items(): + setattr(old_team, key, value) + db.commit() + db.refresh(old_team) + return old_team + + def get_head_device(db: Session, head_id: int): """ Returns one specific head device by given id @@ -410,19 +485,19 @@ def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str): if tema != "all": team = find_team(db, tema) if team is not None: - pcst = get_pcs_by_team(db, team.id) - pc_ids = "(" - for p in pcst: - pc_ids += str(p.id) + ", " - def_pc_ids = pc_ids[:-2] + ")" + devs = get_devices_by_team(db, team.id) + d_ids = "(" + for p in devs: + d_ids += str(p.id) + ", " + def_d_ids = d_ids[:-2] + ")" if pc != "all" and pcs is not None: - if len(def_pc_ids) > 1: - execute_string += " AND logs.pc_id IN " + def_pc_ids + if len(def_d_ids) > 1: + execute_string += " AND logs.device_id IN " + def_d_ids else: - if len(def_pc_ids) > 1: - execute_string += " WHERE logs.pc_id IN " + def_pc_ids + if len(def_d_ids) > 1: + execute_string += " WHERE logs.device_id IN " + def_d_ids if lic != "all": - license = find_license(db, lic) + license = get_licenses_by_name(db, lic) if license is not None: device_licenses = get_license_bodydevice(db, license.id) dev_ids = "(" @@ -454,19 +529,19 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str): if tema != "all": team = find_team(db, tema) if team is not None: - pcst = get_pcs_by_team(db, team.id) - pc_ids = "(" - for p in pcst: - pc_ids += str(p.id) + ", " - def_pc_ids = pc_ids[:-2] + ")" + devs = get_devices_by_team(db, team.id) + d_ids = "(" + for p in devs: + d_ids += str(p.id) + ", " + def_d_ids = d_ids[:-2] + ")" if pc != "all" and pcs is not None: - if len(def_pc_ids) > 1: - execute_string += " AND logs.pc_id IN " + def_pc_ids + if len(def_d_ids) > 1: + execute_string += " AND logs.device_id IN " + def_d_ids else: - if len(def_pc_ids) > 1: - execute_string += " WHERE logs.pc_id IN " + def_pc_ids + if len(def_d_ids) > 1: + execute_string += " WHERE logs.device_id IN " + def_d_ids if lic != "all": - license = find_license(db, lic) + license = get_licenses_by_name(db, lic) if license is not None: device_licenses = get_license_devices(db, license.id) dev_ids = "(" @@ -485,6 +560,72 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str): return result +def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str): + """ + returns filtered devices based on given atributes + """ + execute_string = "SELECT * FROM devices AS device WHERE" + before_me = False + all_all = True + if keyman_id != "all": + all_all = False + keyman_dev = find_device_by_serial(db, keyman_id) + if keyman_dev != None: + if before_me: + execute_string += " AND device.id = " + str(keyman_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(keyman_dev.id) + if license_name != "all": + all_all = False + license = get_licenses_by_name(db, license_name) + if len(license) > 0: + lic_ids = [] + for l in license: + lic_ids.append(l.id) + dev_lics = find_devicelicenses_by_licid_array(db, lic_ids) + lic_ids = "(" + for l in dev_lics: + lic_ids += str(l.device_id) + ", " + def_lic_ids = lic_ids[:-2] + ")" + if before_me: + execute_string += " AND device.id IN " + def_lic_ids + else: + before_me = True + execute_string += " device.id IN " + def_lic_ids + if license_id != "all": + all_all = False + license = find_license(db, license_id) + licen_devs = get_license_devices(db, license.id) + ids = "(" + for lic in licen_devs: + ids += str(lic.device_id) + ", " + def_ids = ids[:-2] + ")" + if license != None: + if before_me: + execute_string += " AND device.id IN " + def_ids + else: + before_me = True + execute_string += " device.id IN " + def_ids + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + if all_all: + before_me = True + execute_string = "SELECT * FROM devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result + + def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_id: int, date: datetime): """ Creates new USB log for usb_logs database table diff --git a/server/sql_app/main.py b/server/sql_app/main.py index 224d136..637bfaf 100644 --- a/server/sql_app/main.py +++ b/server/sql_app/main.py @@ -38,5 +38,5 @@ app.include_router(auth) ''' if __name__ == "__main__": - uvicorn.run(app, host="192.168.0.22", port=8000) + uvicorn.run(app, host="192.168.64.1", port=8000) ''' diff --git a/server/sql_app/models.py b/server/sql_app/models.py index d91cfa5..e3e40a5 100644 --- a/server/sql_app/models.py +++ b/server/sql_app/models.py @@ -14,13 +14,16 @@ class Device(Base): vendor_id = Column(String, index=True, nullable=False) product_id = Column(String, index=True, nullable=False) serial_number = Column(String, index=True, nullable=False) - assigned = Column(Boolean, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) # relationships for foreign keys, thus connecting table with usb_logs and licenses # tables logs = relationship("USBLog", back_populates="device") licenses = relationship("DeviceLicense", back_populates="device_lic") - + team = relationship("Team", back_populates="devices") class USBLog(Base): """ @@ -48,7 +51,8 @@ class License(Base): id = Column(Integer, primary_key=True, index=True) name = Column(String, index=True, nullable=False) - expiration_date = Column(DateTime(timezone=True), server_default=func.now()) + license_id = Column(String, index=True, nullable=False) + expiration_date = Column(DateTime(timezone=True), nullable=True) # relationships for foreign keys, thus connecting table with devices table devices = relationship("DeviceLicense", back_populates="licenses") @@ -97,12 +101,9 @@ class PC(Base): id = Column(Integer, primary_key=True, index=True) username = Column(String, index=True, nullable=False) hostname = Column(String, index=True, nullable=False) - assigned = Column(Boolean, index=True, nullable=False) - team_id = Column(Integer, ForeignKey("teams.id")) # relationships for foreign keys, thus connecting table with teams, usb_logs and ld_logs # tables - team = relationship("Team", back_populates="pcs") logs_pc = relationship("USBLog", back_populates="pc") ld_pc = relationship("LDLog", back_populates="ldpc") @@ -116,9 +117,7 @@ class Team(Base): id = Column(Integer, primary_key=True, index=True) name = Column(String, index=True, nullable=False) - # relationships for foreign keys, thus connecting table with pc table - pcs = relationship("PC", back_populates="team") - + devices = relationship("Device", back_populates="team") class HeadDevice(Base): """ diff --git a/server/sql_app/schemas.py b/server/sql_app/schemas.py index 79becdc..4a7e381 100644 --- a/server/sql_app/schemas.py +++ b/server/sql_app/schemas.py @@ -48,6 +48,8 @@ class DeviceBase(BaseModel): vendor_id: str product_id: str serial_number: str + inventory_number: str + comment: str class DeviceCreate(DeviceBase): @@ -59,7 +61,6 @@ class Device(DeviceCreate): Class used for creating and reading devices entries """ id: int - assigned: bool logs: List[USBLog] = [] licenses: List[DeviceLicense] = [] @@ -67,6 +68,12 @@ class Device(DeviceCreate): orm_mode = True +class DeviceTemp(BaseModel): + vendor_id: str + product_id: str + serial_number: str + + class LDLogBase(BaseModel): timestamp: datetime status: str @@ -140,8 +147,8 @@ class PC(PCCreate): Class used for creating and reading pc entries """ id: int - assigned: bool logs_pc: List[USBLog] = [] + logs_ld: List[LDLog] = [] class Config: orm_mode = True @@ -160,7 +167,7 @@ class Team(TeamCreate): Class used for creating and reading team entries """ id: int - pcs: List[PC] = [] + devices: List[Device] = [] class Config: orm_mode = True @@ -168,6 +175,7 @@ class Team(TeamCreate): class LicenseBase(BaseModel): name: str + license_id: str expiration_date: date @@ -193,7 +201,7 @@ class USBTempBase(BaseModel): username: str hostname: str timestamp: str - device: DeviceBase + device: DeviceTemp status: str @@ -242,6 +250,7 @@ class UserBase(BaseModel): password: str role: str + class UserCreate(UserBase): pass @@ -251,3 +260,4 @@ class User(UserCreate): class Config: orm_mode = True + diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html index b36a923..255a851 100644 --- a/server/templates/body-devices/body_devices.html +++ b/server/templates/body-devices/body_devices.html @@ -22,11 +22,10 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/body-devices-web" selected>Body Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -47,7 +46,7 @@ <table> <TR> <TH>ID</TH> - <TH>Serial Number</TH> + <TH>Lauterbach Body ID</TH> <TH>Licenses</TH> <TH>Status</TH> </TR> diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html index ece156d..8a3452e 100644 --- a/server/templates/body-devices/body_devices_normal.html +++ b/server/templates/body-devices/body_devices_normal.html @@ -22,11 +22,10 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/body-devices-web" selected>Body Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -46,7 +45,7 @@ <table> <TR> <TH>ID</TH> - <TH>Serial Number</TH> + <TH>Lauterbach Body ID</TH> <TH>Licenses</TH> <TH>Status</TH> </TR> diff --git a/server/templates/devices/devicelicense.html b/server/templates/devices/devicelicense.html index b8f8833..e72d585 100644 --- a/server/templates/devices/devicelicense.html +++ b/server/templates/devices/devicelicense.html @@ -7,25 +7,52 @@ <body> <h6><p>Vendor ID: {{device.vendor_id}}</p> <p>Product ID: {{device.product_id}}</p> - <p>Serial Number: {{device.serial_number}}</p> </h6> +<h4>Serial Number: {{device.serial_number}}</h4> <form action="/devices-web/{{device.id}}" method="post"> <label for="lic">Licenses:</label> <select id="lic" name="lic"> {% for license in licenses %} - <option value={{license.id}}>{{license.name}}</option> + <option value={{license.id}}>{{license.name}} : {{license.license_id}}</option> {% endfor %} </select> <input type="submit" value="Connect"> </form> +<div style='padding-top:20px'> <form action="/devices-web-del/{{device.id}}" method="post"> <label for="lic_del">Licenses:</label> <select id="lic_del" name="lic_del"> {% for license in dev_lic %} - <option value={{license.id}}>{{license.name}}</option> + <option value={{license.id}}>{{license.name}} : {{license.license_id}}</option> {% endfor %} </select> <input type="submit" value="Delete"> </form> +</div> +<div style='padding-top:20px'> +<form action="/devices-web-team/{{device.id}}" method="post"> + <label for="team_con">Teams:</label> + <select id="team_con" name="team_con"> + {% for team in teams %} + <option value={{team.id}}>{{team.name}}</option> + {% endfor %} + </select> + <input type="submit" value="Connect"> +</form> +</div> +<div style='padding-top:20px'> +<form action="/devices-web-inv/{{device.id}}" method="post"> + <label for="dev_inv">Inventory Number:</label><br> + <input type="text" id="dev_inv" name="dev_inv" value="{{device.inventory_number}}"> + <input type="submit" value="Submit"> +</form> +</div> +<div style='padding-top:20px'> +<form action="/devices-web-comment/{{device.id}}" method="post"> + <label for="dev_com">Comment:</label><br> + <input type="text" id="dev_com" name="dev_com" value="{{device.comment}}"> + <input type="submit" value="Submit"> +</form> +</div> </body> </html> \ No newline at end of file diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html index e2f0bb7..33a1a21 100644 --- a/server/templates/devices/devices.html +++ b/server/templates/devices/devices.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Devices Details</title> </head> <body> @@ -22,10 +46,9 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> - <option value="/devices-web">Devices</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> + <option value="/devices-web" selected>Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> @@ -35,49 +58,65 @@ <input type="submit" value="OK"> </form> <form action="/devices-web" method="post"> - <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> - <datalist id="licenses"> + <label for="keyman_id">Keyman ID:</label> + <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="" placeholder="all"> + <datalist id="keyman_ids"> + {% for dev in devs %} + <option value="{{dev.serial_number}}"></option> + {% endfor %} + </datalist> + <label for="lic_name">License Name:</label> + <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="" placeholder="all"> + <datalist id="licenses_names"> {% for license in licenses %} <option value="{{license.name}}"></option> {% endfor %} </datalist> + <label for="lic_id">License ID:</label> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <datalist id="licenses_ids"> + {% for license in licenses %} + <option value="{{license.license_id}}"></option> + {% endfor %} + </datalist> + <label for="team">Team:</label> + <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <datalist id="teams"> + {% for team in teams %} + <option value="{{team.name}}">{{team.name}}</option> + {% endfor %} + </datalist> <input type="submit" value="Filter"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> - <TH>Vendor ID</TH> - <TH>Product ID</TH> - <TH>Serial Number</TH> - <TH>Licenses</TH> + <TH>Keyman ID</TH> + <TH>License Type</TH> + <TH>License ID</TH> + <TH>Inventory Number</TH> + <TH>Team</TH> + <TH>Last Username</TH> + <TH>Last Hostname</TH> + <TH>Last Detection</TH> <TH>Status</TH> + <TH>Comment</TH> </TR> - {% for i in range(devs) %} + {% for dev in devices %} <TR> - <TD class="ID"><a href="/device-license/{{devices[i].id}}">{{devices[i].id}}</a></TD> - <TD class="Vendor ID">{{devices[i].vendor_id}}</TD> - <TD class="Product ID">{{devices[i].product_id}}</TD> - <TD class="Serial Number">{{devices[i].serial_number}}</TD> - <TD class="License"> - {% for lic in devices[i].licenses %} - {{lic.licenses.name}}<BR> - {% endfor %} - </TD> - <TD class="Status">{{statuses[i]}}</TD> + <TD class="ID"><a href="/device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD> + <TD class="Serial Number">{{dev['device'].serial_number}}</TD> + <TD class="License">{{dev['license'].name}}</TD> + <TD class="License ID">{{dev['license'].license_id}}</TD> + <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD> + <TD class="Team">{{dev['device'].team.name}}</TD> + <TD class="Last Username">{{dev['log'].pc.username}}</TD> + <TD class="Last Hostname">{{dev['log'].pc.hostname}}</TD> + <TD class="Last Detection">{{dev['log'].timestamp}}</TD> + <TD class="Status">{{dev['log'].status}}</TD> + <TD class="Comment">{{dev['device'].comment}}</TD> </TR> {% endfor %} - <TR> - <TD class="ID"></TD> - <TD class="Vendor ID"></TD> - <TD class="Product ID"></TD> - <TD class="Serial Number"></TD> - <TD class="License"> - <form action="/license-create" method="get"> - <input type="submit" value="Add"> - </form> - </TD> - </TR> </table> </body> </html> diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html index 4e0813f..ac38f54 100644 --- a/server/templates/devices/devices_normal.html +++ b/server/templates/devices/devices_normal.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Devices Details</title> </head> <body> @@ -22,10 +46,9 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> - <option value="/devices-web">Devices</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> + <option value="/devices-web" selected>Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> @@ -43,27 +66,33 @@ </datalist> <input type="submit" value="Filter"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> - <TH>Vendor ID</TH> - <TH>Product ID</TH> - <TH>Serial Number</TH> - <TH>Licenses</TH> + <TH>Keyman ID</TH> + <TH>License Type</TH> + <TH>License ID</TH> + <TH>Inventory Number</TH> + <TH>Team</TH> + <TH>Last Username</TH> + <TH>Last Hostname</TH> + <TH>Last Detection</TH> <TH>Status</TH> + <TH>Comment</TH> </TR> - {% for i in range(devs) %} + {% for dev in devices %} <TR> - <TD class="ID">{{devices[i].id}}</TD> - <TD class="Vendor ID">{{devices[i].vendor_id}}</TD> - <TD class="Product ID">{{devices[i].product_id}}</TD> - <TD class="Serial Number">{{devices[i].serial_number}}</TD> - <TD class="License"> - {% for lic in devices[i].licenses %} - {{lic.licenses.name}}<BR> - {% endfor %} - </TD> - <TD class="Status">{{statuses[i]}}</TD> + <TD class="ID">{{dev['device'].id}}</TD> + <TD class="Serial Number">{{dev['device'].serial_number}}</TD> + <TD class="License">{{dev['license'].name}}</TD> + <TD class="License ID">{{dev['license'].license_id}}</TD> + <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD> + <TD class="Team">{{dev['device'].team.name}}</TD> + <TD class="Last Username">{{dev['log'].pc.username}}</TD> + <TD class="Last Hostname">{{dev['log'].pc.hostname}}</TD> + <TD class="Last Detection">{{dev['log'].timestamp}}</TD> + <TD class="Status">{{dev['log'].status}}</TD> + <TD class="Comment">{{dev['device'].comment}}</TD> </TR> {% endfor %} </table> diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html index deda9b0..f7afdf1 100644 --- a/server/templates/ld-logs/ldlogs.html +++ b/server/templates/ld-logs/ldlogs.html @@ -22,9 +22,8 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web" selected>Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> @@ -66,8 +65,8 @@ <TH>Team</TH> <TH>Timestamp</TH> <TH>Status</TH> - <TH>Head Device Serial Number</TH> - <TH>Body Device Serial Number</TH> + <TH>Lauterbach Head ID</TH> + <TH>Lauterbach Body ID</TH> </TR> {% for log in logs %} <TR> diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html index 0487981..27060e6 100644 --- a/server/templates/ld-logs/ldlogs_normal.html +++ b/server/templates/ld-logs/ldlogs_normal.html @@ -22,9 +22,8 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web" selected>Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> @@ -65,8 +64,8 @@ <TH>Team</TH> <TH>Timestamp</TH> <TH>Status</TH> - <TH>Head Device Serial Number</TH> - <TH>Body Device Serial Number</TH> + <TH>Lauterbach Head ID</TH> + <TH>Lauterbach Body ID</TH> </TR> {% for log in logs %} <TR> diff --git a/server/templates/licenses/license_create.html b/server/templates/licenses/license_create.html index 861174a..707ce4e 100644 --- a/server/templates/licenses/license_create.html +++ b/server/templates/licenses/license_create.html @@ -8,6 +8,8 @@ <form action="/licenses-web" method="post"> <label for="name">Name:</label><br> <input type="text" id="name" name="name"><br><br> + <label for="lic_id">License ID:</label><br> + <input type="text" id="lic_id" name="lic_id"><br><br> <label for="expdate">Expiration Date</label> <input type="date" id="expdate" name="expdate" min={{minimum_date}}> <input type="submit" value="Submit"> diff --git a/server/templates/licenses/licenses.html b/server/templates/licenses/licenses.html index 57a9b61..05c0f43 100644 --- a/server/templates/licenses/licenses.html +++ b/server/templates/licenses/licenses.html @@ -22,14 +22,13 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> - <option value="/licenses-web">Licenses</option> + <option value="/licenses-web" selected>Licenses</option> <option value="/users-web">Users</option> </select> <input type="submit" value="OK"> @@ -37,14 +36,16 @@ <table> <TR> <TH>ID</TH> - <TH>Name</TH> + <TH>License Type</TH> + <TH>License ID</TH> <TH>Expiration Date</TH> </TR> {% for license in licenses %} <TR> <TD class="ID">{{license.id}}</TD> - <TD class="Vendor ID">{{license.name}}</TD> - <TD class="Product ID">{{license.expiration_date}}</TD> + <TD class="License Type">{{license.name}}</TD> + <TD class="License ID">{{license.license_id}}</TD> + <TD class="Expiration Date">{{license.expiration_date}}</TD> </TR> {% endfor %} </table> diff --git a/server/templates/licenses/licenses_normal.html b/server/templates/licenses/licenses_normal.html index 2f580d4..63414bc 100644 --- a/server/templates/licenses/licenses_normal.html +++ b/server/templates/licenses/licenses_normal.html @@ -22,14 +22,13 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> - <option value="/licenses-web">Licenses</option> + <option value="/licenses-web" selected>Licenses</option> </select> <input type="submit" value="OK"> </form> @@ -37,12 +36,14 @@ <TR> <TH>ID</TH> <TH>Name</TH> + <TH>License ID</TH> <TH>Expiration Date</TH> </TR> {% for license in licenses %} <TR> <TD class="ID">{{license.id}}</TD> <TD class="Vendor ID">{{license.name}}</TD> + <TD class="License ID">{{license.license_id}}</TD> <TD class="Product ID">{{license.expiration_date}}</TD> </TR> {% endfor %} diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html index 72295e2..89abe1a 100644 --- a/server/templates/pcs/pcs.html +++ b/server/templates/pcs/pcs.html @@ -22,13 +22,12 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> - <option value="/pcs-web">PCs</option> + <option value="/pcs-web" selected>PCs</option> <option value="/licenses-web">Licenses</option> <option value="/users-web">Users</option> </select> @@ -39,18 +38,12 @@ <TH>ID</TH> <TH>Username</TH> <TH>Hostname</TH> - <TH>Team</TH> </TR> {% for pc in pcs %} <TR> - <TD class="ID"><a href="/pc-team/{{pc.id}}">{{pc.id}}</a></TD> - <TD class="Vendor ID">{{pc.username}}</TD> - <TD class="Product ID">{{pc.hostname}}</TD> - {% if pc.team == None %} - <TD class="Team">NONE</TD> - {% else %} - <TD class="Team">{{pc.team.name}}</TD> - {% endif %} + <TD class="ID">{{pc.id}}</TD> + <TD class="Username">{{pc.username}}</TD> + <TD class="Hostname">{{pc.hostname}}</TD> </TR> {% endfor %} </table> diff --git a/server/templates/pcs/pcs_normal.html b/server/templates/pcs/pcs_normal.html index b6b6cd5..b41000e 100644 --- a/server/templates/pcs/pcs_normal.html +++ b/server/templates/pcs/pcs_normal.html @@ -22,13 +22,12 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> - <option value="/pcs-web">PCs</option> + <option value="/pcs-web" selected>PCs</option> <option value="/licenses-web">Licenses</option> </select> <input type="submit" value="OK"> @@ -38,18 +37,12 @@ <TH>ID</TH> <TH>Username</TH> <TH>Hostname</TH> - <TH>Team</TH> </TR> {% for pc in pcs %} <TR> <TD class="ID">{{pc.id}}</TD> - <TD class="Vendor ID">{{pc.username}}</TD> - <TD class="Product ID">{{pc.hostname}}</TD> - {% if pc.team == None %} - <TD class="Team">NONE</TD> - {% else %} - <TD class="Team">{{pc.team.name}}</TD> - {% endif %} + <TD class="Username">{{pc.username}}</TD> + <TD class="Hostname">{{pc.hostname}}</TD> </TR> {% endfor %} </table> diff --git a/server/templates/teams/team_change.html b/server/templates/teams/team_change.html new file mode 100644 index 0000000..3ef6f23 --- /dev/null +++ b/server/templates/teams/team_change.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>Change team name</title> +</head> +<body> +<h4>Team: {{team.name}}</h4> +<form action="/teams-change-process/{{team.id}}" method="post"> + <label for="name">Name:</label><br> + <input type="text" id="name" name="name"><br><br> + <input type="submit" value="Submit"> +</form> +</body> +</html> \ No newline at end of file diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html index f6945e6..f16933b 100644 --- a/server/templates/teams/teams.html +++ b/server/templates/teams/teams.html @@ -22,12 +22,11 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> - <option value="/teams-web">Teams</option> + <option value="/teams-web" selected>Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> <option value="/users-web">Users</option> @@ -38,17 +37,11 @@ <TR> <TH>ID</TH> <TH>Name</TH> - <TH>Members</TH> </TR> {% for team in teams %} <TR> - <TD class="ID">{{team.id}}</TD> + <TD class="ID"><a href="/team-change/{{team.id}}">{{team.id}}</a></TD> <TD class="Name">{{team.name}}</TD> - <TD class="Members"> - {% for ppl in team.pcs %} - {{ppl.username}}<BR> - {% endfor %} - </TD> </TR> {% endfor %} </table> diff --git a/server/templates/teams/teams_normal.html b/server/templates/teams/teams_normal.html index d25b5b9..a10f217 100644 --- a/server/templates/teams/teams_normal.html +++ b/server/templates/teams/teams_normal.html @@ -22,12 +22,11 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> - <option value="/teams-web">Teams</option> + <option value="/teams-web" selected>Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> </select> @@ -37,17 +36,11 @@ <TR> <TH>ID</TH> <TH>Name</TH> - <TH>Members</TH> </TR> {% for team in teams %} <TR> <TD class="ID">{{team.id}}</TD> <TD class="Vendor ID">{{team.name}}</TD> - <TD class="Members"> - {% for ppl in team.pcs %} - {{ppl.username}}<BR> - {% endfor %} - </TD> </TR> {% endfor %} </table> diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html index 4f1bb07..a9d6901 100644 --- a/server/templates/usb-logs/logs.html +++ b/server/templates/usb-logs/logs.html @@ -22,9 +22,8 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web" selected>Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> @@ -66,8 +65,7 @@ <TH>Team</TH> <TH>Timestamp</TH> <TH>Status</TH> - <TH>Device Product ID</TH> - <TH>Device Serial Number</TH> + <TH>Keyman ID</TH> </TR> {% for log in logs %} <TR> @@ -77,11 +75,10 @@ {% if log.pc.team == None %} <TD class="Team">NONE</TD> {% else %} - <TD class="Team">{{log.pc.team.name}}</TD> + <TD class="Team">{{log.device.team.name}}</TD> {% endif %} <TD class="Timestamp">{{log.timestamp}}</TD> <TD class="Status">{{log.status}}</TD> - <TD class="DeviceProductID">{{log.device.product_id}}</TD> <TD class="DeviceSerialNumber">{{log.device.serial_number}}</TD> </TR> {% endfor %} diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html index aaf52e8..5132d64 100644 --- a/server/templates/usb-logs/logs_normal.html +++ b/server/templates/usb-logs/logs_normal.html @@ -22,9 +22,8 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web" selected>Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> @@ -65,8 +64,7 @@ <TH>Team</TH> <TH>Timestamp</TH> <TH>Status</TH> - <TH>Device Product ID</TH> - <TH>Device Serial Number</TH> + <TH>Keyman ID</TH> </TR> {% for log in logs %} <TR> @@ -76,11 +74,10 @@ {% if log.pc.team == None %} <TD class="Team">NONE</TD> {% else %} - <TD class="Team">{{log.pc.team.name}}</TD> + <TD class="Team">{{log.device.team.name}}</TD> {% endif %} <TD class="Timestamp">{{log.timestamp}}</TD> <TD class="Status">{{log.status}}</TD> - <TD class="DeviceProductID">{{log.device.product_id}}</TD> <TD class="DeviceSerialNumber">{{log.device.serial_number}}</TD> </TR> {% endfor %} diff --git a/server/templates/users/users.html b/server/templates/users/users.html index dfb9e87..9952d85 100644 --- a/server/templates/users/users.html +++ b/server/templates/users/users.html @@ -19,15 +19,14 @@ <form action="" method="get"> <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> - <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Devices</option> <option value="/body-devices-web">Body Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> - <option value="/users-web">Users</option> + <option value="/users-web" selected>Users</option> </select> <input type="submit" value="OK"> </form> -- GitLab From 6ad54e2e2e472842cac061f7627cdd35cb1f25da Mon Sep 17 00:00:00 2001 From: "zemanm98@students.zcu.cz" <Farnhait123*> Date: Sat, 14 May 2022 21:22:15 +0200 Subject: [PATCH 63/67] Changed looks of tables with simple css. Added inventory number and comment to Lauterbach devices. Changed connection between lauterbach devices and license. --- server/sql_app/api/devices.py | 2 +- server/sql_app/api/licenses_web.py | 2 +- server/sql_app/crud.py | 8 ++-- server/sql_app/models.py | 43 ++++++++++--------- server/sql_app/schemas.py | 19 ++++++-- .../templates/body-devices/body_devices.html | 30 +++++++++++-- .../body-devices/body_devices_normal.html | 30 +++++++++++-- server/templates/devices/devices.html | 6 +-- server/templates/devices/devices_normal.html | 4 +- server/templates/ld-logs/ldlogs.html | 30 +++++++++++-- server/templates/ld-logs/ldlogs_normal.html | 30 +++++++++++-- server/templates/licenses/licenses.html | 30 +++++++++++-- .../templates/licenses/licenses_normal.html | 30 +++++++++++-- server/templates/pcs/pcs.html | 30 +++++++++++-- server/templates/pcs/pcs_normal.html | 30 +++++++++++-- server/templates/teams/teams.html | 30 +++++++++++-- server/templates/teams/teams_normal.html | 30 +++++++++++-- server/templates/usb-logs/crossroad.html | 8 ++-- server/templates/usb-logs/logs.html | 30 +++++++++++-- server/templates/usb-logs/logs_normal.html | 30 +++++++++++-- server/templates/users/users.html | 30 +++++++++++-- 21 files changed, 405 insertions(+), 77 deletions(-) diff --git a/server/sql_app/api/devices.py b/server/sql_app/api/devices.py index ec5f3dc..24b6c17 100644 --- a/server/sql_app/api/devices.py +++ b/server/sql_app/api/devices.py @@ -21,7 +21,7 @@ def get_db(): @device.post("/device", response_model=schemas.Device) -def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)): +def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)): """ Endpoint used for creating new device """ diff --git a/server/sql_app/api/licenses_web.py b/server/sql_app/api/licenses_web.py index 3d9bdf5..64a4ec7 100644 --- a/server/sql_app/api/licenses_web.py +++ b/server/sql_app/api/licenses_web.py @@ -60,7 +60,7 @@ async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, d "user": current_user}) @licenses_web.post("/licenses-web") -def create_license(name: str = Form(...), lic_id: str = Form(...), expdate: Optional[date] = Form(None), +def create_license(name: Optional[str] = Form(""), lic_id: str = Form(...), expdate: Optional[date] = Form(None), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ Endpoint called from create license form. Creates new license and redirects to devices-web endpoint diff --git a/server/sql_app/crud.py b/server/sql_app/crud.py index d20873b..6892343 100644 --- a/server/sql_app/crud.py +++ b/server/sql_app/crud.py @@ -376,14 +376,14 @@ def get_head_devices(db: Session, skip: int = 0, limit: int = 100): return db.query(models.HeadDevice).offset(skip).limit(limit).all() -def find_head_device(db: Session, serial: schemas.HeadDeviceBase): +def find_head_device(db: Session, serial: schemas.HeadDeviceTemp): """ Finds one head device by its serial number """ return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first() -def create_head_device(db: Session, log: schemas.HeadDeviceBase): +def create_head_device(db: Session, log: schemas.HeadDeviceTemp): """ Creates new head device """ @@ -408,14 +408,14 @@ def get_body_devices(db: Session, skip: int = 0, limit: int = 100): return db.query(models.BodyDevice).offset(skip).limit(limit).all() -def find_body_device(db: Session, serial: schemas.BodyDeviceBase): +def find_body_device(db: Session, serial: schemas.BodyDeviceTemp): """ Finds one body device by its serial number """ return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first() -def create_body_device(db: Session, log: schemas.BodyDeviceBase): +def create_body_device(db: Session, log: schemas.BodyDeviceTemp): """ Creates new Body device """ diff --git a/server/sql_app/models.py b/server/sql_app/models.py index e3e40a5..9c8225b 100644 --- a/server/sql_app/models.py +++ b/server/sql_app/models.py @@ -25,6 +25,7 @@ class Device(Base): licenses = relationship("DeviceLicense", back_populates="device_lic") team = relationship("Team", back_populates="devices") + class USBLog(Base): """ Class defining database table usb_logs @@ -50,13 +51,15 @@ class License(Base): __tablename__ = "licenses" id = Column(Integer, primary_key=True, index=True) - name = Column(String, index=True, nullable=False) + name = Column(String, index=True, nullable=True) license_id = Column(String, index=True, nullable=False) expiration_date = Column(DateTime(timezone=True), nullable=True) # relationships for foreign keys, thus connecting table with devices table devices = relationship("DeviceLicense", back_populates="licenses") - body_devices = relationship("BodyDeviceLicense", back_populates="b_licenses") + bodydevice_lic = relationship("BodyDevice", back_populates="license") + headdevice_lic = relationship("HeadDevice", back_populates="license") + class DeviceLicense(Base): """ @@ -75,23 +78,6 @@ class DeviceLicense(Base): licenses = relationship("License", back_populates="devices") -class BodyDeviceLicense(Base): - """ - Class defining database table bodydevices_licenses - """ - __tablename__ = "bodydevices_licenses" - - id = Column(Integer, primary_key=True, index=True) - bodydevice_id = Column(Integer, ForeignKey("body_devices.id")) - license_id = Column(Integer, ForeignKey("licenses.id")) - assigned_datetime = Column(String, index=True, nullable=False) - - # relationships for foreign keys, thus connecting table with devices and licenses - # tables - bodydevice_lic = relationship("BodyDevice", back_populates="debug_licenses") - b_licenses = relationship("License", back_populates="body_devices") - - class PC(Base): """ Class defining database table pc @@ -118,6 +104,9 @@ class Team(Base): name = Column(String, index=True, nullable=False) devices = relationship("Device", back_populates="team") + body_devices = relationship("BodyDevice", back_populates="team") + head_devices = relationship("HeadDevice", back_populates="team") + class HeadDevice(Base): """ @@ -127,9 +116,16 @@ class HeadDevice(Base): id = Column(Integer, primary_key=True, index=True) serial_number = Column(String, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) + license_id = Column(Integer, ForeignKey("licenses.id")) # relationships for foreign keys, thus connecting table with ld_logs table h_logs = relationship("LDLog", back_populates="head_device") + license = relationship("License", back_populates="headdevice_lic") + team = relationship("Team", back_populates="head_devices") class BodyDevice(Base): @@ -140,10 +136,16 @@ class BodyDevice(Base): id = Column(Integer, primary_key=True, index=True) serial_number = Column(String, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) + license_id = Column(Integer, ForeignKey("licenses.id")) # relationships for foreign keys, thus connecting table with ld_logs table b_logs = relationship("LDLog", back_populates="body_device") - debug_licenses = relationship("BodyDeviceLicense", back_populates="bodydevice_lic") + license = relationship("License", back_populates="bodydevice_lic") + team = relationship("Team", back_populates="body_devices") class LDLog(Base): @@ -165,6 +167,7 @@ class LDLog(Base): head_device = relationship("HeadDevice", back_populates="h_logs") body_device = relationship("BodyDevice", back_populates="b_logs") + class User(Base): """ Class defining user in database with its own role diff --git a/server/sql_app/schemas.py b/server/sql_app/schemas.py index 4a7e381..eeab5a6 100644 --- a/server/sql_app/schemas.py +++ b/server/sql_app/schemas.py @@ -97,6 +97,8 @@ class LDLog(LDLogCreate): class BodyDeviceBase(BaseModel): serial_number: str + inventory_number: str + comment: str class BodyDeviceCreate(BodyDeviceBase): @@ -114,8 +116,14 @@ class BodyDevice(BodyDeviceCreate): orm_mode = True +class BodyDeviceTemp(BaseModel): + serial_number: str + + class HeadDeviceBase(BaseModel): serial_number: str + inventory_number: str + comment: str class HeadDeviceCreate(HeadDeviceBase): @@ -133,6 +141,10 @@ class HeadDevice(HeadDeviceCreate): orm_mode = True +class HeadDeviceTemp(BaseModel): + serial_number: str + + class PCBase(BaseModel): username: str hostname: str @@ -189,6 +201,8 @@ class License(LicenseCreate): """ id: int devices: List[DeviceLicense] = [] + head_devices: List[HeadDevice] = [] + body_devices: List[BodyDevice] = [] class Config: orm_mode = True @@ -224,8 +238,8 @@ class LDTempBase(BaseModel): username: str hostname: str timestamp: str - head_device: HeadDeviceBase - body_device: BodyDeviceBase + head_device: HeadDeviceTemp + body_device: BodyDeviceTemp status: str @@ -260,4 +274,3 @@ class User(UserCreate): class Config: orm_mode = True - diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html index 255a851..a929689 100644 --- a/server/templates/body-devices/body_devices.html +++ b/server/templates/body-devices/body_devices.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Devices Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web" selected>Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web" selected>Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -43,7 +67,7 @@ </datalist> <input type="submit" value="Filter"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Lauterbach Body ID</TH> diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html index 8a3452e..db8159f 100644 --- a/server/templates/body-devices/body_devices_normal.html +++ b/server/templates/body-devices/body_devices_normal.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Devices Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web" selected>Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web" selected>Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -42,7 +66,7 @@ </datalist> <input type="submit" value="Filter"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Lauterbach Body ID</TH> diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html index 33a1a21..b0e09e2 100644 --- a/server/templates/devices/devices.html +++ b/server/templates/devices/devices.html @@ -48,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web" selected>Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web" selected>Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -65,7 +65,7 @@ <option value="{{dev.serial_number}}"></option> {% endfor %} </datalist> - <label for="lic_name">License Name:</label> + <label for="lic_name">License Type:</label> <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="" placeholder="all"> <datalist id="licenses_names"> {% for license in licenses %} diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html index ac38f54..abd3400 100644 --- a/server/templates/devices/devices_normal.html +++ b/server/templates/devices/devices_normal.html @@ -48,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web" selected>Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web" selected>Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html index f7afdf1..7723f2a 100644 --- a/server/templates/ld-logs/ldlogs.html +++ b/server/templates/ld-logs/ldlogs.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title> LD Logs Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web" selected>Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -57,7 +81,7 @@ </datalist> <input type="submit" value="Filter"> </form> - <table> + <table id="devices"> <TR> <TH>ID</TH> <TH>PC Username</TH> diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html index 27060e6..303b83f 100644 --- a/server/templates/ld-logs/ldlogs_normal.html +++ b/server/templates/ld-logs/ldlogs_normal.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title> LD Logs Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web" selected>Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -56,7 +80,7 @@ </datalist> <input type="submit" value="Filter"> </form> - <table> + <table id="devices"> <TR> <TH>ID</TH> <TH>PC Username</TH> diff --git a/server/templates/licenses/licenses.html b/server/templates/licenses/licenses.html index 05c0f43..1970c77 100644 --- a/server/templates/licenses/licenses.html +++ b/server/templates/licenses/licenses.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Licenses Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web" selected>Licenses</option> @@ -33,7 +57,7 @@ </select> <input type="submit" value="OK"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>License Type</TH> diff --git a/server/templates/licenses/licenses_normal.html b/server/templates/licenses/licenses_normal.html index 63414bc..2656650 100644 --- a/server/templates/licenses/licenses_normal.html +++ b/server/templates/licenses/licenses_normal.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Licenses Details</title> </head> <body> @@ -24,15 +48,15 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web" selected>Licenses</option> </select> <input type="submit" value="OK"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Name</TH> diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html index 89abe1a..a723452 100644 --- a/server/templates/pcs/pcs.html +++ b/server/templates/pcs/pcs.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Pcs Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web" selected>PCs</option> <option value="/licenses-web">Licenses</option> @@ -33,7 +57,7 @@ </select> <input type="submit" value="OK"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Username</TH> diff --git a/server/templates/pcs/pcs_normal.html b/server/templates/pcs/pcs_normal.html index b41000e..1ca892d 100644 --- a/server/templates/pcs/pcs_normal.html +++ b/server/templates/pcs/pcs_normal.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Pcs Details</title> </head> <body> @@ -24,15 +48,15 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web" selected>PCs</option> <option value="/licenses-web">Licenses</option> </select> <input type="submit" value="OK"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Username</TH> diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html index f16933b..6957999 100644 --- a/server/templates/teams/teams.html +++ b/server/templates/teams/teams.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Teams Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web" selected>Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -33,7 +57,7 @@ </select> <input type="submit" value="OK"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Name</TH> diff --git a/server/templates/teams/teams_normal.html b/server/templates/teams/teams_normal.html index a10f217..c928f52 100644 --- a/server/templates/teams/teams_normal.html +++ b/server/templates/teams/teams_normal.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Teams Details</title> </head> <body> @@ -24,15 +48,15 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web" selected>Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> </select> <input type="submit" value="OK"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Name</TH> diff --git a/server/templates/usb-logs/crossroad.html b/server/templates/usb-logs/crossroad.html index f553dc4..01db9b9 100644 --- a/server/templates/usb-logs/crossroad.html +++ b/server/templates/usb-logs/crossroad.html @@ -9,10 +9,10 @@ <label for="view">Choose view:</label> <select id="view" name="view" onchange="this.form.action=this.value;"> <option value=""></option> - <option value="/logs-web">Logs</option> - <option value="/ldlogs-web">LD Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html index a9d6901..34e14cd 100644 --- a/server/templates/usb-logs/logs.html +++ b/server/templates/usb-logs/logs.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Logs Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web" selected>Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -57,7 +81,7 @@ </datalist> <input type="submit" value="Filter"> </form> - <table> + <table id="devices"> <TR> <TH>ID</TH> <TH>PC Username</TH> diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html index 5132d64..99c3a9c 100644 --- a/server/templates/usb-logs/logs_normal.html +++ b/server/templates/usb-logs/logs_normal.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Logs Details</title> </head> <body> @@ -24,8 +48,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web" selected>Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -56,7 +80,7 @@ </datalist> <input type="submit" value="Filter"> </form> - <table> + <table id="devices"> <TR> <TH>ID</TH> <TH>PC Username</TH> diff --git a/server/templates/users/users.html b/server/templates/users/users.html index 9952d85..6b56b9a 100644 --- a/server/templates/users/users.html +++ b/server/templates/users/users.html @@ -1,5 +1,29 @@ <html> <head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> <title>Users Details</title> </head> <body> @@ -21,8 +45,8 @@ <select id="view" name="view" onchange="this.form.action=this.value;"> <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> - <option value="/devices-web">Devices</option> - <option value="/body-devices-web">Body Devices</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -30,7 +54,7 @@ </select> <input type="submit" value="OK"> </form> -<table> +<table id="devices"> <TR> <TH>ID</TH> <TH>Username</TH> -- GitLab From 0fcb708f3eec9a99bb4d6610105394abb368b1c1 Mon Sep 17 00:00:00 2001 From: Matej Zeman <zeman339@gmail.com> Date: Sun, 15 May 2022 15:53:00 +0200 Subject: [PATCH 64/67] re #9846 Changed keyman devices, body devices views. Added Head devices view. Changed filtering of logs, ldlogs, body devices, head devices and keyman devices. Changed HTML tables style and few labels. --- server/doc/sql_app/api/auth.html | 633 ++++++ server/doc/sql_app/api/bodydevices_web.html | 446 ++++ server/doc/sql_app/api/devices.html | 6 +- server/doc/sql_app/api/devices_web.html | 445 +++- server/doc/sql_app/api/headdevices_web.html | 440 ++++ server/doc/sql_app/api/index.html | 25 + server/doc/sql_app/api/ld_logs_web.html | 237 ++ server/doc/sql_app/api/licenses_web.html | 120 +- server/doc/sql_app/api/pcs_web.html | 93 +- server/doc/sql_app/api/teams_web.html | 174 +- server/doc/sql_app/api/usb_logs.html | 8 +- server/doc/sql_app/api/usb_logs_web.html | 81 +- server/doc/sql_app/api/users_web.html | 194 ++ server/doc/sql_app/crud.html | 1914 +++++++++++++++-- .../{documentation.html => index.html} | 0 server/doc/sql_app/main.html | 10 + server/doc/sql_app/models.html | 1150 +++++++--- server/doc/sql_app/schemas.html | 430 +++- server/sql_app/api/auth.py | 9 + server/sql_app/api/bodydevices_web.py | 126 +- server/sql_app/api/devices_web.py | 31 +- server/sql_app/api/headdevices_web.py | 169 ++ server/sql_app/crud.py | 551 ++++- server/sql_app/main.py | 4 +- server/sql_app/schemas.py | 9 + server/templates/auth/login.html | 6 +- server/templates/auth/signup.html | 6 +- .../body-devices/body_device_license.html | 37 +- .../templates/body-devices/body_devices.html | 62 +- .../body-devices/body_devices_normal.html | 53 +- server/templates/devices/devices.html | 3 +- server/templates/devices/devices_normal.html | 3 +- .../templates/head_devices/head_devices.html | 114 + .../head_devices/head_devices_normal.html | 113 + .../templates/head_devices/headlicense.html | 49 + server/templates/ld-logs/ldlogs.html | 15 +- server/templates/ld-logs/ldlogs_normal.html | 17 +- server/templates/licenses/license_create.html | 10 +- server/templates/pcs/pcs.html | 3 +- server/templates/pcs/pcs_normal.html | 3 +- server/templates/teams/team_change.html | 4 +- server/templates/teams/team_create.html | 4 +- server/templates/teams/teams.html | 3 +- server/templates/teams/teams_normal.html | 3 +- server/templates/usb-logs/crossroad.html | 31 +- server/templates/usb-logs/logs.html | 3 +- server/templates/usb-logs/logs_normal.html | 3 +- server/templates/users/users.html | 3 +- 48 files changed, 6887 insertions(+), 966 deletions(-) create mode 100644 server/doc/sql_app/api/auth.html create mode 100644 server/doc/sql_app/api/bodydevices_web.html create mode 100644 server/doc/sql_app/api/headdevices_web.html create mode 100644 server/doc/sql_app/api/ld_logs_web.html create mode 100644 server/doc/sql_app/api/users_web.html rename server/doc/sql_app/{documentation.html => index.html} (100%) create mode 100644 server/sql_app/api/headdevices_web.py create mode 100644 server/templates/head_devices/head_devices.html create mode 100644 server/templates/head_devices/head_devices_normal.html create mode 100644 server/templates/head_devices/headlicense.html diff --git a/server/doc/sql_app/api/auth.html b/server/doc/sql_app/api/auth.html new file mode 100644 index 0000000..38a4bf7 --- /dev/null +++ b/server/doc/sql_app/api/auth.html @@ -0,0 +1,633 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.10.0" /> +<title>sql_app.api.auth API documentation</title> +<meta name="description" content="" /> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> +<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> +<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> +<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>sql_app.api.auth</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">from fastapi import Depends, APIRouter, Form +from fastapi import Request +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi.templating import Jinja2Templates +from fastapi_jwt_auth import AuthJWT +from sqlalchemy.orm import Session +from sql_app import crud +from passlib.context import CryptContext +from pydantic import BaseModel +from ..database import SessionLocal, engine + +# Path to html templates used in this file +templates = Jinja2Templates(directory="../templates/auth") + +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + +# prefix used for all endpoints in this file +auth = APIRouter(prefix="") + + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +class Settings(BaseModel): + authjwt_secret_key: str = "secret" + # Configure application to store and get JWT from cookies + authjwt_token_location: set = {"cookies"} + # Disable CSRF Protection for this example. default is True + authjwt_cookie_csrf_protect: bool = False + + +@AuthJWT.load_config +def get_config(): + return Settings() + + +# admin username and password +fake_users_db = { + "admin": { + "username": "admin", + "password": "admin" + } +} + + +def verify_password(plain_password, hashed_password): + """ + Verifies plain text password with hashed password + """ + return pwd_context.verify(plain_password, hashed_password) + + +def get_hash_password(password): + """ + Returns hashed password + """ + return pwd_context.hash(password) + + +def auth_user(db, username: str, password: str): + """ + Determines if given password belongs to user with given username + """ + user = crud.find_user(db, username) + if not user: + return None + if not verify_password(password, user.password): + return None + return user + + +@auth.get("/signup", response_class=HTMLResponse) +async def signup_get(request: Request): + """ + return html template for signup + """ + return templates.TemplateResponse("signup.html", {"request": request}) + + +@auth.post("/signup", response_class=HTMLResponse) +async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)): + """ + Endpoint called form signup template. Creates new user with role guest that can be changed by admin user + """ + users = crud.get_users(db, 0, 100) + users_names = [] + for u in users: + users_names.append(u.username) + if username not in users_names: + new_user = crud.create_user(db, username, get_hash_password(password), "guest") + if new_user is None: + print("something went wrong") + return """ + <html> + <head> + <title>Signup</title> + </head> + <body> + <h1>New user created. You can go back to previous page.</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """ + else: + return """ + <html> + <head> + <title>Signup</title> + </head> + <body> + <h1>Username taken. Try to choose different username.</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """ + +@auth.get("/login", response_class=HTMLResponse) +async def login_get(request: Request): + """ + return html template for login + """ + return templates.TemplateResponse("login.html", {"request": request}) + + +@auth.post("/login", response_class=HTMLResponse) +async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from login template. Checks if given username and password aligns with admin + username and password and returns token for browser according to given username and password + """ + user = auth_user(db, username, password) + if user != None: + if user.role == "admin": + access_token = Authorize.create_access_token(subject="admin", expires_time=False) + refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False) + else: + access_token = Authorize.create_access_token(subject="guest", expires_time=False) + refresh_token = Authorize.create_refresh_token(subject="guest", expires_time=False) + else: + usr = fake_users_db.get(username) + if usr != None: + if usr["username"] == username and usr["password"] == password: + access_token = Authorize.create_access_token(subject="admin", expires_time=False) + refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False) + else: + return """ + <html> + <head> + <title>Login</title> + </head> + <body> + <h1>Wrong Username or Password</h1> + <form action="/login" method="get"> + <input type="submit" value="Log again" /> + </form> + <form action="/login" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """ + + # Set the JWT cookies in the response + Authorize.set_access_cookies(access_token) + Authorize.set_refresh_cookies(refresh_token) + return """ + <html> + <head> + <title>Login</title> + </head> + <body> + <h1>Now you are logged in, you can continue to previous page.</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """ + + +@auth.post('/refresh') +def refresh(Authorize: AuthJWT = Depends()): + """ + endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are + unlimited. + """ + Authorize.jwt_refresh_token_required() + current_user = Authorize.get_jwt_subject() + new_access_token = Authorize.create_access_token(subject=current_user) + # Set the JWT cookies in the response + Authorize.set_access_cookies(new_access_token) + return {"msg": "The token has been refresh"} + + +@auth.get('/logout', response_class=HTMLResponse) +def logout(Authorize: AuthJWT = Depends()): + """ + Endpoint for deleting cookie token with acces role. + """ + Authorize.jwt_optional() + + Authorize.unset_jwt_cookies() + return """ + <html> + <head> + <title>Logout</title> + </head> + <body> + <h1>Logged Out</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Back" /> + </form> + </body> + </html> + """</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-functions">Functions</h2> +<dl> +<dt id="sql_app.api.auth.auth_user"><code class="name flex"> +<span>def <span class="ident">auth_user</span></span>(<span>db, username: str, password: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Determines if given password belongs to user with given username</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def auth_user(db, username: str, password: str): + """ + Determines if given password belongs to user with given username + """ + user = crud.find_user(db, username) + if not user: + return None + if not verify_password(password, user.password): + return None + return user</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.get_db"><code class="name flex"> +<span>def <span class="ident">get_db</span></span>(<span>)</span> +</code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close()</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.get_hash_password"><code class="name flex"> +<span>def <span class="ident">get_hash_password</span></span>(<span>password)</span> +</code></dt> +<dd> +<div class="desc"><p>Returns hashed password</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_hash_password(password): + """ + Returns hashed password + """ + return pwd_context.hash(password)</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.login"><code class="name flex"> +<span>async def <span class="ident">login</span></span>(<span>username: str = Form(Ellipsis), password: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from login template. Checks if given username and password aligns with admin +username and password and returns token for browser according to given username and password</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@auth.post("/login", response_class=HTMLResponse) +async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from login template. Checks if given username and password aligns with admin + username and password and returns token for browser according to given username and password + """ + user = auth_user(db, username, password) + if user != None: + if user.role == "admin": + access_token = Authorize.create_access_token(subject="admin", expires_time=False) + refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False) + else: + access_token = Authorize.create_access_token(subject="guest", expires_time=False) + refresh_token = Authorize.create_refresh_token(subject="guest", expires_time=False) + else: + usr = fake_users_db.get(username) + if usr != None: + if usr["username"] == username and usr["password"] == password: + access_token = Authorize.create_access_token(subject="admin", expires_time=False) + refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False) + else: + return """ + <html> + <head> + <title>Login</title> + </head> + <body> + <h1>Wrong Username or Password</h1> + <form action="/login" method="get"> + <input type="submit" value="Log again" /> + </form> + <form action="/login" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """ + + # Set the JWT cookies in the response + Authorize.set_access_cookies(access_token) + Authorize.set_refresh_cookies(refresh_token) + return """ + <html> + <head> + <title>Login</title> + </head> + <body> + <h1>Now you are logged in, you can continue to previous page.</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.login_get"><code class="name flex"> +<span>async def <span class="ident">login_get</span></span>(<span>request: starlette.requests.Request)</span> +</code></dt> +<dd> +<div class="desc"><p>return html template for login</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@auth.get("/login", response_class=HTMLResponse) +async def login_get(request: Request): + """ + return html template for login + """ + return templates.TemplateResponse("login.html", {"request": request})</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.logout"><code class="name flex"> +<span>def <span class="ident">logout</span></span>(<span>Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint for deleting cookie token with acces role.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@auth.get('/logout', response_class=HTMLResponse) +def logout(Authorize: AuthJWT = Depends()): + """ + Endpoint for deleting cookie token with acces role. + """ + Authorize.jwt_optional() + + Authorize.unset_jwt_cookies() + return """ + <html> + <head> + <title>Logout</title> + </head> + <body> + <h1>Logged Out</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Back" /> + </form> + </body> + </html> + """</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.refresh"><code class="name flex"> +<span>def <span class="ident">refresh</span></span>(<span>Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are +unlimited.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@auth.post('/refresh') +def refresh(Authorize: AuthJWT = Depends()): + """ + endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are + unlimited. + """ + Authorize.jwt_refresh_token_required() + current_user = Authorize.get_jwt_subject() + new_access_token = Authorize.create_access_token(subject=current_user) + # Set the JWT cookies in the response + Authorize.set_access_cookies(new_access_token) + return {"msg": "The token has been refresh"}</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.signup"><code class="name flex"> +<span>async def <span class="ident">signup</span></span>(<span>username: str = Form(Ellipsis), password: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called form signup template. Creates new user with role guest that can be changed by admin user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@auth.post("/signup", response_class=HTMLResponse) +async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)): + """ + Endpoint called form signup template. Creates new user with role guest that can be changed by admin user + """ + users = crud.get_users(db, 0, 100) + users_names = [] + for u in users: + users_names.append(u.username) + if username not in users_names: + new_user = crud.create_user(db, username, get_hash_password(password), "guest") + if new_user is None: + print("something went wrong") + return """ + <html> + <head> + <title>Signup</title> + </head> + <body> + <h1>New user created. You can go back to previous page.</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """ + else: + return """ + <html> + <head> + <title>Signup</title> + </head> + <body> + <h1>Username taken. Try to choose different username.</h1> + <form action="/logs-web" method="get"> + <input type="submit" value="Home Page" /> + </form> + </body> + </html> + """</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.signup_get"><code class="name flex"> +<span>async def <span class="ident">signup_get</span></span>(<span>request: starlette.requests.Request)</span> +</code></dt> +<dd> +<div class="desc"><p>return html template for signup</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@auth.get("/signup", response_class=HTMLResponse) +async def signup_get(request: Request): + """ + return html template for signup + """ + return templates.TemplateResponse("signup.html", {"request": request})</code></pre> +</details> +</dd> +<dt id="sql_app.api.auth.verify_password"><code class="name flex"> +<span>def <span class="ident">verify_password</span></span>(<span>plain_password, hashed_password)</span> +</code></dt> +<dd> +<div class="desc"><p>Verifies plain text password with hashed password</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def verify_password(plain_password, hashed_password): + """ + Verifies plain text password with hashed password + """ + return pwd_context.verify(plain_password, hashed_password)</code></pre> +</details> +</dd> +</dl> +</section> +<section> +<h2 class="section-title" id="header-classes">Classes</h2> +<dl> +<dt id="sql_app.api.auth.Settings"><code class="flex name class"> +<span>class <span class="ident">Settings</span></span> +<span>(</span><span>**data: Any)</span> +</code></dt> +<dd> +<div class="desc"><p>Create a new model by parsing and validating input data from keyword arguments.</p> +<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class Settings(BaseModel): + authjwt_secret_key: str = "secret" + # Configure application to store and get JWT from cookies + authjwt_token_location: set = {"cookies"} + # Disable CSRF Protection for this example. default is True + authjwt_cookie_csrf_protect: bool = False</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>pydantic.main.BaseModel</li> +<li>pydantic.utils.Representation</li> +</ul> +<h3>Class variables</h3> +<dl> +<dt id="sql_app.api.auth.Settings.authjwt_cookie_csrf_protect"><code class="name">var <span class="ident">authjwt_cookie_csrf_protect</span> : bool</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.api.auth.Settings.authjwt_secret_key"><code class="name">var <span class="ident">authjwt_secret_key</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.api.auth.Settings.authjwt_token_location"><code class="name">var <span class="ident">authjwt_token_location</span> : set</code></dt> +<dd> +<div class="desc"></div> +</dd> +</dl> +</dd> +</dl> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li> +</ul> +</li> +<li><h3><a href="#header-functions">Functions</a></h3> +<ul class="two-column"> +<li><code><a title="sql_app.api.auth.auth_user" href="#sql_app.api.auth.auth_user">auth_user</a></code></li> +<li><code><a title="sql_app.api.auth.get_db" href="#sql_app.api.auth.get_db">get_db</a></code></li> +<li><code><a title="sql_app.api.auth.get_hash_password" href="#sql_app.api.auth.get_hash_password">get_hash_password</a></code></li> +<li><code><a title="sql_app.api.auth.login" href="#sql_app.api.auth.login">login</a></code></li> +<li><code><a title="sql_app.api.auth.login_get" href="#sql_app.api.auth.login_get">login_get</a></code></li> +<li><code><a title="sql_app.api.auth.logout" href="#sql_app.api.auth.logout">logout</a></code></li> +<li><code><a title="sql_app.api.auth.refresh" href="#sql_app.api.auth.refresh">refresh</a></code></li> +<li><code><a title="sql_app.api.auth.signup" href="#sql_app.api.auth.signup">signup</a></code></li> +<li><code><a title="sql_app.api.auth.signup_get" href="#sql_app.api.auth.signup_get">signup_get</a></code></li> +<li><code><a title="sql_app.api.auth.verify_password" href="#sql_app.api.auth.verify_password">verify_password</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="sql_app.api.auth.Settings" href="#sql_app.api.auth.Settings">Settings</a></code></h4> +<ul class=""> +<li><code><a title="sql_app.api.auth.Settings.authjwt_cookie_csrf_protect" href="#sql_app.api.auth.Settings.authjwt_cookie_csrf_protect">authjwt_cookie_csrf_protect</a></code></li> +<li><code><a title="sql_app.api.auth.Settings.authjwt_secret_key" href="#sql_app.api.auth.Settings.authjwt_secret_key">authjwt_secret_key</a></code></li> +<li><code><a title="sql_app.api.auth.Settings.authjwt_token_location" href="#sql_app.api.auth.Settings.authjwt_token_location">authjwt_token_location</a></code></li> +</ul> +</li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> +</footer> +</body> +</html> \ No newline at end of file diff --git a/server/doc/sql_app/api/bodydevices_web.html b/server/doc/sql_app/api/bodydevices_web.html new file mode 100644 index 0000000..958001a --- /dev/null +++ b/server/doc/sql_app/api/bodydevices_web.html @@ -0,0 +1,446 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.10.0" /> +<title>sql_app.api.bodydevices_web API documentation</title> +<meta name="description" content="" /> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> +<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> +<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> +<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>sql_app.api.bodydevices_web</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">from datetime import datetime + +from fastapi import Depends, APIRouter, Form +from fastapi import Request +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi.templating import Jinja2Templates +from fastapi_jwt_auth import AuthJWT +from pydantic import BaseModel +from sqlalchemy.orm import Session +from sql_app.api.auth import fake_users_db +from sql_app import crud, models +from ..database import SessionLocal, engine + +models.Base.metadata.create_all(bind=engine) + +# Path to html templates used in this file +templates = Jinja2Templates(directory="../templates/body-devices") + +# prefix used for all endpoints in this file +body_device_web = APIRouter(prefix="") + + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +@body_device_web.get("/body-devices-web", response_class=HTMLResponse) +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all body devices and necessary attributes + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + + device_dict = [] + devices = crud.get_body_devices(db, skip=skip, limit=limit) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + + +@body_device_web.post("/body-devices-web", response_class=HTMLResponse) +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Endpoint used for filtering body devices by user given inputs. returns html template with only + body devices that has attributes defined by user input + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + device_dict = [] + devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_bodydevices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, + "licenses": licenses, + "user": current_user}) + + +@body_device_web.get("/body-device-license/{device_id}", response_class=HTMLResponse) +async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with one body device and all available licenses that can be assigned to it. Plus available teams + that can be assigned to device, inventory number and comment text input for this device. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + device = crud.get_body_device(db, device_id) + licenses = crud.get_licenses(db, 0, 100) + lic_left = [] + for lic in licenses: + if lic != device.license: + lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) + return templates.TemplateResponse("body_device_license.html", + {"request": request, "device": device, "licenses": lic_left, "teams": teams}) + + +@body_device_web.post("/body-devices-web-lic/{device_id}") +async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template. Connects body device with license + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_license(db, device_id, int(lic)) + return RedirectResponse(url=f"/body-devices-web", status_code=303) + + +@body_device_web.post("/body-devices-web-team/{device_id}") +async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template, connects device with new team + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_team(db, device_id, int(team_con)) + return RedirectResponse(url=f"/body-devices-web", status_code=303) + + +@body_device_web.post("/body-devices-inv/{device_id}") +async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template, updates devices inventory number + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_inv(db, device_id, dev_inv) + return RedirectResponse(url=f"/body-devices-web", status_code=303) + + +@body_device_web.post("/body-devices-comm/{device_id}") +async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template, updates devices comment + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_comm(db, device_id, dev_com) + return RedirectResponse(url=f"/body-devices-web", status_code=303)</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-functions">Functions</h2> +<dl> +<dt id="sql_app.api.bodydevices_web.connect_dev_lic"><code class="name flex"> +<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Returns template with one body device and all available licenses that can be assigned to it. Plus available teams +that can be assigned to device, inventory number and comment text input for this device.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@body_device_web.get("/body-device-license/{device_id}", response_class=HTMLResponse) +async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with one body device and all available licenses that can be assigned to it. Plus available teams + that can be assigned to device, inventory number and comment text input for this device. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + device = crud.get_body_device(db, device_id) + licenses = crud.get_licenses(db, 0, 100) + lic_left = [] + for lic in licenses: + if lic != device.license: + lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) + return templates.TemplateResponse("body_device_license.html", + {"request": request, "device": device, "licenses": lic_left, "teams": teams})</code></pre> +</details> +</dd> +<dt id="sql_app.api.bodydevices_web.connect_post"><code class="name flex"> +<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from template from body_device_license.html template. Connects body device with license +and redirects to body-devices-web endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@body_device_web.post("/body-devices-web-lic/{device_id}") +async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template. Connects body device with license + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_license(db, device_id, int(lic)) + return RedirectResponse(url=f"/body-devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.bodydevices_web.delete_post"><code class="name flex"> +<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, team_con: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from template from body_device_license.html template, connects device with new team +and redirects to body-devices-web endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@body_device_web.post("/body-devices-web-team/{device_id}") +async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template, connects device with new team + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_team(db, device_id, int(team_con)) + return RedirectResponse(url=f"/body-devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.bodydevices_web.device_inv"><code class="name flex"> +<span>async def <span class="ident">device_inv</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from template from body_device_license.html template, updates devices comment +and redirects to body-devices-web endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@body_device_web.post("/body-devices-comm/{device_id}") +async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template, updates devices comment + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_comm(db, device_id, dev_com) + return RedirectResponse(url=f"/body-devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.bodydevices_web.filter_devices"><code class="name flex"> +<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, body_id: str = Form(all), lic_id: str = Form(all), team: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint used for filtering body devices by user given inputs. returns html template with only +body devices that has attributes defined by user input</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@body_device_web.post("/body-devices-web", response_class=HTMLResponse) +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Endpoint used for filtering body devices by user given inputs. returns html template with only + body devices that has attributes defined by user input + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + device_dict = [] + devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_bodydevices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, + "licenses": licenses, + "user": current_user})</code></pre> +</details> +</dd> +<dt id="sql_app.api.bodydevices_web.get_db"><code class="name flex"> +<span>def <span class="ident">get_db</span></span>(<span>)</span> +</code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close()</code></pre> +</details> +</dd> +<dt id="sql_app.api.bodydevices_web.read_devices"><code class="name flex"> +<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Returns template with all body devices and necessary attributes</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@body_device_web.get("/body-devices-web", response_class=HTMLResponse) +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all body devices and necessary attributes + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + + device_dict = [] + devices = crud.get_body_devices(db, skip=skip, limit=limit) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user})</code></pre> +</details> +</dd> +</dl> +</section> +<section> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li> +</ul> +</li> +<li><h3><a href="#header-functions">Functions</a></h3> +<ul class="two-column"> +<li><code><a title="sql_app.api.bodydevices_web.connect_dev_lic" href="#sql_app.api.bodydevices_web.connect_dev_lic">connect_dev_lic</a></code></li> +<li><code><a title="sql_app.api.bodydevices_web.connect_post" href="#sql_app.api.bodydevices_web.connect_post">connect_post</a></code></li> +<li><code><a title="sql_app.api.bodydevices_web.delete_post" href="#sql_app.api.bodydevices_web.delete_post">delete_post</a></code></li> +<li><code><a title="sql_app.api.bodydevices_web.device_inv" href="#sql_app.api.bodydevices_web.device_inv">device_inv</a></code></li> +<li><code><a title="sql_app.api.bodydevices_web.filter_devices" href="#sql_app.api.bodydevices_web.filter_devices">filter_devices</a></code></li> +<li><code><a title="sql_app.api.bodydevices_web.get_db" href="#sql_app.api.bodydevices_web.get_db">get_db</a></code></li> +<li><code><a title="sql_app.api.bodydevices_web.read_devices" href="#sql_app.api.bodydevices_web.read_devices">read_devices</a></code></li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> +</footer> +</body> +</html> \ No newline at end of file diff --git a/server/doc/sql_app/api/devices.html b/server/doc/sql_app/api/devices.html index 44cffd7..0f933d7 100644 --- a/server/doc/sql_app/api/devices.html +++ b/server/doc/sql_app/api/devices.html @@ -49,7 +49,7 @@ def get_db(): @device.post("/device", response_model=schemas.Device) -def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)): +def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)): """ Endpoint used for creating new device """ @@ -84,7 +84,7 @@ def read_device(device_id: int, db: Session = Depends(get_db)): <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="sql_app.api.devices.create_device"><code class="name flex"> -<span>def <span class="ident">create_device</span></span>(<span>device: <a title="sql_app.schemas.DeviceCreate" href="../schemas.html#sql_app.schemas.DeviceCreate">DeviceCreate</a>, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>def <span class="ident">create_device</span></span>(<span>device: <a title="sql_app.schemas.DeviceTemp" href="../schemas.html#sql_app.schemas.DeviceTemp">DeviceTemp</a>, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> </code></dt> <dd> <div class="desc"><p>Endpoint used for creating new device</p></div> @@ -93,7 +93,7 @@ def read_device(device_id: int, db: Session = Depends(get_db)): <span>Expand source code</span> </summary> <pre><code class="python">@device.post("/device", response_model=schemas.Device) -def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)): +def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)): """ Endpoint used for creating new device """ diff --git a/server/doc/sql_app/api/devices_web.html b/server/doc/sql_app/api/devices_web.html index b4028ad..4c54ff9 100644 --- a/server/doc/sql_app/api/devices_web.html +++ b/server/doc/sql_app/api/devices_web.html @@ -26,17 +26,18 @@ <summary> <span>Expand source code</span> </summary> -<pre><code class="python">from typing import List +<pre><code class="python">from datetime import datetime -from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form +from fastapi import Depends, APIRouter, Form +from fastapi import Request +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi.templating import Jinja2Templates +from fastapi_jwt_auth import AuthJWT +from pydantic import BaseModel from sqlalchemy.orm import Session +from sql_app.api.auth import fake_users_db from sql_app import crud, models, schemas -from datetime import datetime from ..database import SessionLocal, engine -from fastapi import FastAPI, Request -from fastapi.responses import HTMLResponse -from fastapi.staticfiles import StaticFiles -from fastapi.templating import Jinja2Templates models.Base.metadata.create_all(bind=engine) @@ -44,7 +45,7 @@ models.Base.metadata.create_all(bind=engine) templates = Jinja2Templates(directory="../templates/devices") # prefix used for all endpoints in this file -device_web = APIRouter(prefix="/api/v1") +device_web = APIRouter(prefix="") # Dependency @@ -57,71 +58,173 @@ def get_db(): @device_web.get("/devices-web", response_class=HTMLResponse) -async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ - Returns template with all devices and its current states + Returns template with all devices and its necessary attributes """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + + device_dict = [] devices = crud.get_devices(db, skip=skip, limit=limit) - statuses = [] - # adding state for each device in list - for i in range(0, len(devices)): - statuses.append(devices[i].logs[len(devices[i].logs)-1].status) + teams = crud.get_teams(db, skip=skip, limit=limit) + # adding dictionary entry with all inforamtions needed in template + for dev in devices: + if len(dev.licenses) > 0: + for lic in dev.licenses: + device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]}) + else: + device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses}) + if current_user == "admin": + return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, + "licenses": licenses, "devs": devices, + "teams": teams, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, + "licenses": licenses, "user": current_user}) @device_web.post("/devices-web", response_class=HTMLResponse) -async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form("all"), - db: Session = Depends(get_db)): +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + keyman_id: str = Form("all"), lic_name: str = Form("all"), + lic_id: str = Form("all"), team: str = Form("all"), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint used for filtering devices by license. returns html template with only + Endpoint used for filtering devices by user given inputs. returns html template with only devices that has assigned license defined by user input """ - devices = crud.get_devices(db, skip=skip, limit=limit) - def_devices = [] + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + device_dict = [] + devices_f = crud.get_filtered_devices(db, keyman_id, lic_name, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_devices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + # adding dictionary entry with all inforamtions needed in template for dev in devices: - for l in dev.licenses: - if dev not in def_devices and l.licenses.name == lic: - def_devices.append(dev) - # if input was default all - if lic == "all": - def_devices = devices - statuses = [] - for i in range(0, len(def_devices)): - statuses.append(def_devices[i].logs[len(def_devices[i].logs) - 1].status) + if len(dev.licenses) > 0: + for lic in dev.licenses: + device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]}) + else: + device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("devices.html", {"request": request, "devs": len(def_devices), "devices": def_devices, - "statuses": statuses, "licenses": licenses}) + if current_user == "admin": + return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, + "licenses": licenses, "devs": devices, + "teams": teams, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, + "licenses": licenses, "user": current_user}) @device_web.get("/device-license/{device_id}", response_class=HTMLResponse) -async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)): +async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ - Returns template with one device and all available licenses that can be assigned to it. + Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can + be assigned to device, inventory number text input and comment text input """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) device = crud.get_device(db, device_id) + dev_licenses = crud.get_device_licenses(db, device_id) + lic_ids = [] + dev_lics = [] + for dev_lic in dev_licenses: + dev_lics.append(dev_lic.licenses) + for dev_lic in dev_licenses: + lic_ids.append(dev_lic.licenses.license_id) licenses = crud.get_licenses(db, 0, 100) + lic_left = [] + for lic in licenses: + if lic.license_id not in lic_ids and lic not in lic_left: + lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) return templates.TemplateResponse("devicelicense.html", - {"request": request, "device": device, "licenses": licenses}) + {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics, + "teams": teams}) -@device_web.post("/devices-web/{device_id}", response_class=HTMLResponse) -async def connect_post(request: Request, device_id: int, lic: str = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): +@device_web.post("/devices-web/{device_id}") +async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ - Endpoint called from template for connecting device with license. Adds entry to devices_licenses - table and returns template with all devices in database + Endpoint called from devicelicense.html template. Adds entry to devices_licenses + table and redirects to devices-web endpoint """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) crud.create_device_license(db, device_id, int(lic), datetime.now()) - devices = crud.get_devices(db, skip=skip, limit=limit) - statuses = [] - # adding state for each device in list - for i in range(0, len(devices)): - statuses.append(devices[i].logs[len(devices[i].logs) - 1].status) - licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses})</code></pre> + return RedirectResponse(url=f"/devices-web", status_code=303) + + +@device_web.post("/devices-web-del/{device_id}") +async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in + bodydevices_licenses table and redirects to devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.delete_device_license(db, device_id, int(lic_del)) + return RedirectResponse(url=f"/devices-web", status_code=303) + + +@device_web.post("/devices-web-team/{device_id}") +async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device(db, device_id, team_con) + return RedirectResponse(url=f"/devices-web", status_code=303) + + +@device_web.post("/devices-web-inv/{device_id}") +async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web + endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device_inv(db, device_id, dev_inv) + return RedirectResponse(url=f"/devices-web", status_code=303) + + +@device_web.post("/devices-web-comment/{device_id}") +async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web + endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device_com(db, device_id, dev_com) + return RedirectResponse(url=f"/devices-web", status_code=303)</code></pre> </details> </section> <section> @@ -132,85 +235,212 @@ async def connect_post(request: Request, device_id: int, lic: str = Form(...), s <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="sql_app.api.devices_web.connect_dev_lic"><code class="name flex"> -<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> -<div class="desc"><p>Returns template with one device and all available licenses that can be assigned to it.</p></div> +<div class="desc"><p>Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can +be assigned to device, inventory number text input and comment text input</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> <pre><code class="python">@device_web.get("/device-license/{device_id}", response_class=HTMLResponse) -async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)): +async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ - Returns template with one device and all available licenses that can be assigned to it. + Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can + be assigned to device, inventory number text input and comment text input """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) device = crud.get_device(db, device_id) + dev_licenses = crud.get_device_licenses(db, device_id) + lic_ids = [] + dev_lics = [] + for dev_lic in dev_licenses: + dev_lics.append(dev_lic.licenses) + for dev_lic in dev_licenses: + lic_ids.append(dev_lic.licenses.license_id) licenses = crud.get_licenses(db, 0, 100) + lic_left = [] + for lic in licenses: + if lic.license_id not in lic_ids and lic not in lic_left: + lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) return templates.TemplateResponse("devicelicense.html", - {"request": request, "device": device, "licenses": licenses})</code></pre> + {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics, + "teams": teams})</code></pre> </details> </dd> <dt id="sql_app.api.devices_web.connect_post"><code class="name flex"> -<span>async def <span class="ident">connect_post</span></span>(<span>request: starlette.requests.Request, device_id: int, lic: str = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> -<div class="desc"><p>Endpoint called from template for connecting device with license. Adds entry to devices_licenses -table and returns template with all devices in database</p></div> +<div class="desc"><p>Endpoint called from devicelicense.html template. Adds entry to devices_licenses +table and redirects to devices-web endpoint</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">@device_web.post("/devices-web/{device_id}", response_class=HTMLResponse) -async def connect_post(request: Request, device_id: int, lic: str = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): +<pre><code class="python">@device_web.post("/devices-web/{device_id}") +async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ - Endpoint called from template for connecting device with license. Adds entry to devices_licenses - table and returns template with all devices in database + Endpoint called from devicelicense.html template. Adds entry to devices_licenses + table and redirects to devices-web endpoint """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) crud.create_device_license(db, device_id, int(lic), datetime.now()) - devices = crud.get_devices(db, skip=skip, limit=limit) - statuses = [] - # adding state for each device in list - for i in range(0, len(devices)): - statuses.append(devices[i].logs[len(devices[i].logs) - 1].status) - licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses})</code></pre> + return RedirectResponse(url=f"/devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.devices_web.delete_post"><code class="name flex"> +<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, lic_del: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in +bodydevices_licenses table and redirects to devices-web endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@device_web.post("/devices-web-del/{device_id}") +async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in + bodydevices_licenses table and redirects to devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.delete_device_license(db, device_id, int(lic_del)) + return RedirectResponse(url=f"/devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.devices_web.dev_comm_new"><code class="name flex"> +<span>async def <span class="ident">dev_comm_new</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web +endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@device_web.post("/devices-web-comment/{device_id}") +async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web + endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device_com(db, device_id, dev_com) + return RedirectResponse(url=f"/devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.devices_web.dev_inv_new"><code class="name flex"> +<span>async def <span class="ident">dev_inv_new</span></span>(<span>device_id: int, dev_inv: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web +endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@device_web.post("/devices-web-inv/{device_id}") +async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web + endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device_inv(db, device_id, dev_inv) + return RedirectResponse(url=f"/devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.devices_web.dev_team_con"><code class="name flex"> +<span>async def <span class="ident">dev_team_con</span></span>(<span>device_id: int, team_con: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@device_web.post("/devices-web-team/{device_id}") +async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_device(db, device_id, team_con) + return RedirectResponse(url=f"/devices-web", status_code=303)</code></pre> </details> </dd> <dt id="sql_app.api.devices_web.filter_devices"><code class="name flex"> -<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, lic: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, keyman_id: str = Form(all), lic_name: str = Form(all), lic_id: str = Form(all), team: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> -<div class="desc"><p>Endpoint used for filtering devices by license. returns html template with only +<div class="desc"><p>Endpoint used for filtering devices by user given inputs. returns html template with only devices that has assigned license defined by user input</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> <pre><code class="python">@device_web.post("/devices-web", response_class=HTMLResponse) -async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form("all"), - db: Session = Depends(get_db)): +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + keyman_id: str = Form("all"), lic_name: str = Form("all"), + lic_id: str = Form("all"), team: str = Form("all"), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint used for filtering devices by license. returns html template with only + Endpoint used for filtering devices by user given inputs. returns html template with only devices that has assigned license defined by user input """ - devices = crud.get_devices(db, skip=skip, limit=limit) - def_devices = [] + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + device_dict = [] + devices_f = crud.get_filtered_devices(db, keyman_id, lic_name, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_devices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + # adding dictionary entry with all inforamtions needed in template for dev in devices: - for l in dev.licenses: - if dev not in def_devices and l.licenses.name == lic: - def_devices.append(dev) - # if input was default all - if lic == "all": - def_devices = devices - statuses = [] - for i in range(0, len(def_devices)): - statuses.append(def_devices[i].logs[len(def_devices[i].logs) - 1].status) + if len(dev.licenses) > 0: + for lic in dev.licenses: + device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]}) + else: + device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("devices.html", {"request": request, "devs": len(def_devices), "devices": def_devices, - "statuses": statuses, "licenses": licenses})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, + "licenses": licenses, "devs": devices, + "teams": teams, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, + "licenses": licenses, "user": current_user})</code></pre> </details> </dd> <dt id="sql_app.api.devices_web.get_db"><code class="name flex"> @@ -231,27 +461,42 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: </details> </dd> <dt id="sql_app.api.devices_web.read_devices"><code class="name flex"> -<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> -<div class="desc"><p>Returns template with all devices and its current states</p></div> +<div class="desc"><p>Returns template with all devices and its necessary attributes</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> <pre><code class="python">@device_web.get("/devices-web", response_class=HTMLResponse) -async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ - Returns template with all devices and its current states + Returns template with all devices and its necessary attributes """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + + device_dict = [] devices = crud.get_devices(db, skip=skip, limit=limit) - statuses = [] - # adding state for each device in list - for i in range(0, len(devices)): - statuses.append(devices[i].logs[len(devices[i].logs)-1].status) + teams = crud.get_teams(db, skip=skip, limit=limit) + # adding dictionary entry with all inforamtions needed in template + for dev in devices: + if len(dev.licenses) > 0: + for lic in dev.licenses: + device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]}) + else: + device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, + "licenses": licenses, "devs": devices, + "teams": teams, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, + "licenses": licenses, "user": current_user})</code></pre> </details> </dd> </dl> @@ -271,9 +516,13 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se </ul> </li> <li><h3><a href="#header-functions">Functions</a></h3> -<ul class=""> +<ul class="two-column"> <li><code><a title="sql_app.api.devices_web.connect_dev_lic" href="#sql_app.api.devices_web.connect_dev_lic">connect_dev_lic</a></code></li> <li><code><a title="sql_app.api.devices_web.connect_post" href="#sql_app.api.devices_web.connect_post">connect_post</a></code></li> +<li><code><a title="sql_app.api.devices_web.delete_post" href="#sql_app.api.devices_web.delete_post">delete_post</a></code></li> +<li><code><a title="sql_app.api.devices_web.dev_comm_new" href="#sql_app.api.devices_web.dev_comm_new">dev_comm_new</a></code></li> +<li><code><a title="sql_app.api.devices_web.dev_inv_new" href="#sql_app.api.devices_web.dev_inv_new">dev_inv_new</a></code></li> +<li><code><a title="sql_app.api.devices_web.dev_team_con" href="#sql_app.api.devices_web.dev_team_con">dev_team_con</a></code></li> <li><code><a title="sql_app.api.devices_web.filter_devices" href="#sql_app.api.devices_web.filter_devices">filter_devices</a></code></li> <li><code><a title="sql_app.api.devices_web.get_db" href="#sql_app.api.devices_web.get_db">get_db</a></code></li> <li><code><a title="sql_app.api.devices_web.read_devices" href="#sql_app.api.devices_web.read_devices">read_devices</a></code></li> diff --git a/server/doc/sql_app/api/headdevices_web.html b/server/doc/sql_app/api/headdevices_web.html new file mode 100644 index 0000000..9d1ba03 --- /dev/null +++ b/server/doc/sql_app/api/headdevices_web.html @@ -0,0 +1,440 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.10.0" /> +<title>sql_app.api.headdevices_web API documentation</title> +<meta name="description" content="" /> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> +<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> +<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> +<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>sql_app.api.headdevices_web</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">from datetime import datetime + +from fastapi import Depends, APIRouter, Form +from fastapi import Request +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi.templating import Jinja2Templates +from fastapi_jwt_auth import AuthJWT +from pydantic import BaseModel +from sqlalchemy.orm import Session +from sql_app.api.auth import fake_users_db +from sql_app import crud, models +from ..database import SessionLocal, engine + +models.Base.metadata.create_all(bind=engine) + +# Path to html templates used in this file +templates = Jinja2Templates(directory="../templates/head_devices") + +# prefix used for all endpoints in this file +head_device_web = APIRouter(prefix="") + + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +@head_device_web.get("/head-devices-web", response_class=HTMLResponse) +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all head devices and necessary attributes + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + + device_dict = [] + devices = crud.get_head_devices(db, skip=skip, limit=limit) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + + +@head_device_web.post("/head-devices-web", response_class=HTMLResponse) +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Endpoint used for filtering head devices by user given inputs. returns html template with only + head devices that has attributes defined by user input + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + device_dict = [] + devices_f = crud.get_filtered_headdevices(db, body_id, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_headdevices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, + "licenses": licenses, + "user": current_user}) + + +@head_device_web.get("/head-device-license/{device_id}", response_class=HTMLResponse) +async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with one head device and all available licenses that can be assigned to it, plus team and comment + and inventory number inputs. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + device = crud.get_head_device(db, device_id) + licenses = crud.get_licenses(db, 0, 100) + lic_left = [] + for lic in licenses: + if lic != device.license: + lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) + return templates.TemplateResponse("headlicense.html", + {"request": request, "device": device, "licenses": lic_left, "teams": teams}) + + +@head_device_web.post("/head-devices-web-lic/{device_id}") +async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_license(db, device_id, int(lic)) + return RedirectResponse(url=f"/head-devices-web", status_code=303) + + +@head_device_web.post("/head-devices-web-team/{device_id}") +async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_team(db, device_id, int(team_con)) + return RedirectResponse(url=f"/head-devices-web", status_code=303) + + +@head_device_web.post("/head-devices-inv/{device_id}") +async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from within from headlicense.html template. Changes head devices inventory number with new one + given from user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_inv(db, device_id, dev_inv) + return RedirectResponse(url=f"/head-devices-web", status_code=303) + + +@head_device_web.post("/head-devices-comm/{device_id}") +async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from within from headlicense.html template. Changes head devices comment with new one + given from user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_comm(db, device_id, dev_com) + return RedirectResponse(url=f"/head-devices-web", status_code=303)</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-functions">Functions</h2> +<dl> +<dt id="sql_app.api.headdevices_web.connect_dev_lic"><code class="name flex"> +<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Returns template with one head device and all available licenses that can be assigned to it, plus team and comment +and inventory number inputs.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@head_device_web.get("/head-device-license/{device_id}", response_class=HTMLResponse) +async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with one head device and all available licenses that can be assigned to it, plus team and comment + and inventory number inputs. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + device = crud.get_head_device(db, device_id) + licenses = crud.get_licenses(db, 0, 100) + lic_left = [] + for lic in licenses: + if lic != device.license: + lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) + return templates.TemplateResponse("headlicense.html", + {"request": request, "device": device, "licenses": lic_left, "teams": teams})</code></pre> +</details> +</dd> +<dt id="sql_app.api.headdevices_web.connect_post"><code class="name flex"> +<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@head_device_web.post("/head-devices-web-lic/{device_id}") +async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_license(db, device_id, int(lic)) + return RedirectResponse(url=f"/head-devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.headdevices_web.delete_post"><code class="name flex"> +<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, team_con: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@head_device_web.post("/head-devices-web-team/{device_id}") +async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_team(db, device_id, int(team_con)) + return RedirectResponse(url=f"/head-devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.headdevices_web.device_inv"><code class="name flex"> +<span>async def <span class="ident">device_inv</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint called from within from headlicense.html template. Changes head devices comment with new one +given from user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@head_device_web.post("/head-devices-comm/{device_id}") +async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from within from headlicense.html template. Changes head devices comment with new one + given from user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_comm(db, device_id, dev_com) + return RedirectResponse(url=f"/head-devices-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.headdevices_web.filter_devices"><code class="name flex"> +<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, body_id: str = Form(all), lic_id: str = Form(all), team: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint used for filtering head devices by user given inputs. returns html template with only +head devices that has attributes defined by user input</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@head_device_web.post("/head-devices-web", response_class=HTMLResponse) +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Endpoint used for filtering head devices by user given inputs. returns html template with only + head devices that has attributes defined by user input + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + device_dict = [] + devices_f = crud.get_filtered_headdevices(db, body_id, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_headdevices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, + "licenses": licenses, + "user": current_user})</code></pre> +</details> +</dd> +<dt id="sql_app.api.headdevices_web.get_db"><code class="name flex"> +<span>def <span class="ident">get_db</span></span>(<span>)</span> +</code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close()</code></pre> +</details> +</dd> +<dt id="sql_app.api.headdevices_web.read_devices"><code class="name flex"> +<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Returns template with all head devices and necessary attributes</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@head_device_web.get("/head-devices-web", response_class=HTMLResponse) +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all head devices and necessary attributes + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + + device_dict = [] + devices = crud.get_head_devices(db, skip=skip, limit=limit) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user})</code></pre> +</details> +</dd> +</dl> +</section> +<section> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li> +</ul> +</li> +<li><h3><a href="#header-functions">Functions</a></h3> +<ul class="two-column"> +<li><code><a title="sql_app.api.headdevices_web.connect_dev_lic" href="#sql_app.api.headdevices_web.connect_dev_lic">connect_dev_lic</a></code></li> +<li><code><a title="sql_app.api.headdevices_web.connect_post" href="#sql_app.api.headdevices_web.connect_post">connect_post</a></code></li> +<li><code><a title="sql_app.api.headdevices_web.delete_post" href="#sql_app.api.headdevices_web.delete_post">delete_post</a></code></li> +<li><code><a title="sql_app.api.headdevices_web.device_inv" href="#sql_app.api.headdevices_web.device_inv">device_inv</a></code></li> +<li><code><a title="sql_app.api.headdevices_web.filter_devices" href="#sql_app.api.headdevices_web.filter_devices">filter_devices</a></code></li> +<li><code><a title="sql_app.api.headdevices_web.get_db" href="#sql_app.api.headdevices_web.get_db">get_db</a></code></li> +<li><code><a title="sql_app.api.headdevices_web.read_devices" href="#sql_app.api.headdevices_web.read_devices">read_devices</a></code></li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> +</footer> +</body> +</html> \ No newline at end of file diff --git a/server/doc/sql_app/api/index.html b/server/doc/sql_app/api/index.html index edd8582..6459f2e 100644 --- a/server/doc/sql_app/api/index.html +++ b/server/doc/sql_app/api/index.html @@ -26,6 +26,14 @@ <section> <h2 class="section-title" id="header-submodules">Sub-modules</h2> <dl> +<dt><code class="name"><a title="sql_app.api.auth" href="auth.html">sql_app.api.auth</a></code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt><code class="name"><a title="sql_app.api.bodydevices_web" href="bodydevices_web.html">sql_app.api.bodydevices_web</a></code></dt> +<dd> +<div class="desc"></div> +</dd> <dt><code class="name"><a title="sql_app.api.devices" href="devices.html">sql_app.api.devices</a></code></dt> <dd> <div class="desc"></div> @@ -34,6 +42,14 @@ <dd> <div class="desc"></div> </dd> +<dt><code class="name"><a title="sql_app.api.headdevices_web" href="headdevices_web.html">sql_app.api.headdevices_web</a></code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt><code class="name"><a title="sql_app.api.ld_logs_web" href="ld_logs_web.html">sql_app.api.ld_logs_web</a></code></dt> +<dd> +<div class="desc"></div> +</dd> <dt><code class="name"><a title="sql_app.api.licenses" href="licenses.html">sql_app.api.licenses</a></code></dt> <dd> <div class="desc"></div> @@ -66,6 +82,10 @@ <dd> <div class="desc"></div> </dd> +<dt><code class="name"><a title="sql_app.api.users_web" href="users_web.html">sql_app.api.users_web</a></code></dt> +<dd> +<div class="desc"></div> +</dd> </dl> </section> <section> @@ -88,8 +108,12 @@ </li> <li><h3><a href="#header-submodules">Sub-modules</a></h3> <ul> +<li><code><a title="sql_app.api.auth" href="auth.html">sql_app.api.auth</a></code></li> +<li><code><a title="sql_app.api.bodydevices_web" href="bodydevices_web.html">sql_app.api.bodydevices_web</a></code></li> <li><code><a title="sql_app.api.devices" href="devices.html">sql_app.api.devices</a></code></li> <li><code><a title="sql_app.api.devices_web" href="devices_web.html">sql_app.api.devices_web</a></code></li> +<li><code><a title="sql_app.api.headdevices_web" href="headdevices_web.html">sql_app.api.headdevices_web</a></code></li> +<li><code><a title="sql_app.api.ld_logs_web" href="ld_logs_web.html">sql_app.api.ld_logs_web</a></code></li> <li><code><a title="sql_app.api.licenses" href="licenses.html">sql_app.api.licenses</a></code></li> <li><code><a title="sql_app.api.licenses_web" href="licenses_web.html">sql_app.api.licenses_web</a></code></li> <li><code><a title="sql_app.api.pcs" href="pcs.html">sql_app.api.pcs</a></code></li> @@ -98,6 +122,7 @@ <li><code><a title="sql_app.api.teams_web" href="teams_web.html">sql_app.api.teams_web</a></code></li> <li><code><a title="sql_app.api.usb_logs" href="usb_logs.html">sql_app.api.usb_logs</a></code></li> <li><code><a title="sql_app.api.usb_logs_web" href="usb_logs_web.html">sql_app.api.usb_logs_web</a></code></li> +<li><code><a title="sql_app.api.users_web" href="users_web.html">sql_app.api.users_web</a></code></li> </ul> </li> </ul> diff --git a/server/doc/sql_app/api/ld_logs_web.html b/server/doc/sql_app/api/ld_logs_web.html new file mode 100644 index 0000000..5336ec6 --- /dev/null +++ b/server/doc/sql_app/api/ld_logs_web.html @@ -0,0 +1,237 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.10.0" /> +<title>sql_app.api.ld_logs_web API documentation</title> +<meta name="description" content="" /> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> +<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> +<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> +<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>sql_app.api.ld_logs_web</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">from typing import List +from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form +from datetime import datetime +from sqlalchemy.orm import Session +from sql_app import crud, models, schemas +from ..database import SessionLocal, engine +from fastapi import FastAPI, Request +from fastapi.responses import HTMLResponse +from fastapi_jwt_auth import AuthJWT +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates + +models.Base.metadata.create_all(bind=engine) + +# Path to html templates used in this file +templates = Jinja2Templates(directory="../templates/ld-logs") + +# prefix used for all endpoints in this file +ldlogs_web = APIRouter(prefix="") + + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +@ldlogs_web.get("/ldlogs-web", response_class=HTMLResponse) +async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all usb logs currently saved in database with its pcs, teams and licenses. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + logs = crud.get_ld_logs(db, skip=skip, limit=limit) + pcs = [] + for log in logs: + if log.pc_id not in pcs: + pcs.append(log.pc_id) + pc_obj = crud.find_pcs(db, pcs) + teams = crud.get_teams(db, skip=skip, limit=limit) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("ldlogs_normal.html", + {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + + +@ldlogs_web.post("/ldlogs-web", response_class=HTMLResponse) +async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"), + skip: int = 0, limit: int = 100, + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Endpoint used for filtering ld logs by user given form inputs. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + log = crud.get_filtered_ldlogs(db, pc, team, lic) + logs_ids = [] + for l in log: + logs_ids.append(l[0]) + logs = crud.find_filtered_ldlogs(db, logs_ids) + pc_obj = crud.get_pcs(db, skip=skip, limit=limit) + teams = crud.get_teams(db, skip=skip, limit=limit) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("ldlogs_normal.html", + {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user})</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-functions">Functions</h2> +<dl> +<dt id="sql_app.api.ld_logs_web.filter_logs"><code class="name flex"> +<span>async def <span class="ident">filter_logs</span></span>(<span>request: starlette.requests.Request, pc: str = Form(all), team: str = Form(all), lic: str = Form(all), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Endpoint used for filtering ld logs by user given form inputs.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@ldlogs_web.post("/ldlogs-web", response_class=HTMLResponse) +async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"), + skip: int = 0, limit: int = 100, + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Endpoint used for filtering ld logs by user given form inputs. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + log = crud.get_filtered_ldlogs(db, pc, team, lic) + logs_ids = [] + for l in log: + logs_ids.append(l[0]) + logs = crud.find_filtered_ldlogs(db, logs_ids) + pc_obj = crud.get_pcs(db, skip=skip, limit=limit) + teams = crud.get_teams(db, skip=skip, limit=limit) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("ldlogs_normal.html", + {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user})</code></pre> +</details> +</dd> +<dt id="sql_app.api.ld_logs_web.get_db"><code class="name flex"> +<span>def <span class="ident">get_db</span></span>(<span>)</span> +</code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close()</code></pre> +</details> +</dd> +<dt id="sql_app.api.ld_logs_web.read_logs"><code class="name flex"> +<span>async def <span class="ident">read_logs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Returns template with all usb logs currently saved in database with its pcs, teams and licenses.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@ldlogs_web.get("/ldlogs-web", response_class=HTMLResponse) +async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all usb logs currently saved in database with its pcs, teams and licenses. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + logs = crud.get_ld_logs(db, skip=skip, limit=limit) + pcs = [] + for log in logs: + if log.pc_id not in pcs: + pcs.append(log.pc_id) + pc_obj = crud.find_pcs(db, pcs) + teams = crud.get_teams(db, skip=skip, limit=limit) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("ldlogs_normal.html", + {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user})</code></pre> +</details> +</dd> +</dl> +</section> +<section> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li> +</ul> +</li> +<li><h3><a href="#header-functions">Functions</a></h3> +<ul class=""> +<li><code><a title="sql_app.api.ld_logs_web.filter_logs" href="#sql_app.api.ld_logs_web.filter_logs">filter_logs</a></code></li> +<li><code><a title="sql_app.api.ld_logs_web.get_db" href="#sql_app.api.ld_logs_web.get_db">get_db</a></code></li> +<li><code><a title="sql_app.api.ld_logs_web.read_logs" href="#sql_app.api.ld_logs_web.read_logs">read_logs</a></code></li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> +</footer> +</body> +</html> \ No newline at end of file diff --git a/server/doc/sql_app/api/licenses_web.html b/server/doc/sql_app/api/licenses_web.html index fb9ff21..0ac98d8 100644 --- a/server/doc/sql_app/api/licenses_web.html +++ b/server/doc/sql_app/api/licenses_web.html @@ -27,14 +27,15 @@ <span>Expand source code</span> </summary> <pre><code class="python">from typing import List - +from typing import Optional from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form from sqlalchemy.orm import Session from datetime import date from sql_app import crud, models, schemas from ..database import SessionLocal, engine from fastapi import FastAPI, Request -from fastapi.responses import HTMLResponse +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi_jwt_auth import AuthJWT from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates @@ -45,7 +46,7 @@ templates = Jinja2Templates(directory="../templates/licenses") device_templates = Jinja2Templates(directory="../templates/devices") # prefix used for all endpoints in this file -licenses_web = APIRouter(prefix="/api/v1") +licenses_web = APIRouter(prefix="") # Dependency @@ -58,38 +59,53 @@ def get_db(): @licenses_web.get("/license-create", response_class=HTMLResponse) -async def licenses_create_web(request: Request): +async def licenses_create_web(request: Request, Authorize: AuthJWT = Depends()): """ Returns template with Form for creating new license. """ - return templates.TemplateResponse("license_create.html", {"request": request}) + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + return templates.TemplateResponse("license_create.html", {"request": request, "minimum_date": date.today()}) @licenses_web.get("/licenses-web", response_class=HTMLResponse) -async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all licenses currently saved in database """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses}) - + if current_user == "admin": + return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("licenses_normal.html", {"request": request, "licenses": licenses, + "user": current_user}) -@licenses_web.post("/licenses-web", response_class=HTMLResponse) -def create_license(request: Request, name: str = Form(...), expdate: date = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): +@licenses_web.post("/licenses-web") +def create_license(name: Optional[str] = Form(""), lic_id: str = Form(...), expdate: Optional[date] = Form(None), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from create license form. Creates new license and returns template with all licenses in database + Endpoint called from create license form. Creates new license and redirects to devices-web endpoint """ - db_license = crud.create_license(db, name, expdate) - if db_license is None: - print("something went wrong") - devices = crud.get_devices(db, skip=skip, limit=limit) - statuses = [] - for i in range(0, len(devices)): - statuses.append(devices[i].logs[len(devices[i].logs) - 1].status) - licenses = crud.get_licenses(db, skip=skip, limit=limit) - return device_templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses})</code></pre> + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + licenses = crud.get_licenses(db, 0, 100) + licenses_ids = [] + for l in licenses: + licenses_ids.append(l.license_id) + if lic_id not in licenses_ids: + db_license = crud.create_license(db, name, lic_id, expdate) + if db_license is None: + print("something went wrong") + return RedirectResponse(url=f"/licenses-web", status_code=303)</code></pre> </details> </section> <section> @@ -100,30 +116,33 @@ def create_license(request: Request, name: str = Form(...), expdate: date = Form <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="sql_app.api.licenses_web.create_license"><code class="name flex"> -<span>def <span class="ident">create_license</span></span>(<span>request: starlette.requests.Request, name: str = Form(Ellipsis), expdate: datetime.date = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>def <span class="ident">create_license</span></span>(<span>name: Optional[str] = Form(), lic_id: str = Form(Ellipsis), expdate: Optional[datetime.date] = Form(None), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> -<div class="desc"><p>Endpoint called from create license form. Creates new license and returns template with all licenses in database</p></div> +<div class="desc"><p>Endpoint called from create license form. Creates new license and redirects to devices-web endpoint</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">@licenses_web.post("/licenses-web", response_class=HTMLResponse) -def create_license(request: Request, name: str = Form(...), expdate: date = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): +<pre><code class="python">@licenses_web.post("/licenses-web") +def create_license(name: Optional[str] = Form(""), lic_id: str = Form(...), expdate: Optional[date] = Form(None), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from create license form. Creates new license and returns template with all licenses in database + Endpoint called from create license form. Creates new license and redirects to devices-web endpoint """ - db_license = crud.create_license(db, name, expdate) - if db_license is None: - print("something went wrong") - devices = crud.get_devices(db, skip=skip, limit=limit) - statuses = [] - for i in range(0, len(devices)): - statuses.append(devices[i].logs[len(devices[i].logs) - 1].status) - licenses = crud.get_licenses(db, skip=skip, limit=limit) - return device_templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses})</code></pre> + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + licenses = crud.get_licenses(db, 0, 100) + licenses_ids = [] + for l in licenses: + licenses_ids.append(l.license_id) + if lic_id not in licenses_ids: + db_license = crud.create_license(db, name, lic_id, expdate) + if db_license is None: + print("something went wrong") + return RedirectResponse(url=f"/licenses-web", status_code=303)</code></pre> </details> </dd> <dt id="sql_app.api.licenses_web.get_db"><code class="name flex"> @@ -144,7 +163,7 @@ def create_license(request: Request, name: str = Form(...), expdate: date = Form </details> </dd> <dt id="sql_app.api.licenses_web.licenses_create_web"><code class="name flex"> -<span>async def <span class="ident">licenses_create_web</span></span>(<span>request: starlette.requests.Request)</span> +<span>async def <span class="ident">licenses_create_web</span></span>(<span>request: starlette.requests.Request, Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> <div class="desc"><p>Returns template with Form for creating new license.</p></div> @@ -153,15 +172,19 @@ def create_license(request: Request, name: str = Form(...), expdate: date = Form <span>Expand source code</span> </summary> <pre><code class="python">@licenses_web.get("/license-create", response_class=HTMLResponse) -async def licenses_create_web(request: Request): +async def licenses_create_web(request: Request, Authorize: AuthJWT = Depends()): """ Returns template with Form for creating new license. """ - return templates.TemplateResponse("license_create.html", {"request": request})</code></pre> + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + return templates.TemplateResponse("license_create.html", {"request": request, "minimum_date": date.today()})</code></pre> </details> </dd> <dt id="sql_app.api.licenses_web.read_licenses_web"><code class="name flex"> -<span>async def <span class="ident">read_licenses_web</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">read_licenses_web</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> <div class="desc"><p>Returns template with all licenses currently saved in database</p></div> @@ -170,12 +193,21 @@ async def licenses_create_web(request: Request): <span>Expand source code</span> </summary> <pre><code class="python">@licenses_web.get("/licenses-web", response_class=HTMLResponse) -async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all licenses currently saved in database """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("licenses_normal.html", {"request": request, "licenses": licenses, + "user": current_user})</code></pre> </details> </dd> </dl> diff --git a/server/doc/sql_app/api/pcs_web.html b/server/doc/sql_app/api/pcs_web.html index 5f11982..3b208a9 100644 --- a/server/doc/sql_app/api/pcs_web.html +++ b/server/doc/sql_app/api/pcs_web.html @@ -32,7 +32,8 @@ from sqlalchemy.orm import Session from sql_app import crud, models, schemas from ..database import SessionLocal, engine from fastapi import FastAPI, Request -from fastapi.responses import HTMLResponse +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi_jwt_auth import AuthJWT from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates @@ -42,7 +43,7 @@ models.Base.metadata.create_all(bind=engine) templates = Jinja2Templates(directory="../templates/pcs") # prefix used for all endpoints in this file -pcs_web = APIRouter(prefix="/api/v1") +pcs_web = APIRouter(prefix="") # Dependency @@ -55,34 +56,19 @@ def get_db(): @pcs_web.get("/pcs-web", response_class=HTMLResponse) -async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all pcs currently saved in database """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() pcs = crud.get_pcs(db, skip=skip, limit=limit) - return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs}) - - -@pcs_web.get("/pc-team/{pc_id}", response_class=HTMLResponse) -async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db)): - """ - Returns template with Form for connecting pc with team - """ - pc = crud.get_pc(db, pc_id) - teams = crud.get_teams(db, 0, 100) - return templates.TemplateResponse("pcteam.html", - {"request": request, "pc": pc, "teams": teams}) - - -@pcs_web.post("/pcs-web/{pc_id}", response_class=HTMLResponse) -async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): - """ - Endpoint called from within form for connecting pc with team. Updates certain pc with new team. - """ - old_pc = crud.update_pc(db, pc_id, team) - pcs = crud.get_pcs(db, skip=skip, limit=limit) - return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("pcs_normal.html", {"request": request, "pcs": pcs, "user": current_user})</code></pre> </details> </section> <section> @@ -92,46 +78,6 @@ async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip <section> <h2 class="section-title" id="header-functions">Functions</h2> <dl> -<dt id="sql_app.api.pcs_web.connect_pc_team"><code class="name flex"> -<span>async def <span class="ident">connect_pc_team</span></span>(<span>request: starlette.requests.Request, pc_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> -</code></dt> -<dd> -<div class="desc"><p>Returns template with Form for connecting pc with team</p></div> -<details class="source"> -<summary> -<span>Expand source code</span> -</summary> -<pre><code class="python">@pcs_web.get("/pc-team/{pc_id}", response_class=HTMLResponse) -async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db)): - """ - Returns template with Form for connecting pc with team - """ - pc = crud.get_pc(db, pc_id) - teams = crud.get_teams(db, 0, 100) - return templates.TemplateResponse("pcteam.html", - {"request": request, "pc": pc, "teams": teams})</code></pre> -</details> -</dd> -<dt id="sql_app.api.pcs_web.connect_post"><code class="name flex"> -<span>async def <span class="ident">connect_post</span></span>(<span>request: starlette.requests.Request, pc_id: int, team: str = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> -</code></dt> -<dd> -<div class="desc"><p>Endpoint called from within form for connecting pc with team. Updates certain pc with new team.</p></div> -<details class="source"> -<summary> -<span>Expand source code</span> -</summary> -<pre><code class="python">@pcs_web.post("/pcs-web/{pc_id}", response_class=HTMLResponse) -async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): - """ - Endpoint called from within form for connecting pc with team. Updates certain pc with new team. - """ - old_pc = crud.update_pc(db, pc_id, team) - pcs = crud.get_pcs(db, skip=skip, limit=limit) - return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs})</code></pre> -</details> -</dd> <dt id="sql_app.api.pcs_web.get_db"><code class="name flex"> <span>def <span class="ident">get_db</span></span>(<span>)</span> </code></dt> @@ -150,7 +96,7 @@ async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip </details> </dd> <dt id="sql_app.api.pcs_web.read_pcs"><code class="name flex"> -<span>async def <span class="ident">read_pcs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">read_pcs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> <div class="desc"><p>Returns template with all pcs currently saved in database</p></div> @@ -159,12 +105,19 @@ async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip <span>Expand source code</span> </summary> <pre><code class="python">@pcs_web.get("/pcs-web", response_class=HTMLResponse) -async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all pcs currently saved in database """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() pcs = crud.get_pcs(db, skip=skip, limit=limit) - return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("pcs_normal.html", {"request": request, "pcs": pcs, "user": current_user})</code></pre> </details> </dd> </dl> @@ -185,8 +138,6 @@ async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Sessio </li> <li><h3><a href="#header-functions">Functions</a></h3> <ul class=""> -<li><code><a title="sql_app.api.pcs_web.connect_pc_team" href="#sql_app.api.pcs_web.connect_pc_team">connect_pc_team</a></code></li> -<li><code><a title="sql_app.api.pcs_web.connect_post" href="#sql_app.api.pcs_web.connect_post">connect_post</a></code></li> <li><code><a title="sql_app.api.pcs_web.get_db" href="#sql_app.api.pcs_web.get_db">get_db</a></code></li> <li><code><a title="sql_app.api.pcs_web.read_pcs" href="#sql_app.api.pcs_web.read_pcs">read_pcs</a></code></li> </ul> diff --git a/server/doc/sql_app/api/teams_web.html b/server/doc/sql_app/api/teams_web.html index bee1c5d..d80c794 100644 --- a/server/doc/sql_app/api/teams_web.html +++ b/server/doc/sql_app/api/teams_web.html @@ -33,7 +33,8 @@ from sqlalchemy.orm import Session from sql_app import crud, models, schemas from ..database import SessionLocal, engine from fastapi import FastAPI, Request -from fastapi.responses import HTMLResponse +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi_jwt_auth import AuthJWT from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates @@ -43,7 +44,7 @@ models.Base.metadata.create_all(bind=engine) templates = Jinja2Templates(directory="../templates/teams") # prefix used for all endpoints in this file -teams_web = APIRouter(prefix="/api/v1") +teams_web = APIRouter(prefix="") # Dependency @@ -56,33 +57,78 @@ def get_db(): @teams_web.get("/teams-web", response_class=HTMLResponse) -async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all teams currently saved in database """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() teams = crud.get_teams(db, skip=skip, limit=limit) - return templates.TemplateResponse("teams.html", {"request": request, "teams": teams}) + if current_user == "admin": + return templates.TemplateResponse("teams.html", {"request": request, "teams": teams, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("teams_normal.html", {"request": request, "teams": teams, "user": current_user}) @teams_web.get("/team-create", response_class=HTMLResponse) -async def team_create_web(request: Request): +async def team_create_web(request: Request, Authorize: AuthJWT = Depends()): """ Returns template with form for creating new team """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) return templates.TemplateResponse("team_create.html", {"request": request}) -@teams_web.post("/teams-web", response_class=HTMLResponse) -def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): +@teams_web.post("/teams-web-con") +def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from within form for creating new team. Creates new team and returns all teams in database + Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams """ - team = crud.create_team(db, name) - if team is None: - print("something went wrong") - teams = crud.get_teams(db, skip=skip, limit=limit) - return templates.TemplateResponse("teams.html", {"request": request, "teams": teams})</code></pre> + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + teams = crud.get_teams(db, 0, 100) + teams_names = [] + for t in teams: + teams_names.append(t.name) + if name not in teams_names: + team = crud.create_team(db, name) + if team is None: + print("something went wrong") + return RedirectResponse(url=f"/teams-web", status_code=303) + + +@teams_web.get("/team-change/{team_id}", response_class=HTMLResponse) +async def team_change_web(request: Request, team_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with form for changing teams name + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + team = crud.get_team(db, team_id) + return templates.TemplateResponse("team_change.html", {"request": request, "team": team}) + +@teams_web.post("/teams-change-process/{team_id}") +async def team_change_process(team_id: int, db:Session = Depends(get_db), name: str = Form(...), + Authorize: AuthJWT = Depends()): + """ + Changes teams name to a new one given by user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + team = crud.change_team(db, team_id, name) + return RedirectResponse(url=f"/teams-web", status_code=303)</code></pre> </details> </section> <section> @@ -93,25 +139,32 @@ def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: i <h2 class="section-title" id="header-functions">Functions</h2> <dl> <dt id="sql_app.api.teams_web.create_team"><code class="name flex"> -<span>def <span class="ident">create_team</span></span>(<span>request: starlette.requests.Request, name: str = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>def <span class="ident">create_team</span></span>(<span>name: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> -<div class="desc"><p>Endpoint called from within form for creating new team. Creates new team and returns all teams in database</p></div> +<div class="desc"><p>Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">@teams_web.post("/teams-web", response_class=HTMLResponse) -def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): +<pre><code class="python">@teams_web.post("/teams-web-con") +def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from within form for creating new team. Creates new team and returns all teams in database + Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams """ - team = crud.create_team(db, name) - if team is None: - print("something went wrong") - teams = crud.get_teams(db, skip=skip, limit=limit) - return templates.TemplateResponse("teams.html", {"request": request, "teams": teams})</code></pre> + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + teams = crud.get_teams(db, 0, 100) + teams_names = [] + for t in teams: + teams_names.append(t.name) + if name not in teams_names: + team = crud.create_team(db, name) + if team is None: + print("something went wrong") + return RedirectResponse(url=f"/teams-web", status_code=303)</code></pre> </details> </dd> <dt id="sql_app.api.teams_web.get_db"><code class="name flex"> @@ -132,7 +185,7 @@ def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: i </details> </dd> <dt id="sql_app.api.teams_web.read_devices"><code class="name flex"> -<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> <div class="desc"><p>Returns template with all teams currently saved in database</p></div> @@ -141,16 +194,69 @@ def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: i <span>Expand source code</span> </summary> <pre><code class="python">@teams_web.get("/teams-web", response_class=HTMLResponse) -async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all teams currently saved in database """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() teams = crud.get_teams(db, skip=skip, limit=limit) - return templates.TemplateResponse("teams.html", {"request": request, "teams": teams})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("teams.html", {"request": request, "teams": teams, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("teams_normal.html", {"request": request, "teams": teams, "user": current_user})</code></pre> +</details> +</dd> +<dt id="sql_app.api.teams_web.team_change_process"><code class="name flex"> +<span>async def <span class="ident">team_change_process</span></span>(<span>team_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), name: str = Form(Ellipsis), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Changes teams name to a new one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@teams_web.post("/teams-change-process/{team_id}") +async def team_change_process(team_id: int, db:Session = Depends(get_db), name: str = Form(...), + Authorize: AuthJWT = Depends()): + """ + Changes teams name to a new one given by user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + team = crud.change_team(db, team_id, name) + return RedirectResponse(url=f"/teams-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.teams_web.team_change_web"><code class="name flex"> +<span>async def <span class="ident">team_change_web</span></span>(<span>request: starlette.requests.Request, team_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Returns template with form for changing teams name</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@teams_web.get("/team-change/{team_id}", response_class=HTMLResponse) +async def team_change_web(request: Request, team_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with form for changing teams name + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + team = crud.get_team(db, team_id) + return templates.TemplateResponse("team_change.html", {"request": request, "team": team})</code></pre> </details> </dd> <dt id="sql_app.api.teams_web.team_create_web"><code class="name flex"> -<span>async def <span class="ident">team_create_web</span></span>(<span>request: starlette.requests.Request)</span> +<span>async def <span class="ident">team_create_web</span></span>(<span>request: starlette.requests.Request, Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> <div class="desc"><p>Returns template with form for creating new team</p></div> @@ -159,10 +265,14 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se <span>Expand source code</span> </summary> <pre><code class="python">@teams_web.get("/team-create", response_class=HTMLResponse) -async def team_create_web(request: Request): +async def team_create_web(request: Request, Authorize: AuthJWT = Depends()): """ Returns template with form for creating new team """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) return templates.TemplateResponse("team_create.html", {"request": request})</code></pre> </details> </dd> @@ -183,10 +293,12 @@ async def team_create_web(request: Request): </ul> </li> <li><h3><a href="#header-functions">Functions</a></h3> -<ul class=""> +<ul class="two-column"> <li><code><a title="sql_app.api.teams_web.create_team" href="#sql_app.api.teams_web.create_team">create_team</a></code></li> <li><code><a title="sql_app.api.teams_web.get_db" href="#sql_app.api.teams_web.get_db">get_db</a></code></li> <li><code><a title="sql_app.api.teams_web.read_devices" href="#sql_app.api.teams_web.read_devices">read_devices</a></code></li> +<li><code><a title="sql_app.api.teams_web.team_change_process" href="#sql_app.api.teams_web.team_change_process">team_change_process</a></code></li> +<li><code><a title="sql_app.api.teams_web.team_change_web" href="#sql_app.api.teams_web.team_change_web">team_change_web</a></code></li> <li><code><a title="sql_app.api.teams_web.team_create_web" href="#sql_app.api.teams_web.team_create_web">team_create_web</a></code></li> </ul> </li> diff --git a/server/doc/sql_app/api/usb_logs.html b/server/doc/sql_app/api/usb_logs.html index 499c94e..68e28ae 100644 --- a/server/doc/sql_app/api/usb_logs.html +++ b/server/doc/sql_app/api/usb_logs.html @@ -76,9 +76,9 @@ def create_ld_logs(log: schemas.LDTempBase, db: Session = Depends(get_db)): head_dev = crud.find_head_device(db, log.head_device) body_dev = crud.find_body_device(db, log.body_device) if head_dev is None: - crud.create_head_device(db, log.head_device) + head_dev = crud.create_head_device(db, log.head_device) if body_dev is None: - crud.create_body_device(db, log.body_device) + body_dev = crud.create_body_device(db, log.body_device) pc = crud.find_pc(db, log.username, log.hostname) if pc is None: @@ -164,9 +164,9 @@ def create_ld_logs(log: schemas.LDTempBase, db: Session = Depends(get_db)): head_dev = crud.find_head_device(db, log.head_device) body_dev = crud.find_body_device(db, log.body_device) if head_dev is None: - crud.create_head_device(db, log.head_device) + head_dev = crud.create_head_device(db, log.head_device) if body_dev is None: - crud.create_body_device(db, log.body_device) + body_dev = crud.create_body_device(db, log.body_device) pc = crud.find_pc(db, log.username, log.hostname) if pc is None: diff --git a/server/doc/sql_app/api/usb_logs_web.html b/server/doc/sql_app/api/usb_logs_web.html index fb54ab6..5c2b0ca 100644 --- a/server/doc/sql_app/api/usb_logs_web.html +++ b/server/doc/sql_app/api/usb_logs_web.html @@ -34,6 +34,7 @@ from sql_app import crud, models, schemas from ..database import SessionLocal, engine from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse +from fastapi_jwt_auth import AuthJWT from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates @@ -43,7 +44,7 @@ models.Base.metadata.create_all(bind=engine) templates = Jinja2Templates(directory="../templates/usb-logs") # prefix used for all endpoints in this file -usblogs_web = APIRouter(prefix="/api/v1") +usblogs_web = APIRouter(prefix="") # Dependency @@ -56,10 +57,13 @@ def get_db(): @usblogs_web.get("/logs-web", response_class=HTMLResponse) -async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all usb logs currently saved in database with its pcs, teams and licenses. """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() logs = crud.get_logs(db, skip=skip, limit=limit) pcs = [] for log in logs: @@ -68,17 +72,24 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi pc_obj = crud.find_pcs(db, pcs) teams = crud.get_teams(db, skip=skip, limit=limit) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses}) + if current_user == "admin": + return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) @usblogs_web.post("/logs-web", response_class=HTMLResponse) async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ Endpoint used for filtering usb logs by user given form inputs. """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() log = crud.get_filtered_logs(db, pc, team, lic) logs_ids = [] for l in log: @@ -87,8 +98,18 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str pc_obj = crud.get_pcs(db, skip=skip, limit=limit) teams = crud.get_teams(db, skip=skip, limit=limit) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + + +@usblogs_web.get("/", response_class=HTMLResponse) +async def crossroad(request: Request): + return templates.TemplateResponse("crossroad.html", {"request": request})</code></pre> </details> </section> <section> @@ -98,8 +119,22 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str <section> <h2 class="section-title" id="header-functions">Functions</h2> <dl> +<dt id="sql_app.api.usb_logs_web.crossroad"><code class="name flex"> +<span>async def <span class="ident">crossroad</span></span>(<span>request: starlette.requests.Request)</span> +</code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@usblogs_web.get("/", response_class=HTMLResponse) +async def crossroad(request: Request): + return templates.TemplateResponse("crossroad.html", {"request": request})</code></pre> +</details> +</dd> <dt id="sql_app.api.usb_logs_web.filter_logs"><code class="name flex"> -<span>async def <span class="ident">filter_logs</span></span>(<span>request: starlette.requests.Request, pc: str = Form(all), team: str = Form(all), lic: str = Form(all), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">filter_logs</span></span>(<span>request: starlette.requests.Request, pc: str = Form(all), team: str = Form(all), lic: str = Form(all), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> <div class="desc"><p>Endpoint used for filtering usb logs by user given form inputs.</p></div> @@ -110,10 +145,12 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str <pre><code class="python">@usblogs_web.post("/logs-web", response_class=HTMLResponse) async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"), skip: int = 0, limit: int = 100, - db: Session = Depends(get_db)): + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ Endpoint used for filtering usb logs by user given form inputs. """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() log = crud.get_filtered_logs(db, pc, team, lic) logs_ids = [] for l in log: @@ -122,8 +159,13 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str pc_obj = crud.get_pcs(db, skip=skip, limit=limit) teams = crud.get_teams(db, skip=skip, limit=limit) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user})</code></pre> </details> </dd> <dt id="sql_app.api.usb_logs_web.get_db"><code class="name flex"> @@ -144,7 +186,7 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str </details> </dd> <dt id="sql_app.api.usb_logs_web.read_logs"><code class="name flex"> -<span>async def <span class="ident">read_logs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span> +<span>async def <span class="ident">read_logs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> </code></dt> <dd> <div class="desc"><p>Returns template with all usb logs currently saved in database with its pcs, teams and licenses.</p></div> @@ -153,10 +195,13 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str <span>Expand source code</span> </summary> <pre><code class="python">@usblogs_web.get("/logs-web", response_class=HTMLResponse) -async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): +async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): """ Returns template with all usb logs currently saved in database with its pcs, teams and licenses. """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() logs = crud.get_logs(db, skip=skip, limit=limit) pcs = [] for log in logs: @@ -165,8 +210,13 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi pc_obj = crud.find_pcs(db, pcs) teams = crud.get_teams(db, skip=skip, limit=limit) licenses = crud.get_licenses(db, skip=skip, limit=limit) - return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses})</code></pre> + if current_user == "admin": + return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, + "licenses": licenses, "user": current_user})</code></pre> </details> </dd> </dl> @@ -187,6 +237,7 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi </li> <li><h3><a href="#header-functions">Functions</a></h3> <ul class=""> +<li><code><a title="sql_app.api.usb_logs_web.crossroad" href="#sql_app.api.usb_logs_web.crossroad">crossroad</a></code></li> <li><code><a title="sql_app.api.usb_logs_web.filter_logs" href="#sql_app.api.usb_logs_web.filter_logs">filter_logs</a></code></li> <li><code><a title="sql_app.api.usb_logs_web.get_db" href="#sql_app.api.usb_logs_web.get_db">get_db</a></code></li> <li><code><a title="sql_app.api.usb_logs_web.read_logs" href="#sql_app.api.usb_logs_web.read_logs">read_logs</a></code></li> diff --git a/server/doc/sql_app/api/users_web.html b/server/doc/sql_app/api/users_web.html new file mode 100644 index 0000000..ac9a9d6 --- /dev/null +++ b/server/doc/sql_app/api/users_web.html @@ -0,0 +1,194 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.10.0" /> +<title>sql_app.api.users_web API documentation</title> +<meta name="description" content="" /> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> +<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> +<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> +<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> +<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>sql_app.api.users_web</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">from typing import List +from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form +from sqlalchemy.orm import Session +from sql_app import crud, models, schemas +from ..database import SessionLocal, engine +from fastapi import FastAPI, Request +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi_jwt_auth import AuthJWT +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates + +models.Base.metadata.create_all(bind=engine) + +# Path to html templates used in this file +templates = Jinja2Templates(directory="../templates/users") + +# prefix used for all endpoints in this file +users = APIRouter(prefix="") + + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +@users.get("/users-web", response_class=HTMLResponse) +async def read_usrs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all users currently saved in database + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + users = crud.get_users(db, skip, limit) + if current_user == "admin": + return templates.TemplateResponse("users.html", {"request": request, "users": users}) + else: + return RedirectResponse(url=f"/logs-web", status_code=303) + + +@users.get("/user-role/{usr_id}", response_class=HTMLResponse) +async def connect_pc_team(usr_id: int, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Changes role of user to either guest or admin depending on old role. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + user = crud.find_user_byid(db, usr_id) + if user.role == "admin": + crud.change_role(db, usr_id, "guest") + else: + crud.change_role(db, usr_id, "admin") + return RedirectResponse(url=f"/users-web", status_code=303)</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-functions">Functions</h2> +<dl> +<dt id="sql_app.api.users_web.connect_pc_team"><code class="name flex"> +<span>async def <span class="ident">connect_pc_team</span></span>(<span>usr_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Changes role of user to either guest or admin depending on old role.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@users.get("/user-role/{usr_id}", response_class=HTMLResponse) +async def connect_pc_team(usr_id: int, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Changes role of user to either guest or admin depending on old role. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + user = crud.find_user_byid(db, usr_id) + if user.role == "admin": + crud.change_role(db, usr_id, "guest") + else: + crud.change_role(db, usr_id, "admin") + return RedirectResponse(url=f"/users-web", status_code=303)</code></pre> +</details> +</dd> +<dt id="sql_app.api.users_web.get_db"><code class="name flex"> +<span>def <span class="ident">get_db</span></span>(<span>)</span> +</code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close()</code></pre> +</details> +</dd> +<dt id="sql_app.api.users_web.read_usrs"><code class="name flex"> +<span>async def <span class="ident">read_usrs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span> +</code></dt> +<dd> +<div class="desc"><p>Returns template with all users currently saved in database</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">@users.get("/users-web", response_class=HTMLResponse) +async def read_usrs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all users currently saved in database + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + users = crud.get_users(db, skip, limit) + if current_user == "admin": + return templates.TemplateResponse("users.html", {"request": request, "users": users}) + else: + return RedirectResponse(url=f"/logs-web", status_code=303)</code></pre> +</details> +</dd> +</dl> +</section> +<section> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li> +</ul> +</li> +<li><h3><a href="#header-functions">Functions</a></h3> +<ul class=""> +<li><code><a title="sql_app.api.users_web.connect_pc_team" href="#sql_app.api.users_web.connect_pc_team">connect_pc_team</a></code></li> +<li><code><a title="sql_app.api.users_web.get_db" href="#sql_app.api.users_web.get_db">get_db</a></code></li> +<li><code><a title="sql_app.api.users_web.read_usrs" href="#sql_app.api.users_web.read_usrs">read_usrs</a></code></li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p> +</footer> +</body> +</html> \ No newline at end of file diff --git a/server/doc/sql_app/crud.html b/server/doc/sql_app/crud.html index b6620d0..3130d1d 100644 --- a/server/doc/sql_app/crud.html +++ b/server/doc/sql_app/crud.html @@ -47,21 +47,82 @@ def get_devices(db: Session, skip: int = 0, limit: int = 100): return db.query(models.Device).offset(skip).limit(limit).all() -def find_device(db: Session, device: schemas.DeviceBase): +def find_device(db: Session, device: schemas.DeviceTemp): """ - finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object + finds one device with serial_number same as in given DeviceBase object """ - return db.query(models.Device).filter(and_(models.Device.product_id == device.product_id, - models.Device.vendor_id == device.vendor_id, - models.Device.serial_number == device.serial_number)).first() + return db.query(models.Device).filter(and_(models.Device.serial_number == device.serial_number)).first() -def create_device(db: Session, device: schemas.DeviceBase): +def find_device_by_serial(db: Session, ser: str): + """ + finds one device with serial_number same as in given DeviceBase object + """ + return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first() + + +def get_devices_with_ids(db: Session, ids: []): + """ + returns all devices with given ids + """ + return db.query(models.Device).filter(models.Device.id.in_(ids)).all() + + +def get_bodydevices_with_ids(db: Session, ids: []): + """ + returns all bodydevices with given ids + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.id.in_(ids)).all() + + +def get_headdevices_with_ids(db: Session, ids: []): + """ + returns all headdevices with given ids + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.id.in_(ids)).all() + + +def find_headdevices_by_team(db: Session, team_id: int): + """ + Returns all head devices in specific team + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.team_id == team_id).all() + + +def find_bodydevices_by_team(db: Session, team_id: int): + """ + Returns all body devices in specific team + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.team_id == team_id).all() + + +def find_headdevices_by_license(db: Session, lic_id: int): + """ + Returns all head devices with specific license + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.license_id == lic_id).all() + + +def find_bodydevices_by_license(db: Session, lic_id: int): + """ + Returns all body devices with specific license + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.license_id == lic_id).all() + + +def get_devices_by_team(db: Session, team: int): + """ + returns all devices with same team + """ + return db.query(models.Device).filter(models.Device.team_id == team).all() + + +def create_device(db: Session, device: schemas.DeviceTemp): """ creates new device with data from given DeviceBase object """ db_device = models.Device(vendor_id=device.vendor_id, product_id=device.product_id, - serial_number=device.serial_number, assigned=False) + serial_number=device.serial_number, inventory_number="", comment="") db.add(db_device) db.commit() db.refresh(db_device) @@ -86,14 +147,18 @@ def find_license(db: Session, name: str): """ finds one license by given string name """ - return db.query(models.License).filter(models.License.name == name).first() + return db.query(models.License).filter(models.License.license_id == name).first() -def create_license(db: Session, name: str, expdate: date): +def get_licenses_by_name(db: Session, name: str): + return db.query(models.License).filter(models.License.name == name).all() + + +def create_license(db: Session, name: str, lic_id: str, expdate: date): """ creates new license with given name and expiration date """ - db_license = models.License(name=name, expiration_date=expdate) + db_license = models.License(name=name, license_id=lic_id, expiration_date=expdate) db.add(db_license) db.commit() db.refresh(db_license) @@ -102,11 +167,33 @@ def create_license(db: Session, name: str, expdate: date): def get_license_devices(db: Session, license_id: int): """ - returns all entries in devices_licenses table + returns all entries in devices_licenses table with given license_id """ return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id == license_id).all() +def find_devicelicenses_by_licid_array(db: Session, lcs: []): + """ + Finds all device_licenses with license_id in given id array + """ + return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id.in_(lcs)).all() + + +def get_device_licenses(db: Session, device_id: int): + """ + returns all entries in devices_licenses table with given device_id + """ + return db.query(models.DeviceLicense).filter(models.DeviceLicense.device_id == device_id).all() + + +def get_devicelicense_by_devicelicense(db: Session, device_id: int, license_id: int): + """ + returns entry in devices_licenses table with given device id and license id + """ + return db.query(models.DeviceLicense).filter(and_(models.DeviceLicense.device_id == device_id, + models.DeviceLicense.license_id == license_id)).first() + + def create_device_license(db: Session, device: int, license: int, time: datetime): """ creates new entry in devices_licenses table with device id, license id and time. @@ -119,6 +206,16 @@ def create_device_license(db: Session, device: int, license: int, time: datetime return db_device_license +def delete_device_license(db: Session, device: int, license: int): + """ + deletes entry in devices_licenses table with device id, license id and time. + """ + db_device_license = get_devicelicense_by_devicelicense(db, device, license) + db_lic = db.delete(db_device_license) + db.commit() + return db_lic + + def find_pc_by_username(db: Session, name: str): """ Finds one pc by given username @@ -133,19 +230,73 @@ def get_pc(db: Session, pc_id: int): return db.query(models.PC).filter(models.PC.id == pc_id).first() -def update_pc(db: Session, pc_id: int, team: str): +def update_device(db: Session, device_id: int, team: str): """ - Function updates team of one specific pc + Updates team of one specific pc """ - old_pc = get_pc(db, pc_id) + old_dev = get_device(db, device_id) team = get_team(db, int(team)) - new = {'id': old_pc.id, 'username': old_pc.username, 'hostname': old_pc.hostname, 'assigned': True, - 'team_id': team.id} + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_device_inv(db: Session, device_id: int, inv: str): + """ + Updates inventory number of one specific pc + """ + old_dev = get_device(db, device_id) + if old_dev.team_id != None: + team = get_team(db, int(old_dev.team_id)) + teamid = team.id + else: + teamid = None + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': inv, + 'comment': old_dev.comment, 'team_id': teamid} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_device_com(db: Session, device_id: int, comm: str): + """ + Updates team of one specific pc + """ + old_dev = get_device(db, device_id) + if old_dev.team_id != None: + team = get_team(db, int(old_dev.team_id)) + teamid = team.id + else: + teamid = None + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': teamid} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def change_role(db: Session, usr_id: int, role: str): + """ + Updates team of one specific pc + """ + old_usr = find_user_byid(db, usr_id) + new = {'id': old_usr.id, 'username': old_usr.username, 'password': old_usr.password, 'role': role} for key, value in new.items(): - setattr(old_pc, key, value) + setattr(old_usr, key, value) db.commit() - db.refresh(old_pc) - return old_pc + db.refresh(old_usr) + return old_usr def get_pcs(db: Session, skip: int = 0, limit: int = 100): @@ -184,18 +335,11 @@ def find_pcs(db: Session, pcs: []): return db.query(models.PC).filter(models.PC.id.in_(pcs)).all() -def get_pcs_by_team(db: Session, team_id: int): - """ - returns all pcs in given team by team id - """ - return db.query(models.PC).filter(models.PC.team_id == team_id).all() - - def create_pc(db: Session, user: str, host: str): """ creates new pc with given username and hostname """ - db_pc = models.PC(username=user, hostname=host, assigned=False) + db_pc = models.PC(username=user, hostname=host) db.add(db_pc) db.commit() db.refresh(db_pc) @@ -234,6 +378,19 @@ def create_team(db: Session, name: str): return db_team +def change_team(db: Session, team_id: int, name: str): + """ + Updates name of one specific team + """ + old_team = get_team(db, team_id) + new = {'id': old_team.id, 'name': name} + for key, value in new.items(): + setattr(old_team, key, value) + db.commit() + db.refresh(old_team) + return old_team + + def get_head_device(db: Session, head_id: int): """ Returns one specific head device by given id @@ -248,14 +405,14 @@ def get_head_devices(db: Session, skip: int = 0, limit: int = 100): return db.query(models.HeadDevice).offset(skip).limit(limit).all() -def find_head_device(db: Session, serial: schemas.HeadDeviceBase): +def find_head_device(db: Session, serial: schemas.HeadDeviceTemp): """ Finds one head device by its serial number """ return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first() -def create_head_device(db: Session, log: schemas.HeadDeviceBase): +def create_head_device(db: Session, log: schemas.HeadDeviceTemp): """ Creates new head device """ @@ -280,29 +437,159 @@ def get_body_devices(db: Session, skip: int = 0, limit: int = 100): return db.query(models.BodyDevice).offset(skip).limit(limit).all() -def find_body_device(db: Session, serial: schemas.BodyDeviceBase): +def find_body_device(db: Session, serial: schemas.BodyDeviceTemp): """ Finds one body device by its serial number """ return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first() -def create_body_device(db: Session, log: schemas.BodyDeviceBase): +def find_bodydevice_by_serial(db: Session, serial: str): + """ + Finds one specific body device by given serial number + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial).first() + + +def find_headdevice_by_serial(db: Session, serial: str): + """ + Finds one specific head device by given serial number + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial).first() + + +def create_body_device(db: Session, log: schemas.BodyDeviceTemp): """ Creates new Body device """ - db_body = models.BodyDevice(serial_number=log.serial_number) + db_body = models.BodyDevice(serial_number=log.serial_number, inventory_number="", comment="") db.add(db_body) db.commit() db.refresh(db_body) return db_body +def update_bodydevice_license(db: Session, device_id: int, lic_id: int): + """ + Updates body devices license with one given by user + """ + old_dev = get_body_device(db, device_id) + lic = get_license(db, lic_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_bodydevice_team(db: Session, device_id: int, team_id: int): + """ + Updates body devices team with one given by user + """ + old_dev = get_body_device(db, device_id) + team = get_team(db, team_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_bodydevice_inv(db: Session, device_id: int, dev_inv: str): + """ + Updates body devices inventory number with new one given by user + """ + old_dev = get_body_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_bodydevice_comm(db: Session, device_id: int, comm: str): + """ + Updates body devices comment with new one given by user + """ + old_dev = get_body_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_license(db: Session, device_id: int, lic_id: int): + """ + Updates head devices license with one given by user + """ + old_dev = get_head_device(db, device_id) + lic = get_license(db, lic_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_team(db: Session, device_id: int, team_id: int): + """ + Updates head devices team with one given by user + """ + old_dev = get_head_device(db, device_id) + team = get_team(db, team_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_inv(db: Session, device_id: int, dev_inv: str): + """ + Updates head devices inventory number with new one given by user + """ + old_dev = get_head_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_comm(db: Session, device_id: int, comm: str): + """ + Updates head devices comment with new one given by user + """ + old_dev = get_head_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + def get_ld_logs(db: Session, skip: int = 0, limit: int = 100): """ Returns all ld debugger logs in database """ - return db.query(models.LDLog).offset(skip).limit(limit).all() + return db.query(models.LDLog).order_by(desc(models.LDLog.timestamp)).offset(skip).limit(limit).all() def create_ld_logs(db: Session, item: schemas.LDTempBase, head_id: int, body_id: int, pc_id: int, date: datetime): @@ -337,43 +624,330 @@ def find_filtered_logs(db: Session, logs: []): return db.query(models.USBLog).filter(models.USBLog.id.in_(logs)).order_by(desc(models.USBLog.timestamp)).all() +def find_filtered_ldlogs(db: Session, logs: []): + """ + Returns all ld logs with ids in given id array. + """ + return db.query(models.LDLog).filter(models.LDLog.id.in_(logs)).order_by(desc(models.LDLog.timestamp)).all() + + +def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str): + """ + Function creates query string used for filtering by pc username, team name and license name. + Depending on selected filters assembles query string for database + """ + execute_string = "SELECT * FROM ld_logs AS logs WHERE" + before_me = False + all_all = True + if pc != "all": + all_all = False + pc = find_pc_by_username(db, pc) + if pc != None: + if before_me: + execute_string += " AND logs.pc_id = " + str(pc.id) + else: + before_me = True + execute_string += " logs.pc_id = " + str(pc.id) + if tema != "all": + all_all = False + team = find_team(db, tema) + if team != None: + head_devices = find_headdevices_by_team(db, team.id) + body_devices = find_bodydevices_by_team(db, team.id) + if len(head_devices) > 0 and len(body_devices) > 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + else: + before_me = True + execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + elif len(head_devices) == 0 and len(body_devices) > 0: + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.body_id IN " + def_b_ids + else: + before_me = True + execute_string += " logs.body_id IN " + def_b_ids + elif len(head_devices) > 0 and len(body_devices) == 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.head_id IN " + def_h_ids + else: + before_me = True + execute_string += " logs.head_id IN " + def_h_ids + else: + if before_me: + execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)" + else: + before_me = True + execute_string += " (logs.head_id = -1 OR logs.body_id = -1)" + if lic != "all": + all_all = False + license = find_license(db, lic) + if license != None: + head_devices = find_headdevices_by_license(db, license.id) + body_devices = find_bodydevices_by_license(db, license.id) + if len(head_devices) > 0 and len(body_devices) > 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + else: + before_me = True + execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + elif len(head_devices) == 0 and len(body_devices) > 0: + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.body_id IN " + def_b_ids + else: + before_me = True + execute_string += " logs.body_id IN " + def_b_ids + elif len(head_devices) > 0 and len(body_devices) == 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.head_id IN " + def_h_ids + else: + before_me = True + execute_string += " logs.head_id IN " + def_h_ids + else: + if before_me: + execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)" + else: + before_me = True + execute_string += " (logs.head_id = -1 OR logs.body_id = -1)" + if all_all: + before_me = True + execute_string = "SELECT * FROM ld_logs AS logs" + + if not before_me: + execute_string = "SELECT * FROM ld_logs AS logs WHERE logs.id = -1" + result = db.execute(execute_string) + return result + + def get_filtered_logs(db: Session, pc: str, tema: str, lic: str): """ Function creates query string used for filtering by pc username, team name and license name. Depending on selected filters assembles query string for database """ execute_string = "SELECT * FROM usb_logs AS logs" + pcs = find_pc_by_username(db, pc) if pc != "all": - pcs = find_pc_by_username(db, pc) - execute_string += " WHERE logs.pc_id = " + str(pcs.id) + if pcs is not None: + execute_string += " WHERE logs.pc_id = " + str(pcs.id) if tema != "all": team = find_team(db, tema) - pcs = get_pcs_by_team(db, team.id) - pc_ids = "(" - for p in pcs: - pc_ids += str(p.id) + ", " - def_pc_ids = pc_ids[:-2] + ")" - if pc != "all": - execute_string += " AND logs.pc_id IN " + def_pc_ids - else: - execute_string += " WHERE logs.pc_id IN " + def_pc_ids + if team is not None: + devs = get_devices_by_team(db, team.id) + d_ids = "(" + for p in devs: + d_ids += str(p.id) + ", " + def_d_ids = d_ids[:-2] + ")" + if pc != "all" and pcs is not None: + if len(def_d_ids) > 1: + execute_string += " AND logs.device_id IN " + def_d_ids + else: + if len(def_d_ids) > 1: + execute_string += " WHERE logs.device_id IN " + def_d_ids if lic != "all": - license = find_license(db, lic) - device_licenses = get_license_devices(db, license.id) - dev_ids = "(" - for dev in device_licenses: - dev_ids += str(dev.device_id) + ", " - defin_ids = dev_ids[:-2] + ")" - if pc != "all" or tema != "all": - execute_string += " AND logs.device_id IN " + defin_ids - else: - execute_string += " WHERE logs.device_id IN " + defin_ids + license = get_licenses_by_name(db, lic) + if license is not None: + device_licenses = get_license_devices(db, license.id) + dev_ids = "(" + for dev in device_licenses: + dev_ids += str(dev.device_id) + ", " + defin_ids = dev_ids[:-2] + ")" + if pc != "all" or tema != "all": + if len(defin_ids) > 1: + execute_string += " AND logs.device_id IN " + defin_ids + else: + if len(defin_ids) > 1: + execute_string += " WHERE logs.device_id IN " + defin_ids # executing assembled query string result = db.execute(execute_string) return result +def get_filtered_bodydevices(db: Session, body_id: str, license_id: str, team: str): + """ + returns filtered body devices based on given attributes + """ + execute_string = "SELECT * FROM body_devices AS device WHERE" + before_me = False + all_all = True + if body_id != "all": + all_all = False + body_dev = find_bodydevice_by_serial(db, body_id) + if body_dev != None: + if before_me: + execute_string += " AND device.id = " + str(body_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(body_dev.id) + if license_id != "all": + all_all = False + license = find_license(db, license_id) + if license != None: + if before_me: + execute_string += " AND device.license_id = " + str(license.id) + else: + before_me = True + execute_string += " device.license_id = " + str(license.id) + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + if all_all: + before_me = True + execute_string = "SELECT * FROM body_devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result + + +def get_filtered_headdevices(db: Session, body_id: str, license_id: str, team: str): + """ + returns filtered head devices based on given attributes + """ + execute_string = "SELECT * FROM head_devices AS device WHERE" + before_me = False + all_all = True + if body_id != "all": + all_all = False + head_dev = find_headdevice_by_serial(db, body_id) + if head_dev != None: + if before_me: + execute_string += " AND device.id = " + str(head_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(head_dev.id) + if license_id != "all": + all_all = False + license = find_license(db, license_id) + if license != None: + if before_me: + execute_string += " AND device.license_id = " + str(license.id) + else: + before_me = True + execute_string += " device.license_id = " + str(license.id) + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + if all_all: + before_me = True + execute_string = "SELECT * FROM body_devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result + + +def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str): + """ + returns filtered keyman devices based on given attributes + """ + execute_string = "SELECT * FROM devices AS device WHERE" + before_me = False + all_all = True + if keyman_id != "all": + all_all = False + keyman_dev = find_device_by_serial(db, keyman_id) + if keyman_dev != None: + if before_me: + execute_string += " AND device.id = " + str(keyman_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(keyman_dev.id) + if license_name != "all": + all_all = False + license = get_licenses_by_name(db, license_name) + if len(license) > 0: + lic_ids = [] + for l in license: + lic_ids.append(l.id) + dev_lics = find_devicelicenses_by_licid_array(db, lic_ids) + lic_ids = "(" + for l in dev_lics: + lic_ids += str(l.device_id) + ", " + def_lic_ids = lic_ids[:-2] + ")" + if before_me: + execute_string += " AND device.id IN " + def_lic_ids + else: + before_me = True + execute_string += " device.id IN " + def_lic_ids + if license_id != "all": + all_all = False + license = find_license(db, license_id) + licen_devs = get_license_devices(db, license.id) + ids = "(" + for lic in licen_devs: + ids += str(lic.device_id) + ", " + def_ids = ids[:-2] + ")" + if license != None: + if before_me: + execute_string += " AND device.id IN " + def_ids + else: + before_me = True + execute_string += " device.id IN " + def_ids + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + if all_all: + before_me = True + execute_string = "SELECT * FROM devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result + + def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_id: int, date: datetime): """ Creates new USB log for usb_logs database table @@ -382,7 +956,39 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i db.add(db_log) db.commit() db.refresh(db_log) - return db_log</code></pre> + return db_log + + +def get_users(db: Session, skip: int = 0, limit: int = 100): + """ + Returns all users saved in database + """ + return db.query(models.User).offset(skip).limit(limit).all() + + +def find_user(db: Session, name: str): + """ + Finds one user by given username + """ + return db.query(models.User).filter(models.User.username == name).first() + + +def find_user_byid(db: Session, id: int): + """ + Finds one user by given id + """ + return db.query(models.User).filter(models.User.id == id).first() + + +def create_user(db: Session, name: str, passw: str, rol: str): + """ + Creates new user + """ + db_user = models.User(username=name, password=passw, role=rol) + db.add(db_user) + db.commit() + db.refresh(db_user) + return db_user</code></pre> </details> </section> <section> @@ -392,8 +998,52 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i <section> <h2 class="section-title" id="header-functions">Functions</h2> <dl> +<dt id="sql_app.crud.change_role"><code class="name flex"> +<span>def <span class="ident">change_role</span></span>(<span>db: sqlalchemy.orm.session.Session, usr_id: int, role: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates team of one specific pc</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def change_role(db: Session, usr_id: int, role: str): + """ + Updates team of one specific pc + """ + old_usr = find_user_byid(db, usr_id) + new = {'id': old_usr.id, 'username': old_usr.username, 'password': old_usr.password, 'role': role} + for key, value in new.items(): + setattr(old_usr, key, value) + db.commit() + db.refresh(old_usr) + return old_usr</code></pre> +</details> +</dd> +<dt id="sql_app.crud.change_team"><code class="name flex"> +<span>def <span class="ident">change_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int, name: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates name of one specific team</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def change_team(db: Session, team_id: int, name: str): + """ + Updates name of one specific team + """ + old_team = get_team(db, team_id) + new = {'id': old_team.id, 'name': name} + for key, value in new.items(): + setattr(old_team, key, value) + db.commit() + db.refresh(old_team) + return old_team</code></pre> +</details> +</dd> <dt id="sql_app.crud.create_body_device"><code class="name flex"> -<span>def <span class="ident">create_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.BodyDeviceBase" href="schemas.html#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a>)</span> +<span>def <span class="ident">create_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.BodyDeviceTemp" href="schemas.html#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a>)</span> </code></dt> <dd> <div class="desc"><p>Creates new Body device</p></div> @@ -401,11 +1051,11 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def create_body_device(db: Session, log: schemas.BodyDeviceBase): +<pre><code class="python">def create_body_device(db: Session, log: schemas.BodyDeviceTemp): """ Creates new Body device """ - db_body = models.BodyDevice(serial_number=log.serial_number) + db_body = models.BodyDevice(serial_number=log.serial_number, inventory_number="", comment="") db.add(db_body) db.commit() db.refresh(db_body) @@ -413,7 +1063,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i </details> </dd> <dt id="sql_app.crud.create_device"><code class="name flex"> -<span>def <span class="ident">create_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceBase" href="schemas.html#sql_app.schemas.DeviceBase">DeviceBase</a>)</span> +<span>def <span class="ident">create_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceTemp" href="schemas.html#sql_app.schemas.DeviceTemp">DeviceTemp</a>)</span> </code></dt> <dd> <div class="desc"><p>creates new device with data from given DeviceBase object</p></div> @@ -421,12 +1071,12 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def create_device(db: Session, device: schemas.DeviceBase): +<pre><code class="python">def create_device(db: Session, device: schemas.DeviceTemp): """ creates new device with data from given DeviceBase object """ db_device = models.Device(vendor_id=device.vendor_id, product_id=device.product_id, - serial_number=device.serial_number, assigned=False) + serial_number=device.serial_number, inventory_number="", comment="") db.add(db_device) db.commit() db.refresh(db_device) @@ -475,7 +1125,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i </details> </dd> <dt id="sql_app.crud.create_head_device"><code class="name flex"> -<span>def <span class="ident">create_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.HeadDeviceBase" href="schemas.html#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a>)</span> +<span>def <span class="ident">create_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.HeadDeviceTemp" href="schemas.html#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a>)</span> </code></dt> <dd> <div class="desc"><p>Creates new head device</p></div> @@ -483,7 +1133,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def create_head_device(db: Session, log: schemas.HeadDeviceBase): +<pre><code class="python">def create_head_device(db: Session, log: schemas.HeadDeviceTemp): """ Creates new head device """ @@ -515,7 +1165,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i </details> </dd> <dt id="sql_app.crud.create_license"><code class="name flex"> -<span>def <span class="ident">create_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str, expdate: datetime.date)</span> +<span>def <span class="ident">create_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str, lic_id: str, expdate: datetime.date)</span> </code></dt> <dd> <div class="desc"><p>creates new license with given name and expiration date</p></div> @@ -523,11 +1173,11 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def create_license(db: Session, name: str, expdate: date): +<pre><code class="python">def create_license(db: Session, name: str, lic_id: str, expdate: date): """ creates new license with given name and expiration date """ - db_license = models.License(name=name, expiration_date=expdate) + db_license = models.License(name=name, license_id=lic_id, expiration_date=expdate) db.add(db_license) db.commit() db.refresh(db_license) @@ -547,7 +1197,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i """ creates new pc with given username and hostname """ - db_pc = models.PC(username=user, hostname=host, assigned=False) + db_pc = models.PC(username=user, hostname=host) db.add(db_pc) db.commit() db.refresh(db_pc) @@ -574,133 +1224,315 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i return db_team</code></pre> </details> </dd> -<dt id="sql_app.crud.find_body_device"><code class="name flex"> -<span>def <span class="ident">find_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.BodyDeviceBase" href="schemas.html#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a>)</span> +<dt id="sql_app.crud.create_user"><code class="name flex"> +<span>def <span class="ident">create_user</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str, passw: str, rol: str)</span> </code></dt> <dd> -<div class="desc"><p>Finds one body device by its serial number</p></div> +<div class="desc"><p>Creates new user</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_body_device(db: Session, serial: schemas.BodyDeviceBase): +<pre><code class="python">def create_user(db: Session, name: str, passw: str, rol: str): """ - Finds one body device by its serial number + Creates new user """ - return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first()</code></pre> + db_user = models.User(username=name, password=passw, role=rol) + db.add(db_user) + db.commit() + db.refresh(db_user) + return db_user</code></pre> </details> </dd> -<dt id="sql_app.crud.find_device"><code class="name flex"> -<span>def <span class="ident">find_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceBase" href="schemas.html#sql_app.schemas.DeviceBase">DeviceBase</a>)</span> +<dt id="sql_app.crud.delete_device_license"><code class="name flex"> +<span>def <span class="ident">delete_device_license</span></span>(<span>db: sqlalchemy.orm.session.Session, device: int, license: int)</span> </code></dt> <dd> -<div class="desc"><p>finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object</p></div> +<div class="desc"><p>deletes entry in devices_licenses table with device id, license id and time.</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_device(db: Session, device: schemas.DeviceBase): +<pre><code class="python">def delete_device_license(db: Session, device: int, license: int): """ - finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object + deletes entry in devices_licenses table with device id, license id and time. """ - return db.query(models.Device).filter(and_(models.Device.product_id == device.product_id, - models.Device.vendor_id == device.vendor_id, - models.Device.serial_number == device.serial_number)).first()</code></pre> + db_device_license = get_devicelicense_by_devicelicense(db, device, license) + db_lic = db.delete(db_device_license) + db.commit() + return db_lic</code></pre> </details> </dd> -<dt id="sql_app.crud.find_filtered_logs"><code class="name flex"> -<span>def <span class="ident">find_filtered_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, logs: [])</span> +<dt id="sql_app.crud.find_body_device"><code class="name flex"> +<span>def <span class="ident">find_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.BodyDeviceTemp" href="schemas.html#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a>)</span> </code></dt> <dd> -<div class="desc"><p>Returns all usb logs with ids in given id array.</p></div> +<div class="desc"><p>Finds one body device by its serial number</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_filtered_logs(db: Session, logs: []): +<pre><code class="python">def find_body_device(db: Session, serial: schemas.BodyDeviceTemp): """ - Returns all usb logs with ids in given id array. + Finds one body device by its serial number """ - return db.query(models.USBLog).filter(models.USBLog.id.in_(logs)).order_by(desc(models.USBLog.timestamp)).all()</code></pre> + return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first()</code></pre> </details> </dd> -<dt id="sql_app.crud.find_head_device"><code class="name flex"> -<span>def <span class="ident">find_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.HeadDeviceBase" href="schemas.html#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a>)</span> +<dt id="sql_app.crud.find_bodydevice_by_serial"><code class="name flex"> +<span>def <span class="ident">find_bodydevice_by_serial</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: str)</span> </code></dt> <dd> -<div class="desc"><p>Finds one head device by its serial number</p></div> +<div class="desc"><p>Finds one specific body device by given serial number</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_head_device(db: Session, serial: schemas.HeadDeviceBase): +<pre><code class="python">def find_bodydevice_by_serial(db: Session, serial: str): """ - Finds one head device by its serial number + Finds one specific body device by given serial number """ - return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first()</code></pre> + return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial).first()</code></pre> </details> </dd> -<dt id="sql_app.crud.find_license"><code class="name flex"> -<span>def <span class="ident">find_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span> +<dt id="sql_app.crud.find_bodydevices_by_license"><code class="name flex"> +<span>def <span class="ident">find_bodydevices_by_license</span></span>(<span>db: sqlalchemy.orm.session.Session, lic_id: int)</span> </code></dt> <dd> -<div class="desc"><p>finds one license by given string name</p></div> +<div class="desc"><p>Returns all body devices with specific license</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_license(db: Session, name: str): +<pre><code class="python">def find_bodydevices_by_license(db: Session, lic_id: int): """ - finds one license by given string name + Returns all body devices with specific license """ - return db.query(models.License).filter(models.License.name == name).first()</code></pre> + return db.query(models.BodyDevice).filter(models.BodyDevice.license_id == lic_id).all()</code></pre> </details> </dd> -<dt id="sql_app.crud.find_pc"><code class="name flex"> -<span>def <span class="ident">find_pc</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str, hostname: str)</span> +<dt id="sql_app.crud.find_bodydevices_by_team"><code class="name flex"> +<span>def <span class="ident">find_bodydevices_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span> </code></dt> <dd> -<div class="desc"><p>Finds one pc with given username and hostname</p></div> +<div class="desc"><p>Returns all body devices in specific team</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_pc(db: Session, username: str, hostname: str): +<pre><code class="python">def find_bodydevices_by_team(db: Session, team_id: int): """ - Finds one pc with given username and hostname + Returns all body devices in specific team """ - return db.query(models.PC).filter(and_(models.PC.username == username, - models.PC.hostname == hostname)).first()</code></pre> + return db.query(models.BodyDevice).filter(models.BodyDevice.team_id == team_id).all()</code></pre> </details> </dd> -<dt id="sql_app.crud.find_pc_by_name"><code class="name flex"> -<span>def <span class="ident">find_pc_by_name</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span> +<dt id="sql_app.crud.find_device"><code class="name flex"> +<span>def <span class="ident">find_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceTemp" href="schemas.html#sql_app.schemas.DeviceTemp">DeviceTemp</a>)</span> </code></dt> <dd> -<div class="desc"><p>Finds one pc by its username</p></div> +<div class="desc"><p>finds one device with +serial_number same as in given DeviceBase object</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_pc_by_name(db: Session, username: str): +<pre><code class="python">def find_device(db: Session, device: schemas.DeviceTemp): """ - Finds one pc by its username + finds one device with serial_number same as in given DeviceBase object """ - return db.query(models.PC).filter(models.PC.username == username).first()</code></pre> + return db.query(models.Device).filter(and_(models.Device.serial_number == device.serial_number)).first()</code></pre> </details> </dd> -<dt id="sql_app.crud.find_pc_by_name_all"><code class="name flex"> -<span>def <span class="ident">find_pc_by_name_all</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span> +<dt id="sql_app.crud.find_device_by_serial"><code class="name flex"> +<span>def <span class="ident">find_device_by_serial</span></span>(<span>db: sqlalchemy.orm.session.Session, ser: str)</span> </code></dt> <dd> -<div class="desc"><p>Finds all pcs with same username</p></div> +<div class="desc"><p>finds one device with serial_number same as in given DeviceBase object</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def find_pc_by_name_all(db: Session, username: str): +<pre><code class="python">def find_device_by_serial(db: Session, ser: str): """ - Finds all pcs with same username + finds one device with serial_number same as in given DeviceBase object + """ + return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_devicelicenses_by_licid_array"><code class="name flex"> +<span>def <span class="ident">find_devicelicenses_by_licid_array</span></span>(<span>db: sqlalchemy.orm.session.Session, lcs: [])</span> +</code></dt> +<dd> +<div class="desc"><p>Finds all device_licenses with license_id in given id array</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_devicelicenses_by_licid_array(db: Session, lcs: []): + """ + Finds all device_licenses with license_id in given id array + """ + return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id.in_(lcs)).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_filtered_ldlogs"><code class="name flex"> +<span>def <span class="ident">find_filtered_ldlogs</span></span>(<span>db: sqlalchemy.orm.session.Session, logs: [])</span> +</code></dt> +<dd> +<div class="desc"><p>Returns all ld logs with ids in given id array.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_filtered_ldlogs(db: Session, logs: []): + """ + Returns all ld logs with ids in given id array. + """ + return db.query(models.LDLog).filter(models.LDLog.id.in_(logs)).order_by(desc(models.LDLog.timestamp)).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_filtered_logs"><code class="name flex"> +<span>def <span class="ident">find_filtered_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, logs: [])</span> +</code></dt> +<dd> +<div class="desc"><p>Returns all usb logs with ids in given id array.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_filtered_logs(db: Session, logs: []): + """ + Returns all usb logs with ids in given id array. + """ + return db.query(models.USBLog).filter(models.USBLog.id.in_(logs)).order_by(desc(models.USBLog.timestamp)).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_head_device"><code class="name flex"> +<span>def <span class="ident">find_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.HeadDeviceTemp" href="schemas.html#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a>)</span> +</code></dt> +<dd> +<div class="desc"><p>Finds one head device by its serial number</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_head_device(db: Session, serial: schemas.HeadDeviceTemp): + """ + Finds one head device by its serial number + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_headdevice_by_serial"><code class="name flex"> +<span>def <span class="ident">find_headdevice_by_serial</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Finds one specific head device by given serial number</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_headdevice_by_serial(db: Session, serial: str): + """ + Finds one specific head device by given serial number + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial).first()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_headdevices_by_license"><code class="name flex"> +<span>def <span class="ident">find_headdevices_by_license</span></span>(<span>db: sqlalchemy.orm.session.Session, lic_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>Returns all head devices with specific license</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_headdevices_by_license(db: Session, lic_id: int): + """ + Returns all head devices with specific license + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.license_id == lic_id).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_headdevices_by_team"><code class="name flex"> +<span>def <span class="ident">find_headdevices_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>Returns all head devices in specific team</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_headdevices_by_team(db: Session, team_id: int): + """ + Returns all head devices in specific team + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.team_id == team_id).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_license"><code class="name flex"> +<span>def <span class="ident">find_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span> +</code></dt> +<dd> +<div class="desc"><p>finds one license by given string name</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_license(db: Session, name: str): + """ + finds one license by given string name + """ + return db.query(models.License).filter(models.License.license_id == name).first()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_pc"><code class="name flex"> +<span>def <span class="ident">find_pc</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str, hostname: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Finds one pc with given username and hostname</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_pc(db: Session, username: str, hostname: str): + """ + Finds one pc with given username and hostname + """ + return db.query(models.PC).filter(and_(models.PC.username == username, + models.PC.hostname == hostname)).first()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_pc_by_name"><code class="name flex"> +<span>def <span class="ident">find_pc_by_name</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Finds one pc by its username</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_pc_by_name(db: Session, username: str): + """ + Finds one pc by its username + """ + return db.query(models.PC).filter(models.PC.username == username).first()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_pc_by_name_all"><code class="name flex"> +<span>def <span class="ident">find_pc_by_name_all</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Finds all pcs with same username</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_pc_by_name_all(db: Session, username: str): + """ + Finds all pcs with same username """ return db.query(models.PC).filter(models.PC.username == username).offset(0).limit(100).all()</code></pre> </details> @@ -753,6 +1585,38 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i return db.query(models.Team).filter(models.Team.name == name).first()</code></pre> </details> </dd> +<dt id="sql_app.crud.find_user"><code class="name flex"> +<span>def <span class="ident">find_user</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Finds one user by given username</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_user(db: Session, name: str): + """ + Finds one user by given username + """ + return db.query(models.User).filter(models.User.username == name).first()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.find_user_byid"><code class="name flex"> +<span>def <span class="ident">find_user_byid</span></span>(<span>db: sqlalchemy.orm.session.Session, id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>Finds one user by given id</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def find_user_byid(db: Session, id: int): + """ + Finds one user by given id + """ + return db.query(models.User).filter(models.User.id == id).first()</code></pre> +</details> +</dd> <dt id="sql_app.crud.get_body_device"><code class="name flex"> <span>def <span class="ident">get_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, body_id: int)</span> </code></dt> @@ -785,6 +1649,22 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i return db.query(models.BodyDevice).offset(skip).limit(limit).all()</code></pre> </details> </dd> +<dt id="sql_app.crud.get_bodydevices_with_ids"><code class="name flex"> +<span>def <span class="ident">get_bodydevices_with_ids</span></span>(<span>db: sqlalchemy.orm.session.Session, ids: [])</span> +</code></dt> +<dd> +<div class="desc"><p>returns all bodydevices with given ids</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_bodydevices_with_ids(db: Session, ids: []): + """ + returns all bodydevices with given ids + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.id.in_(ids)).all()</code></pre> +</details> +</dd> <dt id="sql_app.crud.get_device"><code class="name flex"> <span>def <span class="ident">get_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int)</span> </code></dt> @@ -801,6 +1681,39 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i return db.query(models.Device).filter(models.Device.id == device_id).first()</code></pre> </details> </dd> +<dt id="sql_app.crud.get_device_licenses"><code class="name flex"> +<span>def <span class="ident">get_device_licenses</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>returns all entries in devices_licenses table with given device_id</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_device_licenses(db: Session, device_id: int): + """ + returns all entries in devices_licenses table with given device_id + """ + return db.query(models.DeviceLicense).filter(models.DeviceLicense.device_id == device_id).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.get_devicelicense_by_devicelicense"><code class="name flex"> +<span>def <span class="ident">get_devicelicense_by_devicelicense</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, license_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>returns entry in devices_licenses table with given device id and license id</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_devicelicense_by_devicelicense(db: Session, device_id: int, license_id: int): + """ + returns entry in devices_licenses table with given device id and license id + """ + return db.query(models.DeviceLicense).filter(and_(models.DeviceLicense.device_id == device_id, + models.DeviceLicense.license_id == license_id)).first()</code></pre> +</details> +</dd> <dt id="sql_app.crud.get_devices"><code class="name flex"> <span>def <span class="ident">get_devices</span></span>(<span>db: sqlalchemy.orm.session.Session, skip: int = 0, limit: int = 100)</span> </code></dt> @@ -817,6 +1730,348 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i return db.query(models.Device).offset(skip).limit(limit).all()</code></pre> </details> </dd> +<dt id="sql_app.crud.get_devices_by_team"><code class="name flex"> +<span>def <span class="ident">get_devices_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team: int)</span> +</code></dt> +<dd> +<div class="desc"><p>returns all devices with same team</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_devices_by_team(db: Session, team: int): + """ + returns all devices with same team + """ + return db.query(models.Device).filter(models.Device.team_id == team).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.get_devices_with_ids"><code class="name flex"> +<span>def <span class="ident">get_devices_with_ids</span></span>(<span>db: sqlalchemy.orm.session.Session, ids: [])</span> +</code></dt> +<dd> +<div class="desc"><p>returns all devices with given ids</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_devices_with_ids(db: Session, ids: []): + """ + returns all devices with given ids + """ + return db.query(models.Device).filter(models.Device.id.in_(ids)).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.get_filtered_bodydevices"><code class="name flex"> +<span>def <span class="ident">get_filtered_bodydevices</span></span>(<span>db: sqlalchemy.orm.session.Session, body_id: str, license_id: str, team: str)</span> +</code></dt> +<dd> +<div class="desc"><p>returns filtered body devices based on given attributes</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_filtered_bodydevices(db: Session, body_id: str, license_id: str, team: str): + """ + returns filtered body devices based on given attributes + """ + execute_string = "SELECT * FROM body_devices AS device WHERE" + before_me = False + all_all = True + if body_id != "all": + all_all = False + body_dev = find_bodydevice_by_serial(db, body_id) + if body_dev != None: + if before_me: + execute_string += " AND device.id = " + str(body_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(body_dev.id) + if license_id != "all": + all_all = False + license = find_license(db, license_id) + if license != None: + if before_me: + execute_string += " AND device.license_id = " + str(license.id) + else: + before_me = True + execute_string += " device.license_id = " + str(license.id) + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + if all_all: + before_me = True + execute_string = "SELECT * FROM body_devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result</code></pre> +</details> +</dd> +<dt id="sql_app.crud.get_filtered_devices"><code class="name flex"> +<span>def <span class="ident">get_filtered_devices</span></span>(<span>db: sqlalchemy.orm.session.Session, keyman_id: str, license_name: str, license_id: str, team: str)</span> +</code></dt> +<dd> +<div class="desc"><p>returns filtered keyman devices based on given attributes</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str): + """ + returns filtered keyman devices based on given attributes + """ + execute_string = "SELECT * FROM devices AS device WHERE" + before_me = False + all_all = True + if keyman_id != "all": + all_all = False + keyman_dev = find_device_by_serial(db, keyman_id) + if keyman_dev != None: + if before_me: + execute_string += " AND device.id = " + str(keyman_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(keyman_dev.id) + if license_name != "all": + all_all = False + license = get_licenses_by_name(db, license_name) + if len(license) > 0: + lic_ids = [] + for l in license: + lic_ids.append(l.id) + dev_lics = find_devicelicenses_by_licid_array(db, lic_ids) + lic_ids = "(" + for l in dev_lics: + lic_ids += str(l.device_id) + ", " + def_lic_ids = lic_ids[:-2] + ")" + if before_me: + execute_string += " AND device.id IN " + def_lic_ids + else: + before_me = True + execute_string += " device.id IN " + def_lic_ids + if license_id != "all": + all_all = False + license = find_license(db, license_id) + licen_devs = get_license_devices(db, license.id) + ids = "(" + for lic in licen_devs: + ids += str(lic.device_id) + ", " + def_ids = ids[:-2] + ")" + if license != None: + if before_me: + execute_string += " AND device.id IN " + def_ids + else: + before_me = True + execute_string += " device.id IN " + def_ids + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + if all_all: + before_me = True + execute_string = "SELECT * FROM devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result</code></pre> +</details> +</dd> +<dt id="sql_app.crud.get_filtered_headdevices"><code class="name flex"> +<span>def <span class="ident">get_filtered_headdevices</span></span>(<span>db: sqlalchemy.orm.session.Session, body_id: str, license_id: str, team: str)</span> +</code></dt> +<dd> +<div class="desc"><p>returns filtered head devices based on given attributes</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_filtered_headdevices(db: Session, body_id: str, license_id: str, team: str): + """ + returns filtered head devices based on given attributes + """ + execute_string = "SELECT * FROM head_devices AS device WHERE" + before_me = False + all_all = True + if body_id != "all": + all_all = False + head_dev = find_headdevice_by_serial(db, body_id) + if head_dev != None: + if before_me: + execute_string += " AND device.id = " + str(head_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(head_dev.id) + if license_id != "all": + all_all = False + license = find_license(db, license_id) + if license != None: + if before_me: + execute_string += " AND device.license_id = " + str(license.id) + else: + before_me = True + execute_string += " device.license_id = " + str(license.id) + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + if all_all: + before_me = True + execute_string = "SELECT * FROM body_devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result</code></pre> +</details> +</dd> +<dt id="sql_app.crud.get_filtered_ldlogs"><code class="name flex"> +<span>def <span class="ident">get_filtered_ldlogs</span></span>(<span>db: sqlalchemy.orm.session.Session, pc: str, tema: str, lic: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Function creates query string used for filtering by pc username, team name and license name. +Depending on selected filters assembles query string for database</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str): + """ + Function creates query string used for filtering by pc username, team name and license name. + Depending on selected filters assembles query string for database + """ + execute_string = "SELECT * FROM ld_logs AS logs WHERE" + before_me = False + all_all = True + if pc != "all": + all_all = False + pc = find_pc_by_username(db, pc) + if pc != None: + if before_me: + execute_string += " AND logs.pc_id = " + str(pc.id) + else: + before_me = True + execute_string += " logs.pc_id = " + str(pc.id) + if tema != "all": + all_all = False + team = find_team(db, tema) + if team != None: + head_devices = find_headdevices_by_team(db, team.id) + body_devices = find_bodydevices_by_team(db, team.id) + if len(head_devices) > 0 and len(body_devices) > 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + else: + before_me = True + execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + elif len(head_devices) == 0 and len(body_devices) > 0: + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.body_id IN " + def_b_ids + else: + before_me = True + execute_string += " logs.body_id IN " + def_b_ids + elif len(head_devices) > 0 and len(body_devices) == 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.head_id IN " + def_h_ids + else: + before_me = True + execute_string += " logs.head_id IN " + def_h_ids + else: + if before_me: + execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)" + else: + before_me = True + execute_string += " (logs.head_id = -1 OR logs.body_id = -1)" + if lic != "all": + all_all = False + license = find_license(db, lic) + if license != None: + head_devices = find_headdevices_by_license(db, license.id) + body_devices = find_bodydevices_by_license(db, license.id) + if len(head_devices) > 0 and len(body_devices) > 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + else: + before_me = True + execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + elif len(head_devices) == 0 and len(body_devices) > 0: + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.body_id IN " + def_b_ids + else: + before_me = True + execute_string += " logs.body_id IN " + def_b_ids + elif len(head_devices) > 0 and len(body_devices) == 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.head_id IN " + def_h_ids + else: + before_me = True + execute_string += " logs.head_id IN " + def_h_ids + else: + if before_me: + execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)" + else: + before_me = True + execute_string += " (logs.head_id = -1 OR logs.body_id = -1)" + if all_all: + before_me = True + execute_string = "SELECT * FROM ld_logs AS logs" + + if not before_me: + execute_string = "SELECT * FROM ld_logs AS logs WHERE logs.id = -1" + result = db.execute(execute_string) + return result</code></pre> +</details> +</dd> <dt id="sql_app.crud.get_filtered_logs"><code class="name flex"> <span>def <span class="ident">get_filtered_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, pc: str, tema: str, lic: str)</span> </code></dt> @@ -833,31 +2088,38 @@ Depending on selected filters assembles query string for database</p></div> Depending on selected filters assembles query string for database """ execute_string = "SELECT * FROM usb_logs AS logs" + pcs = find_pc_by_username(db, pc) if pc != "all": - pcs = find_pc_by_username(db, pc) - execute_string += " WHERE logs.pc_id = " + str(pcs.id) + if pcs is not None: + execute_string += " WHERE logs.pc_id = " + str(pcs.id) if tema != "all": team = find_team(db, tema) - pcs = get_pcs_by_team(db, team.id) - pc_ids = "(" - for p in pcs: - pc_ids += str(p.id) + ", " - def_pc_ids = pc_ids[:-2] + ")" - if pc != "all": - execute_string += " AND logs.pc_id IN " + def_pc_ids - else: - execute_string += " WHERE logs.pc_id IN " + def_pc_ids + if team is not None: + devs = get_devices_by_team(db, team.id) + d_ids = "(" + for p in devs: + d_ids += str(p.id) + ", " + def_d_ids = d_ids[:-2] + ")" + if pc != "all" and pcs is not None: + if len(def_d_ids) > 1: + execute_string += " AND logs.device_id IN " + def_d_ids + else: + if len(def_d_ids) > 1: + execute_string += " WHERE logs.device_id IN " + def_d_ids if lic != "all": - license = find_license(db, lic) - device_licenses = get_license_devices(db, license.id) - dev_ids = "(" - for dev in device_licenses: - dev_ids += str(dev.device_id) + ", " - defin_ids = dev_ids[:-2] + ")" - if pc != "all" or tema != "all": - execute_string += " AND logs.device_id IN " + defin_ids - else: - execute_string += " WHERE logs.device_id IN " + defin_ids + license = get_licenses_by_name(db, lic) + if license is not None: + device_licenses = get_license_devices(db, license.id) + dev_ids = "(" + for dev in device_licenses: + dev_ids += str(dev.device_id) + ", " + defin_ids = dev_ids[:-2] + ")" + if pc != "all" or tema != "all": + if len(defin_ids) > 1: + execute_string += " AND logs.device_id IN " + defin_ids + else: + if len(defin_ids) > 1: + execute_string += " WHERE logs.device_id IN " + defin_ids # executing assembled query string result = db.execute(execute_string) @@ -896,6 +2158,22 @@ Depending on selected filters assembles query string for database</p></div> return db.query(models.HeadDevice).offset(skip).limit(limit).all()</code></pre> </details> </dd> +<dt id="sql_app.crud.get_headdevices_with_ids"><code class="name flex"> +<span>def <span class="ident">get_headdevices_with_ids</span></span>(<span>db: sqlalchemy.orm.session.Session, ids: [])</span> +</code></dt> +<dd> +<div class="desc"><p>returns all headdevices with given ids</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_headdevices_with_ids(db: Session, ids: []): + """ + returns all headdevices with given ids + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.id.in_(ids)).all()</code></pre> +</details> +</dd> <dt id="sql_app.crud.get_ld_logs"><code class="name flex"> <span>def <span class="ident">get_ld_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, skip: int = 0, limit: int = 100)</span> </code></dt> @@ -909,7 +2187,7 @@ Depending on selected filters assembles query string for database</p></div> """ Returns all ld debugger logs in database """ - return db.query(models.LDLog).offset(skip).limit(limit).all()</code></pre> + return db.query(models.LDLog).order_by(desc(models.LDLog.timestamp)).offset(skip).limit(limit).all()</code></pre> </details> </dd> <dt id="sql_app.crud.get_license"><code class="name flex"> @@ -932,14 +2210,14 @@ Depending on selected filters assembles query string for database</p></div> <span>def <span class="ident">get_license_devices</span></span>(<span>db: sqlalchemy.orm.session.Session, license_id: int)</span> </code></dt> <dd> -<div class="desc"><p>returns all entries in devices_licenses table</p></div> +<div class="desc"><p>returns all entries in devices_licenses table with given license_id</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> <pre><code class="python">def get_license_devices(db: Session, license_id: int): """ - returns all entries in devices_licenses table + returns all entries in devices_licenses table with given license_id """ return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id == license_id).all()</code></pre> </details> @@ -960,6 +2238,19 @@ Depending on selected filters assembles query string for database</p></div> return db.query(models.License).offset(skip).limit(limit).all()</code></pre> </details> </dd> +<dt id="sql_app.crud.get_licenses_by_name"><code class="name flex"> +<span>def <span class="ident">get_licenses_by_name</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span> +</code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_licenses_by_name(db: Session, name: str): + return db.query(models.License).filter(models.License.name == name).all()</code></pre> +</details> +</dd> <dt id="sql_app.crud.get_log"><code class="name flex"> <span>def <span class="ident">get_log</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, skip: int = 0, limit: int = 100)</span> </code></dt> @@ -1024,22 +2315,6 @@ Depending on selected filters assembles query string for database</p></div> return db.query(models.PC).offset(skip).limit(limit).all()</code></pre> </details> </dd> -<dt id="sql_app.crud.get_pcs_by_team"><code class="name flex"> -<span>def <span class="ident">get_pcs_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span> -</code></dt> -<dd> -<div class="desc"><p>returns all pcs in given team by team id</p></div> -<details class="source"> -<summary> -<span>Expand source code</span> -</summary> -<pre><code class="python">def get_pcs_by_team(db: Session, team_id: int): - """ - returns all pcs in given team by team id - """ - return db.query(models.PC).filter(models.PC.team_id == team_id).all()</code></pre> -</details> -</dd> <dt id="sql_app.crud.get_team"><code class="name flex"> <span>def <span class="ident">get_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span> </code></dt> @@ -1072,28 +2347,291 @@ Depending on selected filters assembles query string for database</p></div> return db.query(models.Team).offset(skip).limit(limit).all()</code></pre> </details> </dd> -<dt id="sql_app.crud.update_pc"><code class="name flex"> -<span>def <span class="ident">update_pc</span></span>(<span>db: sqlalchemy.orm.session.Session, pc_id: int, team: str)</span> +<dt id="sql_app.crud.get_users"><code class="name flex"> +<span>def <span class="ident">get_users</span></span>(<span>db: sqlalchemy.orm.session.Session, skip: int = 0, limit: int = 100)</span> +</code></dt> +<dd> +<div class="desc"><p>Returns all users saved in database</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def get_users(db: Session, skip: int = 0, limit: int = 100): + """ + Returns all users saved in database + """ + return db.query(models.User).offset(skip).limit(limit).all()</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_bodydevice_comm"><code class="name flex"> +<span>def <span class="ident">update_bodydevice_comm</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, comm: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates body devices comment with new one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_bodydevice_comm(db: Session, device_id: int, comm: str): + """ + Updates body devices comment with new one given by user + """ + old_dev = get_body_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_bodydevice_inv"><code class="name flex"> +<span>def <span class="ident">update_bodydevice_inv</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, dev_inv: str)</span> </code></dt> <dd> -<div class="desc"><p>Function updates team of one specific pc</p></div> +<div class="desc"><p>Updates body devices inventory number with new one given by user</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def update_pc(db: Session, pc_id: int, team: str): +<pre><code class="python">def update_bodydevice_inv(db: Session, device_id: int, dev_inv: str): """ - Function updates team of one specific pc + Updates body devices inventory number with new one given by user """ - old_pc = get_pc(db, pc_id) + old_dev = get_body_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_bodydevice_license"><code class="name flex"> +<span>def <span class="ident">update_bodydevice_license</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, lic_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates body devices license with one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_bodydevice_license(db: Session, device_id: int, lic_id: int): + """ + Updates body devices license with one given by user + """ + old_dev = get_body_device(db, device_id) + lic = get_license(db, lic_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_bodydevice_team"><code class="name flex"> +<span>def <span class="ident">update_bodydevice_team</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, team_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates body devices team with one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_bodydevice_team(db: Session, device_id: int, team_id: int): + """ + Updates body devices team with one given by user + """ + old_dev = get_body_device(db, device_id) + team = get_team(db, team_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_device"><code class="name flex"> +<span>def <span class="ident">update_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, team: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates team of one specific pc</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_device(db: Session, device_id: int, team: str): + """ + Updates team of one specific pc + """ + old_dev = get_device(db, device_id) team = get_team(db, int(team)) - new = {'id': old_pc.id, 'username': old_pc.username, 'hostname': old_pc.hostname, 'assigned': True, - 'team_id': team.id} + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_device_com"><code class="name flex"> +<span>def <span class="ident">update_device_com</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, comm: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates team of one specific pc</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_device_com(db: Session, device_id: int, comm: str): + """ + Updates team of one specific pc + """ + old_dev = get_device(db, device_id) + if old_dev.team_id != None: + team = get_team(db, int(old_dev.team_id)) + teamid = team.id + else: + teamid = None + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': teamid} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_device_inv"><code class="name flex"> +<span>def <span class="ident">update_device_inv</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, inv: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates inventory number of one specific pc</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_device_inv(db: Session, device_id: int, inv: str): + """ + Updates inventory number of one specific pc + """ + old_dev = get_device(db, device_id) + if old_dev.team_id != None: + team = get_team(db, int(old_dev.team_id)) + teamid = team.id + else: + teamid = None + new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id, + 'serial_number': old_dev.serial_number, 'inventory_number': inv, + 'comment': old_dev.comment, 'team_id': teamid} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_headdevice_comm"><code class="name flex"> +<span>def <span class="ident">update_headdevice_comm</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, comm: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates head devices comment with new one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_headdevice_comm(db: Session, device_id: int, comm: str): + """ + Updates head devices comment with new one given by user + """ + old_dev = get_head_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_headdevice_inv"><code class="name flex"> +<span>def <span class="ident">update_headdevice_inv</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, dev_inv: str)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates head devices inventory number with new one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_headdevice_inv(db: Session, device_id: int, dev_inv: str): + """ + Updates head devices inventory number with new one given by user + """ + old_dev = get_head_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_headdevice_license"><code class="name flex"> +<span>def <span class="ident">update_headdevice_license</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, lic_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates head devices license with one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_headdevice_license(db: Session, device_id: int, lic_id: int): + """ + Updates head devices license with one given by user + """ + old_dev = get_head_device(db, device_id) + lic = get_license(db, lic_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev</code></pre> +</details> +</dd> +<dt id="sql_app.crud.update_headdevice_team"><code class="name flex"> +<span>def <span class="ident">update_headdevice_team</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, team_id: int)</span> +</code></dt> +<dd> +<div class="desc"><p>Updates head devices team with one given by user</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def update_headdevice_team(db: Session, device_id: int, team_id: int): + """ + Updates head devices team with one given by user + """ + old_dev = get_head_device(db, device_id) + team = get_team(db, team_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id} for key, value in new.items(): - setattr(old_pc, key, value) + setattr(old_dev, key, value) db.commit() - db.refresh(old_pc) - return old_pc</code></pre> + db.refresh(old_dev) + return old_dev</code></pre> </details> </dd> </dl> @@ -1114,6 +2652,8 @@ Depending on selected filters assembles query string for database</p></div> </li> <li><h3><a href="#header-functions">Functions</a></h3> <ul class=""> +<li><code><a title="sql_app.crud.change_role" href="#sql_app.crud.change_role">change_role</a></code></li> +<li><code><a title="sql_app.crud.change_team" href="#sql_app.crud.change_team">change_team</a></code></li> <li><code><a title="sql_app.crud.create_body_device" href="#sql_app.crud.create_body_device">create_body_device</a></code></li> <li><code><a title="sql_app.crud.create_device" href="#sql_app.crud.create_device">create_device</a></code></li> <li><code><a title="sql_app.crud.create_device_license" href="#sql_app.crud.create_device_license">create_device_license</a></code></li> @@ -1123,10 +2663,21 @@ Depending on selected filters assembles query string for database</p></div> <li><code><a title="sql_app.crud.create_license" href="#sql_app.crud.create_license">create_license</a></code></li> <li><code><a title="sql_app.crud.create_pc" href="#sql_app.crud.create_pc">create_pc</a></code></li> <li><code><a title="sql_app.crud.create_team" href="#sql_app.crud.create_team">create_team</a></code></li> +<li><code><a title="sql_app.crud.create_user" href="#sql_app.crud.create_user">create_user</a></code></li> +<li><code><a title="sql_app.crud.delete_device_license" href="#sql_app.crud.delete_device_license">delete_device_license</a></code></li> <li><code><a title="sql_app.crud.find_body_device" href="#sql_app.crud.find_body_device">find_body_device</a></code></li> +<li><code><a title="sql_app.crud.find_bodydevice_by_serial" href="#sql_app.crud.find_bodydevice_by_serial">find_bodydevice_by_serial</a></code></li> +<li><code><a title="sql_app.crud.find_bodydevices_by_license" href="#sql_app.crud.find_bodydevices_by_license">find_bodydevices_by_license</a></code></li> +<li><code><a title="sql_app.crud.find_bodydevices_by_team" href="#sql_app.crud.find_bodydevices_by_team">find_bodydevices_by_team</a></code></li> <li><code><a title="sql_app.crud.find_device" href="#sql_app.crud.find_device">find_device</a></code></li> +<li><code><a title="sql_app.crud.find_device_by_serial" href="#sql_app.crud.find_device_by_serial">find_device_by_serial</a></code></li> +<li><code><a title="sql_app.crud.find_devicelicenses_by_licid_array" href="#sql_app.crud.find_devicelicenses_by_licid_array">find_devicelicenses_by_licid_array</a></code></li> +<li><code><a title="sql_app.crud.find_filtered_ldlogs" href="#sql_app.crud.find_filtered_ldlogs">find_filtered_ldlogs</a></code></li> <li><code><a title="sql_app.crud.find_filtered_logs" href="#sql_app.crud.find_filtered_logs">find_filtered_logs</a></code></li> <li><code><a title="sql_app.crud.find_head_device" href="#sql_app.crud.find_head_device">find_head_device</a></code></li> +<li><code><a title="sql_app.crud.find_headdevice_by_serial" href="#sql_app.crud.find_headdevice_by_serial">find_headdevice_by_serial</a></code></li> +<li><code><a title="sql_app.crud.find_headdevices_by_license" href="#sql_app.crud.find_headdevices_by_license">find_headdevices_by_license</a></code></li> +<li><code><a title="sql_app.crud.find_headdevices_by_team" href="#sql_app.crud.find_headdevices_by_team">find_headdevices_by_team</a></code></li> <li><code><a title="sql_app.crud.find_license" href="#sql_app.crud.find_license">find_license</a></code></li> <li><code><a title="sql_app.crud.find_pc" href="#sql_app.crud.find_pc">find_pc</a></code></li> <li><code><a title="sql_app.crud.find_pc_by_name" href="#sql_app.crud.find_pc_by_name">find_pc_by_name</a></code></li> @@ -1134,25 +2685,48 @@ Depending on selected filters assembles query string for database</p></div> <li><code><a title="sql_app.crud.find_pc_by_username" href="#sql_app.crud.find_pc_by_username">find_pc_by_username</a></code></li> <li><code><a title="sql_app.crud.find_pcs" href="#sql_app.crud.find_pcs">find_pcs</a></code></li> <li><code><a title="sql_app.crud.find_team" href="#sql_app.crud.find_team">find_team</a></code></li> +<li><code><a title="sql_app.crud.find_user" href="#sql_app.crud.find_user">find_user</a></code></li> +<li><code><a title="sql_app.crud.find_user_byid" href="#sql_app.crud.find_user_byid">find_user_byid</a></code></li> <li><code><a title="sql_app.crud.get_body_device" href="#sql_app.crud.get_body_device">get_body_device</a></code></li> <li><code><a title="sql_app.crud.get_body_devices" href="#sql_app.crud.get_body_devices">get_body_devices</a></code></li> +<li><code><a title="sql_app.crud.get_bodydevices_with_ids" href="#sql_app.crud.get_bodydevices_with_ids">get_bodydevices_with_ids</a></code></li> <li><code><a title="sql_app.crud.get_device" href="#sql_app.crud.get_device">get_device</a></code></li> +<li><code><a title="sql_app.crud.get_device_licenses" href="#sql_app.crud.get_device_licenses">get_device_licenses</a></code></li> +<li><code><a title="sql_app.crud.get_devicelicense_by_devicelicense" href="#sql_app.crud.get_devicelicense_by_devicelicense">get_devicelicense_by_devicelicense</a></code></li> <li><code><a title="sql_app.crud.get_devices" href="#sql_app.crud.get_devices">get_devices</a></code></li> +<li><code><a title="sql_app.crud.get_devices_by_team" href="#sql_app.crud.get_devices_by_team">get_devices_by_team</a></code></li> +<li><code><a title="sql_app.crud.get_devices_with_ids" href="#sql_app.crud.get_devices_with_ids">get_devices_with_ids</a></code></li> +<li><code><a title="sql_app.crud.get_filtered_bodydevices" href="#sql_app.crud.get_filtered_bodydevices">get_filtered_bodydevices</a></code></li> +<li><code><a title="sql_app.crud.get_filtered_devices" href="#sql_app.crud.get_filtered_devices">get_filtered_devices</a></code></li> +<li><code><a title="sql_app.crud.get_filtered_headdevices" href="#sql_app.crud.get_filtered_headdevices">get_filtered_headdevices</a></code></li> +<li><code><a title="sql_app.crud.get_filtered_ldlogs" href="#sql_app.crud.get_filtered_ldlogs">get_filtered_ldlogs</a></code></li> <li><code><a title="sql_app.crud.get_filtered_logs" href="#sql_app.crud.get_filtered_logs">get_filtered_logs</a></code></li> <li><code><a title="sql_app.crud.get_head_device" href="#sql_app.crud.get_head_device">get_head_device</a></code></li> <li><code><a title="sql_app.crud.get_head_devices" href="#sql_app.crud.get_head_devices">get_head_devices</a></code></li> +<li><code><a title="sql_app.crud.get_headdevices_with_ids" href="#sql_app.crud.get_headdevices_with_ids">get_headdevices_with_ids</a></code></li> <li><code><a title="sql_app.crud.get_ld_logs" href="#sql_app.crud.get_ld_logs">get_ld_logs</a></code></li> <li><code><a title="sql_app.crud.get_license" href="#sql_app.crud.get_license">get_license</a></code></li> <li><code><a title="sql_app.crud.get_license_devices" href="#sql_app.crud.get_license_devices">get_license_devices</a></code></li> <li><code><a title="sql_app.crud.get_licenses" href="#sql_app.crud.get_licenses">get_licenses</a></code></li> +<li><code><a title="sql_app.crud.get_licenses_by_name" href="#sql_app.crud.get_licenses_by_name">get_licenses_by_name</a></code></li> <li><code><a title="sql_app.crud.get_log" href="#sql_app.crud.get_log">get_log</a></code></li> <li><code><a title="sql_app.crud.get_logs" href="#sql_app.crud.get_logs">get_logs</a></code></li> <li><code><a title="sql_app.crud.get_pc" href="#sql_app.crud.get_pc">get_pc</a></code></li> <li><code><a title="sql_app.crud.get_pcs" href="#sql_app.crud.get_pcs">get_pcs</a></code></li> -<li><code><a title="sql_app.crud.get_pcs_by_team" href="#sql_app.crud.get_pcs_by_team">get_pcs_by_team</a></code></li> <li><code><a title="sql_app.crud.get_team" href="#sql_app.crud.get_team">get_team</a></code></li> <li><code><a title="sql_app.crud.get_teams" href="#sql_app.crud.get_teams">get_teams</a></code></li> -<li><code><a title="sql_app.crud.update_pc" href="#sql_app.crud.update_pc">update_pc</a></code></li> +<li><code><a title="sql_app.crud.get_users" href="#sql_app.crud.get_users">get_users</a></code></li> +<li><code><a title="sql_app.crud.update_bodydevice_comm" href="#sql_app.crud.update_bodydevice_comm">update_bodydevice_comm</a></code></li> +<li><code><a title="sql_app.crud.update_bodydevice_inv" href="#sql_app.crud.update_bodydevice_inv">update_bodydevice_inv</a></code></li> +<li><code><a title="sql_app.crud.update_bodydevice_license" href="#sql_app.crud.update_bodydevice_license">update_bodydevice_license</a></code></li> +<li><code><a title="sql_app.crud.update_bodydevice_team" href="#sql_app.crud.update_bodydevice_team">update_bodydevice_team</a></code></li> +<li><code><a title="sql_app.crud.update_device" href="#sql_app.crud.update_device">update_device</a></code></li> +<li><code><a title="sql_app.crud.update_device_com" href="#sql_app.crud.update_device_com">update_device_com</a></code></li> +<li><code><a title="sql_app.crud.update_device_inv" href="#sql_app.crud.update_device_inv">update_device_inv</a></code></li> +<li><code><a title="sql_app.crud.update_headdevice_comm" href="#sql_app.crud.update_headdevice_comm">update_headdevice_comm</a></code></li> +<li><code><a title="sql_app.crud.update_headdevice_inv" href="#sql_app.crud.update_headdevice_inv">update_headdevice_inv</a></code></li> +<li><code><a title="sql_app.crud.update_headdevice_license" href="#sql_app.crud.update_headdevice_license">update_headdevice_license</a></code></li> +<li><code><a title="sql_app.crud.update_headdevice_team" href="#sql_app.crud.update_headdevice_team">update_headdevice_team</a></code></li> </ul> </li> </ul> diff --git a/server/doc/sql_app/documentation.html b/server/doc/sql_app/index.html similarity index 100% rename from server/doc/sql_app/documentation.html rename to server/doc/sql_app/index.html diff --git a/server/doc/sql_app/main.html b/server/doc/sql_app/main.html index fabf34b..2e35621 100644 --- a/server/doc/sql_app/main.html +++ b/server/doc/sql_app/main.html @@ -37,6 +37,11 @@ from sql_app.api.usb_logs import usblogs from sql_app.api.usb_logs_web import usblogs_web from sql_app.api.teams import teams from sql_app.api.teams_web import teams_web +from sql_app.api.auth import auth +from sql_app.api.ld_logs_web import ldlogs_web +from sql_app.api.bodydevices_web import body_device_web +from sql_app.api.headdevices_web import head_device_web +from sql_app.api.users_web import users from fastapi import FastAPI @@ -55,6 +60,11 @@ app.include_router(licenses_web) app.include_router(pcs_web) app.include_router(teams_web) app.include_router(usblogs_web) +app.include_router(ldlogs_web) +app.include_router(body_device_web) +app.include_router(users) +app.include_router(head_device_web) +app.include_router(auth) if __name__ == "__main__": diff --git a/server/doc/sql_app/models.html b/server/doc/sql_app/models.html index 6cc705a..c554ff0 100644 --- a/server/doc/sql_app/models.html +++ b/server/doc/sql_app/models.html @@ -42,12 +42,16 @@ class Device(Base): vendor_id = Column(String, index=True, nullable=False) product_id = Column(String, index=True, nullable=False) serial_number = Column(String, index=True, nullable=False) - assigned = Column(Boolean, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) # relationships for foreign keys, thus connecting table with usb_logs and licenses # tables logs = relationship("USBLog", back_populates="device") licenses = relationship("DeviceLicense", back_populates="device_lic") + team = relationship("Team", back_populates="devices") class USBLog(Base): @@ -75,11 +79,14 @@ class License(Base): __tablename__ = "licenses" id = Column(Integer, primary_key=True, index=True) - name = Column(String, index=True, nullable=False) - expiration_date = Column(DateTime(timezone=True), server_default=func.now()) + name = Column(String, index=True, nullable=True) + license_id = Column(String, index=True, nullable=False) + expiration_date = Column(DateTime(timezone=True), nullable=True) # relationships for foreign keys, thus connecting table with devices table devices = relationship("DeviceLicense", back_populates="licenses") + bodydevice_lic = relationship("BodyDevice", back_populates="license") + headdevice_lic = relationship("HeadDevice", back_populates="license") class DeviceLicense(Base): @@ -108,12 +115,9 @@ class PC(Base): id = Column(Integer, primary_key=True, index=True) username = Column(String, index=True, nullable=False) hostname = Column(String, index=True, nullable=False) - assigned = Column(Boolean, index=True, nullable=False) - team_id = Column(Integer, ForeignKey("teams.id")) # relationships for foreign keys, thus connecting table with teams, usb_logs and ld_logs # tables - team = relationship("Team", back_populates="pcs") logs_pc = relationship("USBLog", back_populates="pc") ld_pc = relationship("LDLog", back_populates="ldpc") @@ -127,8 +131,9 @@ class Team(Base): id = Column(Integer, primary_key=True, index=True) name = Column(String, index=True, nullable=False) - # relationships for foreign keys, thus connecting table with pc table - pcs = relationship("PC", back_populates="team") + devices = relationship("Device", back_populates="team") + body_devices = relationship("BodyDevice", back_populates="team") + head_devices = relationship("HeadDevice", back_populates="team") class HeadDevice(Base): @@ -139,9 +144,16 @@ class HeadDevice(Base): id = Column(Integer, primary_key=True, index=True) serial_number = Column(String, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) + license_id = Column(Integer, ForeignKey("licenses.id")) # relationships for foreign keys, thus connecting table with ld_logs table h_logs = relationship("LDLog", back_populates="head_device") + license = relationship("License", back_populates="headdevice_lic") + team = relationship("Team", back_populates="head_devices") class BodyDevice(Base): @@ -152,9 +164,16 @@ class BodyDevice(Base): id = Column(Integer, primary_key=True, index=True) serial_number = Column(String, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) + license_id = Column(Integer, ForeignKey("licenses.id")) # relationships for foreign keys, thus connecting table with ld_logs table b_logs = relationship("LDLog", back_populates="body_device") + license = relationship("License", back_populates="bodydevice_lic") + team = relationship("Team", back_populates="body_devices") class LDLog(Base): @@ -174,7 +193,19 @@ class LDLog(Base): # tables ldpc = relationship("PC", back_populates="ld_pc") head_device = relationship("HeadDevice", back_populates="h_logs") - body_device = relationship("BodyDevice", back_populates="b_logs")</code></pre> + body_device = relationship("BodyDevice", back_populates="b_logs") + + +class User(Base): + """ + Class defining user in database with its own role + """ + __tablename__ = "users" + + id = Column(Integer, primary_key=True, index=True) + username = Column(String, index=True, nullable=False) + password = Column(String, index=True, nullable=False) + role = Column(String, index=True, nullable=False)</code></pre> </details> </section> <section> @@ -210,9 +241,16 @@ for example, any mapped columns or relationships.</p></div> id = Column(Integer, primary_key=True, index=True) serial_number = Column(String, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) + license_id = Column(Integer, ForeignKey("licenses.id")) # relationships for foreign keys, thus connecting table with ld_logs table - b_logs = relationship("LDLog", back_populates="body_device")</code></pre> + b_logs = relationship("LDLog", back_populates="body_device") + license = relationship("License", back_populates="bodydevice_lic") + team = relationship("Team", back_populates="body_devices")</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -245,32 +283,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.BodyDevice.id"><code class="name">var <span class="ident">id</span></code></dt> -<dd> -<div class="desc"></div> -<details class="source"> -<summary> -<span>Expand source code</span> -</summary> -<pre><code class="python">def __get__(self, instance, owner): - if instance is None: - return self - - dict_ = instance_dict(instance) - if self._supports_population and self.key in dict_: - return dict_[self.key] - else: - try: - state = instance_state(instance) - except AttributeError as err: - util.raise_( - orm_exc.UnmappedInstanceError(instance), - replace_context=err, - ) - return self.impl.get(state, dict_)</code></pre> -</details> -</dd> -<dt id="sql_app.models.BodyDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt> +<dt id="sql_app.models.BodyDevice.comment"><code class="name">var <span class="ident">comment</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -295,48 +308,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -</dl> -</dd> -<dt id="sql_app.models.Device"><code class="flex name class"> -<span>class <span class="ident">Device</span></span> -<span>(</span><span>**kwargs)</span> -</code></dt> -<dd> -<div class="desc"><p>Class defining database table devices</p> -<p>A simple constructor that allows initialization from kwargs.</p> -<p>Sets attributes on the constructed instance using the names and -values in <code>kwargs</code>.</p> -<p>Only keys that are present as -attributes of the instance's class are allowed. These could be, -for example, any mapped columns or relationships.</p></div> -<details class="source"> -<summary> -<span>Expand source code</span> -</summary> -<pre><code class="python">class Device(Base): - """ - Class defining database table devices - """ - __tablename__ = "devices" - - id = Column(Integer, primary_key=True, index=True) - vendor_id = Column(String, index=True, nullable=False) - product_id = Column(String, index=True, nullable=False) - serial_number = Column(String, index=True, nullable=False) - assigned = Column(Boolean, index=True, nullable=False) - - # relationships for foreign keys, thus connecting table with usb_logs and licenses - # tables - logs = relationship("USBLog", back_populates="device") - licenses = relationship("DeviceLicense", back_populates="device_lic")</code></pre> -</details> -<h3>Ancestors</h3> -<ul class="hlist"> -<li>sqlalchemy.orm.decl_api.Base</li> -</ul> -<h3>Instance variables</h3> -<dl> -<dt id="sql_app.models.Device.assigned"><code class="name">var <span class="ident">assigned</span></code></dt> +<dt id="sql_app.models.BodyDevice.id"><code class="name">var <span class="ident">id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -361,7 +333,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Device.id"><code class="name">var <span class="ident">id</span></code></dt> +<dt id="sql_app.models.BodyDevice.inventory_number"><code class="name">var <span class="ident">inventory_number</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -386,7 +358,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Device.licenses"><code class="name">var <span class="ident">licenses</span></code></dt> +<dt id="sql_app.models.BodyDevice.license"><code class="name">var <span class="ident">license</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -411,7 +383,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Device.logs"><code class="name">var <span class="ident">logs</span></code></dt> +<dt id="sql_app.models.BodyDevice.license_id"><code class="name">var <span class="ident">license_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -436,7 +408,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Device.product_id"><code class="name">var <span class="ident">product_id</span></code></dt> +<dt id="sql_app.models.BodyDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -461,7 +433,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Device.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt> +<dt id="sql_app.models.BodyDevice.team"><code class="name">var <span class="ident">team</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -486,7 +458,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Device.vendor_id"><code class="name">var <span class="ident">vendor_id</span></code></dt> +<dt id="sql_app.models.BodyDevice.team_id"><code class="name">var <span class="ident">team_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -513,12 +485,12 @@ for example, any mapped columns or relationships.</p></div> </dd> </dl> </dd> -<dt id="sql_app.models.DeviceLicense"><code class="flex name class"> -<span>class <span class="ident">DeviceLicense</span></span> +<dt id="sql_app.models.Device"><code class="flex name class"> +<span>class <span class="ident">Device</span></span> <span>(</span><span>**kwargs)</span> </code></dt> <dd> -<div class="desc"><p>Class defining database table devices_licenses</p> +<div class="desc"><p>Class defining database table devices</p> <p>A simple constructor that allows initialization from kwargs.</p> <p>Sets attributes on the constructed instance using the names and values in <code>kwargs</code>.</p> @@ -529,21 +501,26 @@ for example, any mapped columns or relationships.</p></div> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">class DeviceLicense(Base): +<pre><code class="python">class Device(Base): """ - Class defining database table devices_licenses + Class defining database table devices """ - __tablename__ = "devices_licenses" + __tablename__ = "devices" id = Column(Integer, primary_key=True, index=True) - device_id = Column(Integer, ForeignKey("devices.id")) - license_id = Column(Integer, ForeignKey("licenses.id")) - assigned_datetime = Column(String, index=True, nullable=False) + vendor_id = Column(String, index=True, nullable=False) + product_id = Column(String, index=True, nullable=False) + serial_number = Column(String, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) - # relationships for foreign keys, thus connecting table with devices and licenses + team_id = Column(Integer, ForeignKey("teams.id")) + + # relationships for foreign keys, thus connecting table with usb_logs and licenses # tables - device_lic = relationship("Device", back_populates="licenses") - licenses = relationship("License", back_populates="devices")</code></pre> + logs = relationship("USBLog", back_populates="device") + licenses = relationship("DeviceLicense", back_populates="device_lic") + team = relationship("Team", back_populates="devices")</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -551,7 +528,7 @@ for example, any mapped columns or relationships.</p></div> </ul> <h3>Instance variables</h3> <dl> -<dt id="sql_app.models.DeviceLicense.assigned_datetime"><code class="name">var <span class="ident">assigned_datetime</span></code></dt> +<dt id="sql_app.models.Device.comment"><code class="name">var <span class="ident">comment</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -576,7 +553,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.DeviceLicense.device_id"><code class="name">var <span class="ident">device_id</span></code></dt> +<dt id="sql_app.models.Device.id"><code class="name">var <span class="ident">id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -601,7 +578,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.DeviceLicense.device_lic"><code class="name">var <span class="ident">device_lic</span></code></dt> +<dt id="sql_app.models.Device.inventory_number"><code class="name">var <span class="ident">inventory_number</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -626,7 +603,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.DeviceLicense.id"><code class="name">var <span class="ident">id</span></code></dt> +<dt id="sql_app.models.Device.licenses"><code class="name">var <span class="ident">licenses</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -651,7 +628,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.DeviceLicense.license_id"><code class="name">var <span class="ident">license_id</span></code></dt> +<dt id="sql_app.models.Device.logs"><code class="name">var <span class="ident">logs</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -676,7 +653,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.DeviceLicense.licenses"><code class="name">var <span class="ident">licenses</span></code></dt> +<dt id="sql_app.models.Device.product_id"><code class="name">var <span class="ident">product_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -701,43 +678,32 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -</dl> -</dd> -<dt id="sql_app.models.HeadDevice"><code class="flex name class"> -<span>class <span class="ident">HeadDevice</span></span> -<span>(</span><span>**kwargs)</span> -</code></dt> +<dt id="sql_app.models.Device.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt> <dd> -<div class="desc"><p>Class defining database table head_devices</p> -<p>A simple constructor that allows initialization from kwargs.</p> -<p>Sets attributes on the constructed instance using the names and -values in <code>kwargs</code>.</p> -<p>Only keys that are present as -attributes of the instance's class are allowed. These could be, -for example, any mapped columns or relationships.</p></div> +<div class="desc"></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">class HeadDevice(Base): - """ - Class defining database table head_devices - """ - __tablename__ = "head_devices" - - id = Column(Integer, primary_key=True, index=True) - serial_number = Column(String, index=True, nullable=False) +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self - # relationships for foreign keys, thus connecting table with ld_logs table - h_logs = relationship("LDLog", back_populates="head_device")</code></pre> + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> </details> -<h3>Ancestors</h3> -<ul class="hlist"> -<li>sqlalchemy.orm.decl_api.Base</li> -</ul> -<h3>Instance variables</h3> -<dl> -<dt id="sql_app.models.HeadDevice.h_logs"><code class="name">var <span class="ident">h_logs</span></code></dt> +</dd> +<dt id="sql_app.models.Device.team"><code class="name">var <span class="ident">team</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -762,7 +728,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.HeadDevice.id"><code class="name">var <span class="ident">id</span></code></dt> +<dt id="sql_app.models.Device.team_id"><code class="name">var <span class="ident">team_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -787,7 +753,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.HeadDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt> +<dt id="sql_app.models.Device.vendor_id"><code class="name">var <span class="ident">vendor_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -814,12 +780,12 @@ for example, any mapped columns or relationships.</p></div> </dd> </dl> </dd> -<dt id="sql_app.models.LDLog"><code class="flex name class"> -<span>class <span class="ident">LDLog</span></span> +<dt id="sql_app.models.DeviceLicense"><code class="flex name class"> +<span>class <span class="ident">DeviceLicense</span></span> <span>(</span><span>**kwargs)</span> </code></dt> <dd> -<div class="desc"><p>Class defining database table ld_logs</p> +<div class="desc"><p>Class defining database table devices_licenses</p> <p>A simple constructor that allows initialization from kwargs.</p> <p>Sets attributes on the constructed instance using the names and values in <code>kwargs</code>.</p> @@ -830,24 +796,21 @@ for example, any mapped columns or relationships.</p></div> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">class LDLog(Base): +<pre><code class="python">class DeviceLicense(Base): """ - Class defining database table ld_logs + Class defining database table devices_licenses """ - __tablename__ = "ld_logs" + __tablename__ = "devices_licenses" id = Column(Integer, primary_key=True, index=True) - pc_id = Column(Integer, ForeignKey("pc.id")) - timestamp = Column(DateTime(timezone=True), server_default=func.now()) - status = Column(String, index=True, nullable=False) - head_id = Column(Integer, ForeignKey("head_devices.id")) - body_id = Column(Integer, ForeignKey("body_devices.id")) + device_id = Column(Integer, ForeignKey("devices.id")) + license_id = Column(Integer, ForeignKey("licenses.id")) + assigned_datetime = Column(String, index=True, nullable=False) - # relationships for foreign keys, thus connecting table with pc, head_devices and body_devices + # relationships for foreign keys, thus connecting table with devices and licenses # tables - ldpc = relationship("PC", back_populates="ld_pc") - head_device = relationship("HeadDevice", back_populates="h_logs") - body_device = relationship("BodyDevice", back_populates="b_logs")</code></pre> + device_lic = relationship("Device", back_populates="licenses") + licenses = relationship("License", back_populates="devices")</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -855,7 +818,7 @@ for example, any mapped columns or relationships.</p></div> </ul> <h3>Instance variables</h3> <dl> -<dt id="sql_app.models.LDLog.body_device"><code class="name">var <span class="ident">body_device</span></code></dt> +<dt id="sql_app.models.DeviceLicense.assigned_datetime"><code class="name">var <span class="ident">assigned_datetime</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -880,7 +843,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.LDLog.body_id"><code class="name">var <span class="ident">body_id</span></code></dt> +<dt id="sql_app.models.DeviceLicense.device_id"><code class="name">var <span class="ident">device_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -905,7 +868,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.LDLog.head_device"><code class="name">var <span class="ident">head_device</span></code></dt> +<dt id="sql_app.models.DeviceLicense.device_lic"><code class="name">var <span class="ident">device_lic</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -930,7 +893,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.LDLog.head_id"><code class="name">var <span class="ident">head_id</span></code></dt> +<dt id="sql_app.models.DeviceLicense.id"><code class="name">var <span class="ident">id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -955,7 +918,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.LDLog.id"><code class="name">var <span class="ident">id</span></code></dt> +<dt id="sql_app.models.DeviceLicense.license_id"><code class="name">var <span class="ident">license_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -980,7 +943,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.LDLog.ldpc"><code class="name">var <span class="ident">ldpc</span></code></dt> +<dt id="sql_app.models.DeviceLicense.licenses"><code class="name">var <span class="ident">licenses</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1005,30 +968,491 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.LDLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt> +</dl> +</dd> +<dt id="sql_app.models.HeadDevice"><code class="flex name class"> +<span>class <span class="ident">HeadDevice</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> <dd> -<div class="desc"></div> +<div class="desc"><p>Class defining database table head_devices</p> +<p>A simple constructor that allows initialization from kwargs.</p> +<p>Sets attributes on the constructed instance using the names and +values in <code>kwargs</code>.</p> +<p>Only keys that are present as +attributes of the instance's class are allowed. These could be, +for example, any mapped columns or relationships.</p></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">def __get__(self, instance, owner): - if instance is None: - return self +<pre><code class="python">class HeadDevice(Base): + """ + Class defining database table head_devices + """ + __tablename__ = "head_devices" - dict_ = instance_dict(instance) - if self._supports_population and self.key in dict_: - return dict_[self.key] - else: - try: - state = instance_state(instance) - except AttributeError as err: - util.raise_( - orm_exc.UnmappedInstanceError(instance), - replace_context=err, - ) - return self.impl.get(state, dict_)</code></pre> -</details> + id = Column(Integer, primary_key=True, index=True) + serial_number = Column(String, index=True, nullable=False) + inventory_number = Column(String, index=True, nullable=True) + comment = Column(String, index=True, nullable=True) + + team_id = Column(Integer, ForeignKey("teams.id")) + license_id = Column(Integer, ForeignKey("licenses.id")) + + # relationships for foreign keys, thus connecting table with ld_logs table + h_logs = relationship("LDLog", back_populates="head_device") + license = relationship("License", back_populates="headdevice_lic") + team = relationship("Team", back_populates="head_devices")</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>sqlalchemy.orm.decl_api.Base</li> +</ul> +<h3>Instance variables</h3> +<dl> +<dt id="sql_app.models.HeadDevice.comment"><code class="name">var <span class="ident">comment</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.h_logs"><code class="name">var <span class="ident">h_logs</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.id"><code class="name">var <span class="ident">id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.inventory_number"><code class="name">var <span class="ident">inventory_number</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.license"><code class="name">var <span class="ident">license</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.license_id"><code class="name">var <span class="ident">license_id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.team"><code class="name">var <span class="ident">team</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.HeadDevice.team_id"><code class="name">var <span class="ident">team_id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +</dl> +</dd> +<dt id="sql_app.models.LDLog"><code class="flex name class"> +<span>class <span class="ident">LDLog</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> +<dd> +<div class="desc"><p>Class defining database table ld_logs</p> +<p>A simple constructor that allows initialization from kwargs.</p> +<p>Sets attributes on the constructed instance using the names and +values in <code>kwargs</code>.</p> +<p>Only keys that are present as +attributes of the instance's class are allowed. These could be, +for example, any mapped columns or relationships.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class LDLog(Base): + """ + Class defining database table ld_logs + """ + __tablename__ = "ld_logs" + + id = Column(Integer, primary_key=True, index=True) + pc_id = Column(Integer, ForeignKey("pc.id")) + timestamp = Column(DateTime(timezone=True), server_default=func.now()) + status = Column(String, index=True, nullable=False) + head_id = Column(Integer, ForeignKey("head_devices.id")) + body_id = Column(Integer, ForeignKey("body_devices.id")) + + # relationships for foreign keys, thus connecting table with pc, head_devices and body_devices + # tables + ldpc = relationship("PC", back_populates="ld_pc") + head_device = relationship("HeadDevice", back_populates="h_logs") + body_device = relationship("BodyDevice", back_populates="b_logs")</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>sqlalchemy.orm.decl_api.Base</li> +</ul> +<h3>Instance variables</h3> +<dl> +<dt id="sql_app.models.LDLog.body_device"><code class="name">var <span class="ident">body_device</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.LDLog.body_id"><code class="name">var <span class="ident">body_id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.LDLog.head_device"><code class="name">var <span class="ident">head_device</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.LDLog.head_id"><code class="name">var <span class="ident">head_id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.LDLog.id"><code class="name">var <span class="ident">id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.LDLog.ldpc"><code class="name">var <span class="ident">ldpc</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.LDLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> </dd> <dt id="sql_app.models.LDLog.status"><code class="name">var <span class="ident">status</span></code></dt> <dd> @@ -1105,19 +1529,72 @@ for example, any mapped columns or relationships.</p></div> __tablename__ = "licenses" id = Column(Integer, primary_key=True, index=True) - name = Column(String, index=True, nullable=False) - expiration_date = Column(DateTime(timezone=True), server_default=func.now()) + name = Column(String, index=True, nullable=True) + license_id = Column(String, index=True, nullable=False) + expiration_date = Column(DateTime(timezone=True), nullable=True) # relationships for foreign keys, thus connecting table with devices table - devices = relationship("DeviceLicense", back_populates="licenses")</code></pre> + devices = relationship("DeviceLicense", back_populates="licenses") + bodydevice_lic = relationship("BodyDevice", back_populates="license") + headdevice_lic = relationship("HeadDevice", back_populates="license")</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>sqlalchemy.orm.decl_api.Base</li> +</ul> +<h3>Instance variables</h3> +<dl> +<dt id="sql_app.models.License.bodydevice_lic"><code class="name">var <span class="ident">bodydevice_lic</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.License.devices"><code class="name">var <span class="ident">devices</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> </details> -<h3>Ancestors</h3> -<ul class="hlist"> -<li>sqlalchemy.orm.decl_api.Base</li> -</ul> -<h3>Instance variables</h3> -<dl> -<dt id="sql_app.models.License.devices"><code class="name">var <span class="ident">devices</span></code></dt> +</dd> +<dt id="sql_app.models.License.expiration_date"><code class="name">var <span class="ident">expiration_date</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1142,7 +1619,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.License.expiration_date"><code class="name">var <span class="ident">expiration_date</span></code></dt> +<dt id="sql_app.models.License.headdevice_lic"><code class="name">var <span class="ident">headdevice_lic</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1192,6 +1669,31 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> +<dt id="sql_app.models.License.license_id"><code class="name">var <span class="ident">license_id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> <dt id="sql_app.models.License.name"><code class="name">var <span class="ident">name</span></code></dt> <dd> <div class="desc"></div> @@ -1244,12 +1746,9 @@ for example, any mapped columns or relationships.</p></div> id = Column(Integer, primary_key=True, index=True) username = Column(String, index=True, nullable=False) hostname = Column(String, index=True, nullable=False) - assigned = Column(Boolean, index=True, nullable=False) - team_id = Column(Integer, ForeignKey("teams.id")) # relationships for foreign keys, thus connecting table with teams, usb_logs and ld_logs # tables - team = relationship("Team", back_populates="pcs") logs_pc = relationship("USBLog", back_populates="pc") ld_pc = relationship("LDLog", back_populates="ldpc")</code></pre> </details> @@ -1259,7 +1758,7 @@ for example, any mapped columns or relationships.</p></div> </ul> <h3>Instance variables</h3> <dl> -<dt id="sql_app.models.PC.assigned"><code class="name">var <span class="ident">assigned</span></code></dt> +<dt id="sql_app.models.PC.hostname"><code class="name">var <span class="ident">hostname</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1284,7 +1783,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.PC.hostname"><code class="name">var <span class="ident">hostname</span></code></dt> +<dt id="sql_app.models.PC.id"><code class="name">var <span class="ident">id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1309,7 +1808,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.PC.id"><code class="name">var <span class="ident">id</span></code></dt> +<dt id="sql_app.models.PC.ld_pc"><code class="name">var <span class="ident">ld_pc</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1334,7 +1833,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.PC.ld_pc"><code class="name">var <span class="ident">ld_pc</span></code></dt> +<dt id="sql_app.models.PC.logs_pc"><code class="name">var <span class="ident">logs_pc</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1359,7 +1858,69 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.PC.logs_pc"><code class="name">var <span class="ident">logs_pc</span></code></dt> +<dt id="sql_app.models.PC.username"><code class="name">var <span class="ident">username</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +</dl> +</dd> +<dt id="sql_app.models.Team"><code class="flex name class"> +<span>class <span class="ident">Team</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> +<dd> +<div class="desc"><p>Class defining database table teams</p> +<p>A simple constructor that allows initialization from kwargs.</p> +<p>Sets attributes on the constructed instance using the names and +values in <code>kwargs</code>.</p> +<p>Only keys that are present as +attributes of the instance's class are allowed. These could be, +for example, any mapped columns or relationships.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class Team(Base): + """ + Class defining database table teams + """ + __tablename__ = "teams" + + id = Column(Integer, primary_key=True, index=True) + name = Column(String, index=True, nullable=False) + + devices = relationship("Device", back_populates="team") + body_devices = relationship("BodyDevice", back_populates="team") + head_devices = relationship("HeadDevice", back_populates="team")</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>sqlalchemy.orm.decl_api.Base</li> +</ul> +<h3>Instance variables</h3> +<dl> +<dt id="sql_app.models.Team.body_devices"><code class="name">var <span class="ident">body_devices</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1384,7 +1945,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.PC.team"><code class="name">var <span class="ident">team</span></code></dt> +<dt id="sql_app.models.Team.devices"><code class="name">var <span class="ident">devices</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1409,7 +1970,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.PC.team_id"><code class="name">var <span class="ident">team_id</span></code></dt> +<dt id="sql_app.models.Team.head_devices"><code class="name">var <span class="ident">head_devices</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1434,7 +1995,32 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.PC.username"><code class="name">var <span class="ident">username</span></code></dt> +<dt id="sql_app.models.Team.id"><code class="name">var <span class="ident">id</span></code></dt> +<dd> +<div class="desc"></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self + + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> +</details> +</dd> +<dt id="sql_app.models.Team.name"><code class="name">var <span class="ident">name</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1461,12 +2047,12 @@ for example, any mapped columns or relationships.</p></div> </dd> </dl> </dd> -<dt id="sql_app.models.Team"><code class="flex name class"> -<span>class <span class="ident">Team</span></span> +<dt id="sql_app.models.USBLog"><code class="flex name class"> +<span>class <span class="ident">USBLog</span></span> <span>(</span><span>**kwargs)</span> </code></dt> <dd> -<div class="desc"><p>Class defining database table teams</p> +<div class="desc"><p>Class defining database table usb_logs</p> <p>A simple constructor that allows initialization from kwargs.</p> <p>Sets attributes on the constructed instance using the names and values in <code>kwargs</code>.</p> @@ -1477,17 +2063,22 @@ for example, any mapped columns or relationships.</p></div> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">class Team(Base): +<pre><code class="python">class USBLog(Base): """ - Class defining database table teams + Class defining database table usb_logs """ - __tablename__ = "teams" + __tablename__ = "usb_logs" id = Column(Integer, primary_key=True, index=True) - name = Column(String, index=True, nullable=False) + pc_id = Column(Integer, ForeignKey("pc.id")) + timestamp = Column(DateTime(timezone=True), server_default=func.now()) + status = Column(String, index=True, nullable=False) + device_id = Column(Integer, ForeignKey("devices.id")) - # relationships for foreign keys, thus connecting table with pc table - pcs = relationship("PC", back_populates="team")</code></pre> + # relationships for foreign keys, thus connecting table with devices and pc + # tables + device = relationship("Device", back_populates="logs") + pc = relationship("PC", back_populates="logs_pc")</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -1495,7 +2086,7 @@ for example, any mapped columns or relationships.</p></div> </ul> <h3>Instance variables</h3> <dl> -<dt id="sql_app.models.Team.id"><code class="name">var <span class="ident">id</span></code></dt> +<dt id="sql_app.models.USBLog.device"><code class="name">var <span class="ident">device</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1520,7 +2111,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Team.name"><code class="name">var <span class="ident">name</span></code></dt> +<dt id="sql_app.models.USBLog.device_id"><code class="name">var <span class="ident">device_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1545,7 +2136,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.Team.pcs"><code class="name">var <span class="ident">pcs</span></code></dt> +<dt id="sql_app.models.USBLog.id"><code class="name">var <span class="ident">id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1570,48 +2161,32 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -</dl> -</dd> -<dt id="sql_app.models.USBLog"><code class="flex name class"> -<span>class <span class="ident">USBLog</span></span> -<span>(</span><span>**kwargs)</span> -</code></dt> +<dt id="sql_app.models.USBLog.pc"><code class="name">var <span class="ident">pc</span></code></dt> <dd> -<div class="desc"><p>Class defining database table usb_logs</p> -<p>A simple constructor that allows initialization from kwargs.</p> -<p>Sets attributes on the constructed instance using the names and -values in <code>kwargs</code>.</p> -<p>Only keys that are present as -attributes of the instance's class are allowed. These could be, -for example, any mapped columns or relationships.</p></div> +<div class="desc"></div> <details class="source"> <summary> <span>Expand source code</span> </summary> -<pre><code class="python">class USBLog(Base): - """ - Class defining database table usb_logs - """ - __tablename__ = "usb_logs" - - id = Column(Integer, primary_key=True, index=True) - pc_id = Column(Integer, ForeignKey("pc.id")) - timestamp = Column(DateTime(timezone=True), server_default=func.now()) - status = Column(String, index=True, nullable=False) - device_id = Column(Integer, ForeignKey("devices.id")) +<pre><code class="python">def __get__(self, instance, owner): + if instance is None: + return self - # relationships for foreign keys, thus connecting table with devices and pc - # tables - device = relationship("Device", back_populates="logs") - pc = relationship("PC", back_populates="logs_pc")</code></pre> + dict_ = instance_dict(instance) + if self._supports_population and self.key in dict_: + return dict_[self.key] + else: + try: + state = instance_state(instance) + except AttributeError as err: + util.raise_( + orm_exc.UnmappedInstanceError(instance), + replace_context=err, + ) + return self.impl.get(state, dict_)</code></pre> </details> -<h3>Ancestors</h3> -<ul class="hlist"> -<li>sqlalchemy.orm.decl_api.Base</li> -</ul> -<h3>Instance variables</h3> -<dl> -<dt id="sql_app.models.USBLog.device"><code class="name">var <span class="ident">device</span></code></dt> +</dd> +<dt id="sql_app.models.USBLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1636,7 +2211,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.USBLog.device_id"><code class="name">var <span class="ident">device_id</span></code></dt> +<dt id="sql_app.models.USBLog.status"><code class="name">var <span class="ident">status</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1661,7 +2236,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.USBLog.id"><code class="name">var <span class="ident">id</span></code></dt> +<dt id="sql_app.models.USBLog.timestamp"><code class="name">var <span class="ident">timestamp</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1686,7 +2261,42 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.USBLog.pc"><code class="name">var <span class="ident">pc</span></code></dt> +</dl> +</dd> +<dt id="sql_app.models.User"><code class="flex name class"> +<span>class <span class="ident">User</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> +<dd> +<div class="desc"><p>Class defining user in database with its own role</p> +<p>A simple constructor that allows initialization from kwargs.</p> +<p>Sets attributes on the constructed instance using the names and +values in <code>kwargs</code>.</p> +<p>Only keys that are present as +attributes of the instance's class are allowed. These could be, +for example, any mapped columns or relationships.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class User(Base): + """ + Class defining user in database with its own role + """ + __tablename__ = "users" + + id = Column(Integer, primary_key=True, index=True) + username = Column(String, index=True, nullable=False) + password = Column(String, index=True, nullable=False) + role = Column(String, index=True, nullable=False)</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>sqlalchemy.orm.decl_api.Base</li> +</ul> +<h3>Instance variables</h3> +<dl> +<dt id="sql_app.models.User.id"><code class="name">var <span class="ident">id</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1711,7 +2321,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.USBLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt> +<dt id="sql_app.models.User.password"><code class="name">var <span class="ident">password</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1736,7 +2346,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.USBLog.status"><code class="name">var <span class="ident">status</span></code></dt> +<dt id="sql_app.models.User.role"><code class="name">var <span class="ident">role</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1761,7 +2371,7 @@ for example, any mapped columns or relationships.</p></div> return self.impl.get(state, dict_)</code></pre> </details> </dd> -<dt id="sql_app.models.USBLog.timestamp"><code class="name">var <span class="ident">timestamp</span></code></dt> +<dt id="sql_app.models.User.username"><code class="name">var <span class="ident">username</span></code></dt> <dd> <div class="desc"></div> <details class="source"> @@ -1806,21 +2416,30 @@ for example, any mapped columns or relationships.</p></div> <ul> <li> <h4><code><a title="sql_app.models.BodyDevice" href="#sql_app.models.BodyDevice">BodyDevice</a></code></h4> -<ul class=""> +<ul class="two-column"> <li><code><a title="sql_app.models.BodyDevice.b_logs" href="#sql_app.models.BodyDevice.b_logs">b_logs</a></code></li> +<li><code><a title="sql_app.models.BodyDevice.comment" href="#sql_app.models.BodyDevice.comment">comment</a></code></li> <li><code><a title="sql_app.models.BodyDevice.id" href="#sql_app.models.BodyDevice.id">id</a></code></li> +<li><code><a title="sql_app.models.BodyDevice.inventory_number" href="#sql_app.models.BodyDevice.inventory_number">inventory_number</a></code></li> +<li><code><a title="sql_app.models.BodyDevice.license" href="#sql_app.models.BodyDevice.license">license</a></code></li> +<li><code><a title="sql_app.models.BodyDevice.license_id" href="#sql_app.models.BodyDevice.license_id">license_id</a></code></li> <li><code><a title="sql_app.models.BodyDevice.serial_number" href="#sql_app.models.BodyDevice.serial_number">serial_number</a></code></li> +<li><code><a title="sql_app.models.BodyDevice.team" href="#sql_app.models.BodyDevice.team">team</a></code></li> +<li><code><a title="sql_app.models.BodyDevice.team_id" href="#sql_app.models.BodyDevice.team_id">team_id</a></code></li> </ul> </li> <li> <h4><code><a title="sql_app.models.Device" href="#sql_app.models.Device">Device</a></code></h4> <ul class="two-column"> -<li><code><a title="sql_app.models.Device.assigned" href="#sql_app.models.Device.assigned">assigned</a></code></li> +<li><code><a title="sql_app.models.Device.comment" href="#sql_app.models.Device.comment">comment</a></code></li> <li><code><a title="sql_app.models.Device.id" href="#sql_app.models.Device.id">id</a></code></li> +<li><code><a title="sql_app.models.Device.inventory_number" href="#sql_app.models.Device.inventory_number">inventory_number</a></code></li> <li><code><a title="sql_app.models.Device.licenses" href="#sql_app.models.Device.licenses">licenses</a></code></li> <li><code><a title="sql_app.models.Device.logs" href="#sql_app.models.Device.logs">logs</a></code></li> <li><code><a title="sql_app.models.Device.product_id" href="#sql_app.models.Device.product_id">product_id</a></code></li> <li><code><a title="sql_app.models.Device.serial_number" href="#sql_app.models.Device.serial_number">serial_number</a></code></li> +<li><code><a title="sql_app.models.Device.team" href="#sql_app.models.Device.team">team</a></code></li> +<li><code><a title="sql_app.models.Device.team_id" href="#sql_app.models.Device.team_id">team_id</a></code></li> <li><code><a title="sql_app.models.Device.vendor_id" href="#sql_app.models.Device.vendor_id">vendor_id</a></code></li> </ul> </li> @@ -1837,10 +2456,16 @@ for example, any mapped columns or relationships.</p></div> </li> <li> <h4><code><a title="sql_app.models.HeadDevice" href="#sql_app.models.HeadDevice">HeadDevice</a></code></h4> -<ul class=""> +<ul class="two-column"> +<li><code><a title="sql_app.models.HeadDevice.comment" href="#sql_app.models.HeadDevice.comment">comment</a></code></li> <li><code><a title="sql_app.models.HeadDevice.h_logs" href="#sql_app.models.HeadDevice.h_logs">h_logs</a></code></li> <li><code><a title="sql_app.models.HeadDevice.id" href="#sql_app.models.HeadDevice.id">id</a></code></li> +<li><code><a title="sql_app.models.HeadDevice.inventory_number" href="#sql_app.models.HeadDevice.inventory_number">inventory_number</a></code></li> +<li><code><a title="sql_app.models.HeadDevice.license" href="#sql_app.models.HeadDevice.license">license</a></code></li> +<li><code><a title="sql_app.models.HeadDevice.license_id" href="#sql_app.models.HeadDevice.license_id">license_id</a></code></li> <li><code><a title="sql_app.models.HeadDevice.serial_number" href="#sql_app.models.HeadDevice.serial_number">serial_number</a></code></li> +<li><code><a title="sql_app.models.HeadDevice.team" href="#sql_app.models.HeadDevice.team">team</a></code></li> +<li><code><a title="sql_app.models.HeadDevice.team_id" href="#sql_app.models.HeadDevice.team_id">team_id</a></code></li> </ul> </li> <li> @@ -1859,32 +2484,34 @@ for example, any mapped columns or relationships.</p></div> </li> <li> <h4><code><a title="sql_app.models.License" href="#sql_app.models.License">License</a></code></h4> -<ul class=""> +<ul class="two-column"> +<li><code><a title="sql_app.models.License.bodydevice_lic" href="#sql_app.models.License.bodydevice_lic">bodydevice_lic</a></code></li> <li><code><a title="sql_app.models.License.devices" href="#sql_app.models.License.devices">devices</a></code></li> <li><code><a title="sql_app.models.License.expiration_date" href="#sql_app.models.License.expiration_date">expiration_date</a></code></li> +<li><code><a title="sql_app.models.License.headdevice_lic" href="#sql_app.models.License.headdevice_lic">headdevice_lic</a></code></li> <li><code><a title="sql_app.models.License.id" href="#sql_app.models.License.id">id</a></code></li> +<li><code><a title="sql_app.models.License.license_id" href="#sql_app.models.License.license_id">license_id</a></code></li> <li><code><a title="sql_app.models.License.name" href="#sql_app.models.License.name">name</a></code></li> </ul> </li> <li> <h4><code><a title="sql_app.models.PC" href="#sql_app.models.PC">PC</a></code></h4> -<ul class="two-column"> -<li><code><a title="sql_app.models.PC.assigned" href="#sql_app.models.PC.assigned">assigned</a></code></li> +<ul class=""> <li><code><a title="sql_app.models.PC.hostname" href="#sql_app.models.PC.hostname">hostname</a></code></li> <li><code><a title="sql_app.models.PC.id" href="#sql_app.models.PC.id">id</a></code></li> <li><code><a title="sql_app.models.PC.ld_pc" href="#sql_app.models.PC.ld_pc">ld_pc</a></code></li> <li><code><a title="sql_app.models.PC.logs_pc" href="#sql_app.models.PC.logs_pc">logs_pc</a></code></li> -<li><code><a title="sql_app.models.PC.team" href="#sql_app.models.PC.team">team</a></code></li> -<li><code><a title="sql_app.models.PC.team_id" href="#sql_app.models.PC.team_id">team_id</a></code></li> <li><code><a title="sql_app.models.PC.username" href="#sql_app.models.PC.username">username</a></code></li> </ul> </li> <li> <h4><code><a title="sql_app.models.Team" href="#sql_app.models.Team">Team</a></code></h4> <ul class=""> +<li><code><a title="sql_app.models.Team.body_devices" href="#sql_app.models.Team.body_devices">body_devices</a></code></li> +<li><code><a title="sql_app.models.Team.devices" href="#sql_app.models.Team.devices">devices</a></code></li> +<li><code><a title="sql_app.models.Team.head_devices" href="#sql_app.models.Team.head_devices">head_devices</a></code></li> <li><code><a title="sql_app.models.Team.id" href="#sql_app.models.Team.id">id</a></code></li> <li><code><a title="sql_app.models.Team.name" href="#sql_app.models.Team.name">name</a></code></li> -<li><code><a title="sql_app.models.Team.pcs" href="#sql_app.models.Team.pcs">pcs</a></code></li> </ul> </li> <li> @@ -1899,6 +2526,15 @@ for example, any mapped columns or relationships.</p></div> <li><code><a title="sql_app.models.USBLog.timestamp" href="#sql_app.models.USBLog.timestamp">timestamp</a></code></li> </ul> </li> +<li> +<h4><code><a title="sql_app.models.User" href="#sql_app.models.User">User</a></code></h4> +<ul class=""> +<li><code><a title="sql_app.models.User.id" href="#sql_app.models.User.id">id</a></code></li> +<li><code><a title="sql_app.models.User.password" href="#sql_app.models.User.password">password</a></code></li> +<li><code><a title="sql_app.models.User.role" href="#sql_app.models.User.role">role</a></code></li> +<li><code><a title="sql_app.models.User.username" href="#sql_app.models.User.username">username</a></code></li> +</ul> +</li> </ul> </li> </ul> diff --git a/server/doc/sql_app/schemas.html b/server/doc/sql_app/schemas.html index ffeb06a..d37e2ed 100644 --- a/server/doc/sql_app/schemas.html +++ b/server/doc/sql_app/schemas.html @@ -76,6 +76,8 @@ class DeviceBase(BaseModel): vendor_id: str product_id: str serial_number: str + inventory_number: str + comment: str class DeviceCreate(DeviceBase): @@ -87,7 +89,6 @@ class Device(DeviceCreate): Class used for creating and reading devices entries """ id: int - assigned: bool logs: List[USBLog] = [] licenses: List[DeviceLicense] = [] @@ -95,6 +96,15 @@ class Device(DeviceCreate): orm_mode = True +class DeviceTemp(BaseModel): + """ + Class used for reading data from client + """ + vendor_id: str + product_id: str + serial_number: str + + class LDLogBase(BaseModel): timestamp: datetime status: str @@ -118,6 +128,8 @@ class LDLog(LDLogCreate): class BodyDeviceBase(BaseModel): serial_number: str + inventory_number: str + comment: str class BodyDeviceCreate(BodyDeviceBase): @@ -135,8 +147,17 @@ class BodyDevice(BodyDeviceCreate): orm_mode = True +class BodyDeviceTemp(BaseModel): + """ + Class used for reading body device data from client + """ + serial_number: str + + class HeadDeviceBase(BaseModel): serial_number: str + inventory_number: str + comment: str class HeadDeviceCreate(HeadDeviceBase): @@ -154,6 +175,13 @@ class HeadDevice(HeadDeviceCreate): orm_mode = True +class HeadDeviceTemp(BaseModel): + """ + Class used for reading head device data from client + """ + serial_number: str + + class PCBase(BaseModel): username: str hostname: str @@ -168,8 +196,8 @@ class PC(PCCreate): Class used for creating and reading pc entries """ id: int - assigned: bool logs_pc: List[USBLog] = [] + logs_ld: List[LDLog] = [] class Config: orm_mode = True @@ -188,7 +216,7 @@ class Team(TeamCreate): Class used for creating and reading team entries """ id: int - pcs: List[PC] = [] + devices: List[Device] = [] class Config: orm_mode = True @@ -196,6 +224,7 @@ class Team(TeamCreate): class LicenseBase(BaseModel): name: str + license_id: str expiration_date: date @@ -209,6 +238,8 @@ class License(LicenseCreate): """ id: int devices: List[DeviceLicense] = [] + head_devices: List[HeadDevice] = [] + body_devices: List[BodyDevice] = [] class Config: orm_mode = True @@ -221,7 +252,7 @@ class USBTempBase(BaseModel): username: str hostname: str timestamp: str - device: DeviceBase + device: DeviceTemp status: str @@ -244,8 +275,8 @@ class LDTempBase(BaseModel): username: str hostname: str timestamp: str - head_device: HeadDeviceBase - body_device: BodyDeviceBase + head_device: HeadDeviceTemp + body_device: BodyDeviceTemp status: str @@ -258,6 +289,26 @@ class LDTemp(LDTempCreate): head_id: int body_id: int + class Config: + orm_mode = True + + +class UserBase(BaseModel): + """ + Classes used for creating new User entry + """ + username: str + password: str + role: str + + +class UserCreate(UserBase): + pass + + +class User(UserCreate): + id: int + class Config: orm_mode = True</code></pre> </details> @@ -300,6 +351,11 @@ class LDTemp(LDTempCreate): <li>pydantic.main.BaseModel</li> <li>pydantic.utils.Representation</li> </ul> +<h3>Subclasses</h3> +<ul class="hlist"> +<li>pydantic.main.BodyDevice</li> +<li>pydantic.main.BodyDevice</li> +</ul> <h3>Class variables</h3> <dl> <dt id="sql_app.schemas.BodyDevice.Config"><code class="name">var <span class="ident">Config</span></code></dt> @@ -328,7 +384,9 @@ class LDTemp(LDTempCreate): <span>Expand source code</span> </summary> <pre><code class="python">class BodyDeviceBase(BaseModel): - serial_number: str</code></pre> + serial_number: str + inventory_number: str + comment: str</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -341,6 +399,14 @@ class LDTemp(LDTempCreate): </ul> <h3>Class variables</h3> <dl> +<dt id="sql_app.schemas.BodyDeviceBase.comment"><code class="name">var <span class="ident">comment</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.BodyDeviceBase.inventory_number"><code class="name">var <span class="ident">inventory_number</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> <dt id="sql_app.schemas.BodyDeviceBase.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt> <dd> <div class="desc"></div> @@ -372,6 +438,37 @@ class LDTemp(LDTempCreate): <li><a title="sql_app.schemas.BodyDevice" href="#sql_app.schemas.BodyDevice">BodyDevice</a></li> </ul> </dd> +<dt id="sql_app.schemas.BodyDeviceTemp"><code class="flex name class"> +<span>class <span class="ident">BodyDeviceTemp</span></span> +<span>(</span><span>**data: Any)</span> +</code></dt> +<dd> +<div class="desc"><p>Class used for reading body device data from client</p> +<p>Create a new model by parsing and validating input data from keyword arguments.</p> +<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class BodyDeviceTemp(BaseModel): + """ + Class used for reading body device data from client + """ + serial_number: str</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>pydantic.main.BaseModel</li> +<li>pydantic.utils.Representation</li> +</ul> +<h3>Class variables</h3> +<dl> +<dt id="sql_app.schemas.BodyDeviceTemp.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +</dl> +</dd> <dt id="sql_app.schemas.Device"><code class="flex name class"> <span>class <span class="ident">Device</span></span> <span>(</span><span>**data: Any)</span> @@ -389,7 +486,6 @@ class LDTemp(LDTempCreate): Class used for creating and reading devices entries """ id: int - assigned: bool logs: List[USBLog] = [] licenses: List[DeviceLicense] = [] @@ -415,6 +511,8 @@ class LDTemp(LDTempCreate): <li>pydantic.main.Device</li> <li>pydantic.main.Device</li> <li>pydantic.main.Device</li> +<li>pydantic.main.Device</li> +<li>pydantic.main.Device</li> </ul> <h3>Class variables</h3> <dl> @@ -422,10 +520,6 @@ class LDTemp(LDTempCreate): <dd> <div class="desc"></div> </dd> -<dt id="sql_app.schemas.Device.assigned"><code class="name">var <span class="ident">assigned</span> : bool</code></dt> -<dd> -<div class="desc"></div> -</dd> <dt id="sql_app.schemas.Device.id"><code class="name">var <span class="ident">id</span> : int</code></dt> <dd> <div class="desc"></div> @@ -454,7 +548,9 @@ class LDTemp(LDTempCreate): <pre><code class="python">class DeviceBase(BaseModel): vendor_id: str product_id: str - serial_number: str</code></pre> + serial_number: str + inventory_number: str + comment: str</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -467,6 +563,14 @@ class LDTemp(LDTempCreate): </ul> <h3>Class variables</h3> <dl> +<dt id="sql_app.schemas.DeviceBase.comment"><code class="name">var <span class="ident">comment</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.DeviceBase.inventory_number"><code class="name">var <span class="ident">inventory_number</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> <dt id="sql_app.schemas.DeviceBase.product_id"><code class="name">var <span class="ident">product_id</span> : str</code></dt> <dd> <div class="desc"></div> @@ -550,6 +654,8 @@ class LDTemp(LDTempCreate): <li>pydantic.main.DeviceLicense</li> <li>pydantic.main.DeviceLicense</li> <li>pydantic.main.DeviceLicense</li> +<li>pydantic.main.DeviceLicense</li> +<li>pydantic.main.DeviceLicense</li> </ul> <h3>Class variables</h3> <dl> @@ -629,6 +735,47 @@ class LDTemp(LDTempCreate): <li><a title="sql_app.schemas.DeviceLicense" href="#sql_app.schemas.DeviceLicense">DeviceLicense</a></li> </ul> </dd> +<dt id="sql_app.schemas.DeviceTemp"><code class="flex name class"> +<span>class <span class="ident">DeviceTemp</span></span> +<span>(</span><span>**data: Any)</span> +</code></dt> +<dd> +<div class="desc"><p>Class used for reading data from client</p> +<p>Create a new model by parsing and validating input data from keyword arguments.</p> +<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class DeviceTemp(BaseModel): + """ + Class used for reading data from client + """ + vendor_id: str + product_id: str + serial_number: str</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>pydantic.main.BaseModel</li> +<li>pydantic.utils.Representation</li> +</ul> +<h3>Class variables</h3> +<dl> +<dt id="sql_app.schemas.DeviceTemp.product_id"><code class="name">var <span class="ident">product_id</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.DeviceTemp.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.DeviceTemp.vendor_id"><code class="name">var <span class="ident">vendor_id</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +</dl> +</dd> <dt id="sql_app.schemas.HeadDevice"><code class="flex name class"> <span>class <span class="ident">HeadDevice</span></span> <span>(</span><span>**data: Any)</span> @@ -658,6 +805,11 @@ class LDTemp(LDTempCreate): <li>pydantic.main.BaseModel</li> <li>pydantic.utils.Representation</li> </ul> +<h3>Subclasses</h3> +<ul class="hlist"> +<li>pydantic.main.HeadDevice</li> +<li>pydantic.main.HeadDevice</li> +</ul> <h3>Class variables</h3> <dl> <dt id="sql_app.schemas.HeadDevice.Config"><code class="name">var <span class="ident">Config</span></code></dt> @@ -686,7 +838,9 @@ class LDTemp(LDTempCreate): <span>Expand source code</span> </summary> <pre><code class="python">class HeadDeviceBase(BaseModel): - serial_number: str</code></pre> + serial_number: str + inventory_number: str + comment: str</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -699,6 +853,14 @@ class LDTemp(LDTempCreate): </ul> <h3>Class variables</h3> <dl> +<dt id="sql_app.schemas.HeadDeviceBase.comment"><code class="name">var <span class="ident">comment</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.HeadDeviceBase.inventory_number"><code class="name">var <span class="ident">inventory_number</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> <dt id="sql_app.schemas.HeadDeviceBase.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt> <dd> <div class="desc"></div> @@ -730,6 +892,37 @@ class LDTemp(LDTempCreate): <li><a title="sql_app.schemas.HeadDevice" href="#sql_app.schemas.HeadDevice">HeadDevice</a></li> </ul> </dd> +<dt id="sql_app.schemas.HeadDeviceTemp"><code class="flex name class"> +<span>class <span class="ident">HeadDeviceTemp</span></span> +<span>(</span><span>**data: Any)</span> +</code></dt> +<dd> +<div class="desc"><p>Class used for reading head device data from client</p> +<p>Create a new model by parsing and validating input data from keyword arguments.</p> +<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class HeadDeviceTemp(BaseModel): + """ + Class used for reading head device data from client + """ + serial_number: str</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>pydantic.main.BaseModel</li> +<li>pydantic.utils.Representation</li> +</ul> +<h3>Class variables</h3> +<dl> +<dt id="sql_app.schemas.HeadDeviceTemp.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +</dl> +</dd> <dt id="sql_app.schemas.LDLog"><code class="flex name class"> <span>class <span class="ident">LDLog</span></span> <span>(</span><span>**data: Any)</span> @@ -764,6 +957,14 @@ class LDTemp(LDTempCreate): <ul class="hlist"> <li>pydantic.main.LDLog</li> <li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> +<li>pydantic.main.LDLog</li> </ul> <h3>Class variables</h3> <dl> @@ -912,8 +1113,8 @@ class LDTemp(LDTempCreate): username: str hostname: str timestamp: str - head_device: HeadDeviceBase - body_device: BodyDeviceBase + head_device: HeadDeviceTemp + body_device: BodyDeviceTemp status: str</code></pre> </details> <h3>Ancestors</h3> @@ -927,11 +1128,11 @@ class LDTemp(LDTempCreate): </ul> <h3>Class variables</h3> <dl> -<dt id="sql_app.schemas.LDTempBase.body_device"><code class="name">var <span class="ident">body_device</span> : <a title="sql_app.schemas.BodyDeviceBase" href="#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a></code></dt> +<dt id="sql_app.schemas.LDTempBase.body_device"><code class="name">var <span class="ident">body_device</span> : <a title="sql_app.schemas.BodyDeviceTemp" href="#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a></code></dt> <dd> <div class="desc"></div> </dd> -<dt id="sql_app.schemas.LDTempBase.head_device"><code class="name">var <span class="ident">head_device</span> : <a title="sql_app.schemas.HeadDeviceBase" href="#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a></code></dt> +<dt id="sql_app.schemas.LDTempBase.head_device"><code class="name">var <span class="ident">head_device</span> : <a title="sql_app.schemas.HeadDeviceTemp" href="#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a></code></dt> <dd> <div class="desc"></div> </dd> @@ -997,6 +1198,8 @@ class LDTemp(LDTempCreate): """ id: int devices: List[DeviceLicense] = [] + head_devices: List[HeadDevice] = [] + body_devices: List[BodyDevice] = [] class Config: orm_mode = True</code></pre> @@ -1019,10 +1222,18 @@ class LDTemp(LDTempCreate): <dd> <div class="desc"></div> </dd> +<dt id="sql_app.schemas.License.body_devices"><code class="name">var <span class="ident">body_devices</span> : List[<a title="sql_app.schemas.BodyDevice" href="#sql_app.schemas.BodyDevice">BodyDevice</a>]</code></dt> +<dd> +<div class="desc"></div> +</dd> <dt id="sql_app.schemas.License.devices"><code class="name">var <span class="ident">devices</span> : List[<a title="sql_app.schemas.DeviceLicense" href="#sql_app.schemas.DeviceLicense">DeviceLicense</a>]</code></dt> <dd> <div class="desc"></div> </dd> +<dt id="sql_app.schemas.License.head_devices"><code class="name">var <span class="ident">head_devices</span> : List[<a title="sql_app.schemas.HeadDevice" href="#sql_app.schemas.HeadDevice">HeadDevice</a>]</code></dt> +<dd> +<div class="desc"></div> +</dd> <dt id="sql_app.schemas.License.id"><code class="name">var <span class="ident">id</span> : int</code></dt> <dd> <div class="desc"></div> @@ -1042,6 +1253,7 @@ class LDTemp(LDTempCreate): </summary> <pre><code class="python">class LicenseBase(BaseModel): name: str + license_id: str expiration_date: date</code></pre> </details> <h3>Ancestors</h3> @@ -1059,6 +1271,10 @@ class LDTemp(LDTempCreate): <dd> <div class="desc"></div> </dd> +<dt id="sql_app.schemas.LicenseBase.license_id"><code class="name">var <span class="ident">license_id</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> <dt id="sql_app.schemas.LicenseBase.name"><code class="name">var <span class="ident">name</span> : str</code></dt> <dd> <div class="desc"></div> @@ -1107,8 +1323,8 @@ class LDTemp(LDTempCreate): Class used for creating and reading pc entries """ id: int - assigned: bool logs_pc: List[USBLog] = [] + logs_ld: List[LDLog] = [] class Config: orm_mode = True</code></pre> @@ -1128,8 +1344,6 @@ class LDTemp(LDTempCreate): <li>pydantic.main.PC</li> <li>pydantic.main.PC</li> <li>pydantic.main.PC</li> -<li>pydantic.main.PC</li> -<li>pydantic.main.PC</li> </ul> <h3>Class variables</h3> <dl> @@ -1137,11 +1351,11 @@ class LDTemp(LDTempCreate): <dd> <div class="desc"></div> </dd> -<dt id="sql_app.schemas.PC.assigned"><code class="name">var <span class="ident">assigned</span> : bool</code></dt> +<dt id="sql_app.schemas.PC.id"><code class="name">var <span class="ident">id</span> : int</code></dt> <dd> <div class="desc"></div> </dd> -<dt id="sql_app.schemas.PC.id"><code class="name">var <span class="ident">id</span> : int</code></dt> +<dt id="sql_app.schemas.PC.logs_ld"><code class="name">var <span class="ident">logs_ld</span> : List[<a title="sql_app.schemas.LDLog" href="#sql_app.schemas.LDLog">LDLog</a>]</code></dt> <dd> <div class="desc"></div> </dd> @@ -1229,7 +1443,7 @@ class LDTemp(LDTempCreate): Class used for creating and reading team entries """ id: int - pcs: List[PC] = [] + devices: List[Device] = [] class Config: orm_mode = True</code></pre> @@ -1252,11 +1466,11 @@ class LDTemp(LDTempCreate): <dd> <div class="desc"></div> </dd> -<dt id="sql_app.schemas.Team.id"><code class="name">var <span class="ident">id</span> : int</code></dt> +<dt id="sql_app.schemas.Team.devices"><code class="name">var <span class="ident">devices</span> : List[<a title="sql_app.schemas.Device" href="#sql_app.schemas.Device">Device</a>]</code></dt> <dd> <div class="desc"></div> </dd> -<dt id="sql_app.schemas.Team.pcs"><code class="name">var <span class="ident">pcs</span> : List[<a title="sql_app.schemas.PC" href="#sql_app.schemas.PC">PC</a>]</code></dt> +<dt id="sql_app.schemas.Team.id"><code class="name">var <span class="ident">id</span> : int</code></dt> <dd> <div class="desc"></div> </dd> @@ -1512,7 +1726,7 @@ class LDTemp(LDTempCreate): username: str hostname: str timestamp: str - device: DeviceBase + device: DeviceTemp status: str</code></pre> </details> <h3>Ancestors</h3> @@ -1527,7 +1741,7 @@ class LDTemp(LDTempCreate): </ul> <h3>Class variables</h3> <dl> -<dt id="sql_app.schemas.USBTempBase.device"><code class="name">var <span class="ident">device</span> : <a title="sql_app.schemas.DeviceBase" href="#sql_app.schemas.DeviceBase">DeviceBase</a></code></dt> +<dt id="sql_app.schemas.USBTempBase.device"><code class="name">var <span class="ident">device</span> : <a title="sql_app.schemas.DeviceTemp" href="#sql_app.schemas.DeviceTemp">DeviceTemp</a></code></dt> <dd> <div class="desc"></div> </dd> @@ -1571,6 +1785,114 @@ class LDTemp(LDTempCreate): <li>pydantic.utils.Representation</li> </ul> </dd> +<dt id="sql_app.schemas.User"><code class="flex name class"> +<span>class <span class="ident">User</span></span> +<span>(</span><span>**data: Any)</span> +</code></dt> +<dd> +<div class="desc"><p>Classes used for creating new User entry</p> +<p>Create a new model by parsing and validating input data from keyword arguments.</p> +<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class User(UserCreate): + id: int + + class Config: + orm_mode = True</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li><a title="sql_app.schemas.UserCreate" href="#sql_app.schemas.UserCreate">UserCreate</a></li> +<li><a title="sql_app.schemas.UserBase" href="#sql_app.schemas.UserBase">UserBase</a></li> +<li>pydantic.main.BaseModel</li> +<li>pydantic.utils.Representation</li> +</ul> +<h3>Class variables</h3> +<dl> +<dt id="sql_app.schemas.User.Config"><code class="name">var <span class="ident">Config</span></code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.User.id"><code class="name">var <span class="ident">id</span> : int</code></dt> +<dd> +<div class="desc"></div> +</dd> +</dl> +</dd> +<dt id="sql_app.schemas.UserBase"><code class="flex name class"> +<span>class <span class="ident">UserBase</span></span> +<span>(</span><span>**data: Any)</span> +</code></dt> +<dd> +<div class="desc"><p>Classes used for creating new User entry</p> +<p>Create a new model by parsing and validating input data from keyword arguments.</p> +<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class UserBase(BaseModel): + """ + Classes used for creating new User entry + """ + username: str + password: str + role: str</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>pydantic.main.BaseModel</li> +<li>pydantic.utils.Representation</li> +</ul> +<h3>Subclasses</h3> +<ul class="hlist"> +<li><a title="sql_app.schemas.UserCreate" href="#sql_app.schemas.UserCreate">UserCreate</a></li> +</ul> +<h3>Class variables</h3> +<dl> +<dt id="sql_app.schemas.UserBase.password"><code class="name">var <span class="ident">password</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.UserBase.role"><code class="name">var <span class="ident">role</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +<dt id="sql_app.schemas.UserBase.username"><code class="name">var <span class="ident">username</span> : str</code></dt> +<dd> +<div class="desc"></div> +</dd> +</dl> +</dd> +<dt id="sql_app.schemas.UserCreate"><code class="flex name class"> +<span>class <span class="ident">UserCreate</span></span> +<span>(</span><span>**data: Any)</span> +</code></dt> +<dd> +<div class="desc"><p>Classes used for creating new User entry</p> +<p>Create a new model by parsing and validating input data from keyword arguments.</p> +<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div> +<details class="source"> +<summary> +<span>Expand source code</span> +</summary> +<pre><code class="python">class UserCreate(UserBase): + pass</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li><a title="sql_app.schemas.UserBase" href="#sql_app.schemas.UserBase">UserBase</a></li> +<li>pydantic.main.BaseModel</li> +<li>pydantic.utils.Representation</li> +</ul> +<h3>Subclasses</h3> +<ul class="hlist"> +<li><a title="sql_app.schemas.User" href="#sql_app.schemas.User">User</a></li> +</ul> +</dd> </dl> </section> </article> @@ -1598,6 +1920,8 @@ class LDTemp(LDTempCreate): <li> <h4><code><a title="sql_app.schemas.BodyDeviceBase" href="#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a></code></h4> <ul class=""> +<li><code><a title="sql_app.schemas.BodyDeviceBase.comment" href="#sql_app.schemas.BodyDeviceBase.comment">comment</a></code></li> +<li><code><a title="sql_app.schemas.BodyDeviceBase.inventory_number" href="#sql_app.schemas.BodyDeviceBase.inventory_number">inventory_number</a></code></li> <li><code><a title="sql_app.schemas.BodyDeviceBase.serial_number" href="#sql_app.schemas.BodyDeviceBase.serial_number">serial_number</a></code></li> </ul> </li> @@ -1605,10 +1929,15 @@ class LDTemp(LDTempCreate): <h4><code><a title="sql_app.schemas.BodyDeviceCreate" href="#sql_app.schemas.BodyDeviceCreate">BodyDeviceCreate</a></code></h4> </li> <li> +<h4><code><a title="sql_app.schemas.BodyDeviceTemp" href="#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a></code></h4> +<ul class=""> +<li><code><a title="sql_app.schemas.BodyDeviceTemp.serial_number" href="#sql_app.schemas.BodyDeviceTemp.serial_number">serial_number</a></code></li> +</ul> +</li> +<li> <h4><code><a title="sql_app.schemas.Device" href="#sql_app.schemas.Device">Device</a></code></h4> <ul class=""> <li><code><a title="sql_app.schemas.Device.Config" href="#sql_app.schemas.Device.Config">Config</a></code></li> -<li><code><a title="sql_app.schemas.Device.assigned" href="#sql_app.schemas.Device.assigned">assigned</a></code></li> <li><code><a title="sql_app.schemas.Device.id" href="#sql_app.schemas.Device.id">id</a></code></li> <li><code><a title="sql_app.schemas.Device.licenses" href="#sql_app.schemas.Device.licenses">licenses</a></code></li> <li><code><a title="sql_app.schemas.Device.logs" href="#sql_app.schemas.Device.logs">logs</a></code></li> @@ -1617,6 +1946,8 @@ class LDTemp(LDTempCreate): <li> <h4><code><a title="sql_app.schemas.DeviceBase" href="#sql_app.schemas.DeviceBase">DeviceBase</a></code></h4> <ul class=""> +<li><code><a title="sql_app.schemas.DeviceBase.comment" href="#sql_app.schemas.DeviceBase.comment">comment</a></code></li> +<li><code><a title="sql_app.schemas.DeviceBase.inventory_number" href="#sql_app.schemas.DeviceBase.inventory_number">inventory_number</a></code></li> <li><code><a title="sql_app.schemas.DeviceBase.product_id" href="#sql_app.schemas.DeviceBase.product_id">product_id</a></code></li> <li><code><a title="sql_app.schemas.DeviceBase.serial_number" href="#sql_app.schemas.DeviceBase.serial_number">serial_number</a></code></li> <li><code><a title="sql_app.schemas.DeviceBase.vendor_id" href="#sql_app.schemas.DeviceBase.vendor_id">vendor_id</a></code></li> @@ -1644,6 +1975,14 @@ class LDTemp(LDTempCreate): <h4><code><a title="sql_app.schemas.DeviceLicenseCreate" href="#sql_app.schemas.DeviceLicenseCreate">DeviceLicenseCreate</a></code></h4> </li> <li> +<h4><code><a title="sql_app.schemas.DeviceTemp" href="#sql_app.schemas.DeviceTemp">DeviceTemp</a></code></h4> +<ul class=""> +<li><code><a title="sql_app.schemas.DeviceTemp.product_id" href="#sql_app.schemas.DeviceTemp.product_id">product_id</a></code></li> +<li><code><a title="sql_app.schemas.DeviceTemp.serial_number" href="#sql_app.schemas.DeviceTemp.serial_number">serial_number</a></code></li> +<li><code><a title="sql_app.schemas.DeviceTemp.vendor_id" href="#sql_app.schemas.DeviceTemp.vendor_id">vendor_id</a></code></li> +</ul> +</li> +<li> <h4><code><a title="sql_app.schemas.HeadDevice" href="#sql_app.schemas.HeadDevice">HeadDevice</a></code></h4> <ul class=""> <li><code><a title="sql_app.schemas.HeadDevice.Config" href="#sql_app.schemas.HeadDevice.Config">Config</a></code></li> @@ -1654,6 +1993,8 @@ class LDTemp(LDTempCreate): <li> <h4><code><a title="sql_app.schemas.HeadDeviceBase" href="#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a></code></h4> <ul class=""> +<li><code><a title="sql_app.schemas.HeadDeviceBase.comment" href="#sql_app.schemas.HeadDeviceBase.comment">comment</a></code></li> +<li><code><a title="sql_app.schemas.HeadDeviceBase.inventory_number" href="#sql_app.schemas.HeadDeviceBase.inventory_number">inventory_number</a></code></li> <li><code><a title="sql_app.schemas.HeadDeviceBase.serial_number" href="#sql_app.schemas.HeadDeviceBase.serial_number">serial_number</a></code></li> </ul> </li> @@ -1661,6 +2002,12 @@ class LDTemp(LDTempCreate): <h4><code><a title="sql_app.schemas.HeadDeviceCreate" href="#sql_app.schemas.HeadDeviceCreate">HeadDeviceCreate</a></code></h4> </li> <li> +<h4><code><a title="sql_app.schemas.HeadDeviceTemp" href="#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a></code></h4> +<ul class=""> +<li><code><a title="sql_app.schemas.HeadDeviceTemp.serial_number" href="#sql_app.schemas.HeadDeviceTemp.serial_number">serial_number</a></code></li> +</ul> +</li> +<li> <h4><code><a title="sql_app.schemas.LDLog" href="#sql_app.schemas.LDLog">LDLog</a></code></h4> <ul class=""> <li><code><a title="sql_app.schemas.LDLog.Config" href="#sql_app.schemas.LDLog.Config">Config</a></code></li> @@ -1706,7 +2053,9 @@ class LDTemp(LDTempCreate): <h4><code><a title="sql_app.schemas.License" href="#sql_app.schemas.License">License</a></code></h4> <ul class=""> <li><code><a title="sql_app.schemas.License.Config" href="#sql_app.schemas.License.Config">Config</a></code></li> +<li><code><a title="sql_app.schemas.License.body_devices" href="#sql_app.schemas.License.body_devices">body_devices</a></code></li> <li><code><a title="sql_app.schemas.License.devices" href="#sql_app.schemas.License.devices">devices</a></code></li> +<li><code><a title="sql_app.schemas.License.head_devices" href="#sql_app.schemas.License.head_devices">head_devices</a></code></li> <li><code><a title="sql_app.schemas.License.id" href="#sql_app.schemas.License.id">id</a></code></li> </ul> </li> @@ -1714,6 +2063,7 @@ class LDTemp(LDTempCreate): <h4><code><a title="sql_app.schemas.LicenseBase" href="#sql_app.schemas.LicenseBase">LicenseBase</a></code></h4> <ul class=""> <li><code><a title="sql_app.schemas.LicenseBase.expiration_date" href="#sql_app.schemas.LicenseBase.expiration_date">expiration_date</a></code></li> +<li><code><a title="sql_app.schemas.LicenseBase.license_id" href="#sql_app.schemas.LicenseBase.license_id">license_id</a></code></li> <li><code><a title="sql_app.schemas.LicenseBase.name" href="#sql_app.schemas.LicenseBase.name">name</a></code></li> </ul> </li> @@ -1724,8 +2074,8 @@ class LDTemp(LDTempCreate): <h4><code><a title="sql_app.schemas.PC" href="#sql_app.schemas.PC">PC</a></code></h4> <ul class=""> <li><code><a title="sql_app.schemas.PC.Config" href="#sql_app.schemas.PC.Config">Config</a></code></li> -<li><code><a title="sql_app.schemas.PC.assigned" href="#sql_app.schemas.PC.assigned">assigned</a></code></li> <li><code><a title="sql_app.schemas.PC.id" href="#sql_app.schemas.PC.id">id</a></code></li> +<li><code><a title="sql_app.schemas.PC.logs_ld" href="#sql_app.schemas.PC.logs_ld">logs_ld</a></code></li> <li><code><a title="sql_app.schemas.PC.logs_pc" href="#sql_app.schemas.PC.logs_pc">logs_pc</a></code></li> </ul> </li> @@ -1743,8 +2093,8 @@ class LDTemp(LDTempCreate): <h4><code><a title="sql_app.schemas.Team" href="#sql_app.schemas.Team">Team</a></code></h4> <ul class=""> <li><code><a title="sql_app.schemas.Team.Config" href="#sql_app.schemas.Team.Config">Config</a></code></li> +<li><code><a title="sql_app.schemas.Team.devices" href="#sql_app.schemas.Team.devices">devices</a></code></li> <li><code><a title="sql_app.schemas.Team.id" href="#sql_app.schemas.Team.id">id</a></code></li> -<li><code><a title="sql_app.schemas.Team.pcs" href="#sql_app.schemas.Team.pcs">pcs</a></code></li> </ul> </li> <li> @@ -1796,6 +2146,24 @@ class LDTemp(LDTempCreate): <li> <h4><code><a title="sql_app.schemas.USBTempCreate" href="#sql_app.schemas.USBTempCreate">USBTempCreate</a></code></h4> </li> +<li> +<h4><code><a title="sql_app.schemas.User" href="#sql_app.schemas.User">User</a></code></h4> +<ul class=""> +<li><code><a title="sql_app.schemas.User.Config" href="#sql_app.schemas.User.Config">Config</a></code></li> +<li><code><a title="sql_app.schemas.User.id" href="#sql_app.schemas.User.id">id</a></code></li> +</ul> +</li> +<li> +<h4><code><a title="sql_app.schemas.UserBase" href="#sql_app.schemas.UserBase">UserBase</a></code></h4> +<ul class=""> +<li><code><a title="sql_app.schemas.UserBase.password" href="#sql_app.schemas.UserBase.password">password</a></code></li> +<li><code><a title="sql_app.schemas.UserBase.role" href="#sql_app.schemas.UserBase.role">role</a></code></li> +<li><code><a title="sql_app.schemas.UserBase.username" href="#sql_app.schemas.UserBase.username">username</a></code></li> +</ul> +</li> +<li> +<h4><code><a title="sql_app.schemas.UserCreate" href="#sql_app.schemas.UserCreate">UserCreate</a></code></h4> +</li> </ul> </li> </ul> diff --git a/server/sql_app/api/auth.py b/server/sql_app/api/auth.py index a66baca..425d8ba 100644 --- a/server/sql_app/api/auth.py +++ b/server/sql_app/api/auth.py @@ -50,14 +50,23 @@ fake_users_db = { def verify_password(plain_password, hashed_password): + """ + Verifies plain text password with hashed password + """ return pwd_context.verify(plain_password, hashed_password) def get_hash_password(password): + """ + Returns hashed password + """ return pwd_context.hash(password) def auth_user(db, username: str, password: str): + """ + Determines if given password belongs to user with given username + """ user = crud.find_user(db, username) if not user: return None diff --git a/server/sql_app/api/bodydevices_web.py b/server/sql_app/api/bodydevices_web.py index 48b345e..b00c8d8 100644 --- a/server/sql_app/api/bodydevices_web.py +++ b/server/sql_app/api/bodydevices_web.py @@ -33,111 +33,139 @@ def get_db(): async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Returns template with all body devices and its current states + Returns template with all body devices and necessary attributes """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() + device_dict = [] devices = crud.get_body_devices(db, skip=skip, limit=limit) - statuses = [] - # adding state for each device in list - for i in range(0, len(devices)): - statuses.append(devices[i].b_logs[len(devices[i].b_logs) - 1].status) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) if current_user == "admin": - return templates.TemplateResponse("body_devices.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) else: current_user = "guest" - return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devs": len(devices), "devices": devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) @body_device_web.post("/body-devices-web", response_class=HTMLResponse) -async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form("all"), +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint used for filtering body devices by license. returns html template with only - body devices that has assigned license defined by user input + Endpoint used for filtering body devices by user given inputs. returns html template with only + body devices that has attributes defined by user input """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() - devices = crud.get_body_devices(db, skip=skip, limit=limit) - def_devices = [] + device_dict = [] + devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_bodydevices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) for dev in devices: - for l in dev.debug_licenses: - if dev not in def_devices and l.b_licenses.name == lic: - def_devices.append(dev) - # if input was default all - if lic == "all": - def_devices = devices - statuses = [] - for i in range(0, len(def_devices)): - statuses.append(def_devices[i].b_logs[len(def_devices[i].b_logs) - 1].status) + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) if current_user == "admin": - return templates.TemplateResponse("body_devices.html", - {"request": request, "devs": len(def_devices), "devices": def_devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) else: current_user = "guest" - return templates.TemplateResponse("body_devices_normal.html", - {"request": request, "devs": len(def_devices), "devices": def_devices, - "statuses": statuses, "licenses": licenses, "user": current_user}) + return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, + "licenses": licenses, + "user": current_user}) @body_device_web.get("/body-device-license/{device_id}", response_class=HTMLResponse) async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Returns template with one body device and all available licenses that can be assigned to it. + Returns template with one body device and all available licenses that can be assigned to it. Plus available teams + that can be assigned to device, inventory number and comment text input for this device. """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() if current_user != "admin": return RedirectResponse(url=f"/logs-web", status_code=303) device = crud.get_body_device(db, device_id) - dev_licenses = crud.get_bodydevice_license(db, device_id) - lic_names = [] - dev_lics = [] - for dev_lic in dev_licenses: - dev_lics.append(dev_lic.b_licenses) - for dev_lic in dev_licenses: - lic_names.append(dev_lic.b_licenses.name) licenses = crud.get_licenses(db, 0, 100) lic_left = [] for lic in licenses: - if lic.name not in lic_names and lic not in lic_left: + if lic != device.license: lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) return templates.TemplateResponse("body_device_license.html", - {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics}) + {"request": request, "device": device, "licenses": lic_left, "teams": teams}) -@body_device_web.post("/body-devices-web/{device_id}") +@body_device_web.post("/body-devices-web-lic/{device_id}") async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from template for connecting body device with license. Adds entry to bodydevices_licenses - table and redirects to body-devices-web endpoint + Endpoint called from template from body_device_license.html template. Connects body device with license + and redirects to body-devices-web endpoint """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() if current_user != "admin": return RedirectResponse(url=f"/logs-web", status_code=303) - crud.create_body_device_license(db, device_id, int(lic), datetime.now()) + crud.update_bodydevice_license(db, device_id, int(lic)) return RedirectResponse(url=f"/body-devices-web", status_code=303) -@body_device_web.post("/body-devices-web-del/{device_id}") -async def delete_post(device_id: int, b_lic: str = Form(...), db: Session = Depends(get_db), +@body_device_web.post("/body-devices-web-team/{device_id}") +async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from template for connecting body device with license. Adds entry to devices_licenses - table and redirects to body-devices-web endpoint + Endpoint called from template from body_device_license.html template, connects device with new team + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_team(db, device_id, int(team_con)) + return RedirectResponse(url=f"/body-devices-web", status_code=303) + + +@body_device_web.post("/body-devices-inv/{device_id}") +async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template, updates devices inventory number + and redirects to body-devices-web endpoint """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() if current_user != "admin": return RedirectResponse(url=f"/logs-web", status_code=303) - crud.delete_bodydevice_license(db, device_id, int(b_lic)) - return RedirectResponse(url=f"/body-devices-web", status_code=303) \ No newline at end of file + crud.update_bodydevice_inv(db, device_id, dev_inv) + return RedirectResponse(url=f"/body-devices-web", status_code=303) + + +@body_device_web.post("/body-devices-comm/{device_id}") +async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template from body_device_license.html template, updates devices comment + and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_bodydevice_comm(db, device_id, dev_com) + return RedirectResponse(url=f"/body-devices-web", status_code=303) diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py index 73fdf61..ff0f029 100644 --- a/server/sql_app/api/devices_web.py +++ b/server/sql_app/api/devices_web.py @@ -33,7 +33,7 @@ def get_db(): async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Returns template with all devices and its current states + Returns template with all devices and its necessary attributes """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() @@ -65,7 +65,7 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic_id: str = Form("all"), team: str = Form("all"), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint used for filtering devices by license. returns html template with only + Endpoint used for filtering devices by user given inputs. returns html template with only devices that has assigned license defined by user input """ Authorize.jwt_optional() @@ -99,7 +99,8 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Returns template with one device and all available licenses that can be assigned to it. + Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can + be assigned to device, inventory number text input and comment text input """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() @@ -128,7 +129,7 @@ async def connect_dev_lic(request: Request, device_id: int, db: Session = Depend async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from template for connecting device with license. Adds entry to devices_licenses + Endpoint called from devicelicense.html template. Adds entry to devices_licenses table and redirects to devices-web endpoint """ Authorize.jwt_optional() @@ -143,8 +144,8 @@ async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depen async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses - table and redirects to devices-web endpoint + Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in + bodydevices_licenses table and redirects to devices-web endpoint """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() @@ -153,12 +154,12 @@ async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = De crud.delete_device_license(db, device_id, int(lic_del)) return RedirectResponse(url=f"/devices-web", status_code=303) + @device_web.post("/devices-web-team/{device_id}") async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), - Authorize: AuthJWT = Depends()): + Authorize: AuthJWT = Depends()): """ - Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses - table and redirects to devices-web endpoint + Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() @@ -167,12 +168,13 @@ async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = crud.update_device(db, device_id, team_con) return RedirectResponse(url=f"/devices-web", status_code=303) + @device_web.post("/devices-web-inv/{device_id}") async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ - Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses - table and redirects to devices-web endpoint + Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web + endpoint """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() @@ -181,12 +183,13 @@ async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = De crud.update_device_inv(db, device_id, dev_inv) return RedirectResponse(url=f"/devices-web", status_code=303) + @device_web.post("/devices-web-comment/{device_id}") async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), - Authorize: AuthJWT = Depends()): + Authorize: AuthJWT = Depends()): """ - Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses - table and redirects to devices-web endpoint + Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web + endpoint """ Authorize.jwt_optional() current_user = Authorize.get_jwt_subject() diff --git a/server/sql_app/api/headdevices_web.py b/server/sql_app/api/headdevices_web.py new file mode 100644 index 0000000..2e6452b --- /dev/null +++ b/server/sql_app/api/headdevices_web.py @@ -0,0 +1,169 @@ +from datetime import datetime + +from fastapi import Depends, APIRouter, Form +from fastapi import Request +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi.templating import Jinja2Templates +from fastapi_jwt_auth import AuthJWT +from pydantic import BaseModel +from sqlalchemy.orm import Session +from sql_app.api.auth import fake_users_db +from sql_app import crud, models +from ..database import SessionLocal, engine + +models.Base.metadata.create_all(bind=engine) + +# Path to html templates used in this file +templates = Jinja2Templates(directory="templates/head_devices") + +# prefix used for all endpoints in this file +head_device_web = APIRouter(prefix="") + + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +@head_device_web.get("/head-devices-web", response_class=HTMLResponse) +async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with all head devices and necessary attributes + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + + device_dict = [] + devices = crud.get_head_devices(db, skip=skip, limit=limit) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + + +@head_device_web.post("/head-devices-web", response_class=HTMLResponse) +async def filter_devices(request: Request, skip: int = 0, limit: int = 100, + body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"), + db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + """ + Endpoint used for filtering head devices by user given inputs. returns html template with only + head devices that has attributes defined by user input + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + device_dict = [] + devices_f = crud.get_filtered_headdevices(db, body_id, lic_id, team) + ids = [] + for d in devices_f: + ids.append(d[0]) + devices = crud.get_headdevices_with_ids(db, ids) + teams = crud.get_teams(db, skip=skip, limit=limit) + for dev in devices: + lic = crud.get_license(db, dev.license_id) + device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]}) + licenses = crud.get_licenses(db, skip=skip, limit=limit) + if current_user == "admin": + return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, "licenses": licenses, + "user": current_user}) + else: + current_user = "guest" + return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, + "devs": devices, "teams": teams, + "licenses": licenses, + "user": current_user}) + + +@head_device_web.get("/head-device-license/{device_id}", response_class=HTMLResponse) +async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Returns template with one head device and all available licenses that can be assigned to it, plus team and comment + and inventory number inputs. + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + device = crud.get_head_device(db, device_id) + licenses = crud.get_licenses(db, 0, 100) + lic_left = [] + for lic in licenses: + if lic != device.license: + lic_left.append(lic) + teams = crud.get_teams(db, 0, 100) + return templates.TemplateResponse("headlicense.html", + {"request": request, "device": device, "licenses": lic_left, "teams": teams}) + + +@head_device_web.post("/head-devices-web-lic/{device_id}") +async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_license(db, device_id, int(lic)) + return RedirectResponse(url=f"/head-devices-web", status_code=303) + + +@head_device_web.post("/head-devices-web-team/{device_id}") +async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_team(db, device_id, int(team_con)) + return RedirectResponse(url=f"/head-devices-web", status_code=303) + + +@head_device_web.post("/head-devices-inv/{device_id}") +async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from within from headlicense.html template. Changes head devices inventory number with new one + given from user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_inv(db, device_id, dev_inv) + return RedirectResponse(url=f"/head-devices-web", status_code=303) + + +@head_device_web.post("/head-devices-comm/{device_id}") +async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db), + Authorize: AuthJWT = Depends()): + """ + Endpoint called from within from headlicense.html template. Changes head devices comment with new one + given from user + """ + Authorize.jwt_optional() + current_user = Authorize.get_jwt_subject() + if current_user != "admin": + return RedirectResponse(url=f"/logs-web", status_code=303) + crud.update_headdevice_comm(db, device_id, dev_com) + return RedirectResponse(url=f"/head-devices-web", status_code=303) \ No newline at end of file diff --git a/server/sql_app/crud.py b/server/sql_app/crud.py index 6892343..2935853 100644 --- a/server/sql_app/crud.py +++ b/server/sql_app/crud.py @@ -32,18 +32,63 @@ def find_device_by_serial(db: Session, ser: str): """ return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first() + def get_devices_with_ids(db: Session, ids: []): """ returns all devices with given ids """ return db.query(models.Device).filter(models.Device.id.in_(ids)).all() + +def get_bodydevices_with_ids(db: Session, ids: []): + """ + returns all bodydevices with given ids + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.id.in_(ids)).all() + + +def get_headdevices_with_ids(db: Session, ids: []): + """ + returns all headdevices with given ids + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.id.in_(ids)).all() + + +def find_headdevices_by_team(db: Session, team_id: int): + """ + Returns all head devices in specific team + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.team_id == team_id).all() + + +def find_bodydevices_by_team(db: Session, team_id: int): + """ + Returns all body devices in specific team + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.team_id == team_id).all() + + +def find_headdevices_by_license(db: Session, lic_id: int): + """ + Returns all head devices with specific license + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.license_id == lic_id).all() + + +def find_bodydevices_by_license(db: Session, lic_id: int): + """ + Returns all body devices with specific license + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.license_id == lic_id).all() + + def get_devices_by_team(db: Session, team: int): """ returns all devices with same team """ return db.query(models.Device).filter(models.Device.team_id == team).all() + def create_device(db: Session, device: schemas.DeviceTemp): """ creates new device with data from given DeviceBase object @@ -121,28 +166,6 @@ def get_devicelicense_by_devicelicense(db: Session, device_id: int, license_id: models.DeviceLicense.license_id == license_id)).first() -def get_bodydevicelicense_by_bodydevicelicense(db: Session, device_id: int, license_id: int): - """ - returns entry in bodydevices_licenses table with given body device id and license id - """ - return db.query(models.BodyDeviceLicense).filter(and_(models.BodyDeviceLicense.bodydevice_id == device_id, - models.BodyDeviceLicense.license_id == license_id)).first() - - -def get_license_bodydevice(db: Session, license_id: int): - """ - returns all entries in bodydevices_licenses with given license_id - """ - return db.query(models.BodyDeviceLicense).filter(models.BodyDeviceLicense.license_id == license_id).all() - - -def get_bodydevice_license(db: Session, device_id: int): - """ - returns all entries in bodydevices_licenses with given license_id - """ - return db.query(models.BodyDeviceLicense).filter(models.BodyDeviceLicense.bodydevice_id == device_id).all() - - def create_device_license(db: Session, device: int, license: int, time: datetime): """ creates new entry in devices_licenses table with device id, license id and time. @@ -165,28 +188,6 @@ def delete_device_license(db: Session, device: int, license: int): return db_lic -def delete_bodydevice_license(db: Session, device: int, license: int): - """ - deletes entry in devices_licenses table with device id, license id and time. - """ - db_device_license = get_bodydevicelicense_by_bodydevicelicense(db, device, license) - db_lic = db.delete(db_device_license) - db.commit() - return db_lic - - -def create_body_device_license(db: Session, device: int, license: int, time: datetime): - """ - creates new entry in devices_licenses table with device id, license id and time. - """ - db_device_license = models.BodyDeviceLicense(bodydevice_id=device, license_id=license, - assigned_datetime=time) - db.add(db_device_license) - db.commit() - db.refresh(db_device_license) - return db_device_license - - def find_pc_by_username(db: Session, name: str): """ Finds one pc by given username @@ -415,17 +416,147 @@ def find_body_device(db: Session, serial: schemas.BodyDeviceTemp): return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first() +def find_bodydevice_by_serial(db: Session, serial: str): + """ + Finds one specific body device by given serial number + """ + return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial).first() + + +def find_headdevice_by_serial(db: Session, serial: str): + """ + Finds one specific head device by given serial number + """ + return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial).first() + + def create_body_device(db: Session, log: schemas.BodyDeviceTemp): """ Creates new Body device """ - db_body = models.BodyDevice(serial_number=log.serial_number) + db_body = models.BodyDevice(serial_number=log.serial_number, inventory_number="", comment="") db.add(db_body) db.commit() db.refresh(db_body) return db_body +def update_bodydevice_license(db: Session, device_id: int, lic_id: int): + """ + Updates body devices license with one given by user + """ + old_dev = get_body_device(db, device_id) + lic = get_license(db, lic_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_bodydevice_team(db: Session, device_id: int, team_id: int): + """ + Updates body devices team with one given by user + """ + old_dev = get_body_device(db, device_id) + team = get_team(db, team_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_bodydevice_inv(db: Session, device_id: int, dev_inv: str): + """ + Updates body devices inventory number with new one given by user + """ + old_dev = get_body_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_bodydevice_comm(db: Session, device_id: int, comm: str): + """ + Updates body devices comment with new one given by user + """ + old_dev = get_body_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_license(db: Session, device_id: int, lic_id: int): + """ + Updates head devices license with one given by user + """ + old_dev = get_head_device(db, device_id) + lic = get_license(db, lic_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_team(db: Session, device_id: int, team_id: int): + """ + Updates head devices team with one given by user + """ + old_dev = get_head_device(db, device_id) + team = get_team(db, team_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_inv(db: Session, device_id: int, dev_inv: str): + """ + Updates head devices inventory number with new one given by user + """ + old_dev = get_head_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv, + 'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + +def update_headdevice_comm(db: Session, device_id: int, comm: str): + """ + Updates head devices comment with new one given by user + """ + old_dev = get_head_device(db, device_id) + new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number, + 'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id} + for key, value in new.items(): + setattr(old_dev, key, value) + db.commit() + db.refresh(old_dev) + return old_dev + + def get_ld_logs(db: Session, skip: int = 0, limit: int = 100): """ Returns all ld debugger logs in database @@ -477,41 +608,134 @@ def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str): Function creates query string used for filtering by pc username, team name and license name. Depending on selected filters assembles query string for database """ - execute_string = "SELECT * FROM ld_logs AS logs" - pcs = find_pc_by_username(db, pc) + execute_string = "SELECT * FROM ld_logs AS logs WHERE" + before_me = False + all_all = True if pc != "all": - if pcs is not None: - execute_string += " WHERE logs.pc_id = " + str(pcs.id) + all_all = False + pc = find_pc_by_username(db, pc) + if pc != None: + if before_me: + execute_string += " AND logs.pc_id = " + str(pc.id) + else: + before_me = True + execute_string += " logs.pc_id = " + str(pc.id) + else: + if before_me: + execute_string += " AND logs.pc_id = -1" + else: + before_me = True + execute_string += " logs.pc_id = -1" if tema != "all": + all_all = False team = find_team(db, tema) - if team is not None: - devs = get_devices_by_team(db, team.id) - d_ids = "(" - for p in devs: - d_ids += str(p.id) + ", " - def_d_ids = d_ids[:-2] + ")" - if pc != "all" and pcs is not None: - if len(def_d_ids) > 1: - execute_string += " AND logs.device_id IN " + def_d_ids + if team != None: + head_devices = find_headdevices_by_team(db, team.id) + body_devices = find_bodydevices_by_team(db, team.id) + if len(head_devices) > 0 and len(body_devices) > 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + else: + before_me = True + execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + elif len(head_devices) == 0 and len(body_devices) > 0: + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.body_id IN " + def_b_ids + else: + before_me = True + execute_string += " logs.body_id IN " + def_b_ids + elif len(head_devices) > 0 and len(body_devices) == 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.head_id IN " + def_h_ids + else: + before_me = True + execute_string += " logs.head_id IN " + def_h_ids else: - if len(def_d_ids) > 1: - execute_string += " WHERE logs.device_id IN " + def_d_ids + if before_me: + execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)" + else: + before_me = True + execute_string += " (logs.head_id = -1 OR logs.body_id = -1)" + else: + if before_me: + execute_string += " AND logs.pc_id = -1" + else: + before_me = True + execute_string += " logs.pc_id = -1" if lic != "all": - license = get_licenses_by_name(db, lic) - if license is not None: - device_licenses = get_license_bodydevice(db, license.id) - dev_ids = "(" - for dev in device_licenses: - dev_ids += str(dev.bodydevice_id) + ", " - defin_ids = dev_ids[:-2] + ")" - if pc != "all" or tema != "all": - if len(defin_ids) > 1: - execute_string += " AND logs.body_id IN " + defin_ids + all_all = False + license = find_license(db, lic) + if license != None: + head_devices = find_headdevices_by_license(db, license.id) + body_devices = find_bodydevices_by_license(db, license.id) + if len(head_devices) > 0 and len(body_devices) > 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + else: + before_me = True + execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")" + elif len(head_devices) == 0 and len(body_devices) > 0: + b_ids = "(" + for b in body_devices: + b_ids += str(b.id) + ", " + def_b_ids = b_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.body_id IN " + def_b_ids + else: + before_me = True + execute_string += " logs.body_id IN " + def_b_ids + elif len(head_devices) > 0 and len(body_devices) == 0: + h_ids = "(" + for h in head_devices: + h_ids += str(h.id) + ", " + def_h_ids = h_ids[:-2] + ")" + if before_me: + execute_string += " AND logs.head_id IN " + def_h_ids + else: + before_me = True + execute_string += " logs.head_id IN " + def_h_ids else: - if len(defin_ids) > 1: - execute_string += " WHERE logs.body_id IN " + defin_ids + if before_me: + execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)" + else: + before_me = True + execute_string += " (logs.head_id = -1 OR logs.body_id = -1)" + else: + if before_me: + execute_string += " AND logs.pc_id = -1" + else: + before_me = True + execute_string += " logs.pc_id = -1" + if all_all: + before_me = True + execute_string = "SELECT * FROM ld_logs AS logs" - # executing assembled query string + if not before_me: + execute_string = "SELECT * FROM ld_logs AS logs WHERE logs.id = -1" result = db.execute(execute_string) return result @@ -526,6 +750,8 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str): if pc != "all": if pcs is not None: execute_string += " WHERE logs.pc_id = " + str(pcs.id) + else: + execute_string += " WHERE logs.pc_id = -1" if tema != "all": team = find_team(db, tema) if team is not None: @@ -534,16 +760,28 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str): for p in devs: d_ids += str(p.id) + ", " def_d_ids = d_ids[:-2] + ")" - if pc != "all" and pcs is not None: + if pc != "all": if len(def_d_ids) > 1: execute_string += " AND logs.device_id IN " + def_d_ids + else: + execute_string += " AND logs.device_id IN (-1)" else: if len(def_d_ids) > 1: execute_string += " WHERE logs.device_id IN " + def_d_ids + else: + execute_string += " WHERE logs.device_id IN (-1)" + else: + if pc != "all": + execute_string += " AND logs.device_id IN (-1)" + else: + execute_string += " WHERE logs.device_id IN (-1)" if lic != "all": license = get_licenses_by_name(db, lic) - if license is not None: - device_licenses = get_license_devices(db, license.id) + if len(license) > 0: + ids = [] + for l in license: + ids.append(l.id) + device_licenses = find_devicelicenses_by_licid_array(db, ids) dev_ids = "(" for dev in device_licenses: dev_ids += str(dev.device_id) + ", " @@ -551,18 +789,151 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str): if pc != "all" or tema != "all": if len(defin_ids) > 1: execute_string += " AND logs.device_id IN " + defin_ids + else: + execute_string += " AND logs.device_id IN (-1)" else: if len(defin_ids) > 1: execute_string += " WHERE logs.device_id IN " + defin_ids + else: + execute_string += " WHERE logs.device_id IN (-1)" + else: + if pc != "all" or tema != "all": + execute_string += " AND logs.device_id IN (-1)" + else: + execute_string += " WHERE logs.device_id IN (-1)" # executing assembled query string result = db.execute(execute_string) return result +def get_filtered_bodydevices(db: Session, body_id: str, license_id: str, team: str): + """ + returns filtered body devices based on given attributes + """ + execute_string = "SELECT * FROM body_devices AS device WHERE" + before_me = False + all_all = True + if body_id != "all": + all_all = False + body_dev = find_bodydevice_by_serial(db, body_id) + if body_dev != None: + if before_me: + execute_string += " AND device.id = " + str(body_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(body_dev.id) + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" + if license_id != "all": + all_all = False + license = find_license(db, license_id) + if license != None: + if before_me: + execute_string += " AND device.license_id = " + str(license.id) + else: + before_me = True + execute_string += " device.license_id = " + str(license.id) + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" + if all_all: + before_me = True + execute_string = "SELECT * FROM body_devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result + + +def get_filtered_headdevices(db: Session, body_id: str, license_id: str, team: str): + """ + returns filtered head devices based on given attributes + """ + execute_string = "SELECT * FROM head_devices AS device WHERE" + before_me = False + all_all = True + if body_id != "all": + all_all = False + head_dev = find_headdevice_by_serial(db, body_id) + if head_dev != None: + if before_me: + execute_string += " AND device.id = " + str(head_dev.id) + else: + before_me = True + execute_string += " device.id = " + str(head_dev.id) + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" + if license_id != "all": + all_all = False + license = find_license(db, license_id) + if license != None: + if before_me: + execute_string += " AND device.license_id = " + str(license.id) + else: + before_me = True + execute_string += " device.license_id = " + str(license.id) + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" + if team != "all": + all_all = False + tem = find_team(db, team) + if tem != None: + if before_me: + execute_string += " AND device.team_id = " + str(tem.id) + else: + before_me = True + execute_string += " device.team_id = " + str(tem.id) + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" + if all_all: + before_me = True + execute_string = "SELECT * FROM body_devices AS devices" + + if not before_me: + execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1" + result = db.execute(execute_string) + return result + + def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str): """ - returns filtered devices based on given atributes + returns filtered keyman devices based on given attributes """ execute_string = "SELECT * FROM devices AS device WHERE" before_me = False @@ -576,6 +947,12 @@ def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license else: before_me = True execute_string += " device.id = " + str(keyman_dev.id) + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" if license_name != "all": all_all = False license = get_licenses_by_name(db, license_name) @@ -588,20 +965,30 @@ def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license for l in dev_lics: lic_ids += str(l.device_id) + ", " def_lic_ids = lic_ids[:-2] + ")" + if len(def_lic_ids) < 1: + def_lic_ids = "(-1)" if before_me: execute_string += " AND device.id IN " + def_lic_ids else: before_me = True execute_string += " device.id IN " + def_lic_ids + else: + if before_me: + execute_string += " AND device.id = -1" + else: + before_me = True + execute_string += " device.id = -1" if license_id != "all": all_all = False license = find_license(db, license_id) - licen_devs = get_license_devices(db, license.id) - ids = "(" - for lic in licen_devs: - ids += str(lic.device_id) + ", " - def_ids = ids[:-2] + ")" if license != None: + licen_devs = get_license_devices(db, license.id) + ids = "(" + for lic in licen_devs: + ids += str(lic.device_id) + ", " + def_ids = ids[:-2] + ")" + if len(def_ids) < 1: + def_ids = "(-1)" if before_me: execute_string += " AND device.id IN " + def_ids else: diff --git a/server/sql_app/main.py b/server/sql_app/main.py index 637bfaf..5c5bbb5 100644 --- a/server/sql_app/main.py +++ b/server/sql_app/main.py @@ -12,6 +12,7 @@ from sql_app.api.teams_web import teams_web from sql_app.api.auth import auth from sql_app.api.ld_logs_web import ldlogs_web from sql_app.api.bodydevices_web import body_device_web +from sql_app.api.headdevices_web import head_device_web from sql_app.api.users_web import users from fastapi import FastAPI @@ -34,9 +35,10 @@ app.include_router(usblogs_web) app.include_router(ldlogs_web) app.include_router(body_device_web) app.include_router(users) +app.include_router(head_device_web) app.include_router(auth) ''' if __name__ == "__main__": - uvicorn.run(app, host="192.168.64.1", port=8000) + uvicorn.run(app, host="192.168.0.22", port=8000) ''' diff --git a/server/sql_app/schemas.py b/server/sql_app/schemas.py index eeab5a6..afb2bdc 100644 --- a/server/sql_app/schemas.py +++ b/server/sql_app/schemas.py @@ -69,6 +69,9 @@ class Device(DeviceCreate): class DeviceTemp(BaseModel): + """ + Class used for reading data from client + """ vendor_id: str product_id: str serial_number: str @@ -117,6 +120,9 @@ class BodyDevice(BodyDeviceCreate): class BodyDeviceTemp(BaseModel): + """ + Class used for reading body device data from client + """ serial_number: str @@ -142,6 +148,9 @@ class HeadDevice(HeadDeviceCreate): class HeadDeviceTemp(BaseModel): + """ + Class used for reading head device data from client + """ serial_number: str diff --git a/server/templates/auth/login.html b/server/templates/auth/login.html index fa536c5..cccf299 100644 --- a/server/templates/auth/login.html +++ b/server/templates/auth/login.html @@ -7,9 +7,9 @@ <body> <form action="/login" method="post"> <label for="username">Username:</label><br> - <input type="text" id="username" name="username"><br><br> - <label for="password">Password:</label> - <input type="password" id="password" name="password"> + <input type="text" id="username" name="username"><br> + <label for="password">Password:</label><br> + <input type="password" id="password" name="password"><br> <input type="submit" value="LogIn"> </form> </body> diff --git a/server/templates/auth/signup.html b/server/templates/auth/signup.html index b8b19ff..03334be 100644 --- a/server/templates/auth/signup.html +++ b/server/templates/auth/signup.html @@ -7,9 +7,9 @@ <body> <form action="/signup" method="post"> <label for="username">Username:</label><br> - <input type="text" id="username" name="username"><br><br> - <label for="password">Password:</label> - <input type="password" id="password" name="password"> + <input type="text" id="username" name="username"><br> + <label for="password">Password:</label><br> + <input type="password" id="password" name="password"><br> <input type="submit" value="Signup"> </form> </body> diff --git a/server/templates/body-devices/body_device_license.html b/server/templates/body-devices/body_device_license.html index d0c1896..f738966 100644 --- a/server/templates/body-devices/body_device_license.html +++ b/server/templates/body-devices/body_device_license.html @@ -5,26 +5,45 @@ <title>Body Device License Connect</title> </head> <body> -<h6><p>Vendor ID: {{device.vendor_id}}</p> +<h6> <p>Serial Number: {{device.serial_number}}</p> </h6> -<form action="/body-devices-web/{{device.id}}" method="post"> +<h4> + License ID: {{device.license.license_id}} +</h4> +<form action="/body-devices-web-lic/{{device.id}}" method="post"> <label for="lic">Licenses:</label> <select id="lic" name="lic"> {% for license in licenses %} - <option value={{license.id}}>{{license.name}}</option> + <option value={{license.id}}>{{license.license_id}}</option> {% endfor %} </select> <input type="submit" value="Connect"> </form> -<form action="/body-devices-web-del/{{device.id}}" method="post"> - <label for="b_lic">Licenses:</label> - <select id="b_lic" name="b_lic" > - {% for license in dev_lic %} - <option value={{license.id}}>{{license.name}}</option> +<div style='padding-top:20px'> +<form action="/body-devices-web-team/{{device.id}}" method="post"> + <label for="team_con">Teams:</label> + <select id="team_con" name="team_con" > + {% for team in teams %} + <option value={{team.id}}>{{team.name}}</option> {% endfor %} </select> - <input type="submit" value="Delete"> + <input type="submit" value="Connect"> +</form> +</div> +<div style='padding-top:20px'> +<form action="/body-devices-inv/{{device.id}}" method="post"> + <label for="dev_inv">Inventory Number:</label><br> + <input type="text" id="dev_inv" name="dev_inv" value="{{device.inventory_number}}"> + <input type="submit" value="Submit"> +</form> +</div> +<div style='padding-top:20px'> +<form action="/body-devices-comm/{{device.id}}" method="post"> + <label for="dev_com">Comment:</label><br> + <input type="text" id="dev_com" name="dev_com" value="{{device.comment}}"> + <input type="submit" value="Submit"> </form> +</div> </body> </html> \ No newline at end of file diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html index a929689..3492e41 100644 --- a/server/templates/body-devices/body_devices.html +++ b/server/templates/body-devices/body_devices.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web" selected>Lauterbach Devices</option> + <option value="/body-devices-web" selected>Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -58,11 +59,25 @@ <input type="submit" value="OK"> </form> <form action="/body-devices-web" method="post"> - <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> - <datalist id="licenses"> + <label for="body_id">Body Device ID:</label> + <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <datalist id="body_ids"> + {% for dev in devs %} + <option value="{{dev.serial_number}}"></option> + {% endfor %} + </datalist> + <label for="lic_id">License ID:</label> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <datalist id="licenses_ids"> {% for license in licenses %} - <option value="{{license.name}}"></option> + <option value="{{license.license_id}}"></option> + {% endfor %} + </datalist> + <label for="team">Team:</label> + <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <datalist id="teams"> + {% for team in teams %} + <option value="{{team.name}}">{{team.name}}</option> {% endfor %} </datalist> <input type="submit" value="Filter"> @@ -71,30 +86,29 @@ <TR> <TH>ID</TH> <TH>Lauterbach Body ID</TH> - <TH>Licenses</TH> + <TH>License ID</TH> + <TH>Inventory Number</TH> + <TH>Team</TH> + <TH>Last Username</TH> + <TH>Last Hostname</TH> + <TH>Last Detection</TH> <TH>Status</TH> + <TH>Comment</TH> </TR> - {% for i in range(devs) %} + {% for dev in devices %} <TR> - <TD class="ID"><a href="/body-device-license/{{devices[i].id}}">{{devices[i].id}}</a></TD> - <TD class="Serial Number">{{devices[i].serial_number}}</TD> - <TD class="License"> - {% for lic in devices[i].debug_licenses %} - {{lic.b_licenses.name}}<BR> - {% endfor %} - </TD> - <TD class="Status">{{statuses[i]}}</TD> + <TD class="ID"><a href="/body-device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD> + <TD class="Lauterbach Body ID">{{dev['device'].serial_number}}</TD> + <TD class="License ID">{{dev['license'].license_id}}</TD> + <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD> + <TD class="Team">{{dev['device'].team.name}}</TD> + <TD class="Last Username">{{dev['log'].ldpc.username}}</TD> + <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD> + <TD class="Last Detection">{{dev['log'].timestamp}}</TD> + <TD class="Status">{{dev['log'].status}}</TD> + <TD class="Comment">{{dev['device'].comment}}</TD> </TR> {% endfor %} - <TR> - <TD class="ID"></TD> - <TD class="Serial Number"></TD> - <TD class="License"> - <form action="/license-create" method="get"> - <input type="submit" value="Add"> - </form> - </TD> - </TR> </table> </body> </html> \ No newline at end of file diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html index db8159f..39ba939 100644 --- a/server/templates/body-devices/body_devices_normal.html +++ b/server/templates/body-devices/body_devices_normal.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web" selected>Lauterbach Devices</option> + <option value="/body-devices-web" selected>Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -57,11 +58,25 @@ <input type="submit" value="OK"> </form> <form action="/body-devices-web" method="post"> - <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> - <datalist id="licenses"> + <label for="body_id">Body Device ID:</label> + <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <datalist id="body_ids"> + {% for dev in devs %} + <option value="{{dev.serial_number}}"></option> + {% endfor %} + </datalist> + <label for="lic_id">License ID:</label> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <datalist id="licenses_ids"> {% for license in licenses %} - <option value="{{license.name}}"></option> + <option value="{{license.license_id}}"></option> + {% endfor %} + </datalist> + <label for="team">Team:</label> + <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <datalist id="teams"> + {% for team in teams %} + <option value="{{team.name}}">{{team.name}}</option> {% endfor %} </datalist> <input type="submit" value="Filter"> @@ -70,19 +85,27 @@ <TR> <TH>ID</TH> <TH>Lauterbach Body ID</TH> - <TH>Licenses</TH> + <TH>License ID</TH> + <TH>Inventory Number</TH> + <TH>Team</TH> + <TH>Last Username</TH> + <TH>Last Hostname</TH> + <TH>Last Detection</TH> <TH>Status</TH> + <TH>Comment</TH> </TR> - {% for i in range(devs) %} + {% for dev in devices %} <TR> - <TD class="ID">{{devices[i].id}}</TD> - <TD class="Serial Number">{{devices[i].serial_number}}</TD> - <TD class="License"> - {% for lic in devices[i].debug_licenses %} - {{lic.b_licenses.name}}<BR> - {% endfor %} - </TD> - <TD class="Status">{{statuses[i]}}</TD> + <TD class="ID">{{dev['device'].id}}</TD> + <TD class="Lauterbach Body ID">{{dev['device'].serial_number}}</TD> + <TD class="License ID">{{dev['license'].license_id}}</TD> + <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD> + <TD class="Team">{{dev['device'].team.name}}</TD> + <TD class="Last Username">{{dev['log'].ldpc.username}}</TD> + <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD> + <TD class="Last Detection">{{dev['log'].timestamp}}</TD> + <TD class="Status">{{dev['log'].status}}</TD> + <TD class="Comment">{{dev['device'].comment}}</TD> </TR> {% endfor %} </table> diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html index b0e09e2..4d8c620 100644 --- a/server/templates/devices/devices.html +++ b/server/templates/devices/devices.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web" selected>Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html index abd3400..1c77480 100644 --- a/server/templates/devices/devices_normal.html +++ b/server/templates/devices/devices_normal.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web" selected>Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/head_devices/head_devices.html b/server/templates/head_devices/head_devices.html new file mode 100644 index 0000000..42117e4 --- /dev/null +++ b/server/templates/head_devices/head_devices.html @@ -0,0 +1,114 @@ +<html> +<head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> + <title>Head Devices Details</title> +</head> +<body> +<div style='float:left;padding-right:20px'> +<b>Your role: {{user}}</b> +</div> +<div style='float:left;padding-right:5px'> +<form action="/login" method="get"> + <input type="submit" value="Login" /> +</form> +</div> +<div style='float:left;padding-right:5px'> +<form action="/signup" method="get"> + <input type="submit" value="Sign Up" /> +</form> +</div> +<form action="/logout" method="get"> + <input type="submit" value="Logout" /> +</form> +<form action="" method="get"> + <label for="view">Choose view:</label> + <select id="view" name="view" onchange="this.form.action=this.value;"> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web" selected>Lauterbach Head Devices</option> + <option value="/teams-web">Teams</option> + <option value="/pcs-web">PCs</option> + <option value="/licenses-web">Licenses</option> + <option value="/users-web">Users</option> + </select> + <input type="submit" value="OK"> +</form> +<form action="/head-devices-web" method="post"> + <label for="body_id">Head Device ID:</label> + <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <datalist id="body_ids"> + {% for dev in devs %} + <option value="{{dev.serial_number}}"></option> + {% endfor %} + </datalist> + <label for="lic_id">License ID:</label> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <datalist id="licenses_ids"> + {% for license in licenses %} + <option value="{{license.license_id}}"></option> + {% endfor %} + </datalist> + <label for="team">Team:</label> + <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <datalist id="teams"> + {% for team in teams %} + <option value="{{team.name}}">{{team.name}}</option> + {% endfor %} + </datalist> + <input type="submit" value="Filter"> +</form> +<table id="devices"> + <TR> + <TH>ID</TH> + <TH>Lauterbach Head ID</TH> + <TH>License ID</TH> + <TH>Inventory Number</TH> + <TH>Team</TH> + <TH>Last Username</TH> + <TH>Last Hostname</TH> + <TH>Last Detection</TH> + <TH>Status</TH> + <TH>Comment</TH> + </TR> + {% for dev in devices %} + <TR> + <TD class="ID"><a href="/head-device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD> + <TD class="Lauterbach Head ID">{{dev['device'].serial_number}}</TD> + <TD class="License ID">{{dev['license'].license_id}}</TD> + <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD> + <TD class="Team">{{dev['device'].team.name}}</TD> + <TD class="Last Username">{{dev['log'].ldpc.username}}</TD> + <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD> + <TD class="Last Detection">{{dev['log'].timestamp}}</TD> + <TD class="Status">{{dev['log'].status}}</TD> + <TD class="Comment">{{dev['device'].comment}}</TD> + </TR> + {% endfor %} +</table> +</body> +</html> \ No newline at end of file diff --git a/server/templates/head_devices/head_devices_normal.html b/server/templates/head_devices/head_devices_normal.html new file mode 100644 index 0000000..8df6d97 --- /dev/null +++ b/server/templates/head_devices/head_devices_normal.html @@ -0,0 +1,113 @@ +<html> +<head> + <style> + #devices { + font-family: Arial, Helvetica, sans-serif; + border-collapse: collapse; + width: 100%; +} + +#devices td, #devices th { + border: 1px solid #ddd; + padding: 8px; +} + +#devices tr:nth-child(even){background-color: #f2f2f2;} + +#devices tr:hover {background-color: #ddd;} + +#devices th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #47BBF5; + color: black; +} + </style> + <title>Devices Details</title> +</head> +<body> +<div style='float:left;padding-right:20px'> +<b>Your role: {{user}}</b> +</div> +<div style='float:left;padding-right:5px'> +<form action="/login" method="get"> + <input type="submit" value="Login" /> +</form> +</div> +<div style='float:left;padding-right:5px'> +<form action="/signup" method="get"> + <input type="submit" value="Sign Up" /> +</form> +</div> +<form action="/logout" method="get"> + <input type="submit" value="Logout" /> +</form> +<form action="" method="get"> + <label for="view">Choose view:</label> + <select id="view" name="view" onchange="this.form.action=this.value;"> + <option value="/logs-web">Vector Logs</option> + <option value="/ldlogs-web">Lauterbach Logs</option> + <option value="/devices-web">Keyman Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web" selected>Lauterbach Head Devices</option> + <option value="/teams-web">Teams</option> + <option value="/pcs-web">PCs</option> + <option value="/licenses-web">Licenses</option> + </select> + <input type="submit" value="OK"> +</form> +<form action="/head-devices-web" method="post"> + <label for="body_id">Head Device ID:</label> + <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <datalist id="body_ids"> + {% for dev in devs %} + <option value="{{dev.serial_number}}"></option> + {% endfor %} + </datalist> + <label for="lic_id">License ID:</label> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <datalist id="licenses_ids"> + {% for license in licenses %} + <option value="{{license.license_id}}"></option> + {% endfor %} + </datalist> + <label for="team">Team:</label> + <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <datalist id="teams"> + {% for team in teams %} + <option value="{{team.name}}">{{team.name}}</option> + {% endfor %} + </datalist> + <input type="submit" value="Filter"> +</form> +<table id="devices"> + <TR> + <TH>ID</TH> + <TH>Lauterbach Head ID</TH> + <TH>License ID</TH> + <TH>Inventory Number</TH> + <TH>Team</TH> + <TH>Last Username</TH> + <TH>Last Hostname</TH> + <TH>Last Detection</TH> + <TH>Status</TH> + <TH>Comment</TH> + </TR> + {% for dev in devices %} + <TR> + <TD class="ID">{{dev['device'].id}}</TD> + <TD class="Lauterbach Head ID">{{dev['device'].serial_number}}</TD> + <TD class="License ID">{{dev['license'].license_id}}</TD> + <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD> + <TD class="Team">{{dev['device'].team.name}}</TD> + <TD class="Last Username">{{dev['log'].ldpc.username}}</TD> + <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD> + <TD class="Last Detection">{{dev['log'].timestamp}}</TD> + <TD class="Status">{{dev['log'].status}}</TD> + <TD class="Comment">{{dev['device'].comment}}</TD> + </TR> + {% endfor %} +</table> +</body> +</html> \ No newline at end of file diff --git a/server/templates/head_devices/headlicense.html b/server/templates/head_devices/headlicense.html new file mode 100644 index 0000000..784e0bf --- /dev/null +++ b/server/templates/head_devices/headlicense.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>Head Device License Connect</title> +</head> +<body> +<h6> + <p>Serial Number: {{device.serial_number}}</p> +</h6> +<h4> + License ID: {{device.license.license_id}} +</h4> +<form action="/head-devices-web-lic/{{device.id}}" method="post"> + <label for="lic">Licenses:</label> + <select id="lic" name="lic"> + {% for license in licenses %} + <option value={{license.id}}>{{license.license_id}}</option> + {% endfor %} + </select> + <input type="submit" value="Connect"> +</form> +<div style='padding-top:20px'> +<form action="/head-devices-web-team/{{device.id}}" method="post"> + <label for="team_con">Teams:</label> + <select id="team_con" name="team_con" > + {% for team in teams %} + <option value={{team.id}}>{{team.name}}</option> + {% endfor %} + </select> + <input type="submit" value="Connect"> +</form> +</div> +<div style='padding-top:20px'> +<form action="/head-devices-inv/{{device.id}}" method="post"> + <label for="dev_inv">Inventory Number:</label><br> + <input type="text" id="dev_inv" name="dev_inv" value="{{device.inventory_number}}"> + <input type="submit" value="Submit"> +</form> +</div> +<div style='padding-top:20px'> +<form action="/head-devices-comm/{{device.id}}" method="post"> + <label for="dev_com">Comment:</label><br> + <input type="text" id="dev_com" name="dev_com" value="{{device.comment}}"> + <input type="submit" value="Submit"> +</form> +</div> +</body> +</html> \ No newline at end of file diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html index 7723f2a..e7f36cf 100644 --- a/server/templates/ld-logs/ldlogs.html +++ b/server/templates/ld-logs/ldlogs.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web" selected>Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -76,7 +77,7 @@ <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> <datalist id="licenses"> {% for license in licenses %} - <option value="{{license.name}}"></option> + <option value="{{license.license_id}}"></option> {% endfor %} </datalist> <input type="submit" value="Filter"> @@ -86,7 +87,8 @@ <TH>ID</TH> <TH>PC Username</TH> <TH>PC Hostname</TH> - <TH>Team</TH> + <TH>Head Team</TH> + <TH>Body Team</TH> <TH>Timestamp</TH> <TH>Status</TH> <TH>Lauterbach Head ID</TH> @@ -97,11 +99,8 @@ <TD class="ID">{{log.id}}</TD> <TD class="Username">{{log.ldpc.username}}</TD> <TD class="Hostname">{{log.ldpc.hostname}}</TD> - {% if log.ldpc.team == None %} - <TD class="Team">NONE</TD> - {% else %} - <TD class="Team">{{log.ldpc.team.name}}</TD> - {% endif %} + <TD class="Head Team">{{log.head_device.team.name}}</TD> + <TD class="Body Team">{{log.body_device.team.name}}</TD> <TD class="Timestamp">{{log.timestamp}}</TD> <TD class="Status">{{log.status}}</TD> <TD class="HeadDeviceSerialNumber">{{log.head_device.serial_number}}</TD> diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html index 303b83f..bcdf40a 100644 --- a/server/templates/ld-logs/ldlogs_normal.html +++ b/server/templates/ld-logs/ldlogs_normal.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web" selected>Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -75,7 +76,7 @@ <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> <datalist id="licenses"> {% for license in licenses %} - <option value="{{license.name}}"></option> + <option value="{{license.name}} : {{license.license_id}}"></option> {% endfor %} </datalist> <input type="submit" value="Filter"> @@ -85,7 +86,8 @@ <TH>ID</TH> <TH>PC Username</TH> <TH>PC Hostname</TH> - <TH>Team</TH> + <TH>Head Team</TH> + <TH>Body Team</TH> <TH>Timestamp</TH> <TH>Status</TH> <TH>Lauterbach Head ID</TH> @@ -96,17 +98,14 @@ <TD class="ID">{{log.id}}</TD> <TD class="Username">{{log.ldpc.username}}</TD> <TD class="Hostname">{{log.ldpc.hostname}}</TD> - {% if log.ldpc.team == None %} - <TD class="Team">NONE</TD> - {% else %} - <TD class="Team">{{log.ldpc.team.name}}</TD> - {% endif %} + <TD class="Head Team">{{log.head_device.team.name}}</TD> + <TD class="Body Team">{{log.body_device.team.name}}</TD> <TD class="Timestamp">{{log.timestamp}}</TD> <TD class="Status">{{log.status}}</TD> <TD class="HeadDeviceSerialNumber">{{log.head_device.serial_number}}</TD> <TD class="BodyDeviceSerialNumber">{{log.body_device.serial_number}}</TD> </TR> - {% endfor %} + {% endfor %} </table> </body> </html> \ No newline at end of file diff --git a/server/templates/licenses/license_create.html b/server/templates/licenses/license_create.html index 707ce4e..03b9d6a 100644 --- a/server/templates/licenses/license_create.html +++ b/server/templates/licenses/license_create.html @@ -6,12 +6,12 @@ </head> <body> <form action="/licenses-web" method="post"> - <label for="name">Name:</label><br> - <input type="text" id="name" name="name"><br><br> - <label for="lic_id">License ID:</label><br> - <input type="text" id="lic_id" name="lic_id"><br><br> + <label for="name">Name:</label> + <input type="text" id="name" name="name"><br> + <label for="lic_id">License ID:</label> + <input type="text" id="lic_id" name="lic_id"><br> <label for="expdate">Expiration Date</label> - <input type="date" id="expdate" name="expdate" min={{minimum_date}}> + <input type="date" id="expdate" name="expdate" min={{minimum_date}}><br> <input type="submit" value="Submit"> </form> </body> diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html index a723452..ec873ad 100644 --- a/server/templates/pcs/pcs.html +++ b/server/templates/pcs/pcs.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web" selected>PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/pcs/pcs_normal.html b/server/templates/pcs/pcs_normal.html index 1ca892d..c5051aa 100644 --- a/server/templates/pcs/pcs_normal.html +++ b/server/templates/pcs/pcs_normal.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web" selected>PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/teams/team_change.html b/server/templates/teams/team_change.html index 3ef6f23..247d43b 100644 --- a/server/templates/teams/team_change.html +++ b/server/templates/teams/team_change.html @@ -7,8 +7,8 @@ <body> <h4>Team: {{team.name}}</h4> <form action="/teams-change-process/{{team.id}}" method="post"> - <label for="name">Name:</label><br> - <input type="text" id="name" name="name"><br><br> + <label for="name">Name:</label> + <input type="text" id="name" name="name"><br> <input type="submit" value="Submit"> </form> </body> diff --git a/server/templates/teams/team_create.html b/server/templates/teams/team_create.html index 28fb63d..85fc777 100644 --- a/server/templates/teams/team_create.html +++ b/server/templates/teams/team_create.html @@ -6,8 +6,8 @@ </head> <body> <form action="/teams-web-con" method="post"> - <label for="name">Name:</label><br> - <input type="text" id="name" name="name"><br><br> + <label for="name">Name:</label> + <input type="text" id="name" name="name"><br> <input type="submit" value="Submit"> </form> </body> diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html index 6957999..539f3da 100644 --- a/server/templates/teams/teams.html +++ b/server/templates/teams/teams.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web" selected>Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/teams/teams_normal.html b/server/templates/teams/teams_normal.html index c928f52..2a2ac88 100644 --- a/server/templates/teams/teams_normal.html +++ b/server/templates/teams/teams_normal.html @@ -49,7 +49,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web" selected>Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/usb-logs/crossroad.html b/server/templates/usb-logs/crossroad.html index 01db9b9..3f16cf0 100644 --- a/server/templates/usb-logs/crossroad.html +++ b/server/templates/usb-logs/crossroad.html @@ -12,7 +12,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> @@ -24,34 +25,50 @@ <table> <TR> <TH>URL</TH> + <TH>Name</TH> <TH>Purpose</TH> </TR> <TR> <TD class="URL">/logs-web</TD> - <TD class="Purpose">Shows all saves Keyman logs. User can filter through license, team and user</TD> + <TD class="Name">Vector Logs</TD> + <TD class="Purpose">Shows all saved Keyman logs. User can filter through license, team and user</TD> </TR> <TR> <TD class="URL">/ldlogs-web</TD> - <TD class="Purpose">Shows all saves LD debugger logs. User can filter through license, team and user</TD> + <TD class="Name">Lauterbach Logs</TD> + <TD class="Purpose">Shows all saved LD debugger logs. User can filter through license, team and user</TD> </TR> <TR> <TD class="URL">/devices-web</TD> - <TD class="Purpose">Shows all Keyman devices saved in database and its last state (connected, disconnected)</TD> + <TD class="Name">Keyman Devices</TD> + <TD class="Purpose">Shows all Keyman devices saved in database and its license, inventory number, last pc and + last detection. User can filter through keyman id, license type, license id and team</TD> </TR> <TR> <TD class="URL">/body-devices-web</TD> - <TD class="Purpose">Shows all LD Body devices saved in database and its last state (connected, disconnected)</TD> + <TD class="Name">Lauterbach Body Devices</TD> + <TD class="Purpose">Shows all Lauterbach Body devices saved in database and its license, inventory number, last pc and + last detection. User can filter through body device serial nummber, license id and team</TD> + </TR> + <TR> + <TD class="URL">/head-devices-web</TD> + <TD class="Name">Lauterbach Head Devices</TD> + <TD class="Purpose">Shows all Lauterbach Head devices saved in database and its license, inventory number, last pc and + last detection. User can filter through body device serial nummber, license id and team</TD> </TR> <TR> <TD class="URL">/teams-web</TD> - <TD class="Purpose">Shows all teams currently saved in database and its members</TD> + <TD class="Name">Teams</TD> + <TD class="Purpose">Shows all teams currently saved in database</TD> </TR> <TR> <TD class="URL">/pcs-web</TD> - <TD class="Purpose">Shows all PCS currently saved in database and its team</TD> + <TD class="Name">PCs</TD> + <TD class="Purpose">Shows all PCS currently saved in database</TD> </TR> <TR> <TD class="URL">/licenses-web</TD> + <TD class="Name">Licenses</TD> <TD class="Purpose">Shows all Licenses currently saved in database and its expiration date</TD> </TR> </table> diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html index 34e14cd..fdecc00 100644 --- a/server/templates/usb-logs/logs.html +++ b/server/templates/usb-logs/logs.html @@ -49,7 +49,8 @@ <option value="/logs-web" selected>Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html index 99c3a9c..d954447 100644 --- a/server/templates/usb-logs/logs_normal.html +++ b/server/templates/usb-logs/logs_normal.html @@ -49,7 +49,8 @@ <option value="/logs-web" selected>Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> diff --git a/server/templates/users/users.html b/server/templates/users/users.html index 6b56b9a..bdbec4b 100644 --- a/server/templates/users/users.html +++ b/server/templates/users/users.html @@ -46,7 +46,8 @@ <option value="/logs-web">Vector Logs</option> <option value="/ldlogs-web">Lauterbach Logs</option> <option value="/devices-web">Keyman Devices</option> - <option value="/body-devices-web">Lauterbach Devices</option> + <option value="/body-devices-web">Lauterbach Body Devices</option> + <option value="/head-devices-web">Lauterbach Head Devices</option> <option value="/teams-web">Teams</option> <option value="/pcs-web">PCs</option> <option value="/licenses-web">Licenses</option> -- GitLab From 709c735b187f6b414aed23b5760330c5e0336305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Zeman?= <zemanm98@students.zcu.cz> Date: Sun, 15 May 2022 13:56:30 +0000 Subject: [PATCH 65/67] README, changed main page url --- server/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/README.md b/server/README.md index c75cf40..7b87216 100644 --- a/server/README.md +++ b/server/README.md @@ -30,7 +30,7 @@ And docker will create image for server application and postgresql database. Dat Data from database are easily accesibly from web browser. Main web views url is ```bash -http://localhost:8000/api/v1/logs-web +http://localhost:8000/ ``` On this page there is select box at the top of the page for accessing different views on other data in database as well as creating new ones -- GitLab From a7d16717c1525c98c69e7d2ece752095857bc715 Mon Sep 17 00:00:00 2001 From: Pultak <pultak5@gmail.com> Date: Mon, 16 May 2022 13:36:35 +0200 Subject: [PATCH 66/67] re #9845 tests fix after refactoring --- ld_client/LDClient/detection/AInfoFetcher.cs | 2 +- ld_client/LDClient/network/ApiClient.cs | 1 + ld_client/LDClientTests/detection/InfoFetcherTests.cs | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ld_client/LDClient/detection/AInfoFetcher.cs b/ld_client/LDClient/detection/AInfoFetcher.cs index bdacb4a..2b61efa 100644 --- a/ld_client/LDClient/detection/AInfoFetcher.cs +++ b/ld_client/LDClient/detection/AInfoFetcher.cs @@ -115,7 +115,7 @@ public abstract class AInfoFetcher : IInfoFetcher { BodySerialNumber = bodySerialNumber; // Finally, delete the file. - //File.Delete(filePath); + File.Delete(filePath); } catch (Exception exception) { Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}"); return false; diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs index 8668e54..792505a 100644 --- a/ld_client/LDClient/network/ApiClient.cs +++ b/ld_client/LDClient/network/ApiClient.cs @@ -70,6 +70,7 @@ namespace LDClient.network { /// </summary> /// <param name="payload">instance of a payload to be sent off to the server</param> public async Task SendPayloadAsync(Payload payload) { + Program.DefaultLogger.Debug("SendPayloadAsync called."); try { // Create an instance of Stopwatch (to measure how much // the action took). diff --git a/ld_client/LDClientTests/detection/InfoFetcherTests.cs b/ld_client/LDClientTests/detection/InfoFetcherTests.cs index 3285226..35020fa 100644 --- a/ld_client/LDClientTests/detection/InfoFetcherTests.cs +++ b/ld_client/LDClientTests/detection/InfoFetcherTests.cs @@ -8,8 +8,8 @@ using NUnit.Framework; namespace LDClientTests.detection; internal class InfoFetcherTests { - private InfoFetcher _defaultFetcher; - private InfoFetcher _fetcherWithoutPars; + private AInfoFetcher _defaultFetcher; + private AInfoFetcher _fetcherWithoutPars; private readonly string[] _defaultArguments = new[] { "argument 1", "argument 2" , "argument 3"}; @@ -25,14 +25,14 @@ internal class InfoFetcherTests { _mockFileUtils = new Mock<IFileUtils>(MockBehavior.Strict); - _defaultFetcher = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe", + _defaultFetcher = new T32RemFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe", _defaultArguments, 0, 50) { FileUtils = _mockFileUtils.Object, ProcessUtils = _mockProcessUtils.Object }; - _fetcherWithoutPars = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe", + _fetcherWithoutPars = new T32RemFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe", null, 0, 50) { FileUtils = _mockFileUtils.Object, ProcessUtils = _mockProcessUtils.Object -- GitLab From 93d0ec10d1deeb8c7388559f49aa07ad536d5c52 Mon Sep 17 00:00:00 2001 From: Matej Zeman <zeman339@gmail.com> Date: Mon, 16 May 2022 17:08:02 +0200 Subject: [PATCH 67/67] re #9846 Filter text fields keeps their searched content. --- server/sql_app/api/bodydevices_web.py | 18 +++++++++--- server/sql_app/api/devices_web.py | 22 +++++++++++--- server/sql_app/api/headdevices_web.py | 18 +++++++++--- server/sql_app/api/ld_logs_web.py | 18 +++++++++--- server/sql_app/api/usb_logs_web.py | 21 ++++++++++---- server/sql_app/api/users_web.py | 2 +- .../templates/body-devices/body_devices.html | 6 ++-- .../body-devices/body_devices_normal.html | 6 ++-- server/templates/devices/devices.html | 8 ++--- server/templates/devices/devices_normal.html | 29 ++++++++++++++++--- .../templates/head_devices/head_devices.html | 6 ++-- .../head_devices/head_devices_normal.html | 6 ++-- server/templates/ld-logs/ldlogs.html | 6 ++-- server/templates/ld-logs/ldlogs_normal.html | 6 ++-- server/templates/usb-logs/logs.html | 6 ++-- server/templates/usb-logs/logs_normal.html | 6 ++-- server/templates/users/users.html | 3 ++ 17 files changed, 132 insertions(+), 55 deletions(-) diff --git a/server/sql_app/api/bodydevices_web.py b/server/sql_app/api/bodydevices_web.py index b00c8d8..26ae5f9 100644 --- a/server/sql_app/api/bodydevices_web.py +++ b/server/sql_app/api/bodydevices_web.py @@ -48,12 +48,14 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se if current_user == "admin": return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": "", "lic_val": "", + "team_val": ""}) else: current_user = "guest" return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": "", "lic_val": "", + "team_val": ""}) @body_device_web.post("/body-devices-web", response_class=HTMLResponse) @@ -77,16 +79,24 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic = crud.get_license(db, dev.license_id) device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) + if body_id == "all": + body_id = "" + if lic_id == "all": + lic_id = "" + if team == "all": + team = "" if current_user == "admin": return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": body_id, "lic_val": lic_id, + "team_val": team}) else: current_user = "guest" return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": body_id, "lic_val": lic_id, + "team_val": team}) @body_device_web.get("/body-device-license/{device_id}", response_class=HTMLResponse) diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py index ff0f029..82f9458 100644 --- a/server/sql_app/api/devices_web.py +++ b/server/sql_app/api/devices_web.py @@ -51,12 +51,15 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se licenses = crud.get_licenses(db, skip=skip, limit=limit) if current_user == "admin": return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, - "licenses": licenses, "devs": devices, + "licenses": licenses, "devs": devices, "keyman_val": "", + "licn_val": "", "lici_val": "", "team_val": "", "teams": teams, "user": current_user}) else: current_user = "guest" return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "devs": devices, "keyman_val": "", + "licn_val": "", "lici_val": "", "team_val": "", + "teams": teams, "user": current_user}) @device_web.post("/devices-web", response_class=HTMLResponse) @@ -85,14 +88,25 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, else: device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) + if keyman_id == "all": + keyman_id = "" + if lic_name == "all": + lic_name = "" + if lic_id == "all": + lic_id = "" + if team == "all": + team = "" if current_user == "admin": return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict, - "licenses": licenses, "devs": devices, + "licenses": licenses, "devs": devices, "keyman_val": keyman_id, + "licn_val": lic_name, "lici_val": lic_id, "team_val": team, "teams": teams, "user": current_user}) else: current_user = "guest" return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "devs": devices, "keyman_val": keyman_id, + "licn_val": lic_name, "lici_val": lic_id, "team_val": team, + "teams": teams, "user": current_user}) @device_web.get("/device-license/{device_id}", response_class=HTMLResponse) diff --git a/server/sql_app/api/headdevices_web.py b/server/sql_app/api/headdevices_web.py index 2e6452b..974d128 100644 --- a/server/sql_app/api/headdevices_web.py +++ b/server/sql_app/api/headdevices_web.py @@ -48,12 +48,14 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se if current_user == "admin": return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": "", "lic_val": "", + "team_val": ""}) else: current_user = "guest" return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": "", "lic_val": "", + "team_val": ""}) @head_device_web.post("/head-devices-web", response_class=HTMLResponse) @@ -77,16 +79,24 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic = crud.get_license(db, dev.license_id) device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]}) licenses = crud.get_licenses(db, skip=skip, limit=limit) + if body_id == "all": + body_id = "" + if lic_id == "all": + lic_id = "" + if team == "all": + team = "" if current_user == "admin": return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": body_id, "lic_val": lic_id, + "team_val": team}) else: current_user = "guest" return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict, "devs": devices, "teams": teams, "licenses": licenses, - "user": current_user}) + "user": current_user, "body_val": body_id, "lic_val": lic_id, + "team_val": team}) @head_device_web.get("/head-device-license/{device_id}", response_class=HTMLResponse) diff --git a/server/sql_app/api/ld_logs_web.py b/server/sql_app/api/ld_logs_web.py index aef3733..c2059fb 100644 --- a/server/sql_app/api/ld_logs_web.py +++ b/server/sql_app/api/ld_logs_web.py @@ -46,12 +46,14 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi licenses = crud.get_licenses(db, skip=skip, limit=limit) if current_user == "admin": return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": "", + "team_val": "", "lic_val": ""}) else: current_user = "guest" return templates.TemplateResponse("ldlogs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": "", + "team_val": "", "lic_val": ""}) @ldlogs_web.post("/ldlogs-web", response_class=HTMLResponse) @@ -71,11 +73,19 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form( pc_obj = crud.get_pcs(db, skip=skip, limit=limit) teams = crud.get_teams(db, skip=skip, limit=limit) licenses = crud.get_licenses(db, skip=skip, limit=limit) + if team == "all": + team = "" + if pc == "all": + pc = "" + if lic == "all": + lic = "" if current_user == "admin": return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": pc, + "team_val": team, "lic_val": lic}) else: current_user = "guest" return templates.TemplateResponse("ldlogs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": pc, + "team_val": team, "lic_val": lic}) diff --git a/server/sql_app/api/usb_logs_web.py b/server/sql_app/api/usb_logs_web.py index 75ebdc6..13729ef 100644 --- a/server/sql_app/api/usb_logs_web.py +++ b/server/sql_app/api/usb_logs_web.py @@ -46,17 +46,18 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi licenses = crud.get_licenses(db, skip=skip, limit=limit) if current_user == "admin": return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": "", + "team_val": "", "lic_val": ""}) else: current_user = "guest" return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": "", + "team_val": "", "lic_val": ""}) @usblogs_web.post("/logs-web", response_class=HTMLResponse) async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"), - skip: int = 0, limit: int = 100, - db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): + skip: int = 0, limit: int = 100, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): """ Endpoint used for filtering usb logs by user given form inputs. """ @@ -70,13 +71,21 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form( pc_obj = crud.get_pcs(db, skip=skip, limit=limit) teams = crud.get_teams(db, skip=skip, limit=limit) licenses = crud.get_licenses(db, skip=skip, limit=limit) + if team == "all": + team = "" + if pc == "all": + pc = "" + if lic == "all": + lic = "" if current_user == "admin": return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": pc, + "team_val": team, "lic_val": lic}) else: current_user = "guest" return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, - "licenses": licenses, "user": current_user}) + "licenses": licenses, "user": current_user, "pc_val": pc, + "team_val": team, "lic_val": lic}) @usblogs_web.get("/", response_class=HTMLResponse) diff --git a/server/sql_app/api/users_web.py b/server/sql_app/api/users_web.py index 523b22f..41a49d0 100644 --- a/server/sql_app/api/users_web.py +++ b/server/sql_app/api/users_web.py @@ -37,7 +37,7 @@ async def read_usrs(request: Request, skip: int = 0, limit: int = 100, db: Sessi current_user = Authorize.get_jwt_subject() users = crud.get_users(db, skip, limit) if current_user == "admin": - return templates.TemplateResponse("users.html", {"request": request, "users": users}) + return templates.TemplateResponse("users.html", {"request": request, "users": users, "user": current_user}) else: return RedirectResponse(url=f"/logs-web", status_code=303) diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html index 3492e41..8eff2b3 100644 --- a/server/templates/body-devices/body_devices.html +++ b/server/templates/body-devices/body_devices.html @@ -60,21 +60,21 @@ </form> <form action="/body-devices-web" method="post"> <label for="body_id">Body Device ID:</label> - <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();"> <datalist id="body_ids"> {% for dev in devs %} <option value="{{dev.serial_number}}"></option> {% endfor %} </datalist> <label for="lic_id">License ID:</label> - <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses_ids"> {% for license in licenses %} <option value="{{license.license_id}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}">{{team.name}}</option> diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html index 39ba939..f312309 100644 --- a/server/templates/body-devices/body_devices_normal.html +++ b/server/templates/body-devices/body_devices_normal.html @@ -59,21 +59,21 @@ </form> <form action="/body-devices-web" method="post"> <label for="body_id">Body Device ID:</label> - <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();"> <datalist id="body_ids"> {% for dev in devs %} <option value="{{dev.serial_number}}"></option> {% endfor %} </datalist> <label for="lic_id">License ID:</label> - <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses_ids"> {% for license in licenses %} <option value="{{license.license_id}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}">{{team.name}}</option> diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html index 4d8c620..92620fe 100644 --- a/server/templates/devices/devices.html +++ b/server/templates/devices/devices.html @@ -60,28 +60,28 @@ </form> <form action="/devices-web" method="post"> <label for="keyman_id">Keyman ID:</label> - <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="" placeholder="all"> + <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="{{keyman_val}}" placeholder="all" onClick="this.select();"> <datalist id="keyman_ids"> {% for dev in devs %} <option value="{{dev.serial_number}}"></option> {% endfor %} </datalist> <label for="lic_name">License Type:</label> - <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="" placeholder="all"> + <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="{{licn_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses_names"> {% for license in licenses %} <option value="{{license.name}}"></option> {% endfor %} </datalist> <label for="lic_id">License ID:</label> - <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lici_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses_ids"> {% for license in licenses %} <option value="{{license.license_id}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}">{{team.name}}</option> diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html index 1c77480..71f5fb9 100644 --- a/server/templates/devices/devices_normal.html +++ b/server/templates/devices/devices_normal.html @@ -58,13 +58,34 @@ <input type="submit" value="OK"> </form> <form action="/devices-web" method="post"> - <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> - <datalist id="licenses"> + <label for="keyman_id">Keyman ID:</label> + <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="{{keyman_val}}" placeholder="all" onClick="this.select();"> + <datalist id="keyman_ids"> + {% for dev in devs %} + <option value="{{dev.serial_number}}"></option> + {% endfor %} + </datalist> + <label for="lic_name">License Type:</label> + <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="{{licn_val}}" placeholder="all" onClick="this.select();"> + <datalist id="licenses_names"> {% for license in licenses %} <option value="{{license.name}}"></option> {% endfor %} </datalist> + <label for="lic_id">License ID:</label> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lici_val}}" placeholder="all" onClick="this.select();"> + <datalist id="licenses_ids"> + {% for license in licenses %} + <option value="{{license.license_id}}"></option> + {% endfor %} + </datalist> + <label for="team">Team:</label> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> + <datalist id="teams"> + {% for team in teams %} + <option value="{{team.name}}">{{team.name}}</option> + {% endfor %} + </datalist> <input type="submit" value="Filter"> </form> <table id="devices"> @@ -83,7 +104,7 @@ </TR> {% for dev in devices %} <TR> - <TD class="ID">{{dev['device'].id}}</TD> + <TD class="ID"><a href="/device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD> <TD class="Serial Number">{{dev['device'].serial_number}}</TD> <TD class="License">{{dev['license'].name}}</TD> <TD class="License ID">{{dev['license'].license_id}}</TD> diff --git a/server/templates/head_devices/head_devices.html b/server/templates/head_devices/head_devices.html index 42117e4..6c86bda 100644 --- a/server/templates/head_devices/head_devices.html +++ b/server/templates/head_devices/head_devices.html @@ -60,21 +60,21 @@ </form> <form action="/head-devices-web" method="post"> <label for="body_id">Head Device ID:</label> - <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();"> <datalist id="body_ids"> {% for dev in devs %} <option value="{{dev.serial_number}}"></option> {% endfor %} </datalist> <label for="lic_id">License ID:</label> - <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses_ids"> {% for license in licenses %} <option value="{{license.license_id}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}">{{team.name}}</option> diff --git a/server/templates/head_devices/head_devices_normal.html b/server/templates/head_devices/head_devices_normal.html index 8df6d97..baf26a0 100644 --- a/server/templates/head_devices/head_devices_normal.html +++ b/server/templates/head_devices/head_devices_normal.html @@ -59,21 +59,21 @@ </form> <form action="/head-devices-web" method="post"> <label for="body_id">Head Device ID:</label> - <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all"> + <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();"> <datalist id="body_ids"> {% for dev in devs %} <option value="{{dev.serial_number}}"></option> {% endfor %} </datalist> <label for="lic_id">License ID:</label> - <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all"> + <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses_ids"> {% for license in licenses %} <option value="{{license.license_id}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}">{{team.name}}</option> diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html index e7f36cf..cb48627 100644 --- a/server/templates/ld-logs/ldlogs.html +++ b/server/templates/ld-logs/ldlogs.html @@ -60,21 +60,21 @@ </form> <form action="/ldlogs-web" method="post"> <label for="pc">PC:</label> - <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all"> + <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();"> <datalist id="pcs"> {% for pc in pcs %} <option value="{{pc.username}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}"></option> {% endfor %} </datalist> <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> + <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses"> {% for license in licenses %} <option value="{{license.license_id}}"></option> diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html index bcdf40a..c87571f 100644 --- a/server/templates/ld-logs/ldlogs_normal.html +++ b/server/templates/ld-logs/ldlogs_normal.html @@ -59,21 +59,21 @@ </form> <form action="/ldlogs-web" method="post"> <label for="pc">PC:</label> - <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all"> + <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();"> <datalist id="pcs"> {% for pc in pcs %} <option value="{{pc.username}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}"></option> {% endfor %} </datalist> <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> + <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses"> {% for license in licenses %} <option value="{{license.name}} : {{license.license_id}}"></option> diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html index fdecc00..3bafd19 100644 --- a/server/templates/usb-logs/logs.html +++ b/server/templates/usb-logs/logs.html @@ -60,21 +60,21 @@ </form> <form action="/logs-web" method="post"> <label for="pc">PC:</label> - <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all"> + <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();"> <datalist id="pcs"> {% for pc in pcs %} <option value="{{pc.username}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}"></option> {% endfor %} </datalist> <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> + <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses"> {% for license in licenses %} <option value="{{license.name}}"></option> diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html index d954447..a43a0e4 100644 --- a/server/templates/usb-logs/logs_normal.html +++ b/server/templates/usb-logs/logs_normal.html @@ -59,21 +59,21 @@ </form> <form action="/logs-web" method="post"> <label for="pc">PC:</label> - <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all"> + <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();"> <datalist id="pcs"> {% for pc in pcs %} <option value="{{pc.username}}"></option> {% endfor %} </datalist> <label for="team">Team:</label> - <input id="team" name="team" type="text" list="teams" value="" placeholder="all"> + <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();"> <datalist id="teams"> {% for team in teams %} <option value="{{team.name}}"></option> {% endfor %} </datalist> <label for="lic">License:</label> - <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> + <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();"> <datalist id="licenses"> {% for license in licenses %} <option value="{{license.name}}"></option> diff --git a/server/templates/users/users.html b/server/templates/users/users.html index bdbec4b..1f71950 100644 --- a/server/templates/users/users.html +++ b/server/templates/users/users.html @@ -27,6 +27,9 @@ <title>Users Details</title> </head> <body> +<div style='float:left;padding-right:20px'> +<b>Your role: {{user}}</b> +</div> <div style='float:left;padding-right:5px'> <form action="/login" method="get"> <input type="submit" value="Login" /> -- GitLab