mirror of
https://github.com/PepperDash/PepperDashCore.git
synced 2026-02-12 11:14:54 +00:00
Working through little details on ecs-213
This commit is contained in:
Binary file not shown.
@@ -172,12 +172,6 @@ namespace PepperDash.Core
|
||||
}
|
||||
}
|
||||
|
||||
public enum ErrorLogLevel
|
||||
{
|
||||
Error, Warning, Notice, None
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Writes the memory object after timeout
|
||||
/// </summary>
|
||||
@@ -241,5 +235,12 @@ namespace PepperDash.Core
|
||||
{
|
||||
return string.Format(@"\NVRAM\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
|
||||
}
|
||||
|
||||
public enum ErrorLogLevel
|
||||
{
|
||||
Error, Warning, Notice, None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,24 +3,253 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronDataStore;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core.DebugThings;
|
||||
|
||||
namespace PepperDash_Core.Debug
|
||||
|
||||
namespace PepperDash.Core
|
||||
{
|
||||
public class DebugContext
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public class DebugContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the folder location where a given program stores it's debug level memory. By default, the
|
||||
/// file written will be named appNdebug where N is 1-10.
|
||||
/// </summary>
|
||||
public string Key { get; private set; }
|
||||
|
||||
public int Level { get; private set; }
|
||||
///// <summary>
|
||||
///// The name of the file containing the current debug settings.
|
||||
///// </summary>
|
||||
//string FileName = string.Format(@"\nvram\debug\app{0}Debug.json", InitialParametersClass.ApplicationNumber);
|
||||
|
||||
public List<string> Keys { get; private set; }
|
||||
DebugContextSaveData SaveData;
|
||||
|
||||
int SaveTimeoutMs = 30000;
|
||||
|
||||
CTimer SaveTimer;
|
||||
|
||||
|
||||
static List<DebugContext> Contexts = new List<DebugContext>();
|
||||
|
||||
public DebugContext(string name)
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates or gets a debug context
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static DebugContext GetDebugContext(string key)
|
||||
{
|
||||
var context = Contexts.FirstOrDefault(c => c.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
if (context == null)
|
||||
{
|
||||
context = new DebugContext(key);
|
||||
Contexts.Add(context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Do not use. For S+ access.
|
||||
/// </summary>
|
||||
public DebugContext() { }
|
||||
|
||||
DebugContext(string key)
|
||||
{
|
||||
Key = key;
|
||||
if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
|
||||
{
|
||||
// Add command to console
|
||||
CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
|
||||
"appdebug:P [0-2]: Sets the application's console debug message level",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
}
|
||||
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
|
||||
|
||||
LoadMemory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to save memory when shutting down
|
||||
/// </summary>
|
||||
/// <param name="programEventType"></param>
|
||||
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
||||
{
|
||||
if (programEventType == eProgramStatusEventType.Stopping)
|
||||
{
|
||||
if (SaveTimer != null)
|
||||
{
|
||||
SaveTimer.Stop();
|
||||
SaveTimer = null;
|
||||
}
|
||||
Console(0, "Saving debug settings");
|
||||
SaveMemory();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for console command
|
||||
/// </summary>
|
||||
/// <param name="levelString"></param>
|
||||
public void SetDebugFromConsole(string levelString)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(levelString.Trim()))
|
||||
{
|
||||
CrestronConsole.PrintLine("AppDebug level = {0}", SaveData.Level);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDebugLevel(Convert.ToInt32(levelString));
|
||||
}
|
||||
catch
|
||||
{
|
||||
CrestronConsole.PrintLine("Usage: appdebug:P [0-2]");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the debug level
|
||||
/// </summary>
|
||||
/// <param name="level"> Valid values 0 (no debug), 1 (critical), 2 (all messages)</param>
|
||||
public void SetDebugLevel(int level)
|
||||
{
|
||||
if (level <= 2)
|
||||
{
|
||||
SaveData.Level = level;
|
||||
SaveMemoryOnTimeout();
|
||||
|
||||
CrestronConsole.PrintLine("[Application {0}], Debug level set to {1}",
|
||||
InitialParametersClass.ApplicationNumber, SaveData.Level);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints message to console if current debug level is equal to or higher than the level of this message.
|
||||
/// Uses CrestronConsole.PrintLine.
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="format">Console format string</param>
|
||||
/// <param name="items">Object parameters</param>
|
||||
public void Console(uint level, string format, params object[] items)
|
||||
{
|
||||
if (SaveData.Level >= level)
|
||||
CrestronConsole.PrintLine("App {0}:{1}", InitialParametersClass.ApplicationNumber,
|
||||
string.Format(format, items));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a device Key to the beginning of a message
|
||||
/// </summary>
|
||||
public void Console(uint level, IKeyed dev, string format, params object[] items)
|
||||
{
|
||||
if (SaveData.Level >= level)
|
||||
Console(level, "[{0}] {1}", dev.Key, string.Format(format, items));
|
||||
}
|
||||
|
||||
public void Console(uint level, IKeyed dev, Debug.ErrorLogLevel errorLogLevel,
|
||||
string format, params object[] items)
|
||||
{
|
||||
if (SaveData.Level >= level)
|
||||
{
|
||||
var str = string.Format("[{0}] {1}", dev.Key, string.Format(format, items));
|
||||
Console(level, str);
|
||||
LogError(errorLogLevel, str);
|
||||
}
|
||||
}
|
||||
|
||||
public void Console(uint level, Debug.ErrorLogLevel errorLogLevel,
|
||||
string format, params object[] items)
|
||||
{
|
||||
if (SaveData.Level >= level)
|
||||
{
|
||||
var str = string.Format(format, items);
|
||||
Console(level, str);
|
||||
LogError(errorLogLevel, str);
|
||||
}
|
||||
}
|
||||
|
||||
public void LogError(Debug.ErrorLogLevel errorLogLevel, string str)
|
||||
{
|
||||
string msg = string.Format("App {0}:{1}", InitialParametersClass.ApplicationNumber, str);
|
||||
switch (errorLogLevel)
|
||||
{
|
||||
case Debug.ErrorLogLevel.Error:
|
||||
ErrorLog.Error(msg);
|
||||
break;
|
||||
case Debug.ErrorLogLevel.Warning:
|
||||
ErrorLog.Warn(msg);
|
||||
break;
|
||||
case Debug.ErrorLogLevel.Notice:
|
||||
ErrorLog.Notice(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the memory object after timeout
|
||||
/// </summary>
|
||||
void SaveMemoryOnTimeout()
|
||||
{
|
||||
if (SaveTimer == null)
|
||||
SaveTimer = new CTimer(o =>
|
||||
{
|
||||
SaveTimer = null;
|
||||
SaveMemory();
|
||||
}, SaveTimeoutMs);
|
||||
else
|
||||
SaveTimer.Reset(SaveTimeoutMs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the memory - use SaveMemoryOnTimeout
|
||||
/// </summary>
|
||||
void SaveMemory()
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(GetMemoryFileName()))
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(SaveData);
|
||||
sw.Write(json);
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void LoadMemory()
|
||||
{
|
||||
var file = GetMemoryFileName();
|
||||
if (File.Exists(file))
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(file))
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<DebugContextSaveData>(sr.ReadToEnd());
|
||||
if (data != null)
|
||||
{
|
||||
SaveData = data;
|
||||
Debug.Console(0, "Debug memory restored from file");
|
||||
return;
|
||||
}
|
||||
else
|
||||
SaveData = new DebugContextSaveData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to get the file path for this app's debug memory
|
||||
/// </summary>
|
||||
string GetMemoryFileName()
|
||||
{
|
||||
return string.Format(@"\NVRAM\debugSettings\program{0}-{1}", InitialParametersClass.ApplicationNumber, Key);
|
||||
}
|
||||
}
|
||||
|
||||
public class DebugContextSaveData
|
||||
{
|
||||
public int Level { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,17 @@ namespace PepperDash.Core
|
||||
public string Key { get; protected set; }
|
||||
public string Name { get; protected set; }
|
||||
public bool Enabled { get; protected set; }
|
||||
|
||||
///// <summary>
|
||||
///// A place to store reference to the original config object, if any. These values should
|
||||
///// NOT be used as properties on the device as they are all publicly-settable values.
|
||||
///// </summary>
|
||||
//public DeviceConfig Config { get; private set; }
|
||||
///// <summary>
|
||||
///// Helper method to check if Config exists
|
||||
///// </summary>
|
||||
//public bool HasConfig { get { return Config != null; } }
|
||||
|
||||
List<Action> _PreActivationActions;
|
||||
List<Action> _PostActivationActions;
|
||||
|
||||
@@ -35,6 +46,12 @@ namespace PepperDash.Core
|
||||
Name = name;
|
||||
}
|
||||
|
||||
//public Device(DeviceConfig config)
|
||||
// : this(config.Key, config.Name)
|
||||
//{
|
||||
// Config = config;
|
||||
//}
|
||||
|
||||
public void AddPreActivationAction(Action act)
|
||||
{
|
||||
if (_PreActivationActions == null)
|
||||
|
||||
59
Pepperdash Core/Pepperdash Core/DeviceConfig.cs
Normal file
59
Pepperdash Core/Pepperdash Core/DeviceConfig.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using Crestron.SimplSharp;
|
||||
//using Newtonsoft.Json;
|
||||
//using Newtonsoft.Json.Linq;
|
||||
|
||||
//namespace PepperDash.Core
|
||||
//{
|
||||
// public class DeviceConfig
|
||||
// {
|
||||
// [JsonProperty("key")]
|
||||
// public string Key { get; set; }
|
||||
|
||||
// [JsonProperty("name")]
|
||||
// public string Name { get; set; }
|
||||
|
||||
// [JsonProperty("group")]
|
||||
// public string Group { get; set; }
|
||||
|
||||
// [JsonProperty("type")]
|
||||
// public string Type { get; set; }
|
||||
|
||||
// [JsonProperty("properties")]
|
||||
// [JsonConverter(typeof(DevicePropertiesConverter))]
|
||||
// public JToken Properties { get; set; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// public class DevicePropertiesConverter : JsonConverter
|
||||
// {
|
||||
|
||||
// public override bool CanConvert(Type objectType)
|
||||
// {
|
||||
// return objectType == typeof(JToken);
|
||||
// }
|
||||
|
||||
// public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
// {
|
||||
// return JToken.ReadFrom(reader);
|
||||
// }
|
||||
|
||||
// public override bool CanWrite
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
// {
|
||||
// throw new NotImplementedException("SOD OFF HOSER");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -74,6 +74,7 @@
|
||||
<Compile Include="Debug\DebugContext.cs" />
|
||||
<Compile Include="Debug\DebugMemory.cs" />
|
||||
<Compile Include="Device.cs" />
|
||||
<Compile Include="DeviceConfig.cs" />
|
||||
<Compile Include="EthernetHelper.cs" />
|
||||
<Compile Include="Comm\GenericTcpIpClient.cs" />
|
||||
<Compile Include="JsonToSimpl\EventArgs and Constants.cs" />
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
2/15/2017 4:28:49 PM, Info: Initializing SIMPLSharp Services...
|
||||
2/15/2017 4:28:49 PM, Info: ProjectInfo successfully initialized.
|
||||
2/15/2017 4:30:33 PM, Info: Saving project information...
|
||||
2/15/2017 4:30:33 PM, Info: Saving project information...
|
||||
2/15/2017 4:30:33 PM, Info: Saving project information...
|
||||
2/15/2017 4:30:33 PM, Info: Saving project information...
|
||||
2/15/2017 4:30:35 PM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/15/2017 4:30:35 PM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/15/2017 4:30:35 PM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/15/2017 4:30:36 PM, Info: Saving project information...
|
||||
2/15/2017 5:05:01 PM, Info: Terminating SIMPLSharp Services
|
||||
@@ -0,0 +1,15 @@
|
||||
2/16/2017 8:22:09 AM, Info: Initializing SIMPLSharp Services...
|
||||
2/16/2017 8:22:09 AM, Info: ProjectInfo successfully initialized.
|
||||
2/16/2017 8:48:07 AM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/16/2017 8:48:07 AM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/16/2017 8:48:08 AM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/16/2017 8:48:08 AM, Info: Saving project information...
|
||||
2/16/2017 8:49:21 AM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/16/2017 8:49:21 AM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/16/2017 8:49:21 AM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/16/2017 8:49:22 AM, Info: Saving project information...
|
||||
2/16/2017 10:06:57 AM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/16/2017 10:06:58 AM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/16/2017 10:06:58 AM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/16/2017 10:06:58 AM, Info: Saving project information...
|
||||
2/16/2017 11:15:30 AM, Info: Terminating SIMPLSharp Services
|
||||
@@ -0,0 +1,29 @@
|
||||
2/21/2017 1:03:05 PM, Info: Initializing SIMPLSharp Services...
|
||||
2/21/2017 1:03:05 PM, Info: ProjectInfo successfully initialized.
|
||||
2/21/2017 1:07:59 PM, Info: Saving project information...
|
||||
2/21/2017 1:07:59 PM, Info: Saving project information...
|
||||
2/21/2017 1:08:34 PM, Info: Saving project information...
|
||||
2/21/2017 1:08:34 PM, Info: Saving project information...
|
||||
2/21/2017 1:08:34 PM, Info: Saving project information...
|
||||
2/21/2017 1:08:34 PM, Info: Saving project information...
|
||||
2/21/2017 1:08:36 PM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/21/2017 1:08:37 PM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/21/2017 1:08:37 PM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/21/2017 1:08:38 PM, Info: Saving project information...
|
||||
2/21/2017 1:10:56 PM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/21/2017 1:10:56 PM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/21/2017 1:10:56 PM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/21/2017 1:10:56 PM, Info: Saving project information...
|
||||
2/21/2017 1:18:40 PM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/21/2017 1:18:41 PM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/21/2017 1:18:41 PM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/21/2017 1:18:41 PM, Info: Saving project information...
|
||||
2/21/2017 2:28:05 PM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/21/2017 2:28:06 PM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/21/2017 2:28:06 PM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/21/2017 2:28:06 PM, Info: Saving project information...
|
||||
2/21/2017 2:28:40 PM, Info: Validating assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll...
|
||||
2/21/2017 2:28:40 PM, Info: Verifying assembly C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
2/21/2017 2:28:40 PM, Info: Creating Archive C:\Users\hvolmer\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.clz...
|
||||
2/21/2017 2:28:40 PM, Info: Saving project information...
|
||||
2/21/2017 4:31:01 PM, Info: Terminating SIMPLSharp Services
|
||||
Binary file not shown.
@@ -10,8 +10,8 @@
|
||||
<ArchiveName />
|
||||
</RequiredInfo>
|
||||
<OptionalInfo>
|
||||
<CompiledOn>2/15/2017 4:30:35 PM</CompiledOn>
|
||||
<CompilerRev>1.0.6255.29716</CompilerRev>
|
||||
<CompiledOn>2/21/2017 2:28:40 PM</CompiledOn>
|
||||
<CompilerRev>1.0.6261.26042</CompilerRev>
|
||||
</OptionalInfo>
|
||||
<Plugin>
|
||||
<Version>Crestron.SIMPLSharp, Version=2.0.48.0, Culture=neutral, PublicKeyToken=812d080f93e2de10</Version>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
MainAssembly=PepperDash_Core.dll:15c0159d41d05e8dc532bb46356b033d
|
||||
MainAssembly=PepperDash_Core.dll:f8093aacbe4fa6cef78b7af4d978e897
|
||||
MainAssemblyMinFirmwareVersion=1.007.0017
|
||||
MainAssemblyResource=SimplSharpData.dat:315526abf906cded47fb0c7510266a7e
|
||||
ü
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user