diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs
new file mode 100644
index 0000000000..ac27476408
--- /dev/null
+++ b/Emby.Common.Implementations/BaseApplicationHost.cs
@@ -0,0 +1,773 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Events;
+using Emby.Common.Implementations.Devices;
+using Emby.Common.Implementations.IO;
+using Emby.Common.Implementations.ScheduledTasks;
+using Emby.Common.Implementations.Serialization;
+using Emby.Common.Implementations.Updates;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Plugins;
+using MediaBrowser.Common.Progress;
+using MediaBrowser.Common.Security;
+using MediaBrowser.Common.Updates;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Updates;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Extensions;
+using Emby.Common.Implementations.Cryptography;
+using MediaBrowser.Common;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.System;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations
+{
+ ///
+ /// Class BaseApplicationHost
+ ///
+ /// The type of the T application paths type.
+ public abstract class BaseApplicationHost : IApplicationHost
+ where TApplicationPathsType : class, IApplicationPaths
+ {
+ ///
+ /// Occurs when [has pending restart changed].
+ ///
+ public event EventHandler HasPendingRestartChanged;
+
+ ///
+ /// Occurs when [application updated].
+ ///
+ public event EventHandler> ApplicationUpdated;
+
+ ///
+ /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart.
+ ///
+ /// true if this instance has pending application restart; otherwise, false.
+ public bool HasPendingRestart { get; private set; }
+
+ ///
+ /// Gets or sets the logger.
+ ///
+ /// The logger.
+ protected ILogger Logger { get; private set; }
+
+ ///
+ /// Gets or sets the plugins.
+ ///
+ /// The plugins.
+ public IPlugin[] Plugins { get; protected set; }
+
+ ///
+ /// Gets or sets the log manager.
+ ///
+ /// The log manager.
+ public ILogManager LogManager { get; protected set; }
+
+ ///
+ /// Gets the application paths.
+ ///
+ /// The application paths.
+ protected TApplicationPathsType ApplicationPaths { get; private set; }
+
+ ///
+ /// The json serializer
+ ///
+ public IJsonSerializer JsonSerializer { get; private set; }
+
+ ///
+ /// The _XML serializer
+ ///
+ protected readonly IXmlSerializer XmlSerializer;
+
+ ///
+ /// Gets assemblies that failed to load
+ ///
+ /// The failed assemblies.
+ public List FailedAssemblies { get; protected set; }
+
+ ///
+ /// Gets all concrete types.
+ ///
+ /// All concrete types.
+ public Type[] AllConcreteTypes { get; protected set; }
+
+ ///
+ /// The disposable parts
+ ///
+ protected readonly List DisposableParts = new List();
+
+ ///
+ /// Gets a value indicating whether this instance is first run.
+ ///
+ /// true if this instance is first run; otherwise, false.
+ public bool IsFirstRun { get; private set; }
+
+ ///
+ /// Gets the kernel.
+ ///
+ /// The kernel.
+ protected ITaskManager TaskManager { get; private set; }
+ ///
+ /// Gets the HTTP client.
+ ///
+ /// The HTTP client.
+ public IHttpClient HttpClient { get; private set; }
+ ///
+ /// Gets the network manager.
+ ///
+ /// The network manager.
+ protected INetworkManager NetworkManager { get; private set; }
+
+ ///
+ /// Gets the configuration manager.
+ ///
+ /// The configuration manager.
+ protected IConfigurationManager ConfigurationManager { get; private set; }
+
+ protected IFileSystem FileSystemManager { get; private set; }
+
+ protected IIsoManager IsoManager { get; private set; }
+
+ protected ISystemEvents SystemEvents { get; private set; }
+
+ ///
+ /// Gets the name.
+ ///
+ /// The name.
+ public abstract string Name { get; }
+
+ ///
+ /// Gets a value indicating whether this instance is running as service.
+ ///
+ /// true if this instance is running as service; otherwise, false.
+ public abstract bool IsRunningAsService { get; }
+
+ protected ICryptographyProvider CryptographyProvider = new CryptographyProvider();
+
+ private DeviceId _deviceId;
+ public string SystemId
+ {
+ get
+ {
+ if (_deviceId == null)
+ {
+ _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager);
+ }
+
+ return _deviceId.Value;
+ }
+ }
+
+ public virtual string OperatingSystemDisplayName
+ {
+ get { return Environment.OSVersion.VersionString; }
+ }
+
+ public IMemoryStreamProvider MemoryStreamProvider { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected BaseApplicationHost(TApplicationPathsType applicationPaths,
+ ILogManager logManager,
+ IFileSystem fileSystem)
+ {
+ // hack alert, until common can target .net core
+ BaseExtensions.CryptographyProvider = CryptographyProvider;
+
+ XmlSerializer = new XmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer"));
+ FailedAssemblies = new List();
+
+ ApplicationPaths = applicationPaths;
+ LogManager = logManager;
+ FileSystemManager = fileSystem;
+
+ ConfigurationManager = GetConfigurationManager();
+
+ // Initialize this early in case the -v command line option is used
+ Logger = LogManager.GetLogger("App");
+ }
+
+ ///
+ /// Inits this instance.
+ ///
+ /// Task.
+ public virtual async Task Init(IProgress progress)
+ {
+ progress.Report(1);
+
+ JsonSerializer = CreateJsonSerializer();
+
+ MemoryStreamProvider = CreateMemoryStreamProvider();
+ SystemEvents = CreateSystemEvents();
+
+ OnLoggerLoaded(true);
+ LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
+
+ IsFirstRun = !ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted;
+ progress.Report(2);
+
+ LogManager.LogSeverity = ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging
+ ? LogSeverity.Debug
+ : LogSeverity.Info;
+
+ progress.Report(3);
+
+ DiscoverTypes();
+ progress.Report(14);
+
+ SetHttpLimit();
+ progress.Report(15);
+
+ var innerProgress = new ActionableProgress();
+ innerProgress.RegisterAction(p => progress.Report(.8 * p + 15));
+
+ await RegisterResources(innerProgress).ConfigureAwait(false);
+
+ FindParts();
+ progress.Report(95);
+
+ await InstallIsoMounters(CancellationToken.None).ConfigureAwait(false);
+
+ progress.Report(100);
+ }
+
+ protected abstract IMemoryStreamProvider CreateMemoryStreamProvider();
+ protected abstract ISystemEvents CreateSystemEvents();
+
+ protected virtual void OnLoggerLoaded(bool isFirstLoad)
+ {
+ Logger.Info("Application version: {0}", ApplicationVersion);
+
+ if (!isFirstLoad)
+ {
+ LogEnvironmentInfo(Logger, ApplicationPaths, false);
+ }
+
+ // Put the app config in the log for troubleshooting purposes
+ Logger.LogMultiline("Application configuration:", LogSeverity.Info, new StringBuilder(JsonSerializer.SerializeToString(ConfigurationManager.CommonConfiguration)));
+
+ if (Plugins != null)
+ {
+ var pluginBuilder = new StringBuilder();
+
+ foreach (var plugin in Plugins)
+ {
+ pluginBuilder.AppendLine(string.Format("{0} {1}", plugin.Name, plugin.Version));
+ }
+
+ Logger.LogMultiline("Plugins:", LogSeverity.Info, pluginBuilder);
+ }
+ }
+
+ public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths, bool isStartup)
+ {
+ logger.LogMultiline("Emby", LogSeverity.Info, GetBaseExceptionMessage(appPaths));
+ }
+
+ protected static StringBuilder GetBaseExceptionMessage(IApplicationPaths appPaths)
+ {
+ var builder = new StringBuilder();
+
+ builder.AppendLine(string.Format("Command line: {0}", string.Join(" ", Environment.GetCommandLineArgs())));
+
+ builder.AppendLine(string.Format("Operating system: {0}", Environment.OSVersion));
+ builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount));
+ builder.AppendLine(string.Format("64-Bit OS: {0}", Environment.Is64BitOperatingSystem));
+ builder.AppendLine(string.Format("64-Bit Process: {0}", Environment.Is64BitProcess));
+ builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath));
+
+ Type type = Type.GetType("Mono.Runtime");
+ if (type != null)
+ {
+ MethodInfo displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
+ if (displayName != null)
+ {
+ builder.AppendLine("Mono: " + displayName.Invoke(null, null));
+ }
+ }
+
+ builder.AppendLine(string.Format("Application Path: {0}", appPaths.ApplicationPath));
+
+ return builder;
+ }
+
+ protected abstract IJsonSerializer CreateJsonSerializer();
+
+ private void SetHttpLimit()
+ {
+ try
+ {
+ // Increase the max http request limit
+ ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit);
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error setting http limit", ex);
+ }
+ }
+
+ ///
+ /// Installs the iso mounters.
+ ///
+ /// The cancellation token.
+ /// Task.
+ private async Task InstallIsoMounters(CancellationToken cancellationToken)
+ {
+ var list = new List();
+
+ foreach (var isoMounter in GetExports())
+ {
+ try
+ {
+ if (isoMounter.RequiresInstallation && !isoMounter.IsInstalled)
+ {
+ Logger.Info("Installing {0}", isoMounter.Name);
+
+ await isoMounter.Install(cancellationToken).ConfigureAwait(false);
+ }
+
+ list.Add(isoMounter);
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("{0} failed to load.", ex, isoMounter.Name);
+ }
+ }
+
+ IsoManager.AddParts(list);
+ }
+
+ ///
+ /// Runs the startup tasks.
+ ///
+ /// Task.
+ public virtual Task RunStartupTasks()
+ {
+ Resolve().AddTasks(GetExports(false));
+
+ ConfigureAutorun();
+
+ ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
+
+ return Task.FromResult(true);
+ }
+
+ ///
+ /// Configures the autorun.
+ ///
+ private void ConfigureAutorun()
+ {
+ try
+ {
+ ConfigureAutoRunAtStartup(ConfigurationManager.CommonConfiguration.RunAtStartup);
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error configuring autorun", ex);
+ }
+ }
+
+ ///
+ /// Gets the composable part assemblies.
+ ///
+ /// IEnumerable{Assembly}.
+ protected abstract IEnumerable GetComposablePartAssemblies();
+
+ ///
+ /// Gets the configuration manager.
+ ///
+ /// IConfigurationManager.
+ protected abstract IConfigurationManager GetConfigurationManager();
+
+ ///
+ /// Finds the parts.
+ ///
+ protected virtual void FindParts()
+ {
+ ConfigurationManager.AddParts(GetExports());
+ Plugins = GetExports().Select(LoadPlugin).Where(i => i != null).ToArray();
+ }
+
+ private IPlugin LoadPlugin(IPlugin plugin)
+ {
+ try
+ {
+ var assemblyPlugin = plugin as IPluginAssembly;
+
+ if (assemblyPlugin != null)
+ {
+ var assembly = plugin.GetType().Assembly;
+ var assemblyName = assembly.GetName();
+
+ var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
+ var assemblyId = new Guid(attribute.Value);
+
+ var assemblyFileName = assemblyName.Name + ".dll";
+ var assemblyFilePath = Path.Combine(ApplicationPaths.PluginsPath, assemblyFileName);
+
+ assemblyPlugin.SetAttributes(assemblyFilePath, assemblyFileName, assemblyName.Version, assemblyId);
+ }
+
+ var isFirstRun = !File.Exists(plugin.ConfigurationFilePath);
+
+ plugin.SetStartupInfo(isFirstRun, File.GetLastWriteTimeUtc, s => Directory.CreateDirectory(s));
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error loading plugin {0}", ex, plugin.GetType().FullName);
+ return null;
+ }
+
+ return plugin;
+ }
+
+ ///
+ /// Discovers the types.
+ ///
+ protected void DiscoverTypes()
+ {
+ FailedAssemblies.Clear();
+
+ var assemblies = GetComposablePartAssemblies().ToList();
+
+ foreach (var assembly in assemblies)
+ {
+ Logger.Info("Loading {0}", assembly.FullName);
+ }
+
+ AllConcreteTypes = assemblies
+ .SelectMany(GetTypes)
+ .Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType)
+ .ToArray();
+ }
+
+ ///
+ /// Registers resources that classes will depend on
+ ///
+ /// Task.
+ protected virtual Task RegisterResources(IProgress progress)
+ {
+ RegisterSingleInstance(ConfigurationManager);
+ RegisterSingleInstance(this);
+
+ RegisterSingleInstance(ApplicationPaths);
+
+ TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LogManager.GetLogger("TaskManager"), FileSystemManager, SystemEvents);
+
+ RegisterSingleInstance(JsonSerializer);
+ RegisterSingleInstance(XmlSerializer);
+ RegisterSingleInstance(MemoryStreamProvider);
+ RegisterSingleInstance(SystemEvents);
+
+ RegisterSingleInstance(LogManager);
+ RegisterSingleInstance(Logger);
+
+ RegisterSingleInstance(TaskManager);
+
+ RegisterSingleInstance(FileSystemManager);
+
+ HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamProvider);
+ RegisterSingleInstance(HttpClient);
+
+ NetworkManager = CreateNetworkManager(LogManager.GetLogger("NetworkManager"));
+ RegisterSingleInstance(NetworkManager);
+
+ IsoManager = new IsoManager();
+ RegisterSingleInstance(IsoManager);
+
+ return Task.FromResult(true);
+ }
+
+ ///
+ /// Gets a list of types within an assembly
+ /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
+ ///
+ /// The assembly.
+ /// IEnumerable{Type}.
+ /// assembly
+ protected IEnumerable GetTypes(Assembly assembly)
+ {
+ if (assembly == null)
+ {
+ throw new ArgumentNullException("assembly");
+ }
+
+ try
+ {
+ return assembly.GetTypes();
+ }
+ catch (ReflectionTypeLoadException ex)
+ {
+ if (ex.LoaderExceptions != null)
+ {
+ foreach (var loaderException in ex.LoaderExceptions)
+ {
+ Logger.Error("LoaderException: " + loaderException.Message);
+ }
+ }
+
+ // If it fails we can still get a list of the Types it was able to resolve
+ return ex.Types.Where(t => t != null);
+ }
+ }
+
+ protected abstract INetworkManager CreateNetworkManager(ILogger logger);
+
+ ///
+ /// Creates an instance of type and resolves all constructor dependancies
+ ///
+ /// The type.
+ /// System.Object.
+ public abstract object CreateInstance(Type type);
+
+ ///
+ /// Creates the instance safe.
+ ///
+ /// The type.
+ /// System.Object.
+ protected abstract object CreateInstanceSafe(Type type);
+
+ ///
+ /// Registers the specified obj.
+ ///
+ ///
+ /// The obj.
+ /// if set to true [manage lifetime].
+ protected abstract void RegisterSingleInstance(T obj, bool manageLifetime = true)
+ where T : class;
+
+ ///
+ /// Registers the single instance.
+ ///
+ ///
+ /// The func.
+ protected abstract void RegisterSingleInstance(Func func)
+ where T : class;
+
+ ///
+ /// Resolves this instance.
+ ///
+ ///
+ /// ``0.
+ public abstract T Resolve();
+
+ ///
+ /// Resolves this instance.
+ ///
+ ///
+ /// ``0.
+ public abstract T TryResolve();
+
+ ///
+ /// Loads the assembly.
+ ///
+ /// The file.
+ /// Assembly.
+ protected Assembly LoadAssembly(string file)
+ {
+ try
+ {
+ return Assembly.Load(File.ReadAllBytes(file));
+ }
+ catch (Exception ex)
+ {
+ FailedAssemblies.Add(file);
+ Logger.ErrorException("Error loading assembly {0}", ex, file);
+ return null;
+ }
+ }
+
+ ///
+ /// Gets the export types.
+ ///
+ ///
+ /// IEnumerable{Type}.
+ public IEnumerable GetExportTypes()
+ {
+ var currentType = typeof(T);
+
+ return AllConcreteTypes.AsParallel().Where(currentType.IsAssignableFrom);
+ }
+
+ ///
+ /// Gets the exports.
+ ///
+ ///
+ /// if set to true [manage liftime].
+ /// IEnumerable{``0}.
+ public IEnumerable GetExports(bool manageLiftime = true)
+ {
+ var parts = GetExportTypes()
+ .Select(CreateInstanceSafe)
+ .Where(i => i != null)
+ .Cast()
+ .ToList();
+
+ if (manageLiftime)
+ {
+ lock (DisposableParts)
+ {
+ DisposableParts.AddRange(parts.OfType());
+ }
+ }
+
+ return parts;
+ }
+
+ ///
+ /// Gets the application version.
+ ///
+ /// The application version.
+ public abstract Version ApplicationVersion { get; }
+
+ ///
+ /// Handles the ConfigurationUpdated event of the ConfigurationManager control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ ///
+ protected virtual void OnConfigurationUpdated(object sender, EventArgs e)
+ {
+ ConfigureAutorun();
+ }
+
+ protected abstract void ConfigureAutoRunAtStartup(bool autorun);
+
+ ///
+ /// Removes the plugin.
+ ///
+ /// The plugin.
+ public void RemovePlugin(IPlugin plugin)
+ {
+ var list = Plugins.ToList();
+ list.Remove(plugin);
+ Plugins = list.ToArray();
+ }
+
+ ///
+ /// Gets a value indicating whether this instance can self restart.
+ ///
+ /// true if this instance can self restart; otherwise, false.
+ public abstract bool CanSelfRestart { get; }
+
+ ///
+ /// Notifies that the kernel that a change has been made that requires a restart
+ ///
+ public void NotifyPendingRestart()
+ {
+ var changed = !HasPendingRestart;
+
+ HasPendingRestart = true;
+
+ if (changed)
+ {
+ EventHelper.QueueEventIfNotNull(HasPendingRestartChanged, this, EventArgs.Empty, Logger);
+ }
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected virtual void Dispose(bool dispose)
+ {
+ if (dispose)
+ {
+ var type = GetType();
+
+ Logger.Info("Disposing " + type.Name);
+
+ var parts = DisposableParts.Distinct().Where(i => i.GetType() != type).ToList();
+ DisposableParts.Clear();
+
+ foreach (var part in parts)
+ {
+ Logger.Info("Disposing " + part.GetType().Name);
+
+ try
+ {
+ part.Dispose();
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error disposing {0}", ex, part.GetType().Name);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Restarts this instance.
+ ///
+ public abstract Task Restart();
+
+ ///
+ /// Gets or sets a value indicating whether this instance can self update.
+ ///
+ /// true if this instance can self update; otherwise, false.
+ public abstract bool CanSelfUpdate { get; }
+
+ ///
+ /// Checks for update.
+ ///
+ /// The cancellation token.
+ /// The progress.
+ /// Task{CheckForUpdateResult}.
+ public abstract Task CheckForApplicationUpdate(CancellationToken cancellationToken,
+ IProgress progress);
+
+ ///
+ /// Updates the application.
+ ///
+ /// The package that contains the update
+ /// The cancellation token.
+ /// The progress.
+ /// Task.
+ public abstract Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken,
+ IProgress progress);
+
+ ///
+ /// Shuts down.
+ ///
+ public abstract Task Shutdown();
+
+ ///
+ /// Called when [application updated].
+ ///
+ /// The package.
+ protected void OnApplicationUpdated(PackageVersionInfo package)
+ {
+ Logger.Info("Application has been updated to version {0}", package.versionStr);
+
+ EventHelper.FireEventIfNotNull(ApplicationUpdated, this, new GenericEventArgs
+ {
+ Argument = package
+
+ }, Logger);
+
+ NotifyPendingRestart();
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/BaseApplicationPaths.cs b/Emby.Common.Implementations/BaseApplicationPaths.cs
new file mode 100644
index 0000000000..628d62bd48
--- /dev/null
+++ b/Emby.Common.Implementations/BaseApplicationPaths.cs
@@ -0,0 +1,178 @@
+using System.IO;
+using MediaBrowser.Common.Configuration;
+
+namespace Emby.Common.Implementations
+{
+ ///
+ /// Provides a base class to hold common application paths used by both the Ui and Server.
+ /// This can be subclassed to add application-specific paths.
+ ///
+ public abstract class BaseApplicationPaths : IApplicationPaths
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected BaseApplicationPaths(string programDataPath, string applicationPath)
+ {
+ ProgramDataPath = programDataPath;
+ ApplicationPath = applicationPath;
+ }
+
+ public string ApplicationPath { get; private set; }
+ public string ProgramDataPath { get; private set; }
+
+ ///
+ /// Gets the path to the system folder
+ ///
+ public string ProgramSystemPath
+ {
+ get { return Path.GetDirectoryName(ApplicationPath); }
+ }
+
+ ///
+ /// The _data directory
+ ///
+ private string _dataDirectory;
+ ///
+ /// Gets the folder path to the data directory
+ ///
+ /// The data directory.
+ public string DataPath
+ {
+ get
+ {
+ if (_dataDirectory == null)
+ {
+ _dataDirectory = Path.Combine(ProgramDataPath, "data");
+
+ Directory.CreateDirectory(_dataDirectory);
+ }
+
+ return _dataDirectory;
+ }
+ }
+
+ ///
+ /// Gets the image cache path.
+ ///
+ /// The image cache path.
+ public string ImageCachePath
+ {
+ get
+ {
+ return Path.Combine(CachePath, "images");
+ }
+ }
+
+ ///
+ /// Gets the path to the plugin directory
+ ///
+ /// The plugins path.
+ public string PluginsPath
+ {
+ get
+ {
+ return Path.Combine(ProgramDataPath, "plugins");
+ }
+ }
+
+ ///
+ /// Gets the path to the plugin configurations directory
+ ///
+ /// The plugin configurations path.
+ public string PluginConfigurationsPath
+ {
+ get
+ {
+ return Path.Combine(PluginsPath, "configurations");
+ }
+ }
+
+ ///
+ /// Gets the path to where temporary update files will be stored
+ ///
+ /// The plugin configurations path.
+ public string TempUpdatePath
+ {
+ get
+ {
+ return Path.Combine(ProgramDataPath, "updates");
+ }
+ }
+
+ ///
+ /// Gets the path to the log directory
+ ///
+ /// The log directory path.
+ public string LogDirectoryPath
+ {
+ get
+ {
+ return Path.Combine(ProgramDataPath, "logs");
+ }
+ }
+
+ ///
+ /// Gets the path to the application configuration root directory
+ ///
+ /// The configuration directory path.
+ public string ConfigurationDirectoryPath
+ {
+ get
+ {
+ return Path.Combine(ProgramDataPath, "config");
+ }
+ }
+
+ ///
+ /// Gets the path to the system configuration file
+ ///
+ /// The system configuration file path.
+ public string SystemConfigurationFilePath
+ {
+ get
+ {
+ return Path.Combine(ConfigurationDirectoryPath, "system.xml");
+ }
+ }
+
+ ///
+ /// The _cache directory
+ ///
+ private string _cachePath;
+ ///
+ /// Gets the folder path to the cache directory
+ ///
+ /// The cache directory.
+ public string CachePath
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(_cachePath))
+ {
+ _cachePath = Path.Combine(ProgramDataPath, "cache");
+
+ Directory.CreateDirectory(_cachePath);
+ }
+
+ return _cachePath;
+ }
+ set
+ {
+ _cachePath = value;
+ }
+ }
+
+ ///
+ /// Gets the folder path to the temp directory within the cache folder
+ ///
+ /// The temp directory.
+ public string TempDirectory
+ {
+ get
+ {
+ return Path.Combine(CachePath, "temp");
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Configuration/BaseConfigurationManager.cs b/Emby.Common.Implementations/Configuration/BaseConfigurationManager.cs
new file mode 100644
index 0000000000..27c9fe6157
--- /dev/null
+++ b/Emby.Common.Implementations/Configuration/BaseConfigurationManager.cs
@@ -0,0 +1,329 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Events;
+using MediaBrowser.Common.Extensions;
+using Emby.Common.Implementations;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+
+namespace Emby.Common.Implementations.Configuration
+{
+ ///
+ /// Class BaseConfigurationManager
+ ///
+ public abstract class BaseConfigurationManager : IConfigurationManager
+ {
+ ///
+ /// Gets the type of the configuration.
+ ///
+ /// The type of the configuration.
+ protected abstract Type ConfigurationType { get; }
+
+ ///
+ /// Occurs when [configuration updated].
+ ///
+ public event EventHandler ConfigurationUpdated;
+
+ ///
+ /// Occurs when [configuration updating].
+ ///
+ public event EventHandler NamedConfigurationUpdating;
+
+ ///
+ /// Occurs when [named configuration updated].
+ ///
+ public event EventHandler NamedConfigurationUpdated;
+
+ ///
+ /// Gets the logger.
+ ///
+ /// The logger.
+ protected ILogger Logger { get; private set; }
+ ///
+ /// Gets the XML serializer.
+ ///
+ /// The XML serializer.
+ protected IXmlSerializer XmlSerializer { get; private set; }
+
+ ///
+ /// Gets or sets the application paths.
+ ///
+ /// The application paths.
+ public IApplicationPaths CommonApplicationPaths { get; private set; }
+ public readonly IFileSystem FileSystem;
+
+ ///
+ /// The _configuration loaded
+ ///
+ private bool _configurationLoaded;
+ ///
+ /// The _configuration sync lock
+ ///
+ private object _configurationSyncLock = new object();
+ ///
+ /// The _configuration
+ ///
+ private BaseApplicationConfiguration _configuration;
+ ///
+ /// Gets the system configuration
+ ///
+ /// The configuration.
+ public BaseApplicationConfiguration CommonConfiguration
+ {
+ get
+ {
+ // Lazy load
+ LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer, FileSystem));
+ return _configuration;
+ }
+ protected set
+ {
+ _configuration = value;
+
+ _configurationLoaded = value != null;
+ }
+ }
+
+ private ConfigurationStore[] _configurationStores = { };
+ private IConfigurationFactory[] _configurationFactories = { };
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The application paths.
+ /// The log manager.
+ /// The XML serializer.
+ protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
+ {
+ CommonApplicationPaths = applicationPaths;
+ XmlSerializer = xmlSerializer;
+ FileSystem = fileSystem;
+ Logger = logManager.GetLogger(GetType().Name);
+
+ UpdateCachePath();
+ }
+
+ public virtual void AddParts(IEnumerable factories)
+ {
+ _configurationFactories = factories.ToArray();
+
+ _configurationStores = _configurationFactories
+ .SelectMany(i => i.GetConfigurations())
+ .ToArray();
+ }
+
+ ///
+ /// Saves the configuration.
+ ///
+ public void SaveConfiguration()
+ {
+ Logger.Info("Saving system configuration");
+ var path = CommonApplicationPaths.SystemConfigurationFilePath;
+
+ FileSystem.CreateDirectory(Path.GetDirectoryName(path));
+
+ lock (_configurationSyncLock)
+ {
+ XmlSerializer.SerializeToFile(CommonConfiguration, path);
+ }
+
+ OnConfigurationUpdated();
+ }
+
+ ///
+ /// Called when [configuration updated].
+ ///
+ protected virtual void OnConfigurationUpdated()
+ {
+ UpdateCachePath();
+
+ EventHelper.QueueEventIfNotNull(ConfigurationUpdated, this, EventArgs.Empty, Logger);
+ }
+
+ ///
+ /// Replaces the configuration.
+ ///
+ /// The new configuration.
+ /// newConfiguration
+ public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
+ {
+ if (newConfiguration == null)
+ {
+ throw new ArgumentNullException("newConfiguration");
+ }
+
+ ValidateCachePath(newConfiguration);
+
+ CommonConfiguration = newConfiguration;
+ SaveConfiguration();
+ }
+
+ ///
+ /// Updates the items by name path.
+ ///
+ private void UpdateCachePath()
+ {
+ string cachePath;
+
+ if (string.IsNullOrWhiteSpace(CommonConfiguration.CachePath))
+ {
+ cachePath = null;
+ }
+ else
+ {
+ cachePath = Path.Combine(CommonConfiguration.CachePath, "cache");
+ }
+
+ ((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath;
+ }
+
+ ///
+ /// Replaces the cache path.
+ ///
+ /// The new configuration.
+ ///
+ private void ValidateCachePath(BaseApplicationConfiguration newConfig)
+ {
+ var newPath = newConfig.CachePath;
+
+ if (!string.IsNullOrWhiteSpace(newPath)
+ && !string.Equals(CommonConfiguration.CachePath ?? string.Empty, newPath))
+ {
+ // Validate
+ if (!FileSystem.DirectoryExists(newPath))
+ {
+ throw new FileNotFoundException(string.Format("{0} does not exist.", newPath));
+ }
+
+ EnsureWriteAccess(newPath);
+ }
+ }
+
+ protected void EnsureWriteAccess(string path)
+ {
+ var file = Path.Combine(path, Guid.NewGuid().ToString());
+
+ FileSystem.WriteAllText(file, string.Empty);
+ FileSystem.DeleteFile(file);
+ }
+
+ private readonly ConcurrentDictionary _configurations = new ConcurrentDictionary();
+
+ private string GetConfigurationFile(string key)
+ {
+ return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLower() + ".xml");
+ }
+
+ public object GetConfiguration(string key)
+ {
+ return _configurations.GetOrAdd(key, k =>
+ {
+ var file = GetConfigurationFile(key);
+
+ var configurationInfo = _configurationStores
+ .FirstOrDefault(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase));
+
+ if (configurationInfo == null)
+ {
+ throw new ResourceNotFoundException("Configuration with key " + key + " not found.");
+ }
+
+ var configurationType = configurationInfo.ConfigurationType;
+
+ lock (_configurationSyncLock)
+ {
+ return LoadConfiguration(file, configurationType);
+ }
+ });
+ }
+
+ private object LoadConfiguration(string path, Type configurationType)
+ {
+ try
+ {
+ return XmlSerializer.DeserializeFromFile(configurationType, path);
+ }
+ catch (FileNotFoundException)
+ {
+ return Activator.CreateInstance(configurationType);
+ }
+ catch (IOException)
+ {
+ return Activator.CreateInstance(configurationType);
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error loading configuration file: {0}", ex, path);
+
+ return Activator.CreateInstance(configurationType);
+ }
+ }
+
+ public void SaveConfiguration(string key, object configuration)
+ {
+ var configurationStore = GetConfigurationStore(key);
+ var configurationType = configurationStore.ConfigurationType;
+
+ if (configuration.GetType() != configurationType)
+ {
+ throw new ArgumentException("Expected configuration type is " + configurationType.Name);
+ }
+
+ var validatingStore = configurationStore as IValidatingConfiguration;
+ if (validatingStore != null)
+ {
+ var currentConfiguration = GetConfiguration(key);
+
+ validatingStore.Validate(currentConfiguration, configuration);
+ }
+
+ EventHelper.FireEventIfNotNull(NamedConfigurationUpdating, this, new ConfigurationUpdateEventArgs
+ {
+ Key = key,
+ NewConfiguration = configuration
+
+ }, Logger);
+
+ _configurations.AddOrUpdate(key, configuration, (k, v) => configuration);
+
+ var path = GetConfigurationFile(key);
+ FileSystem.CreateDirectory(Path.GetDirectoryName(path));
+
+ lock (_configurationSyncLock)
+ {
+ XmlSerializer.SerializeToFile(configuration, path);
+ }
+
+ OnNamedConfigurationUpdated(key, configuration);
+ }
+
+ protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
+ {
+ EventHelper.FireEventIfNotNull(NamedConfigurationUpdated, this, new ConfigurationUpdateEventArgs
+ {
+ Key = key,
+ NewConfiguration = configuration
+
+ }, Logger);
+ }
+
+ public Type GetConfigurationType(string key)
+ {
+ return GetConfigurationStore(key)
+ .ConfigurationType;
+ }
+
+ private ConfigurationStore GetConfigurationStore(string key)
+ {
+ return _configurationStores
+ .First(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Configuration/ConfigurationHelper.cs b/Emby.Common.Implementations/Configuration/ConfigurationHelper.cs
new file mode 100644
index 0000000000..0d43a651ea
--- /dev/null
+++ b/Emby.Common.Implementations/Configuration/ConfigurationHelper.cs
@@ -0,0 +1,60 @@
+using System;
+using System.IO;
+using System.Linq;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Serialization;
+
+namespace Emby.Common.Implementations.Configuration
+{
+ ///
+ /// Class ConfigurationHelper
+ ///
+ public static class ConfigurationHelper
+ {
+ ///
+ /// Reads an xml configuration file from the file system
+ /// It will immediately re-serialize and save if new serialization data is available due to property changes
+ ///
+ /// The type.
+ /// The path.
+ /// The XML serializer.
+ /// System.Object.
+ public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
+ {
+ object configuration;
+
+ byte[] buffer = null;
+
+ // Use try/catch to avoid the extra file system lookup using File.Exists
+ try
+ {
+ buffer = fileSystem.ReadAllBytes(path);
+
+ configuration = xmlSerializer.DeserializeFromBytes(type, buffer);
+ }
+ catch (Exception)
+ {
+ configuration = Activator.CreateInstance(type);
+ }
+
+ using (var stream = new MemoryStream())
+ {
+ xmlSerializer.SerializeToStream(configuration, stream);
+
+ // Take the object we just got and serialize it back to bytes
+ var newBytes = stream.ToArray();
+
+ // If the file didn't exist before, or if something has changed, re-save
+ if (buffer == null || !buffer.SequenceEqual(newBytes))
+ {
+ fileSystem.CreateDirectory(Path.GetDirectoryName(path));
+
+ // Save it after load in case we got new items
+ fileSystem.WriteAllBytes(path, newBytes);
+ }
+
+ return configuration;
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Common.Implementations/Cryptography/CryptographyProvider.cs
new file mode 100644
index 0000000000..5ece28dc67
--- /dev/null
+++ b/Emby.Common.Implementations/Cryptography/CryptographyProvider.cs
@@ -0,0 +1,30 @@
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using MediaBrowser.Model.Cryptography;
+
+namespace Emby.Common.Implementations.Cryptography
+{
+ public class CryptographyProvider : ICryptographyProvider
+ {
+ public Guid GetMD5(string str)
+ {
+ return new Guid(GetMD5Bytes(str));
+ }
+ public byte[] GetMD5Bytes(string str)
+ {
+ using (var provider = MD5.Create())
+ {
+ return provider.ComputeHash(Encoding.Unicode.GetBytes(str));
+ }
+ }
+ public byte[] GetMD5Bytes(Stream str)
+ {
+ using (var provider = MD5.Create())
+ {
+ return provider.ComputeHash(str);
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Devices/DeviceId.cs b/Emby.Common.Implementations/Devices/DeviceId.cs
new file mode 100644
index 0000000000..3d23ab872b
--- /dev/null
+++ b/Emby.Common.Implementations/Devices/DeviceId.cs
@@ -0,0 +1,109 @@
+using System;
+using System.IO;
+using System.Text;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+
+namespace Emby.Common.Implementations.Devices
+{
+ public class DeviceId
+ {
+ private readonly IApplicationPaths _appPaths;
+ private readonly ILogger _logger;
+ private readonly IFileSystem _fileSystem;
+
+ private readonly object _syncLock = new object();
+
+ private string CachePath
+ {
+ get { return Path.Combine(_appPaths.DataPath, "device.txt"); }
+ }
+
+ private string GetCachedId()
+ {
+ try
+ {
+ lock (_syncLock)
+ {
+ var value = File.ReadAllText(CachePath, Encoding.UTF8);
+
+ Guid guid;
+ if (Guid.TryParse(value, out guid))
+ {
+ return value;
+ }
+
+ _logger.Error("Invalid value found in device id file");
+ }
+ }
+ catch (DirectoryNotFoundException)
+ {
+ }
+ catch (FileNotFoundException)
+ {
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error reading file", ex);
+ }
+
+ return null;
+ }
+
+ private void SaveId(string id)
+ {
+ try
+ {
+ var path = CachePath;
+
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
+
+ lock (_syncLock)
+ {
+ _fileSystem.WriteAllText(path, id, Encoding.UTF8);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error writing to file", ex);
+ }
+ }
+
+ private string GetNewId()
+ {
+ return Guid.NewGuid().ToString("N");
+ }
+
+ private string GetDeviceId()
+ {
+ var id = GetCachedId();
+
+ if (string.IsNullOrWhiteSpace(id))
+ {
+ id = GetNewId();
+ SaveId(id);
+ }
+
+ return id;
+ }
+
+ private string _id;
+
+ public DeviceId(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
+ {
+ if (fileSystem == null) {
+ throw new ArgumentNullException ("fileSystem");
+ }
+
+ _appPaths = appPaths;
+ _logger = logger;
+ _fileSystem = fileSystem;
+ }
+
+ public string Value
+ {
+ get { return _id ?? (_id = GetDeviceId()); }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Emby.Common.Implementations.xproj b/Emby.Common.Implementations/Emby.Common.Implementations.xproj
new file mode 100644
index 0000000000..5bb6e4e589
--- /dev/null
+++ b/Emby.Common.Implementations/Emby.Common.Implementations.xproj
@@ -0,0 +1,23 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 5a27010a-09c6-4e86-93ea-437484c10917
+ Emby.Common.Implementations
+ .\obj
+ .\bin\
+ v4.5.2
+
+
+ 2.0
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Emby.Common.Implementations/HttpClientManager/HttpClientInfo.cs b/Emby.Common.Implementations/HttpClientManager/HttpClientInfo.cs
new file mode 100644
index 0000000000..ca481b33e7
--- /dev/null
+++ b/Emby.Common.Implementations/HttpClientManager/HttpClientInfo.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Emby.Common.Implementations.HttpClientManager
+{
+ ///
+ /// Class HttpClientInfo
+ ///
+ public class HttpClientInfo
+ {
+ ///
+ /// Gets or sets the last timeout.
+ ///
+ /// The last timeout.
+ public DateTime LastTimeout { get; set; }
+ }
+}
diff --git a/Emby.Common.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Common.Implementations/HttpClientManager/HttpClientManager.cs
new file mode 100644
index 0000000000..ea40565472
--- /dev/null
+++ b/Emby.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -0,0 +1,936 @@
+using System.Net.Sockets;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Cache;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Emby.Common.Implementations.HttpClientManager;
+using MediaBrowser.Model.IO;
+
+namespace Emby.Common.Implementations.HttpClientManager
+{
+ ///
+ /// Class HttpClientManager
+ ///
+ public class HttpClientManager : IHttpClient
+ {
+ ///
+ /// When one request to a host times out, we'll ban all other requests for this period of time, to prevent scans from stalling
+ ///
+ private const int TimeoutSeconds = 30;
+
+ ///
+ /// The _logger
+ ///
+ private readonly ILogger _logger;
+
+ ///
+ /// The _app paths
+ ///
+ private readonly IApplicationPaths _appPaths;
+
+ private readonly IFileSystem _fileSystem;
+ private readonly IMemoryStreamProvider _memoryStreamProvider;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The app paths.
+ /// The logger.
+ /// The file system.
+ /// appPaths
+ /// or
+ /// logger
+ public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider)
+ {
+ if (appPaths == null)
+ {
+ throw new ArgumentNullException("appPaths");
+ }
+ if (logger == null)
+ {
+ throw new ArgumentNullException("logger");
+ }
+
+ _logger = logger;
+ _fileSystem = fileSystem;
+ _memoryStreamProvider = memoryStreamProvider;
+ _appPaths = appPaths;
+
+ // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c
+ ServicePointManager.Expect100Continue = false;
+
+ // Trakt requests sometimes fail without this
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
+ }
+
+ ///
+ /// Holds a dictionary of http clients by host. Use GetHttpClient(host) to retrieve or create a client for web requests.
+ /// DON'T dispose it after use.
+ ///
+ /// The HTTP clients.
+ private readonly ConcurrentDictionary _httpClients = new ConcurrentDictionary();
+
+ ///
+ /// Gets
+ ///
+ /// The host.
+ /// if set to true [enable HTTP compression].
+ /// HttpClient.
+ /// host
+ private HttpClientInfo GetHttpClient(string host, bool enableHttpCompression)
+ {
+ if (string.IsNullOrEmpty(host))
+ {
+ throw new ArgumentNullException("host");
+ }
+
+ HttpClientInfo client;
+
+ var key = host + enableHttpCompression;
+
+ if (!_httpClients.TryGetValue(key, out client))
+ {
+ client = new HttpClientInfo();
+
+ _httpClients.TryAdd(key, client);
+ }
+
+ return client;
+ }
+
+ private WebRequest CreateWebRequest(string url)
+ {
+ try
+ {
+ return WebRequest.Create(url);
+ }
+ catch (NotSupportedException)
+ {
+ //Webrequest creation does fail on MONO randomly when using WebRequest.Create
+ //the issue occurs in the GetCreator method here: http://www.oschina.net/code/explore/mono-2.8.1/mcs/class/System/System.Net/WebRequest.cs
+
+ var type = Type.GetType("System.Net.HttpRequestCreator, System, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089");
+ var creator = Activator.CreateInstance(type, nonPublic: true) as IWebRequestCreate;
+ return creator.Create(new Uri(url)) as HttpWebRequest;
+ }
+ }
+
+ private void AddIpv4Option(HttpWebRequest request, HttpRequestOptions options)
+ {
+ request.ServicePoint.BindIPEndPointDelegate = (servicePount, remoteEndPoint, retryCount) =>
+ {
+ if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork)
+ {
+ return new IPEndPoint(IPAddress.Any, 0);
+ }
+ throw new InvalidOperationException("no IPv4 address");
+ };
+ }
+
+ private WebRequest GetRequest(HttpRequestOptions options, string method)
+ {
+ var url = options.Url;
+
+ var uriAddress = new Uri(url);
+ var userInfo = uriAddress.UserInfo;
+ if (!string.IsNullOrWhiteSpace(userInfo))
+ {
+ _logger.Info("Found userInfo in url: {0} ... url: {1}", userInfo, url);
+ url = url.Replace(userInfo + "@", string.Empty);
+ }
+
+ var request = CreateWebRequest(url);
+ var httpWebRequest = request as HttpWebRequest;
+
+ if (httpWebRequest != null)
+ {
+ if (options.PreferIpv4)
+ {
+ AddIpv4Option(httpWebRequest, options);
+ }
+
+ AddRequestHeaders(httpWebRequest, options);
+
+ httpWebRequest.AutomaticDecompression = options.EnableHttpCompression ?
+ (options.DecompressionMethod ?? DecompressionMethods.Deflate) :
+ DecompressionMethods.None;
+ }
+
+ request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
+
+ if (httpWebRequest != null)
+ {
+ if (options.EnableKeepAlive)
+ {
+ httpWebRequest.KeepAlive = true;
+ }
+ }
+
+ request.Method = method;
+ request.Timeout = options.TimeoutMs;
+
+ if (httpWebRequest != null)
+ {
+ if (!string.IsNullOrEmpty(options.Host))
+ {
+ httpWebRequest.Host = options.Host;
+ }
+
+ if (!string.IsNullOrEmpty(options.Referer))
+ {
+ httpWebRequest.Referer = options.Referer;
+ }
+ }
+
+ if (!string.IsNullOrWhiteSpace(userInfo))
+ {
+ var parts = userInfo.Split(':');
+ if (parts.Length == 2)
+ {
+ request.Credentials = GetCredential(url, parts[0], parts[1]);
+ request.PreAuthenticate = true;
+ }
+ }
+
+ return request;
+ }
+
+ private CredentialCache GetCredential(string url, string username, string password)
+ {
+ //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
+ CredentialCache credentialCache = new CredentialCache();
+ credentialCache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
+ return credentialCache;
+ }
+
+ private void AddRequestHeaders(HttpWebRequest request, HttpRequestOptions options)
+ {
+ foreach (var header in options.RequestHeaders.ToList())
+ {
+ if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase))
+ {
+ request.Accept = header.Value;
+ }
+ else if (string.Equals(header.Key, "User-Agent", StringComparison.OrdinalIgnoreCase))
+ {
+ request.UserAgent = header.Value;
+ }
+ else
+ {
+ request.Headers.Set(header.Key, header.Value);
+ }
+ }
+ }
+
+ ///
+ /// Gets the response internal.
+ ///
+ /// The options.
+ /// Task{HttpResponseInfo}.
+ public Task GetResponse(HttpRequestOptions options)
+ {
+ return SendAsync(options, "GET");
+ }
+
+ ///
+ /// Performs a GET request and returns the resulting stream
+ ///
+ /// The options.
+ /// Task{Stream}.
+ public async Task Get(HttpRequestOptions options)
+ {
+ var response = await GetResponse(options).ConfigureAwait(false);
+
+ return response.Content;
+ }
+
+ ///
+ /// Performs a GET request and returns the resulting stream
+ ///
+ /// The URL.
+ /// The resource pool.
+ /// The cancellation token.
+ /// Task{Stream}.
+ public Task Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
+ {
+ return Get(new HttpRequestOptions
+ {
+ Url = url,
+ ResourcePool = resourcePool,
+ CancellationToken = cancellationToken,
+ BufferContent = resourcePool != null
+ });
+ }
+
+ ///
+ /// Gets the specified URL.
+ ///
+ /// The URL.
+ /// The cancellation token.
+ /// Task{Stream}.
+ public Task Get(string url, CancellationToken cancellationToken)
+ {
+ return Get(url, null, cancellationToken);
+ }
+
+ ///
+ /// send as an asynchronous operation.
+ ///
+ /// The options.
+ /// The HTTP method.
+ /// Task{HttpResponseInfo}.
+ ///
+ ///
+ public async Task SendAsync(HttpRequestOptions options, string httpMethod)
+ {
+ if (options.CacheMode == CacheMode.None)
+ {
+ return await SendAsyncInternal(options, httpMethod).ConfigureAwait(false);
+ }
+
+ var url = options.Url;
+ var urlHash = url.ToLower().GetMD5().ToString("N");
+
+ var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash);
+
+ var response = await GetCachedResponse(responseCachePath, options.CacheLength, url).ConfigureAwait(false);
+ if (response != null)
+ {
+ return response;
+ }
+
+ response = await SendAsyncInternal(options, httpMethod).ConfigureAwait(false);
+
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ await CacheResponse(response, responseCachePath).ConfigureAwait(false);
+ }
+
+ return response;
+ }
+
+ private async Task GetCachedResponse(string responseCachePath, TimeSpan cacheLength, string url)
+ {
+ _logger.Info("Checking for cache file {0}", responseCachePath);
+
+ try
+ {
+ if (_fileSystem.GetLastWriteTimeUtc(responseCachePath).Add(cacheLength) > DateTime.UtcNow)
+ {
+ using (var stream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read, true))
+ {
+ var memoryStream = _memoryStreamProvider.CreateNew();
+
+ await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
+ memoryStream.Position = 0;
+
+ return new HttpResponseInfo
+ {
+ ResponseUrl = url,
+ Content = memoryStream,
+ StatusCode = HttpStatusCode.OK,
+ ContentLength = memoryStream.Length
+ };
+ }
+ }
+ }
+ catch (FileNotFoundException)
+ {
+
+ }
+ catch (DirectoryNotFoundException)
+ {
+
+ }
+
+ return null;
+ }
+
+ private async Task CacheResponse(HttpResponseInfo response, string responseCachePath)
+ {
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(responseCachePath));
+
+ using (var responseStream = response.Content)
+ {
+ var memoryStream = _memoryStreamProvider.CreateNew();
+ await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
+ memoryStream.Position = 0;
+
+ using (var fileStream = _fileSystem.GetFileStream(responseCachePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None, true))
+ {
+ await memoryStream.CopyToAsync(fileStream).ConfigureAwait(false);
+
+ memoryStream.Position = 0;
+ response.Content = memoryStream;
+ }
+ }
+ }
+
+ private async Task SendAsyncInternal(HttpRequestOptions options, string httpMethod)
+ {
+ ValidateParams(options);
+
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
+
+ if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
+ {
+ throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url))
+ {
+ IsTimedOut = true
+ };
+ }
+
+ var httpWebRequest = GetRequest(options, httpMethod);
+
+ if (options.RequestContentBytes != null ||
+ !string.IsNullOrEmpty(options.RequestContent) ||
+ string.Equals(httpMethod, "post", StringComparison.OrdinalIgnoreCase))
+ {
+ var bytes = options.RequestContentBytes ??
+ Encoding.UTF8.GetBytes(options.RequestContent ?? string.Empty);
+
+ httpWebRequest.ContentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
+
+ httpWebRequest.ContentLength = bytes.Length;
+ httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length);
+ }
+
+ if (options.ResourcePool != null)
+ {
+ await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
+ }
+
+ if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
+ {
+ if (options.ResourcePool != null)
+ {
+ options.ResourcePool.Release();
+ }
+
+ throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
+ }
+
+ if (options.LogRequest)
+ {
+ _logger.Info("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
+ }
+
+ try
+ {
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ if (!options.BufferContent)
+ {
+ var response = await GetResponseAsync(httpWebRequest, TimeSpan.FromMilliseconds(options.TimeoutMs)).ConfigureAwait(false);
+
+ var httpResponse = (HttpWebResponse)response;
+
+ EnsureSuccessStatusCode(client, httpResponse, options);
+
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ return GetResponseInfo(httpResponse, httpResponse.GetResponseStream(), GetContentLength(httpResponse), httpResponse);
+ }
+
+ using (var response = await GetResponseAsync(httpWebRequest, TimeSpan.FromMilliseconds(options.TimeoutMs)).ConfigureAwait(false))
+ {
+ var httpResponse = (HttpWebResponse)response;
+
+ EnsureSuccessStatusCode(client, httpResponse, options);
+
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ using (var stream = httpResponse.GetResponseStream())
+ {
+ var memoryStream = _memoryStreamProvider.CreateNew();
+
+ await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
+
+ memoryStream.Position = 0;
+
+ return GetResponseInfo(httpResponse, memoryStream, memoryStream.Length, null);
+ }
+ }
+ }
+ catch (OperationCanceledException ex)
+ {
+ throw GetCancellationException(options, client, options.CancellationToken, ex);
+ }
+ catch (Exception ex)
+ {
+ throw GetException(ex, options, client);
+ }
+ finally
+ {
+ if (options.ResourcePool != null)
+ {
+ options.ResourcePool.Release();
+ }
+ }
+ }
+
+ private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, Stream content, long? contentLength, IDisposable disposable)
+ {
+ var responseInfo = new HttpResponseInfo(disposable)
+ {
+ Content = content,
+
+ StatusCode = httpResponse.StatusCode,
+
+ ContentType = httpResponse.ContentType,
+
+ ContentLength = contentLength,
+
+ ResponseUrl = httpResponse.ResponseUri.ToString()
+ };
+
+ if (httpResponse.Headers != null)
+ {
+ SetHeaders(httpResponse.Headers, responseInfo);
+ }
+
+ return responseInfo;
+ }
+
+ private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, string tempFile, long? contentLength)
+ {
+ var responseInfo = new HttpResponseInfo
+ {
+ TempFilePath = tempFile,
+
+ StatusCode = httpResponse.StatusCode,
+
+ ContentType = httpResponse.ContentType,
+
+ ContentLength = contentLength
+ };
+
+ if (httpResponse.Headers != null)
+ {
+ SetHeaders(httpResponse.Headers, responseInfo);
+ }
+
+ return responseInfo;
+ }
+
+ private void SetHeaders(WebHeaderCollection headers, HttpResponseInfo responseInfo)
+ {
+ foreach (var key in headers.AllKeys)
+ {
+ responseInfo.Headers[key] = headers[key];
+ }
+ }
+
+ public Task Post(HttpRequestOptions options)
+ {
+ return SendAsync(options, "POST");
+ }
+
+ ///
+ /// Performs a POST request
+ ///
+ /// The options.
+ /// Params to add to the POST data.
+ /// stream on success, null on failure
+ public async Task Post(HttpRequestOptions options, Dictionary postData)
+ {
+ options.SetPostData(postData);
+
+ var response = await Post(options).ConfigureAwait(false);
+
+ return response.Content;
+ }
+
+ ///
+ /// Performs a POST request
+ ///
+ /// The URL.
+ /// Params to add to the POST data.
+ /// The resource pool.
+ /// The cancellation token.
+ /// stream on success, null on failure
+ public Task Post(string url, Dictionary postData, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
+ {
+ return Post(new HttpRequestOptions
+ {
+ Url = url,
+ ResourcePool = resourcePool,
+ CancellationToken = cancellationToken,
+ BufferContent = resourcePool != null
+
+ }, postData);
+ }
+
+ ///
+ /// Downloads the contents of a given url into a temporary location
+ ///
+ /// The options.
+ /// Task{System.String}.
+ public async Task GetTempFile(HttpRequestOptions options)
+ {
+ var response = await GetTempFileResponse(options).ConfigureAwait(false);
+
+ return response.TempFilePath;
+ }
+
+ public async Task GetTempFileResponse(HttpRequestOptions options)
+ {
+ ValidateParams(options);
+
+ _fileSystem.CreateDirectory(_appPaths.TempDirectory);
+
+ var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp");
+
+ if (options.Progress == null)
+ {
+ throw new ArgumentNullException("progress");
+ }
+
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ var httpWebRequest = GetRequest(options, "GET");
+
+ if (options.ResourcePool != null)
+ {
+ await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
+ }
+
+ options.Progress.Report(0);
+
+ if (options.LogRequest)
+ {
+ _logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
+ }
+
+ var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
+
+ try
+ {
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
+ {
+ var httpResponse = (HttpWebResponse)response;
+
+ EnsureSuccessStatusCode(client, httpResponse, options);
+
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ var contentLength = GetContentLength(httpResponse);
+
+ if (!contentLength.HasValue)
+ {
+ // We're not able to track progress
+ using (var stream = httpResponse.GetResponseStream())
+ {
+ using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
+ {
+ await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
+ }
+ }
+ }
+ else
+ {
+ using (var stream = ProgressStream.CreateReadProgressStream(httpResponse.GetResponseStream(), options.Progress.Report, contentLength.Value))
+ {
+ using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
+ {
+ await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
+ }
+ }
+ }
+
+ options.Progress.Report(100);
+
+ return GetResponseInfo(httpResponse, tempFile, contentLength);
+ }
+ }
+ catch (Exception ex)
+ {
+ DeleteTempFile(tempFile);
+ throw GetException(ex, options, client);
+ }
+ finally
+ {
+ if (options.ResourcePool != null)
+ {
+ options.ResourcePool.Release();
+ }
+ }
+ }
+
+ private long? GetContentLength(HttpWebResponse response)
+ {
+ var length = response.ContentLength;
+
+ if (length == 0)
+ {
+ return null;
+ }
+
+ return length;
+ }
+
+ protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ private Exception GetException(Exception ex, HttpRequestOptions options, HttpClientInfo client)
+ {
+ if (ex is HttpException)
+ {
+ return ex;
+ }
+
+ var webException = ex as WebException
+ ?? ex.InnerException as WebException;
+
+ if (webException != null)
+ {
+ if (options.LogErrors)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+ }
+
+ var exception = new HttpException(ex.Message, ex);
+
+ var response = webException.Response as HttpWebResponse;
+ if (response != null)
+ {
+ exception.StatusCode = response.StatusCode;
+
+ if ((int)response.StatusCode == 429)
+ {
+ client.LastTimeout = DateTime.UtcNow;
+ }
+ }
+
+ return exception;
+ }
+
+ var operationCanceledException = ex as OperationCanceledException
+ ?? ex.InnerException as OperationCanceledException;
+
+ if (operationCanceledException != null)
+ {
+ return GetCancellationException(options, client, options.CancellationToken, operationCanceledException);
+ }
+
+ if (options.LogErrors)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+ }
+
+ return ex;
+ }
+
+ private void DeleteTempFile(string file)
+ {
+ try
+ {
+ _fileSystem.DeleteFile(file);
+ }
+ catch (IOException)
+ {
+ // Might not have been created at all. No need to worry.
+ }
+ }
+
+ private void ValidateParams(HttpRequestOptions options)
+ {
+ if (string.IsNullOrEmpty(options.Url))
+ {
+ throw new ArgumentNullException("options");
+ }
+ }
+
+ ///
+ /// Gets the host from URL.
+ ///
+ /// The URL.
+ /// System.String.
+ private string GetHostFromUrl(string url)
+ {
+ var index = url.IndexOf("://", StringComparison.OrdinalIgnoreCase);
+
+ if (index != -1)
+ {
+ url = url.Substring(index + 3);
+ var host = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
+
+ if (!string.IsNullOrWhiteSpace(host))
+ {
+ return host;
+ }
+ }
+
+ return url;
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected virtual void Dispose(bool dispose)
+ {
+ if (dispose)
+ {
+ _httpClients.Clear();
+ }
+ }
+
+ ///
+ /// Throws the cancellation exception.
+ ///
+ /// The options.
+ /// The client.
+ /// The cancellation token.
+ /// The exception.
+ /// Exception.
+ private Exception GetCancellationException(HttpRequestOptions options, HttpClientInfo client, CancellationToken cancellationToken, OperationCanceledException exception)
+ {
+ // If the HttpClient's timeout is reached, it will cancel the Task internally
+ if (!cancellationToken.IsCancellationRequested)
+ {
+ var msg = string.Format("Connection to {0} timed out", options.Url);
+
+ if (options.LogErrors)
+ {
+ _logger.Error(msg);
+ }
+
+ client.LastTimeout = DateTime.UtcNow;
+
+ // Throw an HttpException so that the caller doesn't think it was cancelled by user code
+ return new HttpException(msg, exception)
+ {
+ IsTimedOut = true
+ };
+ }
+
+ return exception;
+ }
+
+ private void EnsureSuccessStatusCode(HttpClientInfo client, HttpWebResponse response, HttpRequestOptions options)
+ {
+ var statusCode = response.StatusCode;
+
+ var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299;
+
+ if (!isSuccessful)
+ {
+ if (options.LogErrorResponseBody)
+ {
+ try
+ {
+ using (var stream = response.GetResponseStream())
+ {
+ if (stream != null)
+ {
+ using (var reader = new StreamReader(stream))
+ {
+ var msg = reader.ReadToEnd();
+
+ _logger.Error(msg);
+ }
+ }
+ }
+ }
+ catch
+ {
+
+ }
+ }
+ throw new HttpException(response.StatusDescription)
+ {
+ StatusCode = response.StatusCode
+ };
+ }
+ }
+
+ ///
+ /// Posts the specified URL.
+ ///
+ /// The URL.
+ /// The post data.
+ /// The cancellation token.
+ /// Task{Stream}.
+ public Task Post(string url, Dictionary postData, CancellationToken cancellationToken)
+ {
+ return Post(url, postData, null, cancellationToken);
+ }
+
+ private Task GetResponseAsync(WebRequest request, TimeSpan timeout)
+ {
+ var taskCompletion = new TaskCompletionSource();
+
+ Task asyncTask = Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null);
+
+ ThreadPool.RegisterWaitForSingleObject((asyncTask as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, timeout, true);
+ var callback = new TaskCallback { taskCompletion = taskCompletion };
+ asyncTask.ContinueWith(callback.OnSuccess, TaskContinuationOptions.NotOnFaulted);
+
+ // Handle errors
+ asyncTask.ContinueWith(callback.OnError, TaskContinuationOptions.OnlyOnFaulted);
+
+ return taskCompletion.Task;
+ }
+
+ private static void TimeoutCallback(object state, bool timedOut)
+ {
+ if (timedOut)
+ {
+ WebRequest request = (WebRequest)state;
+ if (state != null)
+ {
+ request.Abort();
+ }
+ }
+ }
+
+ private class TaskCallback
+ {
+ public TaskCompletionSource taskCompletion;
+
+ public void OnSuccess(Task task)
+ {
+ taskCompletion.TrySetResult(task.Result);
+ }
+
+ public void OnError(Task task)
+ {
+ if (task.Exception != null)
+ {
+ taskCompletion.TrySetException(task.Exception);
+ }
+ else
+ {
+ taskCompletion.TrySetException(new List());
+ }
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/IO/IsoManager.cs b/Emby.Common.Implementations/IO/IsoManager.cs
new file mode 100644
index 0000000000..14614acaf8
--- /dev/null
+++ b/Emby.Common.Implementations/IO/IsoManager.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.IO;
+
+namespace Emby.Common.Implementations.IO
+{
+ ///
+ /// Class IsoManager
+ ///
+ public class IsoManager : IIsoManager
+ {
+ ///
+ /// The _mounters
+ ///
+ private readonly List _mounters = new List();
+
+ ///
+ /// Mounts the specified iso path.
+ ///
+ /// The iso path.
+ /// The cancellation token.
+ /// IsoMount.
+ /// isoPath
+ ///
+ public Task Mount(string isoPath, CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrEmpty(isoPath))
+ {
+ throw new ArgumentNullException("isoPath");
+ }
+
+ var mounter = _mounters.FirstOrDefault(i => i.CanMount(isoPath));
+
+ if (mounter == null)
+ {
+ throw new ArgumentException(string.Format("No mounters are able to mount {0}", isoPath));
+ }
+
+ return mounter.Mount(isoPath, cancellationToken);
+ }
+
+ ///
+ /// Determines whether this instance can mount the specified path.
+ ///
+ /// The path.
+ /// true if this instance can mount the specified path; otherwise, false.
+ public bool CanMount(string path)
+ {
+ return _mounters.Any(i => i.CanMount(path));
+ }
+
+ ///
+ /// Adds the parts.
+ ///
+ /// The mounters.
+ public void AddParts(IEnumerable mounters)
+ {
+ _mounters.AddRange(mounters);
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ foreach (var mounter in _mounters)
+ {
+ mounter.Dispose();
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs
new file mode 100644
index 0000000000..6317fc08b4
--- /dev/null
+++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs
@@ -0,0 +1,705 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+
+namespace Emby.Common.Implementations.IO
+{
+ ///
+ /// Class ManagedFileSystem
+ ///
+ public class ManagedFileSystem : IFileSystem
+ {
+ protected ILogger Logger;
+
+ private readonly bool _supportsAsyncFileStreams;
+ private char[] _invalidFileNameChars;
+ private readonly List _shortcutHandlers = new List();
+ protected bool EnableFileSystemRequestConcat = true;
+
+ public ManagedFileSystem(ILogger logger, bool supportsAsyncFileStreams, bool enableManagedInvalidFileNameChars)
+ {
+ Logger = logger;
+ _supportsAsyncFileStreams = supportsAsyncFileStreams;
+ SetInvalidFileNameChars(enableManagedInvalidFileNameChars);
+ }
+
+ public void AddShortcutHandler(IShortcutHandler handler)
+ {
+ _shortcutHandlers.Add(handler);
+ }
+
+ protected void SetInvalidFileNameChars(bool enableManagedInvalidFileNameChars)
+ {
+ if (enableManagedInvalidFileNameChars)
+ {
+ _invalidFileNameChars = Path.GetInvalidFileNameChars();
+ }
+ else
+ {
+ // GetInvalidFileNameChars is less restrictive in Linux/Mac than Windows, this mimic Windows behavior for mono under Linux/Mac.
+ _invalidFileNameChars = new char[41] { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
+ '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12',
+ '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D',
+ '\x1E', '\x1F', '\x22', '\x3C', '\x3E', '\x7C', ':', '*', '?', '\\', '/' };
+ }
+ }
+
+ public char DirectorySeparatorChar
+ {
+ get
+ {
+ return Path.DirectorySeparatorChar;
+ }
+ }
+
+ public string GetFullPath(string path)
+ {
+ return Path.GetFullPath(path);
+ }
+
+ ///
+ /// Determines whether the specified filename is shortcut.
+ ///
+ /// The filename.
+ /// true if the specified filename is shortcut; otherwise, false.
+ /// filename
+ public virtual bool IsShortcut(string filename)
+ {
+ if (string.IsNullOrEmpty(filename))
+ {
+ throw new ArgumentNullException("filename");
+ }
+
+ var extension = Path.GetExtension(filename);
+ return _shortcutHandlers.Any(i => string.Equals(extension, i.Extension, StringComparison.OrdinalIgnoreCase));
+ }
+
+ ///
+ /// Resolves the shortcut.
+ ///
+ /// The filename.
+ /// System.String.
+ /// filename
+ public virtual string ResolveShortcut(string filename)
+ {
+ if (string.IsNullOrEmpty(filename))
+ {
+ throw new ArgumentNullException("filename");
+ }
+
+ var extension = Path.GetExtension(filename);
+ var handler = _shortcutHandlers.FirstOrDefault(i => string.Equals(extension, i.Extension, StringComparison.OrdinalIgnoreCase));
+
+ if (handler != null)
+ {
+ return handler.Resolve(filename);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Creates the shortcut.
+ ///
+ /// The shortcut path.
+ /// The target.
+ ///
+ /// shortcutPath
+ /// or
+ /// target
+ ///
+ public void CreateShortcut(string shortcutPath, string target)
+ {
+ if (string.IsNullOrEmpty(shortcutPath))
+ {
+ throw new ArgumentNullException("shortcutPath");
+ }
+
+ if (string.IsNullOrEmpty(target))
+ {
+ throw new ArgumentNullException("target");
+ }
+
+ var extension = Path.GetExtension(shortcutPath);
+ var handler = _shortcutHandlers.FirstOrDefault(i => string.Equals(extension, i.Extension, StringComparison.OrdinalIgnoreCase));
+
+ if (handler != null)
+ {
+ handler.Create(shortcutPath, target);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// Returns a object for the specified file or directory path.
+ ///
+ /// A path to a file or directory.
+ /// A object.
+ /// If the specified path points to a directory, the returned object's
+ /// property will be set to true and all other properties will reflect the properties of the directory.
+ public FileSystemMetadata GetFileSystemInfo(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ // Take a guess to try and avoid two file system hits, but we'll double-check by calling Exists
+ if (Path.HasExtension(path))
+ {
+ var fileInfo = new FileInfo(path);
+
+ if (fileInfo.Exists)
+ {
+ return GetFileSystemMetadata(fileInfo);
+ }
+
+ return GetFileSystemMetadata(new DirectoryInfo(path));
+ }
+ else
+ {
+ var fileInfo = new DirectoryInfo(path);
+
+ if (fileInfo.Exists)
+ {
+ return GetFileSystemMetadata(fileInfo);
+ }
+
+ return GetFileSystemMetadata(new FileInfo(path));
+ }
+ }
+
+ ///
+ /// Returns a object for the specified file path.
+ ///
+ /// A path to a file.
+ /// A object.
+ /// If the specified path points to a directory, the returned object's
+ /// property and the property will both be set to false.
+ /// For automatic handling of files and directories, use .
+ public FileSystemMetadata GetFileInfo(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ var fileInfo = new FileInfo(path);
+
+ return GetFileSystemMetadata(fileInfo);
+ }
+
+ ///
+ /// Returns a object for the specified directory path.
+ ///
+ /// A path to a directory.
+ /// A object.
+ /// If the specified path points to a file, the returned object's
+ /// property will be set to true and the property will be set to false.
+ /// For automatic handling of files and directories, use .
+ public FileSystemMetadata GetDirectoryInfo(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ var fileInfo = new DirectoryInfo(path);
+
+ return GetFileSystemMetadata(fileInfo);
+ }
+
+ private FileSystemMetadata GetFileSystemMetadata(FileSystemInfo info)
+ {
+ var result = new FileSystemMetadata();
+
+ result.Exists = info.Exists;
+ result.FullName = info.FullName;
+ result.Extension = info.Extension;
+ result.Name = info.Name;
+
+ if (result.Exists)
+ {
+ var attributes = info.Attributes;
+ result.IsDirectory = info is DirectoryInfo || (attributes & FileAttributes.Directory) == FileAttributes.Directory;
+ result.IsHidden = (attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
+ result.IsReadOnly = (attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;
+
+ var fileInfo = info as FileInfo;
+ if (fileInfo != null)
+ {
+ result.Length = fileInfo.Length;
+ result.DirectoryName = fileInfo.DirectoryName;
+ }
+
+ result.CreationTimeUtc = GetCreationTimeUtc(info);
+ result.LastWriteTimeUtc = GetLastWriteTimeUtc(info);
+ }
+ else
+ {
+ result.IsDirectory = info is DirectoryInfo;
+ }
+
+ return result;
+ }
+
+ ///
+ /// The space char
+ ///
+ private const char SpaceChar = ' ';
+
+ ///
+ /// Takes a filename and removes invalid characters
+ ///
+ /// The filename.
+ /// System.String.
+ /// filename
+ public string GetValidFilename(string filename)
+ {
+ if (string.IsNullOrEmpty(filename))
+ {
+ throw new ArgumentNullException("filename");
+ }
+
+ var builder = new StringBuilder(filename);
+
+ foreach (var c in _invalidFileNameChars)
+ {
+ builder = builder.Replace(c, SpaceChar);
+ }
+
+ return builder.ToString();
+ }
+
+ ///
+ /// Gets the creation time UTC.
+ ///
+ /// The info.
+ /// DateTime.
+ public DateTime GetCreationTimeUtc(FileSystemInfo info)
+ {
+ // This could throw an error on some file systems that have dates out of range
+ try
+ {
+ return info.CreationTimeUtc;
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error determining CreationTimeUtc for {0}", ex, info.FullName);
+ return DateTime.MinValue;
+ }
+ }
+
+ ///
+ /// Gets the creation time UTC.
+ ///
+ /// The path.
+ /// DateTime.
+ public DateTime GetCreationTimeUtc(string path)
+ {
+ return GetCreationTimeUtc(GetFileSystemInfo(path));
+ }
+
+ public DateTime GetCreationTimeUtc(FileSystemMetadata info)
+ {
+ return info.CreationTimeUtc;
+ }
+
+ public DateTime GetLastWriteTimeUtc(FileSystemMetadata info)
+ {
+ return info.LastWriteTimeUtc;
+ }
+
+ ///
+ /// Gets the creation time UTC.
+ ///
+ /// The info.
+ /// DateTime.
+ public DateTime GetLastWriteTimeUtc(FileSystemInfo info)
+ {
+ // This could throw an error on some file systems that have dates out of range
+ try
+ {
+ return info.LastWriteTimeUtc;
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error determining LastAccessTimeUtc for {0}", ex, info.FullName);
+ return DateTime.MinValue;
+ }
+ }
+
+ ///
+ /// Gets the last write time UTC.
+ ///
+ /// The path.
+ /// DateTime.
+ public DateTime GetLastWriteTimeUtc(string path)
+ {
+ return GetLastWriteTimeUtc(GetFileSystemInfo(path));
+ }
+
+ ///
+ /// Gets the file stream.
+ ///
+ /// The path.
+ /// The mode.
+ /// The access.
+ /// The share.
+ /// if set to true [is asynchronous].
+ /// FileStream.
+ public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, bool isAsync = false)
+ {
+ if (_supportsAsyncFileStreams && isAsync)
+ {
+ return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 262144, true);
+ }
+
+ return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 262144);
+ }
+
+ private FileMode GetFileMode(FileOpenMode mode)
+ {
+ switch (mode)
+ {
+ case FileOpenMode.Append:
+ return FileMode.Append;
+ case FileOpenMode.Create:
+ return FileMode.Create;
+ case FileOpenMode.CreateNew:
+ return FileMode.CreateNew;
+ case FileOpenMode.Open:
+ return FileMode.Open;
+ case FileOpenMode.OpenOrCreate:
+ return FileMode.OpenOrCreate;
+ case FileOpenMode.Truncate:
+ return FileMode.Truncate;
+ default:
+ throw new Exception("Unrecognized FileOpenMode");
+ }
+ }
+
+ private FileAccess GetFileAccess(FileAccessMode mode)
+ {
+ var val = (int)mode;
+
+ return (FileAccess)val;
+ }
+
+ private FileShare GetFileShare(FileShareMode mode)
+ {
+ var val = (int)mode;
+
+ return (FileShare)val;
+ }
+
+ public void SetHidden(string path, bool isHidden)
+ {
+ var info = GetFileInfo(path);
+
+ if (info.Exists && info.IsHidden != isHidden)
+ {
+ if (isHidden)
+ {
+ FileAttributes attributes = File.GetAttributes(path);
+ attributes = RemoveAttribute(attributes, FileAttributes.Hidden);
+ File.SetAttributes(path, attributes);
+ }
+ else
+ {
+ File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden);
+ }
+ }
+ }
+
+ private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
+ {
+ return attributes & ~attributesToRemove;
+ }
+
+ ///
+ /// Swaps the files.
+ ///
+ /// The file1.
+ /// The file2.
+ public void SwapFiles(string file1, string file2)
+ {
+ if (string.IsNullOrEmpty(file1))
+ {
+ throw new ArgumentNullException("file1");
+ }
+
+ if (string.IsNullOrEmpty(file2))
+ {
+ throw new ArgumentNullException("file2");
+ }
+
+ var temp1 = Path.GetTempFileName();
+ var temp2 = Path.GetTempFileName();
+
+ // Copying over will fail against hidden files
+ RemoveHiddenAttribute(file1);
+ RemoveHiddenAttribute(file2);
+
+ CopyFile(file1, temp1, true);
+ CopyFile(file2, temp2, true);
+
+ CopyFile(temp1, file2, true);
+ CopyFile(temp2, file1, true);
+
+ DeleteFile(temp1);
+ DeleteFile(temp2);
+ }
+
+ ///
+ /// Removes the hidden attribute.
+ ///
+ /// The path.
+ private void RemoveHiddenAttribute(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ var currentFile = new FileInfo(path);
+
+ // This will fail if the file is hidden
+ if (currentFile.Exists)
+ {
+ if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ {
+ currentFile.Attributes &= ~FileAttributes.Hidden;
+ }
+ }
+ }
+
+ public bool ContainsSubPath(string parentPath, string path)
+ {
+ if (string.IsNullOrEmpty(parentPath))
+ {
+ throw new ArgumentNullException("parentPath");
+ }
+
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ return path.IndexOf(parentPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) != -1;
+ }
+
+ public bool IsRootPath(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ var parent = Path.GetDirectoryName(path);
+
+ if (!string.IsNullOrEmpty(parent))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public string NormalizePath(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ if (path.EndsWith(":\\", StringComparison.OrdinalIgnoreCase))
+ {
+ return path;
+ }
+
+ return path.TrimEnd(Path.DirectorySeparatorChar);
+ }
+
+ public string GetFileNameWithoutExtension(FileSystemMetadata info)
+ {
+ if (info.IsDirectory)
+ {
+ return info.Name;
+ }
+
+ return Path.GetFileNameWithoutExtension(info.FullName);
+ }
+
+ public string GetFileNameWithoutExtension(string path)
+ {
+ return Path.GetFileNameWithoutExtension(path);
+ }
+
+ public bool IsPathFile(string path)
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ // Cannot use Path.IsPathRooted because it returns false under mono when using windows-based paths, e.g. C:\\
+
+ if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 &&
+ !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ return true;
+
+ //return Path.IsPathRooted(path);
+ }
+
+ public void DeleteFile(string path)
+ {
+ File.Delete(path);
+ }
+
+ public void DeleteDirectory(string path, bool recursive)
+ {
+ Directory.Delete(path, recursive);
+ }
+
+ public void CreateDirectory(string path)
+ {
+ Directory.CreateDirectory(path);
+ }
+
+ public IEnumerable GetDirectories(string path, bool recursive = false)
+ {
+ var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
+
+ return ToMetadata(path, new DirectoryInfo(path).EnumerateDirectories("*", searchOption));
+ }
+
+ public IEnumerable GetFiles(string path, bool recursive = false)
+ {
+ var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
+
+ return ToMetadata(path, new DirectoryInfo(path).EnumerateFiles("*", searchOption));
+ }
+
+ public IEnumerable GetFileSystemEntries(string path, bool recursive = false)
+ {
+ var directoryInfo = new DirectoryInfo(path);
+ var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
+
+ if (EnableFileSystemRequestConcat)
+ {
+ return ToMetadata(path, directoryInfo.EnumerateDirectories("*", searchOption))
+ .Concat(ToMetadata(path, directoryInfo.EnumerateFiles("*", searchOption)));
+ }
+
+ return ToMetadata(path, directoryInfo.EnumerateFileSystemInfos("*", searchOption));
+ }
+
+ private IEnumerable ToMetadata(string parentPath, IEnumerable infos)
+ {
+ return infos.Select(i =>
+ {
+ try
+ {
+ return GetFileSystemMetadata(i);
+ }
+ catch (PathTooLongException)
+ {
+ // Can't log using the FullName because it will throw the PathTooLongExceptiona again
+ //Logger.Warn("Path too long: {0}", i.FullName);
+ Logger.Warn("File or directory path too long. Parent folder: {0}", parentPath);
+ return null;
+ }
+
+ }).Where(i => i != null);
+ }
+
+ public Stream OpenRead(string path)
+ {
+ return File.OpenRead(path);
+ }
+
+ public void CopyFile(string source, string target, bool overwrite)
+ {
+ File.Copy(source, target, overwrite);
+ }
+
+ public void MoveFile(string source, string target)
+ {
+ File.Move(source, target);
+ }
+
+ public void MoveDirectory(string source, string target)
+ {
+ Directory.Move(source, target);
+ }
+
+ public bool DirectoryExists(string path)
+ {
+ return Directory.Exists(path);
+ }
+
+ public bool FileExists(string path)
+ {
+ return File.Exists(path);
+ }
+
+ public string ReadAllText(string path)
+ {
+ return File.ReadAllText(path);
+ }
+
+ public byte[] ReadAllBytes(string path)
+ {
+ return File.ReadAllBytes(path);
+ }
+
+ public void WriteAllText(string path, string text, Encoding encoding)
+ {
+ File.WriteAllText(path, text, encoding);
+ }
+
+ public void WriteAllText(string path, string text)
+ {
+ File.WriteAllText(path, text);
+ }
+
+ public void WriteAllBytes(string path, byte[] bytes)
+ {
+ File.WriteAllBytes(path, bytes);
+ }
+
+ public string ReadAllText(string path, Encoding encoding)
+ {
+ return File.ReadAllText(path, encoding);
+ }
+
+ public IEnumerable GetDirectoryPaths(string path, bool recursive = false)
+ {
+ var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
+ return Directory.EnumerateDirectories(path, "*", searchOption);
+ }
+
+ public IEnumerable GetFilePaths(string path, bool recursive = false)
+ {
+ var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
+ return Directory.EnumerateFiles(path, "*", searchOption);
+ }
+
+ public IEnumerable GetFileSystemEntryPaths(string path, bool recursive = false)
+ {
+ var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
+ return Directory.EnumerateFileSystemEntries(path, "*", searchOption);
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/IO/WindowsFileSystem.cs b/Emby.Common.Implementations/IO/WindowsFileSystem.cs
new file mode 100644
index 0000000000..3eafeb2f76
--- /dev/null
+++ b/Emby.Common.Implementations/IO/WindowsFileSystem.cs
@@ -0,0 +1,13 @@
+using MediaBrowser.Model.Logging;
+
+namespace Emby.Common.Implementations.IO
+{
+ public class WindowsFileSystem : ManagedFileSystem
+ {
+ public WindowsFileSystem(ILogger logger)
+ : base(logger, true, true)
+ {
+ EnableFileSystemRequestConcat = false;
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Networking/BaseNetworkManager.cs b/Emby.Common.Implementations/Networking/BaseNetworkManager.cs
new file mode 100644
index 0000000000..f251d8f709
--- /dev/null
+++ b/Emby.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -0,0 +1,385 @@
+using MediaBrowser.Model.Logging;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Net.Sockets;
+using MediaBrowser.Model.Extensions;
+
+namespace Emby.Common.Implementations.Networking
+{
+ public abstract class BaseNetworkManager
+ {
+ protected ILogger Logger { get; private set; }
+ private DateTime _lastRefresh;
+
+ protected BaseNetworkManager(ILogger logger)
+ {
+ Logger = logger;
+ }
+
+ private List _localIpAddresses;
+ private readonly object _localIpAddressSyncLock = new object();
+
+ ///
+ /// Gets the machine's local ip address
+ ///
+ /// IPAddress.
+ public IEnumerable GetLocalIpAddresses()
+ {
+ const int cacheMinutes = 5;
+
+ lock (_localIpAddressSyncLock)
+ {
+ var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
+
+ if (_localIpAddresses == null || forceRefresh)
+ {
+ var addresses = GetLocalIpAddressesInternal().ToList();
+
+ _localIpAddresses = addresses;
+ _lastRefresh = DateTime.UtcNow;
+
+ return addresses;
+ }
+ }
+
+ return _localIpAddresses;
+ }
+
+ private IEnumerable GetLocalIpAddressesInternal()
+ {
+ var list = GetIPsDefault()
+ .ToList();
+
+ if (list.Count == 0)
+ {
+ list.AddRange(GetLocalIpAddressesFallback());
+ }
+
+ return list.Where(FilterIpAddress).DistinctBy(i => i.ToString());
+ }
+
+ private bool FilterIpAddress(IPAddress address)
+ {
+ var addressString = address.ToString ();
+
+ if (addressString.StartsWith("169.", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool IsInPrivateAddressSpace(string endpoint)
+ {
+ if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ // Handle ipv4 mapped to ipv6
+ endpoint = endpoint.Replace("::ffff:", string.Empty);
+
+ // Private address space:
+ // http://en.wikipedia.org/wiki/Private_network
+
+ if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase))
+ {
+ return Is172AddressPrivate(endpoint);
+ }
+
+ return
+
+ endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) ||
+ endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) ||
+ endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) ||
+ endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase) ||
+ endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase);
+ }
+
+ private bool Is172AddressPrivate(string endpoint)
+ {
+ for (var i = 16; i <= 31; i++)
+ {
+ if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public bool IsInLocalNetwork(string endpoint)
+ {
+ return IsInLocalNetworkInternal(endpoint, true);
+ }
+
+ public bool IsInLocalNetworkInternal(string endpoint, bool resolveHost)
+ {
+ if (string.IsNullOrWhiteSpace(endpoint))
+ {
+ throw new ArgumentNullException("endpoint");
+ }
+
+ IPAddress address;
+ if (IPAddress.TryParse(endpoint, out address))
+ {
+ var addressString = address.ToString();
+
+ int lengthMatch = 100;
+ if (address.AddressFamily == AddressFamily.InterNetwork)
+ {
+ lengthMatch = 4;
+ if (IsInPrivateAddressSpace(addressString))
+ {
+ return true;
+ }
+ }
+ else if (address.AddressFamily == AddressFamily.InterNetworkV6)
+ {
+ lengthMatch = 10;
+ if (IsInPrivateAddressSpace(endpoint))
+ {
+ return true;
+ }
+ }
+
+ // Should be even be doing this with ipv6?
+ if (addressString.Length >= lengthMatch)
+ {
+ var prefix = addressString.Substring(0, lengthMatch);
+
+ if (GetLocalIpAddresses().Any(i => i.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
+ {
+ return true;
+ }
+ }
+ }
+ else if (resolveHost)
+ {
+ Uri uri;
+ if (Uri.TryCreate(endpoint, UriKind.RelativeOrAbsolute, out uri))
+ {
+ try
+ {
+ var host = uri.DnsSafeHost;
+ Logger.Debug("Resolving host {0}", host);
+
+ address = GetIpAddresses(host).FirstOrDefault();
+
+ if (address != null)
+ {
+ Logger.Debug("{0} resolved to {1}", host, address);
+
+ return IsInLocalNetworkInternal(address.ToString(), false);
+ }
+ }
+ catch (InvalidOperationException)
+ {
+ // Can happen with reverse proxy or IIS url rewriting
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error resovling hostname", ex);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public IEnumerable GetIpAddresses(string hostName)
+ {
+ return Dns.GetHostAddresses(hostName);
+ }
+
+ private List GetIPsDefault()
+ {
+ NetworkInterface[] interfaces;
+
+ try
+ {
+ interfaces = NetworkInterface.GetAllNetworkInterfaces();
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error in GetAllNetworkInterfaces", ex);
+ return new List();
+ }
+
+ return interfaces.SelectMany(network => {
+
+ try
+ {
+ Logger.Debug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus);
+
+ var properties = network.GetIPProperties();
+
+ return properties.UnicastAddresses
+ .Where(i => i.IsDnsEligible)
+ .Select(i => i.Address)
+ .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
+ .ToList();
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error querying network interface", ex);
+ return new List();
+ }
+
+ }).DistinctBy(i => i.ToString())
+ .ToList();
+ }
+
+ private IEnumerable GetLocalIpAddressesFallback()
+ {
+ var host = Dns.GetHostEntry(Dns.GetHostName());
+
+ // Reverse them because the last one is usually the correct one
+ // It's not fool-proof so ultimately the consumer will have to examine them and decide
+ return host.AddressList
+ .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
+ .Reverse();
+ }
+
+ ///
+ /// Gets a random port number that is currently available
+ ///
+ /// System.Int32.
+ public int GetRandomUnusedPort()
+ {
+ var listener = new TcpListener(IPAddress.Any, 0);
+ listener.Start();
+ var port = ((IPEndPoint)listener.LocalEndpoint).Port;
+ listener.Stop();
+ return port;
+ }
+
+ ///
+ /// Returns MAC Address from first Network Card in Computer
+ ///
+ /// [string] MAC Address
+ public string GetMacAddress()
+ {
+ return NetworkInterface.GetAllNetworkInterfaces()
+ .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)
+ .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes()))
+ .FirstOrDefault();
+ }
+
+ ///
+ /// Parses the specified endpointstring.
+ ///
+ /// The endpointstring.
+ /// IPEndPoint.
+ public IPEndPoint Parse(string endpointstring)
+ {
+ return Parse(endpointstring, -1);
+ }
+
+ ///
+ /// Parses the specified endpointstring.
+ ///
+ /// The endpointstring.
+ /// The defaultport.
+ /// IPEndPoint.
+ /// Endpoint descriptor may not be empty.
+ ///
+ private static IPEndPoint Parse(string endpointstring, int defaultport)
+ {
+ if (String.IsNullOrEmpty(endpointstring)
+ || endpointstring.Trim().Length == 0)
+ {
+ throw new ArgumentException("Endpoint descriptor may not be empty.");
+ }
+
+ if (defaultport != -1 &&
+ (defaultport < IPEndPoint.MinPort
+ || defaultport > IPEndPoint.MaxPort))
+ {
+ throw new ArgumentException(String.Format("Invalid default port '{0}'", defaultport));
+ }
+
+ string[] values = endpointstring.Split(new char[] { ':' });
+ IPAddress ipaddy;
+ int port = -1;
+
+ //check if we have an IPv6 or ports
+ if (values.Length <= 2) // ipv4 or hostname
+ {
+ port = values.Length == 1 ? defaultport : GetPort(values[1]);
+
+ //try to use the address as IPv4, otherwise get hostname
+ if (!IPAddress.TryParse(values[0], out ipaddy))
+ ipaddy = GetIPfromHost(values[0]);
+ }
+ else if (values.Length > 2) //ipv6
+ {
+ //could [a:b:c]:d
+ if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"))
+ {
+ string ipaddressstring = String.Join(":", values.Take(values.Length - 1).ToArray());
+ ipaddy = IPAddress.Parse(ipaddressstring);
+ port = GetPort(values[values.Length - 1]);
+ }
+ else //[a:b:c] or a:b:c
+ {
+ ipaddy = IPAddress.Parse(endpointstring);
+ port = defaultport;
+ }
+ }
+ else
+ {
+ throw new FormatException(String.Format("Invalid endpoint ipaddress '{0}'", endpointstring));
+ }
+
+ if (port == -1)
+ throw new ArgumentException(String.Format("No port specified: '{0}'", endpointstring));
+
+ return new IPEndPoint(ipaddy, port);
+ }
+
+ protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ ///
+ /// Gets the port.
+ ///
+ /// The p.
+ /// System.Int32.
+ ///
+ private static int GetPort(string p)
+ {
+ int port;
+
+ if (!Int32.TryParse(p, out port)
+ || port < IPEndPoint.MinPort
+ || port > IPEndPoint.MaxPort)
+ {
+ throw new FormatException(String.Format("Invalid end point port '{0}'", p));
+ }
+
+ return port;
+ }
+
+ ///
+ /// Gets the I pfrom host.
+ ///
+ /// The p.
+ /// IPAddress.
+ ///
+ private static IPAddress GetIPfromHost(string p)
+ {
+ var hosts = Dns.GetHostAddresses(p);
+
+ if (hosts == null || hosts.Length == 0)
+ throw new ArgumentException(String.Format("Host not found: {0}", p));
+
+ return hosts[0];
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Properties/AssemblyInfo.cs b/Emby.Common.Implementations/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..1a5abcb274
--- /dev/null
+++ b/Emby.Common.Implementations/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Emby.Common.Implementations")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5a27010a-09c6-4e86-93ea-437484c10917")]
diff --git a/Emby.Common.Implementations/ScheduledTasks/DailyTrigger.cs b/Emby.Common.Implementations/ScheduledTasks/DailyTrigger.cs
new file mode 100644
index 0000000000..5735f80260
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/DailyTrigger.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Globalization;
+using System.Threading;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks
+{
+ ///
+ /// Represents a task trigger that fires everyday
+ ///
+ public class DailyTrigger : ITaskTrigger
+ {
+ ///
+ /// Get the time of day to trigger the task to run
+ ///
+ /// The time of day.
+ public TimeSpan TimeOfDay { get; set; }
+
+ ///
+ /// Gets or sets the timer.
+ ///
+ /// The timer.
+ private Timer Timer { get; set; }
+
+ ///
+ /// Gets the execution properties of this task.
+ ///
+ ///
+ /// The execution properties of this task.
+ ///
+ public TaskExecutionOptions TaskOptions { get; set; }
+
+ ///
+ /// Stars waiting for the trigger action
+ ///
+ /// The last result.
+ /// if set to true [is application startup].
+ public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
+ {
+ DisposeTimer();
+
+ var now = DateTime.Now;
+
+ var triggerDate = now.TimeOfDay > TimeOfDay ? now.Date.AddDays(1) : now.Date;
+ triggerDate = triggerDate.Add(TimeOfDay);
+
+ var dueTime = triggerDate - now;
+
+ logger.Info("Daily trigger for {0} set to fire at {1}, which is {2} minutes from now.", taskName, triggerDate.ToString(), dueTime.TotalMinutes.ToString(CultureInfo.InvariantCulture));
+
+ Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1));
+ }
+
+ ///
+ /// Stops waiting for the trigger action
+ ///
+ public void Stop()
+ {
+ DisposeTimer();
+ }
+
+ ///
+ /// Disposes the timer.
+ ///
+ private void DisposeTimer()
+ {
+ if (Timer != null)
+ {
+ Timer.Dispose();
+ }
+ }
+
+ ///
+ /// Occurs when [triggered].
+ ///
+ public event EventHandler> Triggered;
+
+ ///
+ /// Called when [triggered].
+ ///
+ private void OnTriggered()
+ {
+ if (Triggered != null)
+ {
+ Triggered(this, new GenericEventArgs(TaskOptions));
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/IntervalTrigger.cs b/Emby.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
new file mode 100644
index 0000000000..4d2769d8fb
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Linq;
+using System.Threading;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks
+{
+ ///
+ /// Represents a task trigger that runs repeatedly on an interval
+ ///
+ public class IntervalTrigger : ITaskTrigger
+ {
+ ///
+ /// Gets or sets the interval.
+ ///
+ /// The interval.
+ public TimeSpan Interval { get; set; }
+
+ ///
+ /// Gets or sets the timer.
+ ///
+ /// The timer.
+ private Timer Timer { get; set; }
+
+ ///
+ /// Gets the execution properties of this task.
+ ///
+ ///
+ /// The execution properties of this task.
+ ///
+ public TaskExecutionOptions TaskOptions { get; set; }
+
+ private DateTime _lastStartDate;
+
+ ///
+ /// Stars waiting for the trigger action
+ ///
+ /// The last result.
+ /// if set to true [is application startup].
+ public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
+ {
+ DisposeTimer();
+
+ DateTime triggerDate;
+
+ if (lastResult == null)
+ {
+ // Task has never been completed before
+ triggerDate = DateTime.UtcNow.AddHours(1);
+ }
+ else
+ {
+ triggerDate = new[] { lastResult.EndTimeUtc, _lastStartDate }.Max().Add(Interval);
+ }
+
+ if (DateTime.UtcNow > triggerDate)
+ {
+ triggerDate = DateTime.UtcNow.AddMinutes(1);
+ }
+
+ var dueTime = triggerDate - DateTime.UtcNow;
+ var maxDueTime = TimeSpan.FromDays(7);
+
+ if (dueTime > maxDueTime)
+ {
+ dueTime = maxDueTime;
+ }
+
+ Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1));
+ }
+
+ ///
+ /// Stops waiting for the trigger action
+ ///
+ public void Stop()
+ {
+ DisposeTimer();
+ }
+
+ ///
+ /// Disposes the timer.
+ ///
+ private void DisposeTimer()
+ {
+ if (Timer != null)
+ {
+ Timer.Dispose();
+ }
+ }
+
+ ///
+ /// Occurs when [triggered].
+ ///
+ public event EventHandler> Triggered;
+
+ ///
+ /// Called when [triggered].
+ ///
+ private void OnTriggered()
+ {
+ DisposeTimer();
+
+ if (Triggered != null)
+ {
+ _lastStartDate = DateTime.UtcNow;
+ Triggered(this, new GenericEventArgs(TaskOptions));
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
new file mode 100644
index 0000000000..f288c5c0f4
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -0,0 +1,782 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Events;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.System;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks
+{
+ ///
+ /// Class ScheduledTaskWorker
+ ///
+ public class ScheduledTaskWorker : IScheduledTaskWorker
+ {
+ public event EventHandler> TaskProgress;
+
+ ///
+ /// Gets or sets the scheduled task.
+ ///
+ /// The scheduled task.
+ public IScheduledTask ScheduledTask { get; private set; }
+
+ ///
+ /// Gets or sets the json serializer.
+ ///
+ /// The json serializer.
+ private IJsonSerializer JsonSerializer { get; set; }
+
+ ///
+ /// Gets or sets the application paths.
+ ///
+ /// The application paths.
+ private IApplicationPaths ApplicationPaths { get; set; }
+
+ ///
+ /// Gets the logger.
+ ///
+ /// The logger.
+ private ILogger Logger { get; set; }
+
+ ///
+ /// Gets the task manager.
+ ///
+ /// The task manager.
+ private ITaskManager TaskManager { get; set; }
+ private readonly IFileSystem _fileSystem;
+ private readonly ISystemEvents _systemEvents;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The scheduled task.
+ /// The application paths.
+ /// The task manager.
+ /// The json serializer.
+ /// The logger.
+ ///
+ /// scheduledTask
+ /// or
+ /// applicationPaths
+ /// or
+ /// taskManager
+ /// or
+ /// jsonSerializer
+ /// or
+ /// logger
+ ///
+ public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger, IFileSystem fileSystem, ISystemEvents systemEvents)
+ {
+ if (scheduledTask == null)
+ {
+ throw new ArgumentNullException("scheduledTask");
+ }
+ if (applicationPaths == null)
+ {
+ throw new ArgumentNullException("applicationPaths");
+ }
+ if (taskManager == null)
+ {
+ throw new ArgumentNullException("taskManager");
+ }
+ if (jsonSerializer == null)
+ {
+ throw new ArgumentNullException("jsonSerializer");
+ }
+ if (logger == null)
+ {
+ throw new ArgumentNullException("logger");
+ }
+
+ ScheduledTask = scheduledTask;
+ ApplicationPaths = applicationPaths;
+ TaskManager = taskManager;
+ JsonSerializer = jsonSerializer;
+ Logger = logger;
+ _fileSystem = fileSystem;
+ _systemEvents = systemEvents;
+
+ InitTriggerEvents();
+ }
+
+ private bool _readFromFile = false;
+ ///
+ /// The _last execution result
+ ///
+ private TaskResult _lastExecutionResult;
+ ///
+ /// The _last execution result sync lock
+ ///
+ private readonly object _lastExecutionResultSyncLock = new object();
+ ///
+ /// Gets the last execution result.
+ ///
+ /// The last execution result.
+ public TaskResult LastExecutionResult
+ {
+ get
+ {
+ var path = GetHistoryFilePath();
+
+ lock (_lastExecutionResultSyncLock)
+ {
+ if (_lastExecutionResult == null && !_readFromFile)
+ {
+ try
+ {
+ _lastExecutionResult = JsonSerializer.DeserializeFromFile(path);
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // File doesn't exist. No biggie
+ }
+ catch (FileNotFoundException)
+ {
+ // File doesn't exist. No biggie
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error deserializing {0}", ex, path);
+ }
+ _readFromFile = true;
+ }
+ }
+
+ return _lastExecutionResult;
+ }
+ private set
+ {
+ _lastExecutionResult = value;
+
+ var path = GetHistoryFilePath();
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
+
+ lock (_lastExecutionResultSyncLock)
+ {
+ JsonSerializer.SerializeToFile(value, path);
+ }
+ }
+ }
+
+ ///
+ /// Gets the name.
+ ///
+ /// The name.
+ public string Name
+ {
+ get { return ScheduledTask.Name; }
+ }
+
+ ///
+ /// Gets the description.
+ ///
+ /// The description.
+ public string Description
+ {
+ get { return ScheduledTask.Description; }
+ }
+
+ ///
+ /// Gets the category.
+ ///
+ /// The category.
+ public string Category
+ {
+ get { return ScheduledTask.Category; }
+ }
+
+ ///
+ /// Gets the current cancellation token
+ ///
+ /// The current cancellation token source.
+ private CancellationTokenSource CurrentCancellationTokenSource { get; set; }
+
+ ///
+ /// Gets or sets the current execution start time.
+ ///
+ /// The current execution start time.
+ private DateTime CurrentExecutionStartTime { get; set; }
+
+ ///
+ /// Gets the state.
+ ///
+ /// The state.
+ public TaskState State
+ {
+ get
+ {
+ if (CurrentCancellationTokenSource != null)
+ {
+ return CurrentCancellationTokenSource.IsCancellationRequested
+ ? TaskState.Cancelling
+ : TaskState.Running;
+ }
+
+ return TaskState.Idle;
+ }
+ }
+
+ ///
+ /// Gets the current progress.
+ ///
+ /// The current progress.
+ public double? CurrentProgress { get; private set; }
+
+ ///
+ /// The _triggers
+ ///
+ private Tuple[] _triggers;
+ ///
+ /// Gets the triggers that define when the task will run
+ ///
+ /// The triggers.
+ private Tuple[] InternalTriggers
+ {
+ get
+ {
+ return _triggers;
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ // Cleanup current triggers
+ if (_triggers != null)
+ {
+ DisposeTriggers();
+ }
+
+ _triggers = value.ToArray();
+
+ ReloadTriggerEvents(false);
+ }
+ }
+
+ ///
+ /// Gets the triggers that define when the task will run
+ ///
+ /// The triggers.
+ /// value
+ public TaskTriggerInfo[] Triggers
+ {
+ get
+ {
+ return InternalTriggers.Select(i => i.Item1).ToArray();
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+
+ SaveTriggers(value);
+
+ InternalTriggers = value.Select(i => new Tuple(i, GetTrigger(i))).ToArray();
+ }
+ }
+
+ ///
+ /// The _id
+ ///
+ private string _id;
+
+ ///
+ /// Gets the unique id.
+ ///
+ /// The unique id.
+ public string Id
+ {
+ get
+ {
+ if (_id == null)
+ {
+ _id = ScheduledTask.GetType().FullName.GetMD5().ToString("N");
+ }
+
+ return _id;
+ }
+ }
+
+ private void InitTriggerEvents()
+ {
+ _triggers = LoadTriggers();
+ ReloadTriggerEvents(true);
+ }
+
+ public void ReloadTriggerEvents()
+ {
+ ReloadTriggerEvents(false);
+ }
+
+ ///
+ /// Reloads the trigger events.
+ ///
+ /// if set to true [is application startup].
+ private void ReloadTriggerEvents(bool isApplicationStartup)
+ {
+ foreach (var triggerInfo in InternalTriggers)
+ {
+ var trigger = triggerInfo.Item2;
+
+ trigger.Stop();
+
+ trigger.Triggered -= trigger_Triggered;
+ trigger.Triggered += trigger_Triggered;
+ trigger.Start(LastExecutionResult, Logger, Name, isApplicationStartup);
+ }
+ }
+
+ ///
+ /// Handles the Triggered event of the trigger control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ async void trigger_Triggered(object sender, GenericEventArgs e)
+ {
+ var trigger = (ITaskTrigger)sender;
+
+ var configurableTask = ScheduledTask as IConfigurableScheduledTask;
+
+ if (configurableTask != null && !configurableTask.IsEnabled)
+ {
+ return;
+ }
+
+ Logger.Info("{0} fired for task: {1}", trigger.GetType().Name, Name);
+
+ trigger.Stop();
+
+ TaskManager.QueueScheduledTask(ScheduledTask, e.Argument);
+
+ await Task.Delay(1000).ConfigureAwait(false);
+
+ trigger.Start(LastExecutionResult, Logger, Name, false);
+ }
+
+ private Task _currentTask;
+
+ ///
+ /// Executes the task
+ ///
+ /// Task options.
+ /// Task.
+ /// Cannot execute a Task that is already running
+ public async Task Execute(TaskExecutionOptions options)
+ {
+ var task = ExecuteInternal(options);
+
+ _currentTask = task;
+
+ try
+ {
+ await task.ConfigureAwait(false);
+ }
+ finally
+ {
+ _currentTask = null;
+ }
+ }
+
+ private async Task ExecuteInternal(TaskExecutionOptions options)
+ {
+ // Cancel the current execution, if any
+ if (CurrentCancellationTokenSource != null)
+ {
+ throw new InvalidOperationException("Cannot execute a Task that is already running");
+ }
+
+ var progress = new Progress();
+
+ CurrentCancellationTokenSource = new CancellationTokenSource();
+
+ Logger.Info("Executing {0}", Name);
+
+ ((TaskManager)TaskManager).OnTaskExecuting(this);
+
+ progress.ProgressChanged += progress_ProgressChanged;
+
+ TaskCompletionStatus status;
+ CurrentExecutionStartTime = DateTime.UtcNow;
+
+ Exception failureException = null;
+
+ try
+ {
+ if (options != null && options.MaxRuntimeMs.HasValue)
+ {
+ CurrentCancellationTokenSource.CancelAfter(options.MaxRuntimeMs.Value);
+ }
+
+ var localTask = ScheduledTask.Execute(CurrentCancellationTokenSource.Token, progress);
+
+ await localTask.ConfigureAwait(false);
+
+ status = TaskCompletionStatus.Completed;
+ }
+ catch (OperationCanceledException)
+ {
+ status = TaskCompletionStatus.Cancelled;
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error", ex);
+
+ failureException = ex;
+
+ status = TaskCompletionStatus.Failed;
+ }
+
+ var startTime = CurrentExecutionStartTime;
+ var endTime = DateTime.UtcNow;
+
+ progress.ProgressChanged -= progress_ProgressChanged;
+ CurrentCancellationTokenSource.Dispose();
+ CurrentCancellationTokenSource = null;
+ CurrentProgress = null;
+
+ OnTaskCompleted(startTime, endTime, status, failureException);
+ }
+
+ ///
+ /// Progress_s the progress changed.
+ ///
+ /// The sender.
+ /// The e.
+ void progress_ProgressChanged(object sender, double e)
+ {
+ CurrentProgress = e;
+
+ EventHelper.FireEventIfNotNull(TaskProgress, this, new GenericEventArgs
+ {
+ Argument = e
+
+ }, Logger);
+ }
+
+ ///
+ /// Stops the task if it is currently executing
+ ///
+ /// Cannot cancel a Task unless it is in the Running state.
+ public void Cancel()
+ {
+ if (State != TaskState.Running)
+ {
+ throw new InvalidOperationException("Cannot cancel a Task unless it is in the Running state.");
+ }
+
+ CancelIfRunning();
+ }
+
+ ///
+ /// Cancels if running.
+ ///
+ public void CancelIfRunning()
+ {
+ if (State == TaskState.Running)
+ {
+ Logger.Info("Attempting to cancel Scheduled Task {0}", Name);
+ CurrentCancellationTokenSource.Cancel();
+ }
+ }
+
+ ///
+ /// Gets the scheduled tasks configuration directory.
+ ///
+ /// System.String.
+ private string GetScheduledTasksConfigurationDirectory()
+ {
+ return Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
+ }
+
+ ///
+ /// Gets the scheduled tasks data directory.
+ ///
+ /// System.String.
+ private string GetScheduledTasksDataDirectory()
+ {
+ return Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks");
+ }
+
+ ///
+ /// Gets the history file path.
+ ///
+ /// The history file path.
+ private string GetHistoryFilePath()
+ {
+ return Path.Combine(GetScheduledTasksDataDirectory(), new Guid(Id) + ".js");
+ }
+
+ ///
+ /// Gets the configuration file path.
+ ///
+ /// System.String.
+ private string GetConfigurationFilePath()
+ {
+ return Path.Combine(GetScheduledTasksConfigurationDirectory(), new Guid(Id) + ".js");
+ }
+
+ ///
+ /// Loads the triggers.
+ ///
+ /// IEnumerable{BaseTaskTrigger}.
+ private Tuple[] LoadTriggers()
+ {
+ var settings = LoadTriggerSettings();
+
+ return settings.Select(i => new Tuple(i, GetTrigger(i))).ToArray();
+ }
+
+ private TaskTriggerInfo[] LoadTriggerSettings()
+ {
+ try
+ {
+ return JsonSerializer.DeserializeFromFile>(GetConfigurationFilePath())
+ .ToArray();
+ }
+ catch (FileNotFoundException)
+ {
+ // File doesn't exist. No biggie. Return defaults.
+ return ScheduledTask.GetDefaultTriggers().ToArray();
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // File doesn't exist. No biggie. Return defaults.
+ return ScheduledTask.GetDefaultTriggers().ToArray();
+ }
+ }
+
+ ///
+ /// Saves the triggers.
+ ///
+ /// The triggers.
+ private void SaveTriggers(TaskTriggerInfo[] triggers)
+ {
+ var path = GetConfigurationFilePath();
+
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
+
+ JsonSerializer.SerializeToFile(triggers, path);
+ }
+
+ ///
+ /// Called when [task completed].
+ ///
+ /// The start time.
+ /// The end time.
+ /// The status.
+ private void OnTaskCompleted(DateTime startTime, DateTime endTime, TaskCompletionStatus status, Exception ex)
+ {
+ var elapsedTime = endTime - startTime;
+
+ Logger.Info("{0} {1} after {2} minute(s) and {3} seconds", Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds);
+
+ var result = new TaskResult
+ {
+ StartTimeUtc = startTime,
+ EndTimeUtc = endTime,
+ Status = status,
+ Name = Name,
+ Id = Id
+ };
+
+ result.Key = ScheduledTask.Key;
+
+ if (ex != null)
+ {
+ result.ErrorMessage = ex.Message;
+ result.LongErrorMessage = ex.StackTrace;
+ }
+
+ LastExecutionResult = result;
+
+ ((TaskManager)TaskManager).OnTaskCompleted(this, result);
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected virtual void Dispose(bool dispose)
+ {
+ if (dispose)
+ {
+ DisposeTriggers();
+
+ var wassRunning = State == TaskState.Running;
+ var startTime = CurrentExecutionStartTime;
+
+ var token = CurrentCancellationTokenSource;
+ if (token != null)
+ {
+ try
+ {
+ Logger.Info(Name + ": Cancelling");
+ token.Cancel();
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error calling CancellationToken.Cancel();", ex);
+ }
+ }
+ var task = _currentTask;
+ if (task != null)
+ {
+ try
+ {
+ Logger.Info(Name + ": Waiting on Task");
+ var exited = Task.WaitAll(new[] { task }, 2000);
+
+ if (exited)
+ {
+ Logger.Info(Name + ": Task exited");
+ }
+ else
+ {
+ Logger.Info(Name + ": Timed out waiting for task to stop");
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error calling Task.WaitAll();", ex);
+ }
+ }
+
+ if (token != null)
+ {
+ try
+ {
+ Logger.Debug(Name + ": Disposing CancellationToken");
+ token.Dispose();
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error calling CancellationToken.Dispose();", ex);
+ }
+ }
+ if (wassRunning)
+ {
+ OnTaskCompleted(startTime, DateTime.UtcNow, TaskCompletionStatus.Aborted, null);
+ }
+ }
+ }
+
+ ///
+ /// Converts a TaskTriggerInfo into a concrete BaseTaskTrigger
+ ///
+ /// The info.
+ /// BaseTaskTrigger.
+ ///
+ /// Invalid trigger type: + info.Type
+ private ITaskTrigger GetTrigger(TaskTriggerInfo info)
+ {
+ var options = new TaskExecutionOptions
+ {
+ MaxRuntimeMs = info.MaxRuntimeMs
+ };
+
+ if (info.Type.Equals(typeof(DailyTrigger).Name, StringComparison.OrdinalIgnoreCase))
+ {
+ if (!info.TimeOfDayTicks.HasValue)
+ {
+ throw new ArgumentNullException();
+ }
+
+ return new DailyTrigger
+ {
+ TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value),
+ TaskOptions = options
+ };
+ }
+
+ if (info.Type.Equals(typeof(WeeklyTrigger).Name, StringComparison.OrdinalIgnoreCase))
+ {
+ if (!info.TimeOfDayTicks.HasValue)
+ {
+ throw new ArgumentNullException();
+ }
+
+ if (!info.DayOfWeek.HasValue)
+ {
+ throw new ArgumentNullException();
+ }
+
+ return new WeeklyTrigger
+ {
+ TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value),
+ DayOfWeek = info.DayOfWeek.Value,
+ TaskOptions = options
+ };
+ }
+
+ if (info.Type.Equals(typeof(IntervalTrigger).Name, StringComparison.OrdinalIgnoreCase))
+ {
+ if (!info.IntervalTicks.HasValue)
+ {
+ throw new ArgumentNullException();
+ }
+
+ return new IntervalTrigger
+ {
+ Interval = TimeSpan.FromTicks(info.IntervalTicks.Value),
+ TaskOptions = options
+ };
+ }
+
+ if (info.Type.Equals(typeof(SystemEventTrigger).Name, StringComparison.OrdinalIgnoreCase))
+ {
+ if (!info.SystemEvent.HasValue)
+ {
+ throw new ArgumentNullException();
+ }
+
+ return new SystemEventTrigger(_systemEvents)
+ {
+ SystemEvent = info.SystemEvent.Value,
+ TaskOptions = options
+ };
+ }
+
+ if (info.Type.Equals(typeof(StartupTrigger).Name, StringComparison.OrdinalIgnoreCase))
+ {
+ return new StartupTrigger();
+ }
+
+ throw new ArgumentException("Unrecognized trigger type: " + info.Type);
+ }
+
+ ///
+ /// Disposes each trigger
+ ///
+ private void DisposeTriggers()
+ {
+ foreach (var triggerInfo in InternalTriggers)
+ {
+ var trigger = triggerInfo.Item2;
+ trigger.Triggered -= trigger_Triggered;
+ trigger.Stop();
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/StartupTrigger.cs b/Emby.Common.Implementations/ScheduledTasks/StartupTrigger.cs
new file mode 100644
index 0000000000..8aae644bc9
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/StartupTrigger.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks
+{
+ ///
+ /// Class StartupTaskTrigger
+ ///
+ public class StartupTrigger : ITaskTrigger
+ {
+ public int DelayMs { get; set; }
+
+ ///
+ /// Gets the execution properties of this task.
+ ///
+ ///
+ /// The execution properties of this task.
+ ///
+ public TaskExecutionOptions TaskOptions { get; set; }
+
+ public StartupTrigger()
+ {
+ DelayMs = 3000;
+ }
+
+ ///
+ /// Stars waiting for the trigger action
+ ///
+ /// The last result.
+ /// if set to true [is application startup].
+ public async void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
+ {
+ if (isApplicationStartup)
+ {
+ await Task.Delay(DelayMs).ConfigureAwait(false);
+
+ OnTriggered();
+ }
+ }
+
+ ///
+ /// Stops waiting for the trigger action
+ ///
+ public void Stop()
+ {
+ }
+
+ ///
+ /// Occurs when [triggered].
+ ///
+ public event EventHandler> Triggered;
+
+ ///
+ /// Called when [triggered].
+ ///
+ private void OnTriggered()
+ {
+ if (Triggered != null)
+ {
+ Triggered(this, new GenericEventArgs(TaskOptions));
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs b/Emby.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs
new file mode 100644
index 0000000000..a136a975ae
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/SystemEventTrigger.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.System;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks
+{
+ ///
+ /// Class SystemEventTrigger
+ ///
+ public class SystemEventTrigger : ITaskTrigger
+ {
+ ///
+ /// Gets or sets the system event.
+ ///
+ /// The system event.
+ public SystemEvent SystemEvent { get; set; }
+
+ ///
+ /// Gets the execution properties of this task.
+ ///
+ ///
+ /// The execution properties of this task.
+ ///
+ public TaskExecutionOptions TaskOptions { get; set; }
+
+ private readonly ISystemEvents _systemEvents;
+
+ public SystemEventTrigger(ISystemEvents systemEvents)
+ {
+ _systemEvents = systemEvents;
+ }
+
+ ///
+ /// Stars waiting for the trigger action
+ ///
+ /// The last result.
+ /// if set to true [is application startup].
+ public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
+ {
+ switch (SystemEvent)
+ {
+ case SystemEvent.WakeFromSleep:
+ _systemEvents.Resume += _systemEvents_Resume;
+ break;
+ }
+ }
+
+ private async void _systemEvents_Resume(object sender, EventArgs e)
+ {
+ if (SystemEvent == SystemEvent.WakeFromSleep)
+ {
+ // This value is a bit arbitrary, but add a delay to help ensure network connections have been restored before running the task
+ await Task.Delay(10000).ConfigureAwait(false);
+
+ OnTriggered();
+ }
+ }
+
+ ///
+ /// Stops waiting for the trigger action
+ ///
+ public void Stop()
+ {
+ _systemEvents.Resume -= _systemEvents_Resume;
+ }
+
+ ///
+ /// Occurs when [triggered].
+ ///
+ public event EventHandler> Triggered;
+
+ ///
+ /// Called when [triggered].
+ ///
+ private void OnTriggered()
+ {
+ if (Triggered != null)
+ {
+ Triggered(this, new GenericEventArgs(TaskOptions));
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Common.Implementations/ScheduledTasks/TaskManager.cs
new file mode 100644
index 0000000000..15c36e53a2
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/TaskManager.cs
@@ -0,0 +1,358 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Events;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Tasks;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.System;
+
+namespace Emby.Common.Implementations.ScheduledTasks
+{
+ ///
+ /// Class TaskManager
+ ///
+ public class TaskManager : ITaskManager
+ {
+ public event EventHandler> TaskExecuting;
+ public event EventHandler TaskCompleted;
+
+ ///
+ /// Gets the list of Scheduled Tasks
+ ///
+ /// The scheduled tasks.
+ public IScheduledTaskWorker[] ScheduledTasks { get; private set; }
+
+ ///
+ /// The _task queue
+ ///
+ private readonly ConcurrentQueue> _taskQueue =
+ new ConcurrentQueue>();
+
+ ///
+ /// Gets or sets the json serializer.
+ ///
+ /// The json serializer.
+ private IJsonSerializer JsonSerializer { get; set; }
+
+ ///
+ /// Gets or sets the application paths.
+ ///
+ /// The application paths.
+ private IApplicationPaths ApplicationPaths { get; set; }
+
+ private readonly ISystemEvents _systemEvents;
+
+ ///
+ /// Gets the logger.
+ ///
+ /// The logger.
+ private ILogger Logger { get; set; }
+ private readonly IFileSystem _fileSystem;
+
+ private bool _suspendTriggers;
+
+ public bool SuspendTriggers
+ {
+ get { return _suspendTriggers; }
+ set
+ {
+ Logger.Info("Setting SuspendTriggers to {0}", value);
+ var executeQueued = _suspendTriggers && !value;
+
+ _suspendTriggers = value;
+
+ if (executeQueued)
+ {
+ ExecuteQueuedTasks();
+ }
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The application paths.
+ /// The json serializer.
+ /// The logger.
+ /// kernel
+ public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger, IFileSystem fileSystem, ISystemEvents systemEvents)
+ {
+ ApplicationPaths = applicationPaths;
+ JsonSerializer = jsonSerializer;
+ Logger = logger;
+ _fileSystem = fileSystem;
+ _systemEvents = systemEvents;
+
+ ScheduledTasks = new IScheduledTaskWorker[] { };
+ }
+
+ private void BindToSystemEvent()
+ {
+ _systemEvents.Resume += _systemEvents_Resume;
+ }
+
+ private void _systemEvents_Resume(object sender, EventArgs e)
+ {
+ foreach (var task in ScheduledTasks)
+ {
+ task.ReloadTriggerEvents();
+ }
+ }
+
+ ///
+ /// Cancels if running and queue.
+ ///
+ ///
+ /// Task options.
+ public void CancelIfRunningAndQueue(TaskExecutionOptions options)
+ where T : IScheduledTask
+ {
+ var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
+ ((ScheduledTaskWorker)task).CancelIfRunning();
+
+ QueueScheduledTask(options);
+ }
+
+ public void CancelIfRunningAndQueue()
+ where T : IScheduledTask
+ {
+ CancelIfRunningAndQueue(new TaskExecutionOptions());
+ }
+
+ ///
+ /// Cancels if running
+ ///
+ ///
+ public void CancelIfRunning()
+ where T : IScheduledTask
+ {
+ var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
+ ((ScheduledTaskWorker)task).CancelIfRunning();
+ }
+
+ ///
+ /// Queues the scheduled task.
+ ///
+ ///
+ /// Task options
+ public void QueueScheduledTask(TaskExecutionOptions options)
+ where T : IScheduledTask
+ {
+ var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == typeof(T));
+
+ if (scheduledTask == null)
+ {
+ Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", typeof(T).Name);
+ }
+ else
+ {
+ QueueScheduledTask(scheduledTask, options);
+ }
+ }
+
+ public void QueueScheduledTask()
+ where T : IScheduledTask
+ {
+ QueueScheduledTask(new TaskExecutionOptions());
+ }
+
+ public void QueueIfNotRunning()
+ where T : IScheduledTask
+ {
+ var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
+
+ if (task.State != TaskState.Running)
+ {
+ QueueScheduledTask(new TaskExecutionOptions());
+ }
+ }
+
+ public void Execute()
+ where T : IScheduledTask
+ {
+ var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == typeof(T));
+
+ if (scheduledTask == null)
+ {
+ Logger.Error("Unable to find scheduled task of type {0} in Execute.", typeof(T).Name);
+ }
+ else
+ {
+ var type = scheduledTask.ScheduledTask.GetType();
+
+ Logger.Info("Queueing task {0}", type.Name);
+
+ lock (_taskQueue)
+ {
+ if (scheduledTask.State == TaskState.Idle)
+ {
+ Execute(scheduledTask, new TaskExecutionOptions());
+ }
+ }
+ }
+ }
+
+ ///
+ /// Queues the scheduled task.
+ ///
+ /// The task.
+ /// The task options.
+ public void QueueScheduledTask(IScheduledTask task, TaskExecutionOptions options)
+ {
+ var scheduledTask = ScheduledTasks.FirstOrDefault(t => t.ScheduledTask.GetType() == task.GetType());
+
+ if (scheduledTask == null)
+ {
+ Logger.Error("Unable to find scheduled task of type {0} in QueueScheduledTask.", task.GetType().Name);
+ }
+ else
+ {
+ QueueScheduledTask(scheduledTask, options);
+ }
+ }
+
+ ///
+ /// Queues the scheduled task.
+ ///
+ /// The task.
+ /// The task options.
+ private void QueueScheduledTask(IScheduledTaskWorker task, TaskExecutionOptions options)
+ {
+ var type = task.ScheduledTask.GetType();
+
+ Logger.Info("Queueing task {0}", type.Name);
+
+ lock (_taskQueue)
+ {
+ if (task.State == TaskState.Idle && !SuspendTriggers)
+ {
+ Execute(task, options);
+ return;
+ }
+
+ _taskQueue.Enqueue(new Tuple(type, options));
+ }
+ }
+
+ ///
+ /// Adds the tasks.
+ ///
+ /// The tasks.
+ public void AddTasks(IEnumerable tasks)
+ {
+ var myTasks = ScheduledTasks.ToList();
+
+ var list = tasks.ToList();
+ myTasks.AddRange(list.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger, _fileSystem)));
+
+ ScheduledTasks = myTasks.ToArray();
+
+ BindToSystemEvent();
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected virtual void Dispose(bool dispose)
+ {
+ foreach (var task in ScheduledTasks)
+ {
+ task.Dispose();
+ }
+ }
+
+ public void Cancel(IScheduledTaskWorker task)
+ {
+ ((ScheduledTaskWorker)task).Cancel();
+ }
+
+ public Task Execute(IScheduledTaskWorker task, TaskExecutionOptions options)
+ {
+ return ((ScheduledTaskWorker)task).Execute(options);
+ }
+
+ ///
+ /// Called when [task executing].
+ ///
+ /// The task.
+ internal void OnTaskExecuting(IScheduledTaskWorker task)
+ {
+ EventHelper.FireEventIfNotNull(TaskExecuting, this, new GenericEventArgs
+ {
+ Argument = task
+
+ }, Logger);
+ }
+
+ ///
+ /// Called when [task completed].
+ ///
+ /// The task.
+ /// The result.
+ internal void OnTaskCompleted(IScheduledTaskWorker task, TaskResult result)
+ {
+ EventHelper.FireEventIfNotNull(TaskCompleted, task, new TaskCompletionEventArgs
+ {
+ Result = result,
+ Task = task
+
+ }, Logger);
+
+ ExecuteQueuedTasks();
+ }
+
+ ///
+ /// Executes the queued tasks.
+ ///
+ private void ExecuteQueuedTasks()
+ {
+ if (SuspendTriggers)
+ {
+ return;
+ }
+
+ Logger.Info("ExecuteQueuedTasks");
+
+ // Execute queued tasks
+ lock (_taskQueue)
+ {
+ var list = new List>();
+
+ Tuple item;
+ while (_taskQueue.TryDequeue(out item))
+ {
+ if (list.All(i => i.Item1 != item.Item1))
+ {
+ list.Add(item);
+ }
+ }
+
+ foreach (var enqueuedType in list)
+ {
+ var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == enqueuedType.Item1);
+
+ if (scheduledTask.State == TaskState.Idle)
+ {
+ Execute(scheduledTask, enqueuedType.Item2);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/Emby.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
new file mode 100644
index 0000000000..1cad2e9b83
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
@@ -0,0 +1,215 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks.Tasks
+{
+ ///
+ /// Deletes old cache files
+ ///
+ public class DeleteCacheFileTask : IScheduledTask, IConfigurableScheduledTask
+ {
+ ///
+ /// Gets or sets the application paths.
+ ///
+ /// The application paths.
+ private IApplicationPaths ApplicationPaths { get; set; }
+
+ private readonly ILogger _logger;
+
+ private readonly IFileSystem _fileSystem;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DeleteCacheFileTask(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
+ {
+ ApplicationPaths = appPaths;
+ _logger = logger;
+ _fileSystem = fileSystem;
+ }
+
+ ///
+ /// Creates the triggers that define when the task will run
+ ///
+ /// IEnumerable{BaseTaskTrigger}.
+ public IEnumerable GetDefaultTriggers()
+ {
+ return new[] {
+
+ // Every so often
+ new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
+ };
+ }
+
+ ///
+ /// Returns the task to be executed
+ ///
+ /// The cancellation token.
+ /// The progress.
+ /// Task.
+ public Task Execute(CancellationToken cancellationToken, IProgress progress)
+ {
+ var minDateModified = DateTime.UtcNow.AddDays(-30);
+
+ try
+ {
+ DeleteCacheFilesFromDirectory(cancellationToken, ApplicationPaths.CachePath, minDateModified, progress);
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // No biggie here. Nothing to delete
+ }
+
+ progress.Report(90);
+
+ minDateModified = DateTime.UtcNow.AddDays(-1);
+
+ try
+ {
+ DeleteCacheFilesFromDirectory(cancellationToken, ApplicationPaths.TempDirectory, minDateModified, progress);
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // No biggie here. Nothing to delete
+ }
+
+ return Task.FromResult(true);
+ }
+
+
+ ///
+ /// Deletes the cache files from directory with a last write time less than a given date
+ ///
+ /// The task cancellation token.
+ /// The directory.
+ /// The min date modified.
+ /// The progress.
+ private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress progress)
+ {
+ var filesToDelete = _fileSystem.GetFiles(directory, true)
+ .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
+ .ToList();
+
+ var index = 0;
+
+ foreach (var file in filesToDelete)
+ {
+ double percent = index;
+ percent /= filesToDelete.Count;
+
+ progress.Report(100 * percent);
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ DeleteFile(file.FullName);
+
+ index++;
+ }
+
+ DeleteEmptyFolders(directory);
+
+ progress.Report(100);
+ }
+
+ private void DeleteEmptyFolders(string parent)
+ {
+ foreach (var directory in _fileSystem.GetDirectoryPaths(parent))
+ {
+ DeleteEmptyFolders(directory);
+ if (!_fileSystem.GetFileSystemEntryPaths(directory).Any())
+ {
+ try
+ {
+ _fileSystem.DeleteDirectory(directory, false);
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ _logger.ErrorException("Error deleting directory {0}", ex, directory);
+ }
+ catch (IOException ex)
+ {
+ _logger.ErrorException("Error deleting directory {0}", ex, directory);
+ }
+ }
+ }
+ }
+
+ private void DeleteFile(string path)
+ {
+ try
+ {
+ _fileSystem.DeleteFile(path);
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ _logger.ErrorException("Error deleting file {0}", ex, path);
+ }
+ catch (IOException ex)
+ {
+ _logger.ErrorException("Error deleting file {0}", ex, path);
+ }
+ }
+
+ ///
+ /// Gets the name of the task
+ ///
+ /// The name.
+ public string Name
+ {
+ get { return "Cache file cleanup"; }
+ }
+
+ public string Key
+ {
+ get { return "DeleteCacheFiles"; }
+ }
+
+ ///
+ /// Gets the description.
+ ///
+ /// The description.
+ public string Description
+ {
+ get { return "Deletes cache files no longer needed by the system"; }
+ }
+
+ ///
+ /// Gets the category.
+ ///
+ /// The category.
+ public string Category
+ {
+ get
+ {
+ return "Maintenance";
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether this instance is hidden.
+ ///
+ /// true if this instance is hidden; otherwise, false.
+ public bool IsHidden
+ {
+ get { return true; }
+ }
+
+ public bool IsEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsLogged
+ {
+ get { return true; }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/Emby.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
new file mode 100644
index 0000000000..3f43fa8894
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks.Tasks
+{
+ ///
+ /// Deletes old log files
+ ///
+ public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask
+ {
+ ///
+ /// Gets or sets the configuration manager.
+ ///
+ /// The configuration manager.
+ private IConfigurationManager ConfigurationManager { get; set; }
+
+ private readonly IFileSystem _fileSystem;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The configuration manager.
+ public DeleteLogFileTask(IConfigurationManager configurationManager, IFileSystem fileSystem)
+ {
+ ConfigurationManager = configurationManager;
+ _fileSystem = fileSystem;
+ }
+
+ ///
+ /// Creates the triggers that define when the task will run
+ ///
+ /// IEnumerable{BaseTaskTrigger}.
+ public IEnumerable GetDefaultTriggers()
+ {
+ return new[] {
+
+ // Every so often
+ new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
+ };
+ }
+
+ ///
+ /// Returns the task to be executed
+ ///
+ /// The cancellation token.
+ /// The progress.
+ /// Task.
+ public Task Execute(CancellationToken cancellationToken, IProgress progress)
+ {
+ // Delete log files more than n days old
+ var minDateModified = DateTime.UtcNow.AddDays(-ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
+
+ var filesToDelete = _fileSystem.GetFiles(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, true)
+ .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
+ .ToList();
+
+ var index = 0;
+
+ foreach (var file in filesToDelete)
+ {
+ double percent = index;
+ percent /= filesToDelete.Count;
+
+ progress.Report(100 * percent);
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ _fileSystem.DeleteFile(file.FullName);
+
+ index++;
+ }
+
+ progress.Report(100);
+
+ return Task.FromResult(true);
+ }
+
+ public string Key
+ {
+ get { return "CleanLogFiles"; }
+ }
+
+ ///
+ /// Gets the name of the task
+ ///
+ /// The name.
+ public string Name
+ {
+ get { return "Log file cleanup"; }
+ }
+
+ ///
+ /// Gets the description.
+ ///
+ /// The description.
+ public string Description
+ {
+ get { return string.Format("Deletes log files that are more than {0} days old.", ConfigurationManager.CommonConfiguration.LogFileRetentionDays); }
+ }
+
+ ///
+ /// Gets the category.
+ ///
+ /// The category.
+ public string Category
+ {
+ get
+ {
+ return "Maintenance";
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether this instance is hidden.
+ ///
+ /// true if this instance is hidden; otherwise, false.
+ public bool IsHidden
+ {
+ get { return true; }
+ }
+
+ public bool IsEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsLogged
+ {
+ get { return true; }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs b/Emby.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs
new file mode 100644
index 0000000000..80411de055
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks.Tasks
+{
+ ///
+ /// Class ReloadLoggerFileTask
+ ///
+ public class ReloadLoggerFileTask : IScheduledTask, IConfigurableScheduledTask
+ {
+ ///
+ /// Gets or sets the log manager.
+ ///
+ /// The log manager.
+ private ILogManager LogManager { get; set; }
+ ///
+ /// Gets or sets the configuration manager.
+ ///
+ /// The configuration manager.
+ private IConfigurationManager ConfigurationManager { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The logManager.
+ /// The configuration manager.
+ public ReloadLoggerFileTask(ILogManager logManager, IConfigurationManager configurationManager)
+ {
+ LogManager = logManager;
+ ConfigurationManager = configurationManager;
+ }
+
+ ///
+ /// Gets the default triggers.
+ ///
+ /// IEnumerable{BaseTaskTrigger}.
+ public IEnumerable GetDefaultTriggers()
+ {
+ var trigger = new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerDaily, TimeOfDayTicks = TimeSpan.FromHours(0).Ticks }; //12am
+
+ return new[] { trigger };
+ }
+
+ ///
+ /// Executes the internal.
+ ///
+ /// The cancellation token.
+ /// The progress.
+ /// Task.
+ public Task Execute(CancellationToken cancellationToken, IProgress progress)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ progress.Report(0);
+
+ LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging
+ ? LogSeverity.Debug
+ : LogSeverity.Info);
+
+ return Task.FromResult(true);
+ }
+
+ ///
+ /// Gets the name.
+ ///
+ /// The name.
+ public string Name
+ {
+ get { return "Start new log file"; }
+ }
+
+ public string Key { get; }
+
+ ///
+ /// Gets the description.
+ ///
+ /// The description.
+ public string Description
+ {
+ get { return "Moves logging to a new file to help reduce log file sizes."; }
+ }
+
+ ///
+ /// Gets the category.
+ ///
+ /// The category.
+ public string Category
+ {
+ get { return "Application"; }
+ }
+
+ public bool IsHidden
+ {
+ get { return true; }
+ }
+
+ public bool IsEnabled
+ {
+ get { return true; }
+ }
+
+ public bool IsLogged
+ {
+ get { return true; }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs b/Emby.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
new file mode 100644
index 0000000000..91540ba164
--- /dev/null
+++ b/Emby.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Threading;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
+
+namespace Emby.Common.Implementations.ScheduledTasks
+{
+ ///
+ /// Represents a task trigger that fires on a weekly basis
+ ///
+ public class WeeklyTrigger : ITaskTrigger
+ {
+ ///
+ /// Get the time of day to trigger the task to run
+ ///
+ /// The time of day.
+ public TimeSpan TimeOfDay { get; set; }
+
+ ///
+ /// Gets or sets the day of week.
+ ///
+ /// The day of week.
+ public DayOfWeek DayOfWeek { get; set; }
+
+ ///
+ /// Gets the execution properties of this task.
+ ///
+ ///
+ /// The execution properties of this task.
+ ///
+ public TaskExecutionOptions TaskOptions { get; set; }
+
+ ///
+ /// Gets or sets the timer.
+ ///
+ /// The timer.
+ private Timer Timer { get; set; }
+
+ ///
+ /// Stars waiting for the trigger action
+ ///
+ /// The last result.
+ /// if set to true [is application startup].
+ public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup)
+ {
+ DisposeTimer();
+
+ var triggerDate = GetNextTriggerDateTime();
+
+ Timer = new Timer(state => OnTriggered(), null, triggerDate - DateTime.Now, TimeSpan.FromMilliseconds(-1));
+ }
+
+ ///
+ /// Gets the next trigger date time.
+ ///
+ /// DateTime.
+ private DateTime GetNextTriggerDateTime()
+ {
+ var now = DateTime.Now;
+
+ // If it's on the same day
+ if (now.DayOfWeek == DayOfWeek)
+ {
+ // It's either later today, or a week from now
+ return now.TimeOfDay < TimeOfDay ? now.Date.Add(TimeOfDay) : now.Date.AddDays(7).Add(TimeOfDay);
+ }
+
+ var triggerDate = now.Date;
+
+ // Walk the date forward until we get to the trigger day
+ while (triggerDate.DayOfWeek != DayOfWeek)
+ {
+ triggerDate = triggerDate.AddDays(1);
+ }
+
+ // Return the trigger date plus the time offset
+ return triggerDate.Add(TimeOfDay);
+ }
+
+ ///
+ /// Stops waiting for the trigger action
+ ///
+ public void Stop()
+ {
+ DisposeTimer();
+ }
+
+ ///
+ /// Disposes the timer.
+ ///
+ private void DisposeTimer()
+ {
+ if (Timer != null)
+ {
+ Timer.Dispose();
+ }
+ }
+
+ ///
+ /// Occurs when [triggered].
+ ///
+ public event EventHandler> Triggered;
+
+ ///
+ /// Called when [triggered].
+ ///
+ private void OnTriggered()
+ {
+ if (Triggered != null)
+ {
+ Triggered(this, new GenericEventArgs(TaskOptions));
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Serialization/XmlSerializer.cs b/Emby.Common.Implementations/Serialization/XmlSerializer.cs
new file mode 100644
index 0000000000..ca162e8683
--- /dev/null
+++ b/Emby.Common.Implementations/Serialization/XmlSerializer.cs
@@ -0,0 +1,130 @@
+using MediaBrowser.Model.Serialization;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+
+namespace Emby.Common.Implementations.Serialization
+{
+ ///
+ /// Provides a wrapper around third party xml serialization.
+ ///
+ public class XmlSerializer : IXmlSerializer
+ {
+ private readonly IFileSystem _fileSystem;
+ private readonly ILogger _logger;
+
+ public XmlSerializer(IFileSystem fileSystem, ILogger logger)
+ {
+ _fileSystem = fileSystem;
+ _logger = logger;
+ }
+
+ // Need to cache these
+ // http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html
+ private readonly Dictionary _serializers =
+ new Dictionary();
+
+ private System.Xml.Serialization.XmlSerializer GetSerializer(Type type)
+ {
+ var key = type.FullName;
+ lock (_serializers)
+ {
+ System.Xml.Serialization.XmlSerializer serializer;
+ if (!_serializers.TryGetValue(key, out serializer))
+ {
+ serializer = new System.Xml.Serialization.XmlSerializer(type);
+ _serializers[key] = serializer;
+ }
+ return serializer;
+ }
+ }
+
+ ///
+ /// Serializes to writer.
+ ///
+ /// The obj.
+ /// The writer.
+ private void SerializeToWriter(object obj, XmlWriter writer)
+ {
+ //writer.Formatting = Formatting.Indented;
+ var netSerializer = GetSerializer(obj.GetType());
+ netSerializer.Serialize(writer, obj);
+ }
+
+ ///
+ /// Deserializes from stream.
+ ///
+ /// The type.
+ /// The stream.
+ /// System.Object.
+ public object DeserializeFromStream(Type type, Stream stream)
+ {
+ using (var reader = XmlReader.Create(stream))
+ {
+ var netSerializer = GetSerializer(type);
+ return netSerializer.Deserialize(reader);
+ }
+ }
+
+ ///
+ /// Serializes to stream.
+ ///
+ /// The obj.
+ /// The stream.
+ public void SerializeToStream(object obj, Stream stream)
+ {
+ using (var writer = XmlWriter.Create(stream))
+ {
+ SerializeToWriter(obj, writer);
+ }
+ }
+
+ ///
+ /// Serializes to file.
+ ///
+ /// The obj.
+ /// The file.
+ public void SerializeToFile(object obj, string file)
+ {
+ _logger.Debug("Serializing to file {0}", file);
+ using (var stream = new FileStream(file, FileMode.Create))
+ {
+ SerializeToStream(obj, stream);
+ }
+ }
+
+ ///
+ /// Deserializes from file.
+ ///
+ /// The type.
+ /// The file.
+ /// System.Object.
+ public object DeserializeFromFile(Type type, string file)
+ {
+ _logger.Debug("Deserializing file {0}", file);
+ using (var stream = _fileSystem.OpenRead(file))
+ {
+ return DeserializeFromStream(type, stream);
+ }
+ }
+
+ ///
+ /// Deserializes from bytes.
+ ///
+ /// The type.
+ /// The buffer.
+ /// System.Object.
+ public object DeserializeFromBytes(Type type, byte[] buffer)
+ {
+ using (var stream = new MemoryStream(buffer))
+ {
+ return DeserializeFromStream(type, stream);
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/Updates/GithubUpdater.cs b/Emby.Common.Implementations/Updates/GithubUpdater.cs
new file mode 100644
index 0000000000..42bc29ed5d
--- /dev/null
+++ b/Emby.Common.Implementations/Updates/GithubUpdater.cs
@@ -0,0 +1,269 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Updates;
+
+namespace Emby.Common.Implementations.Updates
+{
+ public class GithubUpdater
+ {
+ private readonly IHttpClient _httpClient;
+ private readonly IJsonSerializer _jsonSerializer;
+
+ public GithubUpdater(IHttpClient httpClient, IJsonSerializer jsonSerializer)
+ {
+ _httpClient = httpClient;
+ _jsonSerializer = jsonSerializer;
+ }
+
+ public async Task CheckForUpdateResult(string organzation, string repository, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename, TimeSpan cacheLength, CancellationToken cancellationToken)
+ {
+ var url = string.Format("https://api.github.com/repos/{0}/{1}/releases", organzation, repository);
+
+ var options = new HttpRequestOptions
+ {
+ Url = url,
+ EnableKeepAlive = false,
+ CancellationToken = cancellationToken,
+ UserAgent = "Emby/3.0",
+ BufferContent = false
+ };
+
+ if (cacheLength.Ticks > 0)
+ {
+ options.CacheMode = CacheMode.Unconditional;
+ options.CacheLength = cacheLength;
+ }
+
+ using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
+ {
+ var obj = _jsonSerializer.DeserializeFromStream(stream);
+
+ return CheckForUpdateResult(obj, minVersion, updateLevel, assetFilename, packageName, targetFilename);
+ }
+ }
+
+ private CheckForUpdateResult CheckForUpdateResult(RootObject[] obj, Version minVersion, PackageVersionClass updateLevel, string assetFilename, string packageName, string targetFilename)
+ {
+ if (updateLevel == PackageVersionClass.Release)
+ {
+ // Technically all we need to do is check that it's not pre-release
+ // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly.
+ obj = obj.Where(i => !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) && !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray();
+ }
+ else if (updateLevel == PackageVersionClass.Beta)
+ {
+ obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase)).ToArray();
+ }
+ else if (updateLevel == PackageVersionClass.Dev)
+ {
+ obj = obj.Where(i => !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) || i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase)).ToArray();
+ }
+
+ var availableUpdate = obj
+ .Select(i => CheckForUpdateResult(i, minVersion, assetFilename, packageName, targetFilename))
+ .Where(i => i != null)
+ .OrderByDescending(i => Version.Parse(i.AvailableVersion))
+ .FirstOrDefault();
+
+ return availableUpdate ?? new CheckForUpdateResult
+ {
+ IsUpdateAvailable = false
+ };
+ }
+
+ private bool MatchesUpdateLevel(RootObject i, PackageVersionClass updateLevel)
+ {
+ if (updateLevel == PackageVersionClass.Beta)
+ {
+ return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase);
+ }
+ if (updateLevel == PackageVersionClass.Dev)
+ {
+ return !i.prerelease || i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) ||
+ i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase);
+ }
+
+ // Technically all we need to do is check that it's not pre-release
+ // But let's addititional checks for -beta and -dev to handle builds that might be temporarily tagged incorrectly.
+ return !i.prerelease && !i.name.EndsWith("-beta", StringComparison.OrdinalIgnoreCase) &&
+ !i.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase);
+ }
+
+ public async Task> GetLatestReleases(string organzation, string repository, string assetFilename, CancellationToken cancellationToken)
+ {
+ var list = new List();
+
+ var url = string.Format("https://api.github.com/repos/{0}/{1}/releases", organzation, repository);
+
+ var options = new HttpRequestOptions
+ {
+ Url = url,
+ EnableKeepAlive = false,
+ CancellationToken = cancellationToken,
+ UserAgent = "Emby/3.0",
+ BufferContent = false
+ };
+
+ using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
+ {
+ var obj = _jsonSerializer.DeserializeFromStream(stream);
+
+ obj = obj.Where(i => (i.assets ?? new List()).Any(a => IsAsset(a, assetFilename))).ToArray();
+
+ list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Release)).OrderByDescending(GetVersion).Take(1));
+ list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Beta)).OrderByDescending(GetVersion).Take(1));
+ list.AddRange(obj.Where(i => MatchesUpdateLevel(i, PackageVersionClass.Dev)).OrderByDescending(GetVersion).Take(1));
+
+ return list;
+ }
+ }
+
+ public Version GetVersion(RootObject obj)
+ {
+ Version version;
+ if (!Version.TryParse(obj.tag_name, out version))
+ {
+ return new Version(1, 0);
+ }
+
+ return version;
+ }
+
+ private CheckForUpdateResult CheckForUpdateResult(RootObject obj, Version minVersion, string assetFilename, string packageName, string targetFilename)
+ {
+ Version version;
+ if (!Version.TryParse(obj.tag_name, out version))
+ {
+ return null;
+ }
+
+ if (version < minVersion)
+ {
+ return null;
+ }
+
+ var asset = (obj.assets ?? new List()).FirstOrDefault(i => IsAsset(i, assetFilename));
+
+ if (asset == null)
+ {
+ return null;
+ }
+
+ return new CheckForUpdateResult
+ {
+ AvailableVersion = version.ToString(),
+ IsUpdateAvailable = version > minVersion,
+ Package = new PackageVersionInfo
+ {
+ classification = obj.prerelease ?
+ (obj.name.EndsWith("-dev", StringComparison.OrdinalIgnoreCase) ? PackageVersionClass.Dev : PackageVersionClass.Beta) :
+ PackageVersionClass.Release,
+ name = packageName,
+ sourceUrl = asset.browser_download_url,
+ targetFilename = targetFilename,
+ versionStr = version.ToString(),
+ requiredVersionStr = "1.0.0",
+ description = obj.body,
+ infoUrl = obj.html_url
+ }
+ };
+ }
+
+ private bool IsAsset(Asset asset, string assetFilename)
+ {
+ var downloadFilename = Path.GetFileName(asset.browser_download_url) ?? string.Empty;
+
+ if (downloadFilename.IndexOf(assetFilename, StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ return true;
+ }
+
+ return string.Equals(assetFilename, downloadFilename, StringComparison.OrdinalIgnoreCase);
+ }
+
+ public class Uploader
+ {
+ public string login { get; set; }
+ public int id { get; set; }
+ public string avatar_url { get; set; }
+ public string gravatar_id { get; set; }
+ public string url { get; set; }
+ public string html_url { get; set; }
+ public string followers_url { get; set; }
+ public string following_url { get; set; }
+ public string gists_url { get; set; }
+ public string starred_url { get; set; }
+ public string subscriptions_url { get; set; }
+ public string organizations_url { get; set; }
+ public string repos_url { get; set; }
+ public string events_url { get; set; }
+ public string received_events_url { get; set; }
+ public string type { get; set; }
+ public bool site_admin { get; set; }
+ }
+
+ public class Asset
+ {
+ public string url { get; set; }
+ public int id { get; set; }
+ public string name { get; set; }
+ public object label { get; set; }
+ public Uploader uploader { get; set; }
+ public string content_type { get; set; }
+ public string state { get; set; }
+ public int size { get; set; }
+ public int download_count { get; set; }
+ public string created_at { get; set; }
+ public string updated_at { get; set; }
+ public string browser_download_url { get; set; }
+ }
+
+ public class Author
+ {
+ public string login { get; set; }
+ public int id { get; set; }
+ public string avatar_url { get; set; }
+ public string gravatar_id { get; set; }
+ public string url { get; set; }
+ public string html_url { get; set; }
+ public string followers_url { get; set; }
+ public string following_url { get; set; }
+ public string gists_url { get; set; }
+ public string starred_url { get; set; }
+ public string subscriptions_url { get; set; }
+ public string organizations_url { get; set; }
+ public string repos_url { get; set; }
+ public string events_url { get; set; }
+ public string received_events_url { get; set; }
+ public string type { get; set; }
+ public bool site_admin { get; set; }
+ }
+
+ public class RootObject
+ {
+ public string url { get; set; }
+ public string assets_url { get; set; }
+ public string upload_url { get; set; }
+ public string html_url { get; set; }
+ public int id { get; set; }
+ public string tag_name { get; set; }
+ public string target_commitish { get; set; }
+ public string name { get; set; }
+ public bool draft { get; set; }
+ public Author author { get; set; }
+ public bool prerelease { get; set; }
+ public string created_at { get; set; }
+ public string published_at { get; set; }
+ public List assets { get; set; }
+ public string tarball_url { get; set; }
+ public string zipball_url { get; set; }
+ public string body { get; set; }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/project.fragment.lock.json b/Emby.Common.Implementations/project.fragment.lock.json
new file mode 100644
index 0000000000..6a89a6320c
--- /dev/null
+++ b/Emby.Common.Implementations/project.fragment.lock.json
@@ -0,0 +1,39 @@
+{
+ "version": 2,
+ "exports": {
+ "MediaBrowser.Common/1.0.0": {
+ "type": "project",
+ "framework": ".NETPortable,Version=v4.5,Profile=Profile7",
+ "compile": {
+ "bin/Debug/MediaBrowser.Common.dll": {}
+ },
+ "runtime": {
+ "bin/Debug/MediaBrowser.Common.dll": {}
+ },
+ "contentFiles": {
+ "bin/Debug/MediaBrowser.Common.pdb": {
+ "buildAction": "None",
+ "codeLanguage": "any",
+ "copyToOutput": true
+ }
+ }
+ },
+ "MediaBrowser.Model/1.0.0": {
+ "type": "project",
+ "framework": ".NETPortable,Version=v4.5,Profile=Profile7",
+ "compile": {
+ "bin/Debug/MediaBrowser.Model.dll": {}
+ },
+ "runtime": {
+ "bin/Debug/MediaBrowser.Model.dll": {}
+ },
+ "contentFiles": {
+ "bin/Debug/MediaBrowser.Model.pdb": {
+ "buildAction": "None",
+ "codeLanguage": "any",
+ "copyToOutput": true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Emby.Common.Implementations/project.json b/Emby.Common.Implementations/project.json
new file mode 100644
index 0000000000..d939215740
--- /dev/null
+++ b/Emby.Common.Implementations/project.json
@@ -0,0 +1,48 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+
+ },
+
+ "frameworks": {
+ "net46": {
+ "frameworkAssemblies": {
+ "System.Collections": "4.0.0.0",
+ "System.IO": "4.0.0.0",
+ "System.Net": "4.0.0.0",
+ "System.Net.Http": "4.0.0.0",
+ "System.Net.Http.WebRequest": "4.0.0.0",
+ "System.Net.Primitives": "4.0.0.0",
+ "System.Runtime": "4.0.0.0",
+ "System.Text.Encoding": "4.0.0.0",
+ "System.Threading": "4.0.0.0",
+ "System.Threading.Tasks": "4.0.0.0",
+ "System.Xml": "4.0.0.0",
+ "System.Xml.Serialization": "4.0.0.0"
+ },
+ "dependencies": {
+ "MediaBrowser.Common": {
+ "target": "project"
+ },
+ "MediaBrowser.Model": {
+ "target": "project"
+ }
+ }
+ },
+ "netstandard1.6": {
+ "imports": "dnxcore50",
+ "dependencies": {
+ "NETStandard.Library": "1.6.0",
+ "MediaBrowser.Common": {
+ "target": "project"
+ },
+ "MediaBrowser.Model": {
+ "target": "project"
+ },
+ "System.Net.Requests": "4.0.11",
+ "System.Xml.XmlSerializer": "4.0.11"
+ }
+ }
+ }
+}
diff --git a/Emby.Common.Implementations/project.lock.json b/Emby.Common.Implementations/project.lock.json
new file mode 100644
index 0000000000..6313434a71
--- /dev/null
+++ b/Emby.Common.Implementations/project.lock.json
@@ -0,0 +1,4403 @@
+{
+ "locked": false,
+ "version": 2,
+ "targets": {
+ ".NETFramework,Version=v4.6": {
+ "MediaBrowser.Common/1.0.0": {
+ "type": "project",
+ "framework": ".NETPortable,Version=v4.5,Profile=Profile7",
+ "dependencies": {
+ "MediaBrowser.Model": "1.0.0"
+ }
+ },
+ "MediaBrowser.Model/1.0.0": {
+ "type": "project",
+ "framework": ".NETPortable,Version=v4.5,Profile=Profile7"
+ }
+ },
+ ".NETStandard,Version=v1.6": {
+ "Microsoft.NETCore.Platforms/1.0.1": {
+ "type": "package",
+ "compile": {
+ "lib/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.0/_._": {}
+ }
+ },
+ "Microsoft.NETCore.Targets/1.0.1": {
+ "type": "package",
+ "compile": {
+ "lib/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.0/_._": {}
+ }
+ },
+ "Microsoft.Win32.Primitives/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/Microsoft.Win32.Primitives.dll": {}
+ }
+ },
+ "NETStandard.Library/1.6.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.Win32.Primitives": "4.0.1",
+ "System.AppContext": "4.1.0",
+ "System.Collections": "4.0.11",
+ "System.Collections.Concurrent": "4.0.12",
+ "System.Console": "4.0.0",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Diagnostics.Tools": "4.0.1",
+ "System.Diagnostics.Tracing": "4.1.0",
+ "System.Globalization": "4.0.11",
+ "System.Globalization.Calendars": "4.0.1",
+ "System.IO": "4.1.0",
+ "System.IO.Compression": "4.1.0",
+ "System.IO.Compression.ZipFile": "4.0.1",
+ "System.IO.FileSystem": "4.0.1",
+ "System.IO.FileSystem.Primitives": "4.0.1",
+ "System.Linq": "4.1.0",
+ "System.Linq.Expressions": "4.1.0",
+ "System.Net.Http": "4.1.0",
+ "System.Net.Primitives": "4.0.11",
+ "System.Net.Sockets": "4.1.0",
+ "System.ObjectModel": "4.0.12",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Extensions": "4.0.1",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
+ "System.Runtime.Numerics": "4.0.1",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Security.Cryptography.Encoding": "4.0.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Security.Cryptography.X509Certificates": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Text.Encoding.Extensions": "4.0.11",
+ "System.Text.RegularExpressions": "4.1.0",
+ "System.Threading": "4.0.11",
+ "System.Threading.Tasks": "4.0.11",
+ "System.Threading.Timer": "4.0.1",
+ "System.Xml.ReaderWriter": "4.0.11",
+ "System.Xml.XDocument": "4.0.11"
+ }
+ },
+ "runtime.native.System/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1"
+ },
+ "compile": {
+ "lib/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.0/_._": {}
+ }
+ },
+ "runtime.native.System.IO.Compression/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1"
+ },
+ "compile": {
+ "lib/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.0/_._": {}
+ }
+ },
+ "runtime.native.System.Net.Http/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1"
+ },
+ "compile": {
+ "lib/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.0/_._": {}
+ }
+ },
+ "runtime.native.System.Security.Cryptography/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1"
+ },
+ "compile": {
+ "lib/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.0/_._": {}
+ }
+ },
+ "System.AppContext/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.6/System.AppContext.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.6/System.AppContext.dll": {}
+ }
+ },
+ "System.Buffers/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Diagnostics.Tracing": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Threading": "4.0.11"
+ },
+ "compile": {
+ "lib/netstandard1.1/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.1/System.Buffers.dll": {}
+ }
+ },
+ "System.Collections/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Collections.dll": {}
+ }
+ },
+ "System.Collections.Concurrent/4.0.12": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Diagnostics.Tracing": "4.1.0",
+ "System.Globalization": "4.0.11",
+ "System.Reflection": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Threading": "4.0.11",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Collections.Concurrent.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Collections.Concurrent.dll": {}
+ }
+ },
+ "System.Console/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.IO": "4.1.0",
+ "System.Runtime": "4.1.0",
+ "System.Text.Encoding": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Console.dll": {}
+ }
+ },
+ "System.Diagnostics.Debug/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Diagnostics.Debug.dll": {}
+ }
+ },
+ "System.Diagnostics.DiagnosticSource/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Tracing": "4.1.0",
+ "System.Reflection": "4.1.0",
+ "System.Runtime": "4.1.0",
+ "System.Threading": "4.0.11"
+ },
+ "compile": {
+ "lib/netstandard1.3/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Diagnostics.DiagnosticSource.dll": {}
+ }
+ },
+ "System.Diagnostics.Tools/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.0/System.Diagnostics.Tools.dll": {}
+ }
+ },
+ "System.Diagnostics.Tracing/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.5/System.Diagnostics.Tracing.dll": {}
+ }
+ },
+ "System.Globalization/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Globalization.dll": {}
+ }
+ },
+ "System.Globalization.Calendars/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Globalization": "4.0.11",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Globalization.Calendars.dll": {}
+ }
+ },
+ "System.Globalization.Extensions/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Globalization": "4.0.11",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.InteropServices": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/_._": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.3/System.Globalization.Extensions.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.3/System.Globalization.Extensions.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.IO/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.5/System.IO.dll": {}
+ }
+ },
+ "System.IO.Compression/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading": "4.0.11",
+ "System.Threading.Tasks": "4.0.11",
+ "runtime.native.System": "4.0.0",
+ "runtime.native.System.IO.Compression": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.IO.Compression.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.3/System.IO.Compression.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.3/System.IO.Compression.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.IO.Compression.ZipFile/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Buffers": "4.0.0",
+ "System.IO": "4.1.0",
+ "System.IO.Compression": "4.1.0",
+ "System.IO.FileSystem": "4.0.1",
+ "System.IO.FileSystem.Primitives": "4.0.1",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Text.Encoding": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.IO.Compression.ZipFile.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.IO.Compression.ZipFile.dll": {}
+ }
+ },
+ "System.IO.FileSystem/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.IO": "4.1.0",
+ "System.IO.FileSystem.Primitives": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.IO.FileSystem.dll": {}
+ }
+ },
+ "System.IO.FileSystem.Primitives/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.IO.FileSystem.Primitives.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.IO.FileSystem.Primitives.dll": {}
+ }
+ },
+ "System.Linq/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.6/System.Linq.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.6/System.Linq.dll": {}
+ }
+ },
+ "System.Linq.Expressions/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Linq": "4.1.0",
+ "System.ObjectModel": "4.0.12",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Emit": "4.0.1",
+ "System.Reflection.Emit.ILGeneration": "4.0.1",
+ "System.Reflection.Emit.Lightweight": "4.0.1",
+ "System.Reflection.Extensions": "4.0.1",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Reflection.TypeExtensions": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Threading": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.6/System.Linq.Expressions.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.6/System.Linq.Expressions.dll": {}
+ }
+ },
+ "System.Net.Http/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Diagnostics.DiagnosticSource": "4.0.0",
+ "System.Diagnostics.Tracing": "4.1.0",
+ "System.Globalization": "4.0.11",
+ "System.Globalization.Extensions": "4.0.1",
+ "System.IO": "4.1.0",
+ "System.IO.FileSystem": "4.0.1",
+ "System.Net.Primitives": "4.0.11",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Security.Cryptography.Encoding": "4.0.0",
+ "System.Security.Cryptography.OpenSsl": "4.0.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Security.Cryptography.X509Certificates": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading": "4.0.11",
+ "System.Threading.Tasks": "4.0.11",
+ "runtime.native.System": "4.0.0",
+ "runtime.native.System.Net.Http": "4.0.1",
+ "runtime.native.System.Security.Cryptography": "4.0.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Net.Http.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.6/System.Net.Http.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.3/System.Net.Http.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Net.Primitives/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Handles": "4.0.1"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Net.Primitives.dll": {}
+ }
+ },
+ "System.Net.Requests/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Diagnostics.Tracing": "4.1.0",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Net.Http": "4.1.0",
+ "System.Net.Primitives": "4.0.11",
+ "System.Net.WebHeaderCollection": "4.0.1",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Threading": "4.0.11",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Net.Requests.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.3/System.Net.Requests.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.3/System.Net.Requests.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Net.Sockets/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.IO": "4.1.0",
+ "System.Net.Primitives": "4.0.11",
+ "System.Runtime": "4.1.0",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Net.Sockets.dll": {}
+ }
+ },
+ "System.Net.WebHeaderCollection/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Net.WebHeaderCollection.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Net.WebHeaderCollection.dll": {}
+ }
+ },
+ "System.ObjectModel/4.0.12": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Threading": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.ObjectModel.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.ObjectModel.dll": {}
+ }
+ },
+ "System.Reflection/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.IO": "4.1.0",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.5/System.Reflection.dll": {}
+ }
+ },
+ "System.Reflection.Emit/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.IO": "4.1.0",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Emit.ILGeneration": "4.0.1",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.1/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Reflection.Emit.dll": {}
+ }
+ },
+ "System.Reflection.Emit.ILGeneration/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Reflection.Emit.ILGeneration.dll": {}
+ }
+ },
+ "System.Reflection.Emit.Lightweight/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Emit.ILGeneration": "4.0.1",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Reflection.Emit.Lightweight.dll": {}
+ }
+ },
+ "System.Reflection.Extensions/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Reflection": "4.1.0",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.0/System.Reflection.Extensions.dll": {}
+ }
+ },
+ "System.Reflection.Primitives/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.0/System.Reflection.Primitives.dll": {}
+ }
+ },
+ "System.Reflection.TypeExtensions/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Reflection": "4.1.0",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.5/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.5/System.Reflection.TypeExtensions.dll": {}
+ }
+ },
+ "System.Resources.ResourceManager/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Globalization": "4.0.11",
+ "System.Reflection": "4.1.0",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.0/System.Resources.ResourceManager.dll": {}
+ }
+ },
+ "System.Runtime/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1"
+ },
+ "compile": {
+ "ref/netstandard1.5/System.Runtime.dll": {}
+ }
+ },
+ "System.Runtime.Extensions/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.5/System.Runtime.Extensions.dll": {}
+ }
+ },
+ "System.Runtime.Handles/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Runtime.Handles.dll": {}
+ }
+ },
+ "System.Runtime.InteropServices/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Handles": "4.0.1"
+ },
+ "compile": {
+ "ref/netstandard1.5/System.Runtime.InteropServices.dll": {}
+ }
+ },
+ "System.Runtime.InteropServices.RuntimeInformation/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Reflection": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Threading": "4.0.11",
+ "runtime.native.System": "4.0.0"
+ },
+ "compile": {
+ "ref/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Runtime.Numerics/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Globalization": "4.0.11",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.1/System.Runtime.Numerics.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Runtime.Numerics.dll": {}
+ }
+ },
+ "System.Security.Cryptography.Algorithms/4.2.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Collections": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Runtime.Numerics": "4.0.1",
+ "System.Security.Cryptography.Encoding": "4.0.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Text.Encoding": "4.0.11",
+ "runtime.native.System.Security.Cryptography": "4.0.0"
+ },
+ "compile": {
+ "ref/netstandard1.6/System.Security.Cryptography.Algorithms.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.Algorithms.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.6/System.Security.Cryptography.Algorithms.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Security.Cryptography.Cng/4.2.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.IO": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Security.Cryptography.Encoding": "4.0.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Text.Encoding": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.6/_._": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.Cng.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.6/System.Security.Cryptography.Cng.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Security.Cryptography.Csp/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.IO": "4.1.0",
+ "System.Reflection": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Security.Cryptography.Encoding": "4.0.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/_._": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.3/System.Security.Cryptography.Csp.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.3/System.Security.Cryptography.Csp.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Security.Cryptography.Encoding/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Collections": "4.0.11",
+ "System.Collections.Concurrent": "4.0.12",
+ "System.Linq": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Text.Encoding": "4.0.11",
+ "runtime.native.System.Security.Cryptography": "4.0.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Security.Cryptography.Encoding.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.3/System.Security.Cryptography.Encoding.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.3/System.Security.Cryptography.Encoding.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Security.Cryptography.OpenSsl/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Runtime.Numerics": "4.0.1",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Security.Cryptography.Encoding": "4.0.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Text.Encoding": "4.0.11",
+ "runtime.native.System.Security.Cryptography": "4.0.0"
+ },
+ "compile": {
+ "ref/netstandard1.6/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.6/System.Security.Cryptography.OpenSsl.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.OpenSsl.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ }
+ }
+ },
+ "System.Security.Cryptography.Primitives/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Threading": "4.0.11",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Security.Cryptography.Primitives.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Security.Cryptography.Primitives.dll": {}
+ }
+ },
+ "System.Security.Cryptography.X509Certificates/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.Globalization.Calendars": "4.0.1",
+ "System.IO": "4.1.0",
+ "System.IO.FileSystem": "4.0.1",
+ "System.IO.FileSystem.Primitives": "4.0.1",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.Handles": "4.0.1",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Runtime.Numerics": "4.0.1",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Security.Cryptography.Cng": "4.2.0",
+ "System.Security.Cryptography.Csp": "4.0.0",
+ "System.Security.Cryptography.Encoding": "4.0.0",
+ "System.Security.Cryptography.OpenSsl": "4.0.0",
+ "System.Security.Cryptography.Primitives": "4.0.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading": "4.0.11",
+ "runtime.native.System": "4.0.0",
+ "runtime.native.System.Net.Http": "4.0.1",
+ "runtime.native.System.Security.Cryptography": "4.0.0"
+ },
+ "compile": {
+ "ref/netstandard1.4/System.Security.Cryptography.X509Certificates.dll": {}
+ },
+ "runtimeTargets": {
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.X509Certificates.dll": {
+ "assetType": "runtime",
+ "rid": "unix"
+ },
+ "runtimes/win/lib/netstandard1.6/System.Security.Cryptography.X509Certificates.dll": {
+ "assetType": "runtime",
+ "rid": "win"
+ }
+ }
+ },
+ "System.Text.Encoding/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Text.Encoding.dll": {}
+ }
+ },
+ "System.Text.Encoding.Extensions/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Text.Encoding": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Text.Encoding.Extensions.dll": {}
+ }
+ },
+ "System.Text.RegularExpressions/4.1.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Threading": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.6/System.Text.RegularExpressions.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.6/System.Text.RegularExpressions.dll": {}
+ }
+ },
+ "System.Threading/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "System.Runtime": "4.1.0",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Threading.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Threading.dll": {}
+ }
+ },
+ "System.Threading.Tasks/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Threading.Tasks.dll": {}
+ }
+ },
+ "System.Threading.Tasks.Extensions/4.0.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Runtime": "4.1.0",
+ "System.Threading.Tasks": "4.0.11"
+ },
+ "compile": {
+ "lib/netstandard1.0/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.0/System.Threading.Tasks.Extensions.dll": {}
+ }
+ },
+ "System.Threading.Timer/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1",
+ "Microsoft.NETCore.Targets": "1.0.1",
+ "System.Runtime": "4.1.0"
+ },
+ "compile": {
+ "ref/netstandard1.2/System.Threading.Timer.dll": {}
+ }
+ },
+ "System.Xml.ReaderWriter/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.IO.FileSystem": "4.0.1",
+ "System.IO.FileSystem.Primitives": "4.0.1",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Runtime.InteropServices": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Text.Encoding.Extensions": "4.0.11",
+ "System.Text.RegularExpressions": "4.1.0",
+ "System.Threading.Tasks": "4.0.11",
+ "System.Threading.Tasks.Extensions": "4.0.0"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Xml.ReaderWriter.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Xml.ReaderWriter.dll": {}
+ }
+ },
+ "System.Xml.XDocument/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Diagnostics.Tools": "4.0.1",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Reflection": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading": "4.0.11",
+ "System.Xml.ReaderWriter": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Xml.XDocument.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Xml.XDocument.dll": {}
+ }
+ },
+ "System.Xml.XmlDocument/4.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Threading": "4.0.11",
+ "System.Xml.ReaderWriter": "4.0.11"
+ },
+ "compile": {
+ "ref/netstandard1.3/_._": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Xml.XmlDocument.dll": {}
+ }
+ },
+ "System.Xml.XmlSerializer/4.0.11": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Linq": "4.1.0",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Emit": "4.0.1",
+ "System.Reflection.Emit.ILGeneration": "4.0.1",
+ "System.Reflection.Extensions": "4.0.1",
+ "System.Reflection.Primitives": "4.0.1",
+ "System.Reflection.TypeExtensions": "4.1.0",
+ "System.Resources.ResourceManager": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Text.RegularExpressions": "4.1.0",
+ "System.Threading": "4.0.11",
+ "System.Xml.ReaderWriter": "4.0.11",
+ "System.Xml.XmlDocument": "4.0.1"
+ },
+ "compile": {
+ "ref/netstandard1.3/System.Xml.XmlSerializer.dll": {}
+ },
+ "runtime": {
+ "lib/netstandard1.3/System.Xml.XmlSerializer.dll": {}
+ }
+ },
+ "MediaBrowser.Common/1.0.0": {
+ "type": "project",
+ "framework": ".NETStandard,Version=v1.6",
+ "dependencies": {
+ "MediaBrowser.Model": "1.0.0",
+ "NETStandard.Library": "1.6.0"
+ }
+ },
+ "MediaBrowser.Model/1.0.0": {
+ "type": "project",
+ "framework": ".NETStandard,Version=v1.6",
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ }
+ }
+ },
+ "libraries": {
+ "Microsoft.NETCore.Platforms/1.0.1": {
+ "sha512": "2G6OjjJzwBfNOO8myRV/nFrbTw5iA+DEm0N+qUqhrOmaVtn4pC77h38I1jsXGw5VH55+dPfQsqHD0We9sCl9FQ==",
+ "type": "package",
+ "path": "Microsoft.NETCore.Platforms/1.0.1",
+ "files": [
+ "Microsoft.NETCore.Platforms.1.0.1.nupkg.sha512",
+ "Microsoft.NETCore.Platforms.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.0/_._",
+ "runtime.json"
+ ]
+ },
+ "Microsoft.NETCore.Targets/1.0.1": {
+ "sha512": "rkn+fKobF/cbWfnnfBOQHKVKIOpxMZBvlSHkqDWgBpwGDcLRduvs3D9OLGeV6GWGvVwNlVi2CBbTjuPmtHvyNw==",
+ "type": "package",
+ "path": "Microsoft.NETCore.Targets/1.0.1",
+ "files": [
+ "Microsoft.NETCore.Targets.1.0.1.nupkg.sha512",
+ "Microsoft.NETCore.Targets.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.0/_._",
+ "runtime.json"
+ ]
+ },
+ "Microsoft.Win32.Primitives/4.0.1": {
+ "sha512": "fQnBHO9DgcmkC9dYSJoBqo6sH1VJwJprUHh8F3hbcRlxiQiBUuTntdk8tUwV490OqC2kQUrinGwZyQHTieuXRA==",
+ "type": "package",
+ "path": "Microsoft.Win32.Primitives/4.0.1",
+ "files": [
+ "Microsoft.Win32.Primitives.4.0.1.nupkg.sha512",
+ "Microsoft.Win32.Primitives.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/Microsoft.Win32.Primitives.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/Microsoft.Win32.Primitives.dll",
+ "ref/netstandard1.3/Microsoft.Win32.Primitives.dll",
+ "ref/netstandard1.3/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/de/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/es/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/fr/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/it/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/ja/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/ko/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/ru/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/zh-hans/Microsoft.Win32.Primitives.xml",
+ "ref/netstandard1.3/zh-hant/Microsoft.Win32.Primitives.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "NETStandard.Library/1.6.0": {
+ "sha512": "ypsCvIdCZ4IoYASJHt6tF2fMo7N30NLgV1EbmC+snO490OMl9FvVxmumw14rhReWU3j3g7BYudG6YCrchwHJlA==",
+ "type": "package",
+ "path": "NETStandard.Library/1.6.0",
+ "files": [
+ "NETStandard.Library.1.6.0.nupkg.sha512",
+ "NETStandard.Library.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt"
+ ]
+ },
+ "runtime.native.System/4.0.0": {
+ "sha512": "QfS/nQI7k/BLgmLrw7qm7YBoULEvgWnPI+cYsbfCVFTW8Aj+i8JhccxcFMu1RWms0YZzF+UHguNBK4Qn89e2Sg==",
+ "type": "package",
+ "path": "runtime.native.System/4.0.0",
+ "files": [
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.0/_._",
+ "runtime.native.System.4.0.0.nupkg.sha512",
+ "runtime.native.System.nuspec"
+ ]
+ },
+ "runtime.native.System.IO.Compression/4.1.0": {
+ "sha512": "Ob7nvnJBox1aaB222zSVZSkf4WrebPG4qFscfK7vmD7P7NxoSxACQLtO7ytWpqXDn2wcd/+45+EAZ7xjaPip8A==",
+ "type": "package",
+ "path": "runtime.native.System.IO.Compression/4.1.0",
+ "files": [
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.0/_._",
+ "runtime.native.System.IO.Compression.4.1.0.nupkg.sha512",
+ "runtime.native.System.IO.Compression.nuspec"
+ ]
+ },
+ "runtime.native.System.Net.Http/4.0.1": {
+ "sha512": "Nh0UPZx2Vifh8r+J+H2jxifZUD3sBrmolgiFWJd2yiNrxO0xTa6bAw3YwRn1VOiSen/tUXMS31ttNItCZ6lKuA==",
+ "type": "package",
+ "path": "runtime.native.System.Net.Http/4.0.1",
+ "files": [
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.0/_._",
+ "runtime.native.System.Net.Http.4.0.1.nupkg.sha512",
+ "runtime.native.System.Net.Http.nuspec"
+ ]
+ },
+ "runtime.native.System.Security.Cryptography/4.0.0": {
+ "sha512": "2CQK0jmO6Eu7ZeMgD+LOFbNJSXHFVQbCJJkEyEwowh1SCgYnrn9W9RykMfpeeVGw7h4IBvYikzpGUlmZTUafJw==",
+ "type": "package",
+ "path": "runtime.native.System.Security.Cryptography/4.0.0",
+ "files": [
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.0/_._",
+ "runtime.native.System.Security.Cryptography.4.0.0.nupkg.sha512",
+ "runtime.native.System.Security.Cryptography.nuspec"
+ ]
+ },
+ "System.AppContext/4.1.0": {
+ "sha512": "3QjO4jNV7PdKkmQAVp9atA+usVnKRwI3Kx1nMwJ93T0LcQfx7pKAYk0nKz5wn1oP5iqlhZuy6RXOFdhr7rDwow==",
+ "type": "package",
+ "path": "System.AppContext/4.1.0",
+ "files": [
+ "System.AppContext.4.1.0.nupkg.sha512",
+ "System.AppContext.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.AppContext.dll",
+ "lib/net463/System.AppContext.dll",
+ "lib/netcore50/System.AppContext.dll",
+ "lib/netstandard1.6/System.AppContext.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.AppContext.dll",
+ "ref/net463/System.AppContext.dll",
+ "ref/netstandard/_._",
+ "ref/netstandard1.3/System.AppContext.dll",
+ "ref/netstandard1.3/System.AppContext.xml",
+ "ref/netstandard1.3/de/System.AppContext.xml",
+ "ref/netstandard1.3/es/System.AppContext.xml",
+ "ref/netstandard1.3/fr/System.AppContext.xml",
+ "ref/netstandard1.3/it/System.AppContext.xml",
+ "ref/netstandard1.3/ja/System.AppContext.xml",
+ "ref/netstandard1.3/ko/System.AppContext.xml",
+ "ref/netstandard1.3/ru/System.AppContext.xml",
+ "ref/netstandard1.3/zh-hans/System.AppContext.xml",
+ "ref/netstandard1.3/zh-hant/System.AppContext.xml",
+ "ref/netstandard1.6/System.AppContext.dll",
+ "ref/netstandard1.6/System.AppContext.xml",
+ "ref/netstandard1.6/de/System.AppContext.xml",
+ "ref/netstandard1.6/es/System.AppContext.xml",
+ "ref/netstandard1.6/fr/System.AppContext.xml",
+ "ref/netstandard1.6/it/System.AppContext.xml",
+ "ref/netstandard1.6/ja/System.AppContext.xml",
+ "ref/netstandard1.6/ko/System.AppContext.xml",
+ "ref/netstandard1.6/ru/System.AppContext.xml",
+ "ref/netstandard1.6/zh-hans/System.AppContext.xml",
+ "ref/netstandard1.6/zh-hant/System.AppContext.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/aot/lib/netcore50/System.AppContext.dll"
+ ]
+ },
+ "System.Buffers/4.0.0": {
+ "sha512": "msXumHfjjURSkvxUjYuq4N2ghHoRi2VpXcKMA7gK6ujQfU3vGpl+B6ld0ATRg+FZFpRyA6PgEPA+VlIkTeNf2w==",
+ "type": "package",
+ "path": "System.Buffers/4.0.0",
+ "files": [
+ "System.Buffers.4.0.0.nupkg.sha512",
+ "System.Buffers.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.1/.xml",
+ "lib/netstandard1.1/System.Buffers.dll"
+ ]
+ },
+ "System.Collections/4.0.11": {
+ "sha512": "YUJGz6eFKqS0V//mLt25vFGrrCvOnsXjlvFQs+KimpwNxug9x0Pzy4PlFMU3Q2IzqAa9G2L4LsK3+9vCBK7oTg==",
+ "type": "package",
+ "path": "System.Collections/4.0.11",
+ "files": [
+ "System.Collections.4.0.11.nupkg.sha512",
+ "System.Collections.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Collections.dll",
+ "ref/netcore50/System.Collections.xml",
+ "ref/netcore50/de/System.Collections.xml",
+ "ref/netcore50/es/System.Collections.xml",
+ "ref/netcore50/fr/System.Collections.xml",
+ "ref/netcore50/it/System.Collections.xml",
+ "ref/netcore50/ja/System.Collections.xml",
+ "ref/netcore50/ko/System.Collections.xml",
+ "ref/netcore50/ru/System.Collections.xml",
+ "ref/netcore50/zh-hans/System.Collections.xml",
+ "ref/netcore50/zh-hant/System.Collections.xml",
+ "ref/netstandard1.0/System.Collections.dll",
+ "ref/netstandard1.0/System.Collections.xml",
+ "ref/netstandard1.0/de/System.Collections.xml",
+ "ref/netstandard1.0/es/System.Collections.xml",
+ "ref/netstandard1.0/fr/System.Collections.xml",
+ "ref/netstandard1.0/it/System.Collections.xml",
+ "ref/netstandard1.0/ja/System.Collections.xml",
+ "ref/netstandard1.0/ko/System.Collections.xml",
+ "ref/netstandard1.0/ru/System.Collections.xml",
+ "ref/netstandard1.0/zh-hans/System.Collections.xml",
+ "ref/netstandard1.0/zh-hant/System.Collections.xml",
+ "ref/netstandard1.3/System.Collections.dll",
+ "ref/netstandard1.3/System.Collections.xml",
+ "ref/netstandard1.3/de/System.Collections.xml",
+ "ref/netstandard1.3/es/System.Collections.xml",
+ "ref/netstandard1.3/fr/System.Collections.xml",
+ "ref/netstandard1.3/it/System.Collections.xml",
+ "ref/netstandard1.3/ja/System.Collections.xml",
+ "ref/netstandard1.3/ko/System.Collections.xml",
+ "ref/netstandard1.3/ru/System.Collections.xml",
+ "ref/netstandard1.3/zh-hans/System.Collections.xml",
+ "ref/netstandard1.3/zh-hant/System.Collections.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Collections.Concurrent/4.0.12": {
+ "sha512": "2gBcbb3drMLgxlI0fBfxMA31ec6AEyYCHygGse4vxceJan8mRIWeKJ24BFzN7+bi/NFTgdIgufzb94LWO5EERQ==",
+ "type": "package",
+ "path": "System.Collections.Concurrent/4.0.12",
+ "files": [
+ "System.Collections.Concurrent.4.0.12.nupkg.sha512",
+ "System.Collections.Concurrent.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.Collections.Concurrent.dll",
+ "lib/netstandard1.3/System.Collections.Concurrent.dll",
+ "lib/portable-net45+win8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Collections.Concurrent.dll",
+ "ref/netcore50/System.Collections.Concurrent.xml",
+ "ref/netcore50/de/System.Collections.Concurrent.xml",
+ "ref/netcore50/es/System.Collections.Concurrent.xml",
+ "ref/netcore50/fr/System.Collections.Concurrent.xml",
+ "ref/netcore50/it/System.Collections.Concurrent.xml",
+ "ref/netcore50/ja/System.Collections.Concurrent.xml",
+ "ref/netcore50/ko/System.Collections.Concurrent.xml",
+ "ref/netcore50/ru/System.Collections.Concurrent.xml",
+ "ref/netcore50/zh-hans/System.Collections.Concurrent.xml",
+ "ref/netcore50/zh-hant/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/System.Collections.Concurrent.dll",
+ "ref/netstandard1.1/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/de/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/es/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/fr/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/it/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/ja/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/ko/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/ru/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/zh-hans/System.Collections.Concurrent.xml",
+ "ref/netstandard1.1/zh-hant/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/System.Collections.Concurrent.dll",
+ "ref/netstandard1.3/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/de/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/es/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/fr/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/it/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/ja/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/ko/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/ru/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/zh-hans/System.Collections.Concurrent.xml",
+ "ref/netstandard1.3/zh-hant/System.Collections.Concurrent.xml",
+ "ref/portable-net45+win8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Console/4.0.0": {
+ "sha512": "qSKUSOIiYA/a0g5XXdxFcUFmv1hNICBD7QZ0QhGYVipPIhvpiydY8VZqr1thmCXvmn8aipMg64zuanB4eotK9A==",
+ "type": "package",
+ "path": "System.Console/4.0.0",
+ "files": [
+ "System.Console.4.0.0.nupkg.sha512",
+ "System.Console.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Console.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Console.dll",
+ "ref/netstandard1.3/System.Console.dll",
+ "ref/netstandard1.3/System.Console.xml",
+ "ref/netstandard1.3/de/System.Console.xml",
+ "ref/netstandard1.3/es/System.Console.xml",
+ "ref/netstandard1.3/fr/System.Console.xml",
+ "ref/netstandard1.3/it/System.Console.xml",
+ "ref/netstandard1.3/ja/System.Console.xml",
+ "ref/netstandard1.3/ko/System.Console.xml",
+ "ref/netstandard1.3/ru/System.Console.xml",
+ "ref/netstandard1.3/zh-hans/System.Console.xml",
+ "ref/netstandard1.3/zh-hant/System.Console.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Diagnostics.Debug/4.0.11": {
+ "sha512": "w5U95fVKHY4G8ASs/K5iK3J5LY+/dLFd4vKejsnI/ZhBsWS9hQakfx3Zr7lRWKg4tAw9r4iktyvsTagWkqYCiw==",
+ "type": "package",
+ "path": "System.Diagnostics.Debug/4.0.11",
+ "files": [
+ "System.Diagnostics.Debug.4.0.11.nupkg.sha512",
+ "System.Diagnostics.Debug.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Diagnostics.Debug.dll",
+ "ref/netcore50/System.Diagnostics.Debug.xml",
+ "ref/netcore50/de/System.Diagnostics.Debug.xml",
+ "ref/netcore50/es/System.Diagnostics.Debug.xml",
+ "ref/netcore50/fr/System.Diagnostics.Debug.xml",
+ "ref/netcore50/it/System.Diagnostics.Debug.xml",
+ "ref/netcore50/ja/System.Diagnostics.Debug.xml",
+ "ref/netcore50/ko/System.Diagnostics.Debug.xml",
+ "ref/netcore50/ru/System.Diagnostics.Debug.xml",
+ "ref/netcore50/zh-hans/System.Diagnostics.Debug.xml",
+ "ref/netcore50/zh-hant/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/System.Diagnostics.Debug.dll",
+ "ref/netstandard1.0/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/de/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/es/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/fr/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/it/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/ja/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/ko/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/ru/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/zh-hans/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.0/zh-hant/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/System.Diagnostics.Debug.dll",
+ "ref/netstandard1.3/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/de/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/es/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/fr/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/it/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/ja/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/ko/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/ru/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/zh-hans/System.Diagnostics.Debug.xml",
+ "ref/netstandard1.3/zh-hant/System.Diagnostics.Debug.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Diagnostics.DiagnosticSource/4.0.0": {
+ "sha512": "YKglnq4BMTJxfcr6nuT08g+yJ0UxdePIHxosiLuljuHIUR6t4KhFsyaHOaOc1Ofqp0PUvJ0EmcgiEz6T7vEx3w==",
+ "type": "package",
+ "path": "System.Diagnostics.DiagnosticSource/4.0.0",
+ "files": [
+ "System.Diagnostics.DiagnosticSource.4.0.0.nupkg.sha512",
+ "System.Diagnostics.DiagnosticSource.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/net46/System.Diagnostics.DiagnosticSource.dll",
+ "lib/net46/System.Diagnostics.DiagnosticSource.xml",
+ "lib/netstandard1.1/System.Diagnostics.DiagnosticSource.dll",
+ "lib/netstandard1.1/System.Diagnostics.DiagnosticSource.xml",
+ "lib/netstandard1.3/System.Diagnostics.DiagnosticSource.dll",
+ "lib/netstandard1.3/System.Diagnostics.DiagnosticSource.xml",
+ "lib/portable-net45+win8+wpa81/System.Diagnostics.DiagnosticSource.dll",
+ "lib/portable-net45+win8+wpa81/System.Diagnostics.DiagnosticSource.xml"
+ ]
+ },
+ "System.Diagnostics.Tools/4.0.1": {
+ "sha512": "xBfJ8pnd4C17dWaC9FM6aShzbJcRNMChUMD42I6772KGGrqaFdumwhn9OdM68erj1ueNo3xdQ1EwiFjK5k8p0g==",
+ "type": "package",
+ "path": "System.Diagnostics.Tools/4.0.1",
+ "files": [
+ "System.Diagnostics.Tools.4.0.1.nupkg.sha512",
+ "System.Diagnostics.Tools.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Diagnostics.Tools.dll",
+ "ref/netcore50/System.Diagnostics.Tools.xml",
+ "ref/netcore50/de/System.Diagnostics.Tools.xml",
+ "ref/netcore50/es/System.Diagnostics.Tools.xml",
+ "ref/netcore50/fr/System.Diagnostics.Tools.xml",
+ "ref/netcore50/it/System.Diagnostics.Tools.xml",
+ "ref/netcore50/ja/System.Diagnostics.Tools.xml",
+ "ref/netcore50/ko/System.Diagnostics.Tools.xml",
+ "ref/netcore50/ru/System.Diagnostics.Tools.xml",
+ "ref/netcore50/zh-hans/System.Diagnostics.Tools.xml",
+ "ref/netcore50/zh-hant/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/System.Diagnostics.Tools.dll",
+ "ref/netstandard1.0/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/de/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/es/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/fr/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/it/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/ja/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/ko/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/ru/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/zh-hans/System.Diagnostics.Tools.xml",
+ "ref/netstandard1.0/zh-hant/System.Diagnostics.Tools.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Diagnostics.Tracing/4.1.0": {
+ "sha512": "vDN1PoMZCkkdNjvZLql592oYJZgS7URcJzJ7bxeBgGtx5UtR5leNm49VmfHGqIffX4FKacHbI3H6UyNSHQknBg==",
+ "type": "package",
+ "path": "System.Diagnostics.Tracing/4.1.0",
+ "files": [
+ "System.Diagnostics.Tracing.4.1.0.nupkg.sha512",
+ "System.Diagnostics.Tracing.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net462/System.Diagnostics.Tracing.dll",
+ "lib/portable-net45+win8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net462/System.Diagnostics.Tracing.dll",
+ "ref/netcore50/System.Diagnostics.Tracing.dll",
+ "ref/netcore50/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/de/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/es/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/fr/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/it/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/ja/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/ko/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/ru/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/zh-hans/System.Diagnostics.Tracing.xml",
+ "ref/netcore50/zh-hant/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/System.Diagnostics.Tracing.dll",
+ "ref/netstandard1.1/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/de/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/es/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/fr/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/it/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/ja/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/ko/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/ru/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/zh-hans/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.1/zh-hant/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/System.Diagnostics.Tracing.dll",
+ "ref/netstandard1.2/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/de/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/es/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/fr/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/it/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/ja/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/ko/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/ru/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/zh-hans/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.2/zh-hant/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/System.Diagnostics.Tracing.dll",
+ "ref/netstandard1.3/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/de/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/es/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/fr/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/it/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/ja/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/ko/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/ru/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/zh-hans/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.3/zh-hant/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/System.Diagnostics.Tracing.dll",
+ "ref/netstandard1.5/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/de/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/es/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/fr/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/it/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/ja/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/ko/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/ru/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/zh-hans/System.Diagnostics.Tracing.xml",
+ "ref/netstandard1.5/zh-hant/System.Diagnostics.Tracing.xml",
+ "ref/portable-net45+win8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Globalization/4.0.11": {
+ "sha512": "B95h0YLEL2oSnwF/XjqSWKnwKOy/01VWkNlsCeMTFJLLabflpGV26nK164eRs5GiaRSBGpOxQ3pKoSnnyZN5pg==",
+ "type": "package",
+ "path": "System.Globalization/4.0.11",
+ "files": [
+ "System.Globalization.4.0.11.nupkg.sha512",
+ "System.Globalization.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Globalization.dll",
+ "ref/netcore50/System.Globalization.xml",
+ "ref/netcore50/de/System.Globalization.xml",
+ "ref/netcore50/es/System.Globalization.xml",
+ "ref/netcore50/fr/System.Globalization.xml",
+ "ref/netcore50/it/System.Globalization.xml",
+ "ref/netcore50/ja/System.Globalization.xml",
+ "ref/netcore50/ko/System.Globalization.xml",
+ "ref/netcore50/ru/System.Globalization.xml",
+ "ref/netcore50/zh-hans/System.Globalization.xml",
+ "ref/netcore50/zh-hant/System.Globalization.xml",
+ "ref/netstandard1.0/System.Globalization.dll",
+ "ref/netstandard1.0/System.Globalization.xml",
+ "ref/netstandard1.0/de/System.Globalization.xml",
+ "ref/netstandard1.0/es/System.Globalization.xml",
+ "ref/netstandard1.0/fr/System.Globalization.xml",
+ "ref/netstandard1.0/it/System.Globalization.xml",
+ "ref/netstandard1.0/ja/System.Globalization.xml",
+ "ref/netstandard1.0/ko/System.Globalization.xml",
+ "ref/netstandard1.0/ru/System.Globalization.xml",
+ "ref/netstandard1.0/zh-hans/System.Globalization.xml",
+ "ref/netstandard1.0/zh-hant/System.Globalization.xml",
+ "ref/netstandard1.3/System.Globalization.dll",
+ "ref/netstandard1.3/System.Globalization.xml",
+ "ref/netstandard1.3/de/System.Globalization.xml",
+ "ref/netstandard1.3/es/System.Globalization.xml",
+ "ref/netstandard1.3/fr/System.Globalization.xml",
+ "ref/netstandard1.3/it/System.Globalization.xml",
+ "ref/netstandard1.3/ja/System.Globalization.xml",
+ "ref/netstandard1.3/ko/System.Globalization.xml",
+ "ref/netstandard1.3/ru/System.Globalization.xml",
+ "ref/netstandard1.3/zh-hans/System.Globalization.xml",
+ "ref/netstandard1.3/zh-hant/System.Globalization.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Globalization.Calendars/4.0.1": {
+ "sha512": "L1c6IqeQ88vuzC1P81JeHmHA8mxq8a18NUBNXnIY/BVb+TCyAaGIFbhpZt60h9FJNmisymoQkHEFSE9Vslja1Q==",
+ "type": "package",
+ "path": "System.Globalization.Calendars/4.0.1",
+ "files": [
+ "System.Globalization.Calendars.4.0.1.nupkg.sha512",
+ "System.Globalization.Calendars.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Globalization.Calendars.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Globalization.Calendars.dll",
+ "ref/netstandard1.3/System.Globalization.Calendars.dll",
+ "ref/netstandard1.3/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/de/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/es/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/fr/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/it/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/ja/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/ko/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/ru/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/zh-hans/System.Globalization.Calendars.xml",
+ "ref/netstandard1.3/zh-hant/System.Globalization.Calendars.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Globalization.Extensions/4.0.1": {
+ "sha512": "KKo23iKeOaIg61SSXwjANN7QYDr/3op3OWGGzDzz7mypx0Za0fZSeG0l6cco8Ntp8YMYkIQcAqlk8yhm5/Uhcg==",
+ "type": "package",
+ "path": "System.Globalization.Extensions/4.0.1",
+ "files": [
+ "System.Globalization.Extensions.4.0.1.nupkg.sha512",
+ "System.Globalization.Extensions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Globalization.Extensions.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Globalization.Extensions.dll",
+ "ref/netstandard1.3/System.Globalization.Extensions.dll",
+ "ref/netstandard1.3/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/de/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/es/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/fr/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/it/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/ja/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/ko/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/ru/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/zh-hans/System.Globalization.Extensions.xml",
+ "ref/netstandard1.3/zh-hant/System.Globalization.Extensions.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.3/System.Globalization.Extensions.dll",
+ "runtimes/win/lib/net46/System.Globalization.Extensions.dll",
+ "runtimes/win/lib/netstandard1.3/System.Globalization.Extensions.dll"
+ ]
+ },
+ "System.IO/4.1.0": {
+ "sha512": "3KlTJceQc3gnGIaHZ7UBZO26SHL1SHE4ddrmiwumFnId+CEHP+O8r386tZKaE6zlk5/mF8vifMBzHj9SaXN+mQ==",
+ "type": "package",
+ "path": "System.IO/4.1.0",
+ "files": [
+ "System.IO.4.1.0.nupkg.sha512",
+ "System.IO.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net462/System.IO.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net462/System.IO.dll",
+ "ref/netcore50/System.IO.dll",
+ "ref/netcore50/System.IO.xml",
+ "ref/netcore50/de/System.IO.xml",
+ "ref/netcore50/es/System.IO.xml",
+ "ref/netcore50/fr/System.IO.xml",
+ "ref/netcore50/it/System.IO.xml",
+ "ref/netcore50/ja/System.IO.xml",
+ "ref/netcore50/ko/System.IO.xml",
+ "ref/netcore50/ru/System.IO.xml",
+ "ref/netcore50/zh-hans/System.IO.xml",
+ "ref/netcore50/zh-hant/System.IO.xml",
+ "ref/netstandard1.0/System.IO.dll",
+ "ref/netstandard1.0/System.IO.xml",
+ "ref/netstandard1.0/de/System.IO.xml",
+ "ref/netstandard1.0/es/System.IO.xml",
+ "ref/netstandard1.0/fr/System.IO.xml",
+ "ref/netstandard1.0/it/System.IO.xml",
+ "ref/netstandard1.0/ja/System.IO.xml",
+ "ref/netstandard1.0/ko/System.IO.xml",
+ "ref/netstandard1.0/ru/System.IO.xml",
+ "ref/netstandard1.0/zh-hans/System.IO.xml",
+ "ref/netstandard1.0/zh-hant/System.IO.xml",
+ "ref/netstandard1.3/System.IO.dll",
+ "ref/netstandard1.3/System.IO.xml",
+ "ref/netstandard1.3/de/System.IO.xml",
+ "ref/netstandard1.3/es/System.IO.xml",
+ "ref/netstandard1.3/fr/System.IO.xml",
+ "ref/netstandard1.3/it/System.IO.xml",
+ "ref/netstandard1.3/ja/System.IO.xml",
+ "ref/netstandard1.3/ko/System.IO.xml",
+ "ref/netstandard1.3/ru/System.IO.xml",
+ "ref/netstandard1.3/zh-hans/System.IO.xml",
+ "ref/netstandard1.3/zh-hant/System.IO.xml",
+ "ref/netstandard1.5/System.IO.dll",
+ "ref/netstandard1.5/System.IO.xml",
+ "ref/netstandard1.5/de/System.IO.xml",
+ "ref/netstandard1.5/es/System.IO.xml",
+ "ref/netstandard1.5/fr/System.IO.xml",
+ "ref/netstandard1.5/it/System.IO.xml",
+ "ref/netstandard1.5/ja/System.IO.xml",
+ "ref/netstandard1.5/ko/System.IO.xml",
+ "ref/netstandard1.5/ru/System.IO.xml",
+ "ref/netstandard1.5/zh-hans/System.IO.xml",
+ "ref/netstandard1.5/zh-hant/System.IO.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.IO.Compression/4.1.0": {
+ "sha512": "TjnBS6eztThSzeSib+WyVbLzEdLKUcEHN69VtS3u8aAsSc18FU6xCZlNWWsEd8SKcXAE+y1sOu7VbU8sUeM0sg==",
+ "type": "package",
+ "path": "System.IO.Compression/4.1.0",
+ "files": [
+ "System.IO.Compression.4.1.0.nupkg.sha512",
+ "System.IO.Compression.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net46/System.IO.Compression.dll",
+ "lib/portable-net45+win8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net46/System.IO.Compression.dll",
+ "ref/netcore50/System.IO.Compression.dll",
+ "ref/netcore50/System.IO.Compression.xml",
+ "ref/netcore50/de/System.IO.Compression.xml",
+ "ref/netcore50/es/System.IO.Compression.xml",
+ "ref/netcore50/fr/System.IO.Compression.xml",
+ "ref/netcore50/it/System.IO.Compression.xml",
+ "ref/netcore50/ja/System.IO.Compression.xml",
+ "ref/netcore50/ko/System.IO.Compression.xml",
+ "ref/netcore50/ru/System.IO.Compression.xml",
+ "ref/netcore50/zh-hans/System.IO.Compression.xml",
+ "ref/netcore50/zh-hant/System.IO.Compression.xml",
+ "ref/netstandard1.1/System.IO.Compression.dll",
+ "ref/netstandard1.1/System.IO.Compression.xml",
+ "ref/netstandard1.1/de/System.IO.Compression.xml",
+ "ref/netstandard1.1/es/System.IO.Compression.xml",
+ "ref/netstandard1.1/fr/System.IO.Compression.xml",
+ "ref/netstandard1.1/it/System.IO.Compression.xml",
+ "ref/netstandard1.1/ja/System.IO.Compression.xml",
+ "ref/netstandard1.1/ko/System.IO.Compression.xml",
+ "ref/netstandard1.1/ru/System.IO.Compression.xml",
+ "ref/netstandard1.1/zh-hans/System.IO.Compression.xml",
+ "ref/netstandard1.1/zh-hant/System.IO.Compression.xml",
+ "ref/netstandard1.3/System.IO.Compression.dll",
+ "ref/netstandard1.3/System.IO.Compression.xml",
+ "ref/netstandard1.3/de/System.IO.Compression.xml",
+ "ref/netstandard1.3/es/System.IO.Compression.xml",
+ "ref/netstandard1.3/fr/System.IO.Compression.xml",
+ "ref/netstandard1.3/it/System.IO.Compression.xml",
+ "ref/netstandard1.3/ja/System.IO.Compression.xml",
+ "ref/netstandard1.3/ko/System.IO.Compression.xml",
+ "ref/netstandard1.3/ru/System.IO.Compression.xml",
+ "ref/netstandard1.3/zh-hans/System.IO.Compression.xml",
+ "ref/netstandard1.3/zh-hant/System.IO.Compression.xml",
+ "ref/portable-net45+win8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.3/System.IO.Compression.dll",
+ "runtimes/win/lib/net46/System.IO.Compression.dll",
+ "runtimes/win/lib/netstandard1.3/System.IO.Compression.dll"
+ ]
+ },
+ "System.IO.Compression.ZipFile/4.0.1": {
+ "sha512": "hBQYJzfTbQURF10nLhd+az2NHxsU6MU7AB8RUf4IolBP5lOAm4Luho851xl+CqslmhI5ZH/el8BlngEk4lBkaQ==",
+ "type": "package",
+ "path": "System.IO.Compression.ZipFile/4.0.1",
+ "files": [
+ "System.IO.Compression.ZipFile.4.0.1.nupkg.sha512",
+ "System.IO.Compression.ZipFile.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.IO.Compression.ZipFile.dll",
+ "lib/netstandard1.3/System.IO.Compression.ZipFile.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.IO.Compression.ZipFile.dll",
+ "ref/netstandard1.3/System.IO.Compression.ZipFile.dll",
+ "ref/netstandard1.3/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/de/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/es/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/fr/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/it/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/ja/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/ko/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/ru/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/zh-hans/System.IO.Compression.ZipFile.xml",
+ "ref/netstandard1.3/zh-hant/System.IO.Compression.ZipFile.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.IO.FileSystem/4.0.1": {
+ "sha512": "IBErlVq5jOggAD69bg1t0pJcHaDbJbWNUZTPI96fkYWzwYbN6D9wRHMULLDd9dHsl7C2YsxXL31LMfPI1SWt8w==",
+ "type": "package",
+ "path": "System.IO.FileSystem/4.0.1",
+ "files": [
+ "System.IO.FileSystem.4.0.1.nupkg.sha512",
+ "System.IO.FileSystem.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.IO.FileSystem.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.IO.FileSystem.dll",
+ "ref/netstandard1.3/System.IO.FileSystem.dll",
+ "ref/netstandard1.3/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/de/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/es/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/fr/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/it/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/ja/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/ko/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/ru/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/zh-hans/System.IO.FileSystem.xml",
+ "ref/netstandard1.3/zh-hant/System.IO.FileSystem.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.IO.FileSystem.Primitives/4.0.1": {
+ "sha512": "kWkKD203JJKxJeE74p8aF8y4Qc9r9WQx4C0cHzHPrY3fv/L/IhWnyCHaFJ3H1QPOH6A93whlQ2vG5nHlBDvzWQ==",
+ "type": "package",
+ "path": "System.IO.FileSystem.Primitives/4.0.1",
+ "files": [
+ "System.IO.FileSystem.Primitives.4.0.1.nupkg.sha512",
+ "System.IO.FileSystem.Primitives.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.IO.FileSystem.Primitives.dll",
+ "lib/netstandard1.3/System.IO.FileSystem.Primitives.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.IO.FileSystem.Primitives.dll",
+ "ref/netstandard1.3/System.IO.FileSystem.Primitives.dll",
+ "ref/netstandard1.3/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/de/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/es/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/fr/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/it/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/ja/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/ko/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/ru/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/zh-hans/System.IO.FileSystem.Primitives.xml",
+ "ref/netstandard1.3/zh-hant/System.IO.FileSystem.Primitives.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Linq/4.1.0": {
+ "sha512": "bQ0iYFOQI0nuTnt+NQADns6ucV4DUvMdwN6CbkB1yj8i7arTGiTN5eok1kQwdnnNWSDZfIUySQY+J3d5KjWn0g==",
+ "type": "package",
+ "path": "System.Linq/4.1.0",
+ "files": [
+ "System.Linq.4.1.0.nupkg.sha512",
+ "System.Linq.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net463/System.Linq.dll",
+ "lib/netcore50/System.Linq.dll",
+ "lib/netstandard1.6/System.Linq.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net463/System.Linq.dll",
+ "ref/netcore50/System.Linq.dll",
+ "ref/netcore50/System.Linq.xml",
+ "ref/netcore50/de/System.Linq.xml",
+ "ref/netcore50/es/System.Linq.xml",
+ "ref/netcore50/fr/System.Linq.xml",
+ "ref/netcore50/it/System.Linq.xml",
+ "ref/netcore50/ja/System.Linq.xml",
+ "ref/netcore50/ko/System.Linq.xml",
+ "ref/netcore50/ru/System.Linq.xml",
+ "ref/netcore50/zh-hans/System.Linq.xml",
+ "ref/netcore50/zh-hant/System.Linq.xml",
+ "ref/netstandard1.0/System.Linq.dll",
+ "ref/netstandard1.0/System.Linq.xml",
+ "ref/netstandard1.0/de/System.Linq.xml",
+ "ref/netstandard1.0/es/System.Linq.xml",
+ "ref/netstandard1.0/fr/System.Linq.xml",
+ "ref/netstandard1.0/it/System.Linq.xml",
+ "ref/netstandard1.0/ja/System.Linq.xml",
+ "ref/netstandard1.0/ko/System.Linq.xml",
+ "ref/netstandard1.0/ru/System.Linq.xml",
+ "ref/netstandard1.0/zh-hans/System.Linq.xml",
+ "ref/netstandard1.0/zh-hant/System.Linq.xml",
+ "ref/netstandard1.6/System.Linq.dll",
+ "ref/netstandard1.6/System.Linq.xml",
+ "ref/netstandard1.6/de/System.Linq.xml",
+ "ref/netstandard1.6/es/System.Linq.xml",
+ "ref/netstandard1.6/fr/System.Linq.xml",
+ "ref/netstandard1.6/it/System.Linq.xml",
+ "ref/netstandard1.6/ja/System.Linq.xml",
+ "ref/netstandard1.6/ko/System.Linq.xml",
+ "ref/netstandard1.6/ru/System.Linq.xml",
+ "ref/netstandard1.6/zh-hans/System.Linq.xml",
+ "ref/netstandard1.6/zh-hant/System.Linq.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Linq.Expressions/4.1.0": {
+ "sha512": "I+y02iqkgmCAyfbqOmSDOgqdZQ5tTj80Akm5BPSS8EeB0VGWdy6X1KCoYe8Pk6pwDoAKZUOdLVxnTJcExiv5zw==",
+ "type": "package",
+ "path": "System.Linq.Expressions/4.1.0",
+ "files": [
+ "System.Linq.Expressions.4.1.0.nupkg.sha512",
+ "System.Linq.Expressions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net463/System.Linq.Expressions.dll",
+ "lib/netcore50/System.Linq.Expressions.dll",
+ "lib/netstandard1.6/System.Linq.Expressions.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net463/System.Linq.Expressions.dll",
+ "ref/netcore50/System.Linq.Expressions.dll",
+ "ref/netcore50/System.Linq.Expressions.xml",
+ "ref/netcore50/de/System.Linq.Expressions.xml",
+ "ref/netcore50/es/System.Linq.Expressions.xml",
+ "ref/netcore50/fr/System.Linq.Expressions.xml",
+ "ref/netcore50/it/System.Linq.Expressions.xml",
+ "ref/netcore50/ja/System.Linq.Expressions.xml",
+ "ref/netcore50/ko/System.Linq.Expressions.xml",
+ "ref/netcore50/ru/System.Linq.Expressions.xml",
+ "ref/netcore50/zh-hans/System.Linq.Expressions.xml",
+ "ref/netcore50/zh-hant/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/System.Linq.Expressions.dll",
+ "ref/netstandard1.0/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/de/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/es/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/fr/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/it/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/ja/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/ko/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/ru/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/zh-hans/System.Linq.Expressions.xml",
+ "ref/netstandard1.0/zh-hant/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/System.Linq.Expressions.dll",
+ "ref/netstandard1.3/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/de/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/es/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/fr/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/it/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/ja/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/ko/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/ru/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/zh-hans/System.Linq.Expressions.xml",
+ "ref/netstandard1.3/zh-hant/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/System.Linq.Expressions.dll",
+ "ref/netstandard1.6/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/de/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/es/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/fr/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/it/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/ja/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/ko/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/ru/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/zh-hans/System.Linq.Expressions.xml",
+ "ref/netstandard1.6/zh-hant/System.Linq.Expressions.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/aot/lib/netcore50/System.Linq.Expressions.dll"
+ ]
+ },
+ "System.Net.Http/4.1.0": {
+ "sha512": "ULq9g3SOPVuupt+Y3U+A37coXzdNisB1neFCSKzBwo182u0RDddKJF8I5+HfyXqK6OhJPgeoAwWXrbiUXuRDsg==",
+ "type": "package",
+ "path": "System.Net.Http/4.1.0",
+ "files": [
+ "System.Net.Http.4.1.0.nupkg.sha512",
+ "System.Net.Http.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/Xamarinmac20/_._",
+ "lib/monoandroid10/_._",
+ "lib/monotouch10/_._",
+ "lib/net45/_._",
+ "lib/net46/System.Net.Http.dll",
+ "lib/portable-net45+win8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/Xamarinmac20/_._",
+ "ref/monoandroid10/_._",
+ "ref/monotouch10/_._",
+ "ref/net45/_._",
+ "ref/net46/System.Net.Http.dll",
+ "ref/net46/System.Net.Http.xml",
+ "ref/net46/de/System.Net.Http.xml",
+ "ref/net46/es/System.Net.Http.xml",
+ "ref/net46/fr/System.Net.Http.xml",
+ "ref/net46/it/System.Net.Http.xml",
+ "ref/net46/ja/System.Net.Http.xml",
+ "ref/net46/ko/System.Net.Http.xml",
+ "ref/net46/ru/System.Net.Http.xml",
+ "ref/net46/zh-hans/System.Net.Http.xml",
+ "ref/net46/zh-hant/System.Net.Http.xml",
+ "ref/netcore50/System.Net.Http.dll",
+ "ref/netcore50/System.Net.Http.xml",
+ "ref/netcore50/de/System.Net.Http.xml",
+ "ref/netcore50/es/System.Net.Http.xml",
+ "ref/netcore50/fr/System.Net.Http.xml",
+ "ref/netcore50/it/System.Net.Http.xml",
+ "ref/netcore50/ja/System.Net.Http.xml",
+ "ref/netcore50/ko/System.Net.Http.xml",
+ "ref/netcore50/ru/System.Net.Http.xml",
+ "ref/netcore50/zh-hans/System.Net.Http.xml",
+ "ref/netcore50/zh-hant/System.Net.Http.xml",
+ "ref/netstandard1.1/System.Net.Http.dll",
+ "ref/netstandard1.1/System.Net.Http.xml",
+ "ref/netstandard1.1/de/System.Net.Http.xml",
+ "ref/netstandard1.1/es/System.Net.Http.xml",
+ "ref/netstandard1.1/fr/System.Net.Http.xml",
+ "ref/netstandard1.1/it/System.Net.Http.xml",
+ "ref/netstandard1.1/ja/System.Net.Http.xml",
+ "ref/netstandard1.1/ko/System.Net.Http.xml",
+ "ref/netstandard1.1/ru/System.Net.Http.xml",
+ "ref/netstandard1.1/zh-hans/System.Net.Http.xml",
+ "ref/netstandard1.1/zh-hant/System.Net.Http.xml",
+ "ref/netstandard1.3/System.Net.Http.dll",
+ "ref/netstandard1.3/System.Net.Http.xml",
+ "ref/netstandard1.3/de/System.Net.Http.xml",
+ "ref/netstandard1.3/es/System.Net.Http.xml",
+ "ref/netstandard1.3/fr/System.Net.Http.xml",
+ "ref/netstandard1.3/it/System.Net.Http.xml",
+ "ref/netstandard1.3/ja/System.Net.Http.xml",
+ "ref/netstandard1.3/ko/System.Net.Http.xml",
+ "ref/netstandard1.3/ru/System.Net.Http.xml",
+ "ref/netstandard1.3/zh-hans/System.Net.Http.xml",
+ "ref/netstandard1.3/zh-hant/System.Net.Http.xml",
+ "ref/portable-net45+win8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.6/System.Net.Http.dll",
+ "runtimes/win/lib/net46/System.Net.Http.dll",
+ "runtimes/win/lib/netcore50/System.Net.Http.dll",
+ "runtimes/win/lib/netstandard1.3/System.Net.Http.dll"
+ ]
+ },
+ "System.Net.Primitives/4.0.11": {
+ "sha512": "hVvfl4405DRjA2408luZekbPhplJK03j2Y2lSfMlny7GHXlkByw1iLnc9mgKW0GdQn73vvMcWrWewAhylXA4Nw==",
+ "type": "package",
+ "path": "System.Net.Primitives/4.0.11",
+ "files": [
+ "System.Net.Primitives.4.0.11.nupkg.sha512",
+ "System.Net.Primitives.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Net.Primitives.dll",
+ "ref/netcore50/System.Net.Primitives.xml",
+ "ref/netcore50/de/System.Net.Primitives.xml",
+ "ref/netcore50/es/System.Net.Primitives.xml",
+ "ref/netcore50/fr/System.Net.Primitives.xml",
+ "ref/netcore50/it/System.Net.Primitives.xml",
+ "ref/netcore50/ja/System.Net.Primitives.xml",
+ "ref/netcore50/ko/System.Net.Primitives.xml",
+ "ref/netcore50/ru/System.Net.Primitives.xml",
+ "ref/netcore50/zh-hans/System.Net.Primitives.xml",
+ "ref/netcore50/zh-hant/System.Net.Primitives.xml",
+ "ref/netstandard1.0/System.Net.Primitives.dll",
+ "ref/netstandard1.0/System.Net.Primitives.xml",
+ "ref/netstandard1.0/de/System.Net.Primitives.xml",
+ "ref/netstandard1.0/es/System.Net.Primitives.xml",
+ "ref/netstandard1.0/fr/System.Net.Primitives.xml",
+ "ref/netstandard1.0/it/System.Net.Primitives.xml",
+ "ref/netstandard1.0/ja/System.Net.Primitives.xml",
+ "ref/netstandard1.0/ko/System.Net.Primitives.xml",
+ "ref/netstandard1.0/ru/System.Net.Primitives.xml",
+ "ref/netstandard1.0/zh-hans/System.Net.Primitives.xml",
+ "ref/netstandard1.0/zh-hant/System.Net.Primitives.xml",
+ "ref/netstandard1.1/System.Net.Primitives.dll",
+ "ref/netstandard1.1/System.Net.Primitives.xml",
+ "ref/netstandard1.1/de/System.Net.Primitives.xml",
+ "ref/netstandard1.1/es/System.Net.Primitives.xml",
+ "ref/netstandard1.1/fr/System.Net.Primitives.xml",
+ "ref/netstandard1.1/it/System.Net.Primitives.xml",
+ "ref/netstandard1.1/ja/System.Net.Primitives.xml",
+ "ref/netstandard1.1/ko/System.Net.Primitives.xml",
+ "ref/netstandard1.1/ru/System.Net.Primitives.xml",
+ "ref/netstandard1.1/zh-hans/System.Net.Primitives.xml",
+ "ref/netstandard1.1/zh-hant/System.Net.Primitives.xml",
+ "ref/netstandard1.3/System.Net.Primitives.dll",
+ "ref/netstandard1.3/System.Net.Primitives.xml",
+ "ref/netstandard1.3/de/System.Net.Primitives.xml",
+ "ref/netstandard1.3/es/System.Net.Primitives.xml",
+ "ref/netstandard1.3/fr/System.Net.Primitives.xml",
+ "ref/netstandard1.3/it/System.Net.Primitives.xml",
+ "ref/netstandard1.3/ja/System.Net.Primitives.xml",
+ "ref/netstandard1.3/ko/System.Net.Primitives.xml",
+ "ref/netstandard1.3/ru/System.Net.Primitives.xml",
+ "ref/netstandard1.3/zh-hans/System.Net.Primitives.xml",
+ "ref/netstandard1.3/zh-hant/System.Net.Primitives.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Net.Requests/4.0.11": {
+ "sha512": "e7FQ55FBFfztR50qocJdMcwxivKsZw1vcxUXILwdCd1YuGv734JIJuW/jX66/VStDfary3/2+G36A8a3AInpfg==",
+ "type": "package",
+ "path": "System.Net.Requests/4.0.11",
+ "files": [
+ "System.Net.Requests.4.0.11.nupkg.sha512",
+ "System.Net.Requests.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net46/_._",
+ "ref/netcore50/System.Net.Requests.dll",
+ "ref/netcore50/System.Net.Requests.xml",
+ "ref/netcore50/de/System.Net.Requests.xml",
+ "ref/netcore50/es/System.Net.Requests.xml",
+ "ref/netcore50/fr/System.Net.Requests.xml",
+ "ref/netcore50/it/System.Net.Requests.xml",
+ "ref/netcore50/ja/System.Net.Requests.xml",
+ "ref/netcore50/ko/System.Net.Requests.xml",
+ "ref/netcore50/ru/System.Net.Requests.xml",
+ "ref/netcore50/zh-hans/System.Net.Requests.xml",
+ "ref/netcore50/zh-hant/System.Net.Requests.xml",
+ "ref/netstandard1.0/System.Net.Requests.dll",
+ "ref/netstandard1.0/System.Net.Requests.xml",
+ "ref/netstandard1.0/de/System.Net.Requests.xml",
+ "ref/netstandard1.0/es/System.Net.Requests.xml",
+ "ref/netstandard1.0/fr/System.Net.Requests.xml",
+ "ref/netstandard1.0/it/System.Net.Requests.xml",
+ "ref/netstandard1.0/ja/System.Net.Requests.xml",
+ "ref/netstandard1.0/ko/System.Net.Requests.xml",
+ "ref/netstandard1.0/ru/System.Net.Requests.xml",
+ "ref/netstandard1.0/zh-hans/System.Net.Requests.xml",
+ "ref/netstandard1.0/zh-hant/System.Net.Requests.xml",
+ "ref/netstandard1.1/System.Net.Requests.dll",
+ "ref/netstandard1.1/System.Net.Requests.xml",
+ "ref/netstandard1.1/de/System.Net.Requests.xml",
+ "ref/netstandard1.1/es/System.Net.Requests.xml",
+ "ref/netstandard1.1/fr/System.Net.Requests.xml",
+ "ref/netstandard1.1/it/System.Net.Requests.xml",
+ "ref/netstandard1.1/ja/System.Net.Requests.xml",
+ "ref/netstandard1.1/ko/System.Net.Requests.xml",
+ "ref/netstandard1.1/ru/System.Net.Requests.xml",
+ "ref/netstandard1.1/zh-hans/System.Net.Requests.xml",
+ "ref/netstandard1.1/zh-hant/System.Net.Requests.xml",
+ "ref/netstandard1.3/System.Net.Requests.dll",
+ "ref/netstandard1.3/System.Net.Requests.xml",
+ "ref/netstandard1.3/de/System.Net.Requests.xml",
+ "ref/netstandard1.3/es/System.Net.Requests.xml",
+ "ref/netstandard1.3/fr/System.Net.Requests.xml",
+ "ref/netstandard1.3/it/System.Net.Requests.xml",
+ "ref/netstandard1.3/ja/System.Net.Requests.xml",
+ "ref/netstandard1.3/ko/System.Net.Requests.xml",
+ "ref/netstandard1.3/ru/System.Net.Requests.xml",
+ "ref/netstandard1.3/zh-hans/System.Net.Requests.xml",
+ "ref/netstandard1.3/zh-hant/System.Net.Requests.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.3/System.Net.Requests.dll",
+ "runtimes/win/lib/net46/_._",
+ "runtimes/win/lib/netstandard1.3/System.Net.Requests.dll"
+ ]
+ },
+ "System.Net.Sockets/4.1.0": {
+ "sha512": "xAz0N3dAV/aR/9g8r0Y5oEqU1JRsz29F5EGb/WVHmX3jVSLqi2/92M5hTad2aNWovruXrJpJtgZ9fccPMG9uSw==",
+ "type": "package",
+ "path": "System.Net.Sockets/4.1.0",
+ "files": [
+ "System.Net.Sockets.4.1.0.nupkg.sha512",
+ "System.Net.Sockets.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Net.Sockets.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Net.Sockets.dll",
+ "ref/netstandard1.3/System.Net.Sockets.dll",
+ "ref/netstandard1.3/System.Net.Sockets.xml",
+ "ref/netstandard1.3/de/System.Net.Sockets.xml",
+ "ref/netstandard1.3/es/System.Net.Sockets.xml",
+ "ref/netstandard1.3/fr/System.Net.Sockets.xml",
+ "ref/netstandard1.3/it/System.Net.Sockets.xml",
+ "ref/netstandard1.3/ja/System.Net.Sockets.xml",
+ "ref/netstandard1.3/ko/System.Net.Sockets.xml",
+ "ref/netstandard1.3/ru/System.Net.Sockets.xml",
+ "ref/netstandard1.3/zh-hans/System.Net.Sockets.xml",
+ "ref/netstandard1.3/zh-hant/System.Net.Sockets.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Net.WebHeaderCollection/4.0.1": {
+ "sha512": "Hs0P/pYpYfmKlS+C3djfbMKZhnVhQeZn0R2ETB4a6DZ0lvj3ij+sRtJ4VGXEVRa08DRhKhRlm3Rz3O+f62qzTQ==",
+ "type": "package",
+ "path": "System.Net.WebHeaderCollection/4.0.1",
+ "files": [
+ "System.Net.WebHeaderCollection.4.0.1.nupkg.sha512",
+ "System.Net.WebHeaderCollection.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/_._",
+ "lib/netstandard1.3/System.Net.WebHeaderCollection.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/_._",
+ "ref/netstandard1.3/System.Net.WebHeaderCollection.dll",
+ "ref/netstandard1.3/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/de/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/es/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/fr/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/it/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/ja/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/ko/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/ru/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/zh-hans/System.Net.WebHeaderCollection.xml",
+ "ref/netstandard1.3/zh-hant/System.Net.WebHeaderCollection.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.ObjectModel/4.0.12": {
+ "sha512": "tAgJM1xt3ytyMoW4qn4wIqgJYm7L7TShRZG4+Q4Qsi2PCcj96pXN7nRywS9KkB3p/xDUjc2HSwP9SROyPYDYKQ==",
+ "type": "package",
+ "path": "System.ObjectModel/4.0.12",
+ "files": [
+ "System.ObjectModel.4.0.12.nupkg.sha512",
+ "System.ObjectModel.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.ObjectModel.dll",
+ "lib/netstandard1.3/System.ObjectModel.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.ObjectModel.dll",
+ "ref/netcore50/System.ObjectModel.xml",
+ "ref/netcore50/de/System.ObjectModel.xml",
+ "ref/netcore50/es/System.ObjectModel.xml",
+ "ref/netcore50/fr/System.ObjectModel.xml",
+ "ref/netcore50/it/System.ObjectModel.xml",
+ "ref/netcore50/ja/System.ObjectModel.xml",
+ "ref/netcore50/ko/System.ObjectModel.xml",
+ "ref/netcore50/ru/System.ObjectModel.xml",
+ "ref/netcore50/zh-hans/System.ObjectModel.xml",
+ "ref/netcore50/zh-hant/System.ObjectModel.xml",
+ "ref/netstandard1.0/System.ObjectModel.dll",
+ "ref/netstandard1.0/System.ObjectModel.xml",
+ "ref/netstandard1.0/de/System.ObjectModel.xml",
+ "ref/netstandard1.0/es/System.ObjectModel.xml",
+ "ref/netstandard1.0/fr/System.ObjectModel.xml",
+ "ref/netstandard1.0/it/System.ObjectModel.xml",
+ "ref/netstandard1.0/ja/System.ObjectModel.xml",
+ "ref/netstandard1.0/ko/System.ObjectModel.xml",
+ "ref/netstandard1.0/ru/System.ObjectModel.xml",
+ "ref/netstandard1.0/zh-hans/System.ObjectModel.xml",
+ "ref/netstandard1.0/zh-hant/System.ObjectModel.xml",
+ "ref/netstandard1.3/System.ObjectModel.dll",
+ "ref/netstandard1.3/System.ObjectModel.xml",
+ "ref/netstandard1.3/de/System.ObjectModel.xml",
+ "ref/netstandard1.3/es/System.ObjectModel.xml",
+ "ref/netstandard1.3/fr/System.ObjectModel.xml",
+ "ref/netstandard1.3/it/System.ObjectModel.xml",
+ "ref/netstandard1.3/ja/System.ObjectModel.xml",
+ "ref/netstandard1.3/ko/System.ObjectModel.xml",
+ "ref/netstandard1.3/ru/System.ObjectModel.xml",
+ "ref/netstandard1.3/zh-hans/System.ObjectModel.xml",
+ "ref/netstandard1.3/zh-hant/System.ObjectModel.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Reflection/4.1.0": {
+ "sha512": "JCKANJ0TI7kzoQzuwB/OoJANy1Lg338B6+JVacPl4TpUwi3cReg3nMLplMq2uqYfHFQpKIlHAUVAJlImZz/4ng==",
+ "type": "package",
+ "path": "System.Reflection/4.1.0",
+ "files": [
+ "System.Reflection.4.1.0.nupkg.sha512",
+ "System.Reflection.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net462/System.Reflection.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net462/System.Reflection.dll",
+ "ref/netcore50/System.Reflection.dll",
+ "ref/netcore50/System.Reflection.xml",
+ "ref/netcore50/de/System.Reflection.xml",
+ "ref/netcore50/es/System.Reflection.xml",
+ "ref/netcore50/fr/System.Reflection.xml",
+ "ref/netcore50/it/System.Reflection.xml",
+ "ref/netcore50/ja/System.Reflection.xml",
+ "ref/netcore50/ko/System.Reflection.xml",
+ "ref/netcore50/ru/System.Reflection.xml",
+ "ref/netcore50/zh-hans/System.Reflection.xml",
+ "ref/netcore50/zh-hant/System.Reflection.xml",
+ "ref/netstandard1.0/System.Reflection.dll",
+ "ref/netstandard1.0/System.Reflection.xml",
+ "ref/netstandard1.0/de/System.Reflection.xml",
+ "ref/netstandard1.0/es/System.Reflection.xml",
+ "ref/netstandard1.0/fr/System.Reflection.xml",
+ "ref/netstandard1.0/it/System.Reflection.xml",
+ "ref/netstandard1.0/ja/System.Reflection.xml",
+ "ref/netstandard1.0/ko/System.Reflection.xml",
+ "ref/netstandard1.0/ru/System.Reflection.xml",
+ "ref/netstandard1.0/zh-hans/System.Reflection.xml",
+ "ref/netstandard1.0/zh-hant/System.Reflection.xml",
+ "ref/netstandard1.3/System.Reflection.dll",
+ "ref/netstandard1.3/System.Reflection.xml",
+ "ref/netstandard1.3/de/System.Reflection.xml",
+ "ref/netstandard1.3/es/System.Reflection.xml",
+ "ref/netstandard1.3/fr/System.Reflection.xml",
+ "ref/netstandard1.3/it/System.Reflection.xml",
+ "ref/netstandard1.3/ja/System.Reflection.xml",
+ "ref/netstandard1.3/ko/System.Reflection.xml",
+ "ref/netstandard1.3/ru/System.Reflection.xml",
+ "ref/netstandard1.3/zh-hans/System.Reflection.xml",
+ "ref/netstandard1.3/zh-hant/System.Reflection.xml",
+ "ref/netstandard1.5/System.Reflection.dll",
+ "ref/netstandard1.5/System.Reflection.xml",
+ "ref/netstandard1.5/de/System.Reflection.xml",
+ "ref/netstandard1.5/es/System.Reflection.xml",
+ "ref/netstandard1.5/fr/System.Reflection.xml",
+ "ref/netstandard1.5/it/System.Reflection.xml",
+ "ref/netstandard1.5/ja/System.Reflection.xml",
+ "ref/netstandard1.5/ko/System.Reflection.xml",
+ "ref/netstandard1.5/ru/System.Reflection.xml",
+ "ref/netstandard1.5/zh-hans/System.Reflection.xml",
+ "ref/netstandard1.5/zh-hant/System.Reflection.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Reflection.Emit/4.0.1": {
+ "sha512": "P2wqAj72fFjpP6wb9nSfDqNBMab+2ovzSDzUZK7MVIm54tBJEPr9jWfSjjoTpPwj1LeKcmX3vr0ttyjSSFM47g==",
+ "type": "package",
+ "path": "System.Reflection.Emit/4.0.1",
+ "files": [
+ "System.Reflection.Emit.4.0.1.nupkg.sha512",
+ "System.Reflection.Emit.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.Reflection.Emit.dll",
+ "lib/netstandard1.3/System.Reflection.Emit.dll",
+ "lib/xamarinmac20/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/net45/_._",
+ "ref/netstandard1.1/System.Reflection.Emit.dll",
+ "ref/netstandard1.1/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/de/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/es/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/fr/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/it/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/ja/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/ko/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/ru/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/zh-hans/System.Reflection.Emit.xml",
+ "ref/netstandard1.1/zh-hant/System.Reflection.Emit.xml",
+ "ref/xamarinmac20/_._"
+ ]
+ },
+ "System.Reflection.Emit.ILGeneration/4.0.1": {
+ "sha512": "Ov6dU8Bu15Bc7zuqttgHF12J5lwSWyTf1S+FJouUXVMSqImLZzYaQ+vRr1rQ0OZ0HqsrwWl4dsKHELckQkVpgA==",
+ "type": "package",
+ "path": "System.Reflection.Emit.ILGeneration/4.0.1",
+ "files": [
+ "System.Reflection.Emit.ILGeneration.4.0.1.nupkg.sha512",
+ "System.Reflection.Emit.ILGeneration.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/net45/_._",
+ "lib/netcore50/System.Reflection.Emit.ILGeneration.dll",
+ "lib/netstandard1.3/System.Reflection.Emit.ILGeneration.dll",
+ "lib/portable-net45+wp8/_._",
+ "lib/wp80/_._",
+ "ref/net45/_._",
+ "ref/netstandard1.0/System.Reflection.Emit.ILGeneration.dll",
+ "ref/netstandard1.0/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/de/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/es/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/fr/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/it/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/ja/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/ko/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/ru/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/zh-hans/System.Reflection.Emit.ILGeneration.xml",
+ "ref/netstandard1.0/zh-hant/System.Reflection.Emit.ILGeneration.xml",
+ "ref/portable-net45+wp8/_._",
+ "ref/wp80/_._",
+ "runtimes/aot/lib/netcore50/_._"
+ ]
+ },
+ "System.Reflection.Emit.Lightweight/4.0.1": {
+ "sha512": "sSzHHXueZ5Uh0OLpUQprhr+ZYJrLPA2Cmr4gn0wj9+FftNKXx8RIMKvO9qnjk2ebPYUjZ+F2ulGdPOsvj+MEjA==",
+ "type": "package",
+ "path": "System.Reflection.Emit.Lightweight/4.0.1",
+ "files": [
+ "System.Reflection.Emit.Lightweight.4.0.1.nupkg.sha512",
+ "System.Reflection.Emit.Lightweight.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/net45/_._",
+ "lib/netcore50/System.Reflection.Emit.Lightweight.dll",
+ "lib/netstandard1.3/System.Reflection.Emit.Lightweight.dll",
+ "lib/portable-net45+wp8/_._",
+ "lib/wp80/_._",
+ "ref/net45/_._",
+ "ref/netstandard1.0/System.Reflection.Emit.Lightweight.dll",
+ "ref/netstandard1.0/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/de/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/es/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/fr/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/it/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/ja/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/ko/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/ru/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/zh-hans/System.Reflection.Emit.Lightweight.xml",
+ "ref/netstandard1.0/zh-hant/System.Reflection.Emit.Lightweight.xml",
+ "ref/portable-net45+wp8/_._",
+ "ref/wp80/_._",
+ "runtimes/aot/lib/netcore50/_._"
+ ]
+ },
+ "System.Reflection.Extensions/4.0.1": {
+ "sha512": "GYrtRsZcMuHF3sbmRHfMYpvxZoIN2bQGrYGerUiWLEkqdEUQZhH3TRSaC/oI4wO0II1RKBPlpIa1TOMxIcOOzQ==",
+ "type": "package",
+ "path": "System.Reflection.Extensions/4.0.1",
+ "files": [
+ "System.Reflection.Extensions.4.0.1.nupkg.sha512",
+ "System.Reflection.Extensions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Reflection.Extensions.dll",
+ "ref/netcore50/System.Reflection.Extensions.xml",
+ "ref/netcore50/de/System.Reflection.Extensions.xml",
+ "ref/netcore50/es/System.Reflection.Extensions.xml",
+ "ref/netcore50/fr/System.Reflection.Extensions.xml",
+ "ref/netcore50/it/System.Reflection.Extensions.xml",
+ "ref/netcore50/ja/System.Reflection.Extensions.xml",
+ "ref/netcore50/ko/System.Reflection.Extensions.xml",
+ "ref/netcore50/ru/System.Reflection.Extensions.xml",
+ "ref/netcore50/zh-hans/System.Reflection.Extensions.xml",
+ "ref/netcore50/zh-hant/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/System.Reflection.Extensions.dll",
+ "ref/netstandard1.0/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/de/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/es/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/fr/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/it/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/ja/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/ko/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/ru/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/zh-hans/System.Reflection.Extensions.xml",
+ "ref/netstandard1.0/zh-hant/System.Reflection.Extensions.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Reflection.Primitives/4.0.1": {
+ "sha512": "4inTox4wTBaDhB7V3mPvp9XlCbeGYWVEM9/fXALd52vNEAVisc1BoVWQPuUuD0Ga//dNbA/WeMy9u9mzLxGTHQ==",
+ "type": "package",
+ "path": "System.Reflection.Primitives/4.0.1",
+ "files": [
+ "System.Reflection.Primitives.4.0.1.nupkg.sha512",
+ "System.Reflection.Primitives.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Reflection.Primitives.dll",
+ "ref/netcore50/System.Reflection.Primitives.xml",
+ "ref/netcore50/de/System.Reflection.Primitives.xml",
+ "ref/netcore50/es/System.Reflection.Primitives.xml",
+ "ref/netcore50/fr/System.Reflection.Primitives.xml",
+ "ref/netcore50/it/System.Reflection.Primitives.xml",
+ "ref/netcore50/ja/System.Reflection.Primitives.xml",
+ "ref/netcore50/ko/System.Reflection.Primitives.xml",
+ "ref/netcore50/ru/System.Reflection.Primitives.xml",
+ "ref/netcore50/zh-hans/System.Reflection.Primitives.xml",
+ "ref/netcore50/zh-hant/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/System.Reflection.Primitives.dll",
+ "ref/netstandard1.0/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/de/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/es/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/fr/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/it/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/ja/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/ko/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/ru/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/zh-hans/System.Reflection.Primitives.xml",
+ "ref/netstandard1.0/zh-hant/System.Reflection.Primitives.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Reflection.TypeExtensions/4.1.0": {
+ "sha512": "tsQ/ptQ3H5FYfON8lL4MxRk/8kFyE0A+tGPXmVP967cT/gzLHYxIejIYSxp4JmIeFHVP78g/F2FE1mUUTbDtrg==",
+ "type": "package",
+ "path": "System.Reflection.TypeExtensions/4.1.0",
+ "files": [
+ "System.Reflection.TypeExtensions.4.1.0.nupkg.sha512",
+ "System.Reflection.TypeExtensions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Reflection.TypeExtensions.dll",
+ "lib/net462/System.Reflection.TypeExtensions.dll",
+ "lib/netcore50/System.Reflection.TypeExtensions.dll",
+ "lib/netstandard1.5/System.Reflection.TypeExtensions.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Reflection.TypeExtensions.dll",
+ "ref/net462/System.Reflection.TypeExtensions.dll",
+ "ref/netstandard1.3/System.Reflection.TypeExtensions.dll",
+ "ref/netstandard1.3/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/de/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/es/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/fr/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/it/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/ja/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/ko/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/ru/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/zh-hans/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.3/zh-hant/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/System.Reflection.TypeExtensions.dll",
+ "ref/netstandard1.5/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/de/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/es/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/fr/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/it/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/ja/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/ko/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/ru/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/zh-hans/System.Reflection.TypeExtensions.xml",
+ "ref/netstandard1.5/zh-hant/System.Reflection.TypeExtensions.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/aot/lib/netcore50/System.Reflection.TypeExtensions.dll"
+ ]
+ },
+ "System.Resources.ResourceManager/4.0.1": {
+ "sha512": "TxwVeUNoTgUOdQ09gfTjvW411MF+w9MBYL7AtNVc+HtBCFlutPLhUCdZjNkjbhj3bNQWMdHboF0KIWEOjJssbA==",
+ "type": "package",
+ "path": "System.Resources.ResourceManager/4.0.1",
+ "files": [
+ "System.Resources.ResourceManager.4.0.1.nupkg.sha512",
+ "System.Resources.ResourceManager.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Resources.ResourceManager.dll",
+ "ref/netcore50/System.Resources.ResourceManager.xml",
+ "ref/netcore50/de/System.Resources.ResourceManager.xml",
+ "ref/netcore50/es/System.Resources.ResourceManager.xml",
+ "ref/netcore50/fr/System.Resources.ResourceManager.xml",
+ "ref/netcore50/it/System.Resources.ResourceManager.xml",
+ "ref/netcore50/ja/System.Resources.ResourceManager.xml",
+ "ref/netcore50/ko/System.Resources.ResourceManager.xml",
+ "ref/netcore50/ru/System.Resources.ResourceManager.xml",
+ "ref/netcore50/zh-hans/System.Resources.ResourceManager.xml",
+ "ref/netcore50/zh-hant/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/System.Resources.ResourceManager.dll",
+ "ref/netstandard1.0/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/de/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/es/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/fr/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/it/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/ja/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/ko/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/ru/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/zh-hans/System.Resources.ResourceManager.xml",
+ "ref/netstandard1.0/zh-hant/System.Resources.ResourceManager.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Runtime/4.1.0": {
+ "sha512": "v6c/4Yaa9uWsq+JMhnOFewrYkgdNHNG2eMKuNqRn8P733rNXeRCGvV5FkkjBXn2dbVkPXOsO0xjsEeM1q2zC0g==",
+ "type": "package",
+ "path": "System.Runtime/4.1.0",
+ "files": [
+ "System.Runtime.4.1.0.nupkg.sha512",
+ "System.Runtime.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net462/System.Runtime.dll",
+ "lib/portable-net45+win8+wp80+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net462/System.Runtime.dll",
+ "ref/netcore50/System.Runtime.dll",
+ "ref/netcore50/System.Runtime.xml",
+ "ref/netcore50/de/System.Runtime.xml",
+ "ref/netcore50/es/System.Runtime.xml",
+ "ref/netcore50/fr/System.Runtime.xml",
+ "ref/netcore50/it/System.Runtime.xml",
+ "ref/netcore50/ja/System.Runtime.xml",
+ "ref/netcore50/ko/System.Runtime.xml",
+ "ref/netcore50/ru/System.Runtime.xml",
+ "ref/netcore50/zh-hans/System.Runtime.xml",
+ "ref/netcore50/zh-hant/System.Runtime.xml",
+ "ref/netstandard1.0/System.Runtime.dll",
+ "ref/netstandard1.0/System.Runtime.xml",
+ "ref/netstandard1.0/de/System.Runtime.xml",
+ "ref/netstandard1.0/es/System.Runtime.xml",
+ "ref/netstandard1.0/fr/System.Runtime.xml",
+ "ref/netstandard1.0/it/System.Runtime.xml",
+ "ref/netstandard1.0/ja/System.Runtime.xml",
+ "ref/netstandard1.0/ko/System.Runtime.xml",
+ "ref/netstandard1.0/ru/System.Runtime.xml",
+ "ref/netstandard1.0/zh-hans/System.Runtime.xml",
+ "ref/netstandard1.0/zh-hant/System.Runtime.xml",
+ "ref/netstandard1.2/System.Runtime.dll",
+ "ref/netstandard1.2/System.Runtime.xml",
+ "ref/netstandard1.2/de/System.Runtime.xml",
+ "ref/netstandard1.2/es/System.Runtime.xml",
+ "ref/netstandard1.2/fr/System.Runtime.xml",
+ "ref/netstandard1.2/it/System.Runtime.xml",
+ "ref/netstandard1.2/ja/System.Runtime.xml",
+ "ref/netstandard1.2/ko/System.Runtime.xml",
+ "ref/netstandard1.2/ru/System.Runtime.xml",
+ "ref/netstandard1.2/zh-hans/System.Runtime.xml",
+ "ref/netstandard1.2/zh-hant/System.Runtime.xml",
+ "ref/netstandard1.3/System.Runtime.dll",
+ "ref/netstandard1.3/System.Runtime.xml",
+ "ref/netstandard1.3/de/System.Runtime.xml",
+ "ref/netstandard1.3/es/System.Runtime.xml",
+ "ref/netstandard1.3/fr/System.Runtime.xml",
+ "ref/netstandard1.3/it/System.Runtime.xml",
+ "ref/netstandard1.3/ja/System.Runtime.xml",
+ "ref/netstandard1.3/ko/System.Runtime.xml",
+ "ref/netstandard1.3/ru/System.Runtime.xml",
+ "ref/netstandard1.3/zh-hans/System.Runtime.xml",
+ "ref/netstandard1.3/zh-hant/System.Runtime.xml",
+ "ref/netstandard1.5/System.Runtime.dll",
+ "ref/netstandard1.5/System.Runtime.xml",
+ "ref/netstandard1.5/de/System.Runtime.xml",
+ "ref/netstandard1.5/es/System.Runtime.xml",
+ "ref/netstandard1.5/fr/System.Runtime.xml",
+ "ref/netstandard1.5/it/System.Runtime.xml",
+ "ref/netstandard1.5/ja/System.Runtime.xml",
+ "ref/netstandard1.5/ko/System.Runtime.xml",
+ "ref/netstandard1.5/ru/System.Runtime.xml",
+ "ref/netstandard1.5/zh-hans/System.Runtime.xml",
+ "ref/netstandard1.5/zh-hant/System.Runtime.xml",
+ "ref/portable-net45+win8+wp80+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Runtime.Extensions/4.1.0": {
+ "sha512": "CUOHjTT/vgP0qGW22U4/hDlOqXmcPq5YicBaXdUR2UiUoLwBT+olO6we4DVbq57jeX5uXH2uerVZhf0qGj+sVQ==",
+ "type": "package",
+ "path": "System.Runtime.Extensions/4.1.0",
+ "files": [
+ "System.Runtime.Extensions.4.1.0.nupkg.sha512",
+ "System.Runtime.Extensions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net462/System.Runtime.Extensions.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net462/System.Runtime.Extensions.dll",
+ "ref/netcore50/System.Runtime.Extensions.dll",
+ "ref/netcore50/System.Runtime.Extensions.xml",
+ "ref/netcore50/de/System.Runtime.Extensions.xml",
+ "ref/netcore50/es/System.Runtime.Extensions.xml",
+ "ref/netcore50/fr/System.Runtime.Extensions.xml",
+ "ref/netcore50/it/System.Runtime.Extensions.xml",
+ "ref/netcore50/ja/System.Runtime.Extensions.xml",
+ "ref/netcore50/ko/System.Runtime.Extensions.xml",
+ "ref/netcore50/ru/System.Runtime.Extensions.xml",
+ "ref/netcore50/zh-hans/System.Runtime.Extensions.xml",
+ "ref/netcore50/zh-hant/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/System.Runtime.Extensions.dll",
+ "ref/netstandard1.0/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/de/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/es/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/fr/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/it/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/ja/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/ko/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/ru/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/zh-hans/System.Runtime.Extensions.xml",
+ "ref/netstandard1.0/zh-hant/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/System.Runtime.Extensions.dll",
+ "ref/netstandard1.3/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/de/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/es/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/fr/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/it/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/ja/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/ko/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/ru/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/zh-hans/System.Runtime.Extensions.xml",
+ "ref/netstandard1.3/zh-hant/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/System.Runtime.Extensions.dll",
+ "ref/netstandard1.5/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/de/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/es/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/fr/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/it/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/ja/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/ko/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/ru/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/zh-hans/System.Runtime.Extensions.xml",
+ "ref/netstandard1.5/zh-hant/System.Runtime.Extensions.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Runtime.Handles/4.0.1": {
+ "sha512": "nCJvEKguXEvk2ymk1gqj625vVnlK3/xdGzx0vOKicQkoquaTBJTP13AIYkocSUwHCLNBwUbXTqTWGDxBTWpt7g==",
+ "type": "package",
+ "path": "System.Runtime.Handles/4.0.1",
+ "files": [
+ "System.Runtime.Handles.4.0.1.nupkg.sha512",
+ "System.Runtime.Handles.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/_._",
+ "ref/netstandard1.3/System.Runtime.Handles.dll",
+ "ref/netstandard1.3/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/de/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/es/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/fr/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/it/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/ja/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/ko/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/ru/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/zh-hans/System.Runtime.Handles.xml",
+ "ref/netstandard1.3/zh-hant/System.Runtime.Handles.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Runtime.InteropServices/4.1.0": {
+ "sha512": "16eu3kjHS633yYdkjwShDHZLRNMKVi/s0bY8ODiqJ2RfMhDMAwxZaUaWVnZ2P71kr/or+X9o/xFWtNqz8ivieQ==",
+ "type": "package",
+ "path": "System.Runtime.InteropServices/4.1.0",
+ "files": [
+ "System.Runtime.InteropServices.4.1.0.nupkg.sha512",
+ "System.Runtime.InteropServices.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net462/System.Runtime.InteropServices.dll",
+ "lib/portable-net45+win8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net462/System.Runtime.InteropServices.dll",
+ "ref/netcore50/System.Runtime.InteropServices.dll",
+ "ref/netcore50/System.Runtime.InteropServices.xml",
+ "ref/netcore50/de/System.Runtime.InteropServices.xml",
+ "ref/netcore50/es/System.Runtime.InteropServices.xml",
+ "ref/netcore50/fr/System.Runtime.InteropServices.xml",
+ "ref/netcore50/it/System.Runtime.InteropServices.xml",
+ "ref/netcore50/ja/System.Runtime.InteropServices.xml",
+ "ref/netcore50/ko/System.Runtime.InteropServices.xml",
+ "ref/netcore50/ru/System.Runtime.InteropServices.xml",
+ "ref/netcore50/zh-hans/System.Runtime.InteropServices.xml",
+ "ref/netcore50/zh-hant/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/System.Runtime.InteropServices.dll",
+ "ref/netstandard1.1/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/de/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/es/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/fr/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/it/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/ja/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/ko/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/ru/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/zh-hans/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.1/zh-hant/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/System.Runtime.InteropServices.dll",
+ "ref/netstandard1.2/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/de/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/es/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/fr/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/it/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/ja/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/ko/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/ru/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/zh-hans/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.2/zh-hant/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/System.Runtime.InteropServices.dll",
+ "ref/netstandard1.3/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/de/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/es/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/fr/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/it/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/ja/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/ko/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/ru/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/zh-hans/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.3/zh-hant/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/System.Runtime.InteropServices.dll",
+ "ref/netstandard1.5/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/de/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/es/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/fr/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/it/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/ja/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/ko/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/ru/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/zh-hans/System.Runtime.InteropServices.xml",
+ "ref/netstandard1.5/zh-hant/System.Runtime.InteropServices.xml",
+ "ref/portable-net45+win8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Runtime.InteropServices.RuntimeInformation/4.0.0": {
+ "sha512": "hWPhJxc453RCa8Z29O91EmfGeZIHX1ZH2A8L6lYQVSaKzku2DfArSfMEb1/MYYzPQRJZeu0c9dmYeJKxW5Fgng==",
+ "type": "package",
+ "path": "System.Runtime.InteropServices.RuntimeInformation/4.0.0",
+ "files": [
+ "System.Runtime.InteropServices.RuntimeInformation.4.0.0.nupkg.sha512",
+ "System.Runtime.InteropServices.RuntimeInformation.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "lib/win8/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "lib/wpa81/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/aot/lib/netcore50/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "runtimes/unix/lib/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "runtimes/win/lib/net45/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "runtimes/win/lib/netcore50/System.Runtime.InteropServices.RuntimeInformation.dll",
+ "runtimes/win/lib/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll"
+ ]
+ },
+ "System.Runtime.Numerics/4.0.1": {
+ "sha512": "+XbKFuzdmLP3d1o9pdHu2nxjNr2OEPqGzKeegPLCUMM71a0t50A/rOcIRmGs9wR7a8KuHX6hYs/7/TymIGLNqg==",
+ "type": "package",
+ "path": "System.Runtime.Numerics/4.0.1",
+ "files": [
+ "System.Runtime.Numerics.4.0.1.nupkg.sha512",
+ "System.Runtime.Numerics.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.Runtime.Numerics.dll",
+ "lib/netstandard1.3/System.Runtime.Numerics.dll",
+ "lib/portable-net45+win8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Runtime.Numerics.dll",
+ "ref/netcore50/System.Runtime.Numerics.xml",
+ "ref/netcore50/de/System.Runtime.Numerics.xml",
+ "ref/netcore50/es/System.Runtime.Numerics.xml",
+ "ref/netcore50/fr/System.Runtime.Numerics.xml",
+ "ref/netcore50/it/System.Runtime.Numerics.xml",
+ "ref/netcore50/ja/System.Runtime.Numerics.xml",
+ "ref/netcore50/ko/System.Runtime.Numerics.xml",
+ "ref/netcore50/ru/System.Runtime.Numerics.xml",
+ "ref/netcore50/zh-hans/System.Runtime.Numerics.xml",
+ "ref/netcore50/zh-hant/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/System.Runtime.Numerics.dll",
+ "ref/netstandard1.1/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/de/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/es/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/fr/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/it/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/ja/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/ko/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/ru/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/zh-hans/System.Runtime.Numerics.xml",
+ "ref/netstandard1.1/zh-hant/System.Runtime.Numerics.xml",
+ "ref/portable-net45+win8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Security.Cryptography.Algorithms/4.2.0": {
+ "sha512": "8JQFxbLVdrtIOKMDN38Fn0GWnqYZw/oMlwOUG/qz1jqChvyZlnUmu+0s7wLx7JYua/nAXoESpHA3iw11QFWhXg==",
+ "type": "package",
+ "path": "System.Security.Cryptography.Algorithms/4.2.0",
+ "files": [
+ "System.Security.Cryptography.Algorithms.4.2.0.nupkg.sha512",
+ "System.Security.Cryptography.Algorithms.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Security.Cryptography.Algorithms.dll",
+ "lib/net461/System.Security.Cryptography.Algorithms.dll",
+ "lib/net463/System.Security.Cryptography.Algorithms.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Security.Cryptography.Algorithms.dll",
+ "ref/net461/System.Security.Cryptography.Algorithms.dll",
+ "ref/net463/System.Security.Cryptography.Algorithms.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.Algorithms.dll",
+ "ref/netstandard1.4/System.Security.Cryptography.Algorithms.dll",
+ "ref/netstandard1.6/System.Security.Cryptography.Algorithms.dll",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.Algorithms.dll",
+ "runtimes/win/lib/net46/System.Security.Cryptography.Algorithms.dll",
+ "runtimes/win/lib/net461/System.Security.Cryptography.Algorithms.dll",
+ "runtimes/win/lib/net463/System.Security.Cryptography.Algorithms.dll",
+ "runtimes/win/lib/netcore50/System.Security.Cryptography.Algorithms.dll",
+ "runtimes/win/lib/netstandard1.6/System.Security.Cryptography.Algorithms.dll"
+ ]
+ },
+ "System.Security.Cryptography.Cng/4.2.0": {
+ "sha512": "cUJ2h+ZvONDe28Szw3st5dOHdjndhJzQ2WObDEXAWRPEQBtVItVoxbXM/OEsTthl3cNn2dk2k0I3y45igCQcLw==",
+ "type": "package",
+ "path": "System.Security.Cryptography.Cng/4.2.0",
+ "files": [
+ "System.Security.Cryptography.Cng.4.2.0.nupkg.sha512",
+ "System.Security.Cryptography.Cng.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/net46/System.Security.Cryptography.Cng.dll",
+ "lib/net461/System.Security.Cryptography.Cng.dll",
+ "lib/net463/System.Security.Cryptography.Cng.dll",
+ "ref/net46/System.Security.Cryptography.Cng.dll",
+ "ref/net461/System.Security.Cryptography.Cng.dll",
+ "ref/net463/System.Security.Cryptography.Cng.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.Cng.dll",
+ "ref/netstandard1.4/System.Security.Cryptography.Cng.dll",
+ "ref/netstandard1.6/System.Security.Cryptography.Cng.dll",
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.Cng.dll",
+ "runtimes/win/lib/net46/System.Security.Cryptography.Cng.dll",
+ "runtimes/win/lib/net461/System.Security.Cryptography.Cng.dll",
+ "runtimes/win/lib/net463/System.Security.Cryptography.Cng.dll",
+ "runtimes/win/lib/netstandard1.4/System.Security.Cryptography.Cng.dll",
+ "runtimes/win/lib/netstandard1.6/System.Security.Cryptography.Cng.dll"
+ ]
+ },
+ "System.Security.Cryptography.Csp/4.0.0": {
+ "sha512": "/i1Usuo4PgAqgbPNC0NjbO3jPW//BoBlTpcWFD1EHVbidH21y4c1ap5bbEMSGAXjAShhMH4abi/K8fILrnu4BQ==",
+ "type": "package",
+ "path": "System.Security.Cryptography.Csp/4.0.0",
+ "files": [
+ "System.Security.Cryptography.Csp.4.0.0.nupkg.sha512",
+ "System.Security.Cryptography.Csp.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Security.Cryptography.Csp.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Security.Cryptography.Csp.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.Csp.dll",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.3/System.Security.Cryptography.Csp.dll",
+ "runtimes/win/lib/net46/System.Security.Cryptography.Csp.dll",
+ "runtimes/win/lib/netcore50/_._",
+ "runtimes/win/lib/netstandard1.3/System.Security.Cryptography.Csp.dll"
+ ]
+ },
+ "System.Security.Cryptography.Encoding/4.0.0": {
+ "sha512": "FbKgE5MbxSQMPcSVRgwM6bXN3GtyAh04NkV8E5zKCBE26X0vYW0UtTa2FIgkH33WVqBVxRgxljlVYumWtU+HcQ==",
+ "type": "package",
+ "path": "System.Security.Cryptography.Encoding/4.0.0",
+ "files": [
+ "System.Security.Cryptography.Encoding.4.0.0.nupkg.sha512",
+ "System.Security.Cryptography.Encoding.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Security.Cryptography.Encoding.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Security.Cryptography.Encoding.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.Encoding.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/de/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/es/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/fr/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/it/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/ja/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/ko/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/ru/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/zh-hans/System.Security.Cryptography.Encoding.xml",
+ "ref/netstandard1.3/zh-hant/System.Security.Cryptography.Encoding.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.3/System.Security.Cryptography.Encoding.dll",
+ "runtimes/win/lib/net46/System.Security.Cryptography.Encoding.dll",
+ "runtimes/win/lib/netstandard1.3/System.Security.Cryptography.Encoding.dll"
+ ]
+ },
+ "System.Security.Cryptography.OpenSsl/4.0.0": {
+ "sha512": "HUG/zNUJwEiLkoURDixzkzZdB5yGA5pQhDP93ArOpDPQMteURIGERRNzzoJlmTreLBWr5lkFSjjMSk8ySEpQMw==",
+ "type": "package",
+ "path": "System.Security.Cryptography.OpenSsl/4.0.0",
+ "files": [
+ "System.Security.Cryptography.OpenSsl.4.0.0.nupkg.sha512",
+ "System.Security.Cryptography.OpenSsl.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.6/System.Security.Cryptography.OpenSsl.dll",
+ "ref/netstandard1.6/System.Security.Cryptography.OpenSsl.dll",
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.OpenSsl.dll"
+ ]
+ },
+ "System.Security.Cryptography.Primitives/4.0.0": {
+ "sha512": "Wkd7QryWYjkQclX0bngpntW5HSlMzeJU24UaLJQ7YTfI8ydAVAaU2J+HXLLABOVJlKTVvAeL0Aj39VeTe7L+oA==",
+ "type": "package",
+ "path": "System.Security.Cryptography.Primitives/4.0.0",
+ "files": [
+ "System.Security.Cryptography.Primitives.4.0.0.nupkg.sha512",
+ "System.Security.Cryptography.Primitives.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Security.Cryptography.Primitives.dll",
+ "lib/netstandard1.3/System.Security.Cryptography.Primitives.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Security.Cryptography.Primitives.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.Primitives.dll",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Security.Cryptography.X509Certificates/4.1.0": {
+ "sha512": "4HEfsQIKAhA1+ApNn729Gi09zh+lYWwyIuViihoMDWp1vQnEkL2ct7mAbhBlLYm+x/L4Rr/pyGge1lIY635e0w==",
+ "type": "package",
+ "path": "System.Security.Cryptography.X509Certificates/4.1.0",
+ "files": [
+ "System.Security.Cryptography.X509Certificates.4.1.0.nupkg.sha512",
+ "System.Security.Cryptography.X509Certificates.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Security.Cryptography.X509Certificates.dll",
+ "lib/net461/System.Security.Cryptography.X509Certificates.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Security.Cryptography.X509Certificates.dll",
+ "ref/net461/System.Security.Cryptography.X509Certificates.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.X509Certificates.dll",
+ "ref/netstandard1.3/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/de/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/es/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/fr/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/it/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/ja/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/ko/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/ru/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/zh-hans/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.3/zh-hant/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/System.Security.Cryptography.X509Certificates.dll",
+ "ref/netstandard1.4/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/de/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/es/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/fr/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/it/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/ja/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/ko/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/ru/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/zh-hans/System.Security.Cryptography.X509Certificates.xml",
+ "ref/netstandard1.4/zh-hant/System.Security.Cryptography.X509Certificates.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/unix/lib/netstandard1.6/System.Security.Cryptography.X509Certificates.dll",
+ "runtimes/win/lib/net46/System.Security.Cryptography.X509Certificates.dll",
+ "runtimes/win/lib/net461/System.Security.Cryptography.X509Certificates.dll",
+ "runtimes/win/lib/netcore50/System.Security.Cryptography.X509Certificates.dll",
+ "runtimes/win/lib/netstandard1.6/System.Security.Cryptography.X509Certificates.dll"
+ ]
+ },
+ "System.Text.Encoding/4.0.11": {
+ "sha512": "U3gGeMlDZXxCEiY4DwVLSacg+DFWCvoiX+JThA/rvw37Sqrku7sEFeVBBBMBnfB6FeZHsyDx85HlKL19x0HtZA==",
+ "type": "package",
+ "path": "System.Text.Encoding/4.0.11",
+ "files": [
+ "System.Text.Encoding.4.0.11.nupkg.sha512",
+ "System.Text.Encoding.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Text.Encoding.dll",
+ "ref/netcore50/System.Text.Encoding.xml",
+ "ref/netcore50/de/System.Text.Encoding.xml",
+ "ref/netcore50/es/System.Text.Encoding.xml",
+ "ref/netcore50/fr/System.Text.Encoding.xml",
+ "ref/netcore50/it/System.Text.Encoding.xml",
+ "ref/netcore50/ja/System.Text.Encoding.xml",
+ "ref/netcore50/ko/System.Text.Encoding.xml",
+ "ref/netcore50/ru/System.Text.Encoding.xml",
+ "ref/netcore50/zh-hans/System.Text.Encoding.xml",
+ "ref/netcore50/zh-hant/System.Text.Encoding.xml",
+ "ref/netstandard1.0/System.Text.Encoding.dll",
+ "ref/netstandard1.0/System.Text.Encoding.xml",
+ "ref/netstandard1.0/de/System.Text.Encoding.xml",
+ "ref/netstandard1.0/es/System.Text.Encoding.xml",
+ "ref/netstandard1.0/fr/System.Text.Encoding.xml",
+ "ref/netstandard1.0/it/System.Text.Encoding.xml",
+ "ref/netstandard1.0/ja/System.Text.Encoding.xml",
+ "ref/netstandard1.0/ko/System.Text.Encoding.xml",
+ "ref/netstandard1.0/ru/System.Text.Encoding.xml",
+ "ref/netstandard1.0/zh-hans/System.Text.Encoding.xml",
+ "ref/netstandard1.0/zh-hant/System.Text.Encoding.xml",
+ "ref/netstandard1.3/System.Text.Encoding.dll",
+ "ref/netstandard1.3/System.Text.Encoding.xml",
+ "ref/netstandard1.3/de/System.Text.Encoding.xml",
+ "ref/netstandard1.3/es/System.Text.Encoding.xml",
+ "ref/netstandard1.3/fr/System.Text.Encoding.xml",
+ "ref/netstandard1.3/it/System.Text.Encoding.xml",
+ "ref/netstandard1.3/ja/System.Text.Encoding.xml",
+ "ref/netstandard1.3/ko/System.Text.Encoding.xml",
+ "ref/netstandard1.3/ru/System.Text.Encoding.xml",
+ "ref/netstandard1.3/zh-hans/System.Text.Encoding.xml",
+ "ref/netstandard1.3/zh-hant/System.Text.Encoding.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Text.Encoding.Extensions/4.0.11": {
+ "sha512": "jtbiTDtvfLYgXn8PTfWI+SiBs51rrmO4AAckx4KR6vFK9Wzf6tI8kcRdsYQNwriUeQ1+CtQbM1W4cMbLXnj/OQ==",
+ "type": "package",
+ "path": "System.Text.Encoding.Extensions/4.0.11",
+ "files": [
+ "System.Text.Encoding.Extensions.4.0.11.nupkg.sha512",
+ "System.Text.Encoding.Extensions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Text.Encoding.Extensions.dll",
+ "ref/netcore50/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/de/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/es/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/fr/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/it/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/ja/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/ko/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/ru/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/zh-hans/System.Text.Encoding.Extensions.xml",
+ "ref/netcore50/zh-hant/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/System.Text.Encoding.Extensions.dll",
+ "ref/netstandard1.0/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/de/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/es/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/fr/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/it/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/ja/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/ko/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/ru/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/zh-hans/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.0/zh-hant/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/System.Text.Encoding.Extensions.dll",
+ "ref/netstandard1.3/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/de/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/es/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/fr/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/it/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/ja/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/ko/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/ru/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/zh-hans/System.Text.Encoding.Extensions.xml",
+ "ref/netstandard1.3/zh-hant/System.Text.Encoding.Extensions.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Text.RegularExpressions/4.1.0": {
+ "sha512": "i88YCXpRTjCnoSQZtdlHkAOx4KNNik4hMy83n0+Ftlb7jvV6ZiZWMpnEZHhjBp6hQVh8gWd/iKNPzlPF7iyA2g==",
+ "type": "package",
+ "path": "System.Text.RegularExpressions/4.1.0",
+ "files": [
+ "System.Text.RegularExpressions.4.1.0.nupkg.sha512",
+ "System.Text.RegularExpressions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/net463/System.Text.RegularExpressions.dll",
+ "lib/netcore50/System.Text.RegularExpressions.dll",
+ "lib/netstandard1.6/System.Text.RegularExpressions.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/net463/System.Text.RegularExpressions.dll",
+ "ref/netcore50/System.Text.RegularExpressions.dll",
+ "ref/netcore50/System.Text.RegularExpressions.xml",
+ "ref/netcore50/de/System.Text.RegularExpressions.xml",
+ "ref/netcore50/es/System.Text.RegularExpressions.xml",
+ "ref/netcore50/fr/System.Text.RegularExpressions.xml",
+ "ref/netcore50/it/System.Text.RegularExpressions.xml",
+ "ref/netcore50/ja/System.Text.RegularExpressions.xml",
+ "ref/netcore50/ko/System.Text.RegularExpressions.xml",
+ "ref/netcore50/ru/System.Text.RegularExpressions.xml",
+ "ref/netcore50/zh-hans/System.Text.RegularExpressions.xml",
+ "ref/netcore50/zh-hant/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/System.Text.RegularExpressions.dll",
+ "ref/netstandard1.0/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/de/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/es/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/fr/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/it/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/ja/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/ko/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/ru/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/zh-hans/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.0/zh-hant/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/System.Text.RegularExpressions.dll",
+ "ref/netstandard1.3/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/de/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/es/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/fr/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/it/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/ja/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/ko/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/ru/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/zh-hans/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.3/zh-hant/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/System.Text.RegularExpressions.dll",
+ "ref/netstandard1.6/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/de/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/es/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/fr/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/it/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/ja/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/ko/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/ru/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/zh-hans/System.Text.RegularExpressions.xml",
+ "ref/netstandard1.6/zh-hant/System.Text.RegularExpressions.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Threading/4.0.11": {
+ "sha512": "N+3xqIcg3VDKyjwwCGaZ9HawG9aC6cSDI+s7ROma310GQo8vilFZa86hqKppwTHleR/G0sfOzhvgnUxWCR/DrQ==",
+ "type": "package",
+ "path": "System.Threading/4.0.11",
+ "files": [
+ "System.Threading.4.0.11.nupkg.sha512",
+ "System.Threading.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.Threading.dll",
+ "lib/netstandard1.3/System.Threading.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Threading.dll",
+ "ref/netcore50/System.Threading.xml",
+ "ref/netcore50/de/System.Threading.xml",
+ "ref/netcore50/es/System.Threading.xml",
+ "ref/netcore50/fr/System.Threading.xml",
+ "ref/netcore50/it/System.Threading.xml",
+ "ref/netcore50/ja/System.Threading.xml",
+ "ref/netcore50/ko/System.Threading.xml",
+ "ref/netcore50/ru/System.Threading.xml",
+ "ref/netcore50/zh-hans/System.Threading.xml",
+ "ref/netcore50/zh-hant/System.Threading.xml",
+ "ref/netstandard1.0/System.Threading.dll",
+ "ref/netstandard1.0/System.Threading.xml",
+ "ref/netstandard1.0/de/System.Threading.xml",
+ "ref/netstandard1.0/es/System.Threading.xml",
+ "ref/netstandard1.0/fr/System.Threading.xml",
+ "ref/netstandard1.0/it/System.Threading.xml",
+ "ref/netstandard1.0/ja/System.Threading.xml",
+ "ref/netstandard1.0/ko/System.Threading.xml",
+ "ref/netstandard1.0/ru/System.Threading.xml",
+ "ref/netstandard1.0/zh-hans/System.Threading.xml",
+ "ref/netstandard1.0/zh-hant/System.Threading.xml",
+ "ref/netstandard1.3/System.Threading.dll",
+ "ref/netstandard1.3/System.Threading.xml",
+ "ref/netstandard1.3/de/System.Threading.xml",
+ "ref/netstandard1.3/es/System.Threading.xml",
+ "ref/netstandard1.3/fr/System.Threading.xml",
+ "ref/netstandard1.3/it/System.Threading.xml",
+ "ref/netstandard1.3/ja/System.Threading.xml",
+ "ref/netstandard1.3/ko/System.Threading.xml",
+ "ref/netstandard1.3/ru/System.Threading.xml",
+ "ref/netstandard1.3/zh-hans/System.Threading.xml",
+ "ref/netstandard1.3/zh-hant/System.Threading.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/aot/lib/netcore50/System.Threading.dll"
+ ]
+ },
+ "System.Threading.Tasks/4.0.11": {
+ "sha512": "k1S4Gc6IGwtHGT8188RSeGaX86Qw/wnrgNLshJvsdNUOPP9etMmo8S07c+UlOAx4K/xLuN9ivA1bD0LVurtIxQ==",
+ "type": "package",
+ "path": "System.Threading.Tasks/4.0.11",
+ "files": [
+ "System.Threading.Tasks.4.0.11.nupkg.sha512",
+ "System.Threading.Tasks.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Threading.Tasks.dll",
+ "ref/netcore50/System.Threading.Tasks.xml",
+ "ref/netcore50/de/System.Threading.Tasks.xml",
+ "ref/netcore50/es/System.Threading.Tasks.xml",
+ "ref/netcore50/fr/System.Threading.Tasks.xml",
+ "ref/netcore50/it/System.Threading.Tasks.xml",
+ "ref/netcore50/ja/System.Threading.Tasks.xml",
+ "ref/netcore50/ko/System.Threading.Tasks.xml",
+ "ref/netcore50/ru/System.Threading.Tasks.xml",
+ "ref/netcore50/zh-hans/System.Threading.Tasks.xml",
+ "ref/netcore50/zh-hant/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/System.Threading.Tasks.dll",
+ "ref/netstandard1.0/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/de/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/es/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/fr/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/it/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/ja/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/ko/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/ru/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/zh-hans/System.Threading.Tasks.xml",
+ "ref/netstandard1.0/zh-hant/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/System.Threading.Tasks.dll",
+ "ref/netstandard1.3/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/de/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/es/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/fr/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/it/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/ja/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/ko/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/ru/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/zh-hans/System.Threading.Tasks.xml",
+ "ref/netstandard1.3/zh-hant/System.Threading.Tasks.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Threading.Tasks.Extensions/4.0.0": {
+ "sha512": "pH4FZDsZQ/WmgJtN4LWYmRdJAEeVkyriSwrv2Teoe5FOU0Yxlb6II6GL8dBPOfRmutHGATduj3ooMt7dJ2+i+w==",
+ "type": "package",
+ "path": "System.Threading.Tasks.Extensions/4.0.0",
+ "files": [
+ "System.Threading.Tasks.Extensions.4.0.0.nupkg.sha512",
+ "System.Threading.Tasks.Extensions.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/netstandard1.0/System.Threading.Tasks.Extensions.dll",
+ "lib/netstandard1.0/System.Threading.Tasks.Extensions.xml",
+ "lib/portable-net45+win8+wp8+wpa81/System.Threading.Tasks.Extensions.dll",
+ "lib/portable-net45+win8+wp8+wpa81/System.Threading.Tasks.Extensions.xml"
+ ]
+ },
+ "System.Threading.Timer/4.0.1": {
+ "sha512": "saGfUV8uqVW6LeURiqxcGhZ24PzuRNaUBtbhVeuUAvky1naH395A/1nY0P2bWvrw/BreRtIB/EzTDkGBpqCwEw==",
+ "type": "package",
+ "path": "System.Threading.Timer/4.0.1",
+ "files": [
+ "System.Threading.Timer.4.0.1.nupkg.sha512",
+ "System.Threading.Timer.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net451/_._",
+ "lib/portable-net451+win81+wpa81/_._",
+ "lib/win81/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net451/_._",
+ "ref/netcore50/System.Threading.Timer.dll",
+ "ref/netcore50/System.Threading.Timer.xml",
+ "ref/netcore50/de/System.Threading.Timer.xml",
+ "ref/netcore50/es/System.Threading.Timer.xml",
+ "ref/netcore50/fr/System.Threading.Timer.xml",
+ "ref/netcore50/it/System.Threading.Timer.xml",
+ "ref/netcore50/ja/System.Threading.Timer.xml",
+ "ref/netcore50/ko/System.Threading.Timer.xml",
+ "ref/netcore50/ru/System.Threading.Timer.xml",
+ "ref/netcore50/zh-hans/System.Threading.Timer.xml",
+ "ref/netcore50/zh-hant/System.Threading.Timer.xml",
+ "ref/netstandard1.2/System.Threading.Timer.dll",
+ "ref/netstandard1.2/System.Threading.Timer.xml",
+ "ref/netstandard1.2/de/System.Threading.Timer.xml",
+ "ref/netstandard1.2/es/System.Threading.Timer.xml",
+ "ref/netstandard1.2/fr/System.Threading.Timer.xml",
+ "ref/netstandard1.2/it/System.Threading.Timer.xml",
+ "ref/netstandard1.2/ja/System.Threading.Timer.xml",
+ "ref/netstandard1.2/ko/System.Threading.Timer.xml",
+ "ref/netstandard1.2/ru/System.Threading.Timer.xml",
+ "ref/netstandard1.2/zh-hans/System.Threading.Timer.xml",
+ "ref/netstandard1.2/zh-hant/System.Threading.Timer.xml",
+ "ref/portable-net451+win81+wpa81/_._",
+ "ref/win81/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Xml.ReaderWriter/4.0.11": {
+ "sha512": "ZIiLPsf67YZ9zgr31vzrFaYQqxRPX9cVHjtPSnmx4eN6lbS/yEyYNr2vs1doGDEscF0tjCZFsk9yUg1sC9e8tg==",
+ "type": "package",
+ "path": "System.Xml.ReaderWriter/4.0.11",
+ "files": [
+ "System.Xml.ReaderWriter.4.0.11.nupkg.sha512",
+ "System.Xml.ReaderWriter.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.Xml.ReaderWriter.dll",
+ "lib/netstandard1.3/System.Xml.ReaderWriter.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Xml.ReaderWriter.dll",
+ "ref/netcore50/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/de/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/es/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/fr/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/it/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/ja/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/ko/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/ru/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/zh-hans/System.Xml.ReaderWriter.xml",
+ "ref/netcore50/zh-hant/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/System.Xml.ReaderWriter.dll",
+ "ref/netstandard1.0/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/de/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/es/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/fr/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/it/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/ja/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/ko/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/ru/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/zh-hans/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.0/zh-hant/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/System.Xml.ReaderWriter.dll",
+ "ref/netstandard1.3/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/de/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/es/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/fr/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/it/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/ja/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/ko/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/ru/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/zh-hans/System.Xml.ReaderWriter.xml",
+ "ref/netstandard1.3/zh-hant/System.Xml.ReaderWriter.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Xml.XDocument/4.0.11": {
+ "sha512": "Mk2mKmPi0nWaoiYeotq1dgeNK1fqWh61+EK+w4Wu8SWuTYLzpUnschb59bJtGywaPq7SmTuPf44wrXRwbIrukg==",
+ "type": "package",
+ "path": "System.Xml.XDocument/4.0.11",
+ "files": [
+ "System.Xml.XDocument.4.0.11.nupkg.sha512",
+ "System.Xml.XDocument.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.Xml.XDocument.dll",
+ "lib/netstandard1.3/System.Xml.XDocument.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Xml.XDocument.dll",
+ "ref/netcore50/System.Xml.XDocument.xml",
+ "ref/netcore50/de/System.Xml.XDocument.xml",
+ "ref/netcore50/es/System.Xml.XDocument.xml",
+ "ref/netcore50/fr/System.Xml.XDocument.xml",
+ "ref/netcore50/it/System.Xml.XDocument.xml",
+ "ref/netcore50/ja/System.Xml.XDocument.xml",
+ "ref/netcore50/ko/System.Xml.XDocument.xml",
+ "ref/netcore50/ru/System.Xml.XDocument.xml",
+ "ref/netcore50/zh-hans/System.Xml.XDocument.xml",
+ "ref/netcore50/zh-hant/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/System.Xml.XDocument.dll",
+ "ref/netstandard1.0/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/de/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/es/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/fr/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/it/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/ja/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/ko/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/ru/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/zh-hans/System.Xml.XDocument.xml",
+ "ref/netstandard1.0/zh-hant/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/System.Xml.XDocument.dll",
+ "ref/netstandard1.3/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/de/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/es/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/fr/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/it/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/ja/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/ko/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/ru/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/zh-hans/System.Xml.XDocument.xml",
+ "ref/netstandard1.3/zh-hant/System.Xml.XDocument.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Xml.XmlDocument/4.0.1": {
+ "sha512": "sDTrZPX5RBEsyGtaNEM48kd2SjfcyF+Nol2SdfrtOVbbjxe3lrJ+EfuidLgzTfd6SZoBi+nI2X8McT/kTp3/RQ==",
+ "type": "package",
+ "path": "System.Xml.XmlDocument/4.0.1",
+ "files": [
+ "System.Xml.XmlDocument.4.0.1.nupkg.sha512",
+ "System.Xml.XmlDocument.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net46/System.Xml.XmlDocument.dll",
+ "lib/netstandard1.3/System.Xml.XmlDocument.dll",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net46/System.Xml.XmlDocument.dll",
+ "ref/netstandard1.3/System.Xml.XmlDocument.dll",
+ "ref/netstandard1.3/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/de/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/es/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/fr/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/it/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/ja/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/ko/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/ru/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/zh-hans/System.Xml.XmlDocument.xml",
+ "ref/netstandard1.3/zh-hant/System.Xml.XmlDocument.xml",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._"
+ ]
+ },
+ "System.Xml.XmlSerializer/4.0.11": {
+ "sha512": "FrazwwqfIXTfq23mfv4zH+BjqkSFNaNFBtjzu3I9NRmG8EELYyrv/fJnttCIwRMFRR/YKXF1hmsMmMEnl55HGw==",
+ "type": "package",
+ "path": "System.Xml.XmlSerializer/4.0.11",
+ "files": [
+ "System.Xml.XmlSerializer.4.0.11.nupkg.sha512",
+ "System.Xml.XmlSerializer.nuspec",
+ "ThirdPartyNotices.txt",
+ "dotnet_library_license.txt",
+ "lib/MonoAndroid10/_._",
+ "lib/MonoTouch10/_._",
+ "lib/net45/_._",
+ "lib/netcore50/System.Xml.XmlSerializer.dll",
+ "lib/netstandard1.3/System.Xml.XmlSerializer.dll",
+ "lib/portable-net45+win8+wp8+wpa81/_._",
+ "lib/win8/_._",
+ "lib/wp80/_._",
+ "lib/wpa81/_._",
+ "lib/xamarinios10/_._",
+ "lib/xamarinmac20/_._",
+ "lib/xamarintvos10/_._",
+ "lib/xamarinwatchos10/_._",
+ "ref/MonoAndroid10/_._",
+ "ref/MonoTouch10/_._",
+ "ref/net45/_._",
+ "ref/netcore50/System.Xml.XmlSerializer.dll",
+ "ref/netcore50/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/de/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/es/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/fr/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/it/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/ja/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/ko/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/ru/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/zh-hans/System.Xml.XmlSerializer.xml",
+ "ref/netcore50/zh-hant/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/System.Xml.XmlSerializer.dll",
+ "ref/netstandard1.0/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/de/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/es/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/fr/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/it/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/ja/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/ko/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/ru/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/zh-hans/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.0/zh-hant/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/System.Xml.XmlSerializer.dll",
+ "ref/netstandard1.3/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/de/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/es/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/fr/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/it/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/ja/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/ko/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/ru/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/zh-hans/System.Xml.XmlSerializer.xml",
+ "ref/netstandard1.3/zh-hant/System.Xml.XmlSerializer.xml",
+ "ref/portable-net45+win8+wp8+wpa81/_._",
+ "ref/win8/_._",
+ "ref/wp80/_._",
+ "ref/wpa81/_._",
+ "ref/xamarinios10/_._",
+ "ref/xamarinmac20/_._",
+ "ref/xamarintvos10/_._",
+ "ref/xamarinwatchos10/_._",
+ "runtimes/aot/lib/netcore50/System.Xml.XmlSerializer.dll"
+ ]
+ },
+ "MediaBrowser.Common/1.0.0": {
+ "type": "project",
+ "path": "../MediaBrowser.Common/project.json",
+ "msbuildProject": "../MediaBrowser.Common/MediaBrowser.Common.csproj"
+ },
+ "MediaBrowser.Model/1.0.0": {
+ "type": "project",
+ "path": "../MediaBrowser.Model/project.json",
+ "msbuildProject": "../MediaBrowser.Model/MediaBrowser.Model.csproj"
+ }
+ },
+ "projectFileDependencyGroups": {
+ "": [],
+ ".NETFramework,Version=v4.6": [
+ "MediaBrowser.Common",
+ "MediaBrowser.Model",
+ "System.Collections >= 4.0.0",
+ "System.IO >= 4.0.0",
+ "System.Net >= 4.0.0",
+ "System.Net.Http >= 4.0.0",
+ "System.Net.Http.WebRequest >= 4.0.0",
+ "System.Net.Primitives >= 4.0.0",
+ "System.Runtime >= 4.0.0",
+ "System.Text.Encoding >= 4.0.0",
+ "System.Threading >= 4.0.0",
+ "System.Threading.Tasks >= 4.0.0",
+ "System.Xml >= 4.0.0",
+ "System.Xml.Serialization >= 4.0.0"
+ ],
+ ".NETStandard,Version=v1.6": [
+ "MediaBrowser.Common",
+ "MediaBrowser.Model",
+ "NETStandard.Library >= 1.6.0",
+ "System.Net.Requests >= 4.0.11",
+ "System.Xml.XmlSerializer >= 4.0.11"
+ ]
+ },
+ "tools": {},
+ "projectFileToolGroups": {}
+}
\ No newline at end of file
diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
index 4b9d78c9ca..ec96818aa6 100644
--- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
+++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs
@@ -3,7 +3,6 @@ using MediaBrowser.Common.Events;
using MediaBrowser.Common.Implementations.Devices;
using MediaBrowser.Common.Implementations.IO;
using MediaBrowser.Common.Implementations.ScheduledTasks;
-using MediaBrowser.Common.Implementations.Security;
using MediaBrowser.Common.Implementations.Serialization;
using MediaBrowser.Common.Implementations.Updates;
using MediaBrowser.Common.Net;
@@ -31,6 +30,7 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Implementations.Cryptography;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
namespace MediaBrowser.Common.Implementations
@@ -121,11 +121,6 @@ namespace MediaBrowser.Common.Implementations
/// The kernel.
protected ITaskManager TaskManager { get; private set; }
///
- /// Gets the security manager.
- ///
- /// The security manager.
- protected ISecurityManager SecurityManager { get; private set; }
- ///
/// Gets the HTTP client.
///
/// The HTTP client.
@@ -142,16 +137,12 @@ namespace MediaBrowser.Common.Implementations
/// The configuration manager.
protected IConfigurationManager ConfigurationManager { get; private set; }
- ///
- /// Gets or sets the installation manager.
- ///
- /// The installation manager.
- protected IInstallationManager InstallationManager { get; private set; }
-
protected IFileSystem FileSystemManager { get; private set; }
protected IIsoManager IsoManager { get; private set; }
+ protected ISystemEvents SystemEvents { get; private set; }
+
///
/// Gets the name.
///
@@ -221,6 +212,7 @@ namespace MediaBrowser.Common.Implementations
JsonSerializer = CreateJsonSerializer();
MemoryStreamProvider = CreateMemoryStreamProvider();
+ SystemEvents = CreateSystemEvents();
OnLoggerLoaded(true);
LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false);
@@ -254,6 +246,7 @@ namespace MediaBrowser.Common.Implementations
}
protected abstract IMemoryStreamProvider CreateMemoryStreamProvider();
+ protected abstract ISystemEvents CreateSystemEvents();
protected virtual void OnLoggerLoaded(bool isFirstLoad)
{
@@ -473,11 +466,12 @@ namespace MediaBrowser.Common.Implementations
RegisterSingleInstance(ApplicationPaths);
- TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LogManager.GetLogger("TaskManager"), FileSystemManager);
+ TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LogManager.GetLogger("TaskManager"), FileSystemManager, SystemEvents);
RegisterSingleInstance(JsonSerializer);
RegisterSingleInstance(XmlSerializer);
RegisterSingleInstance(MemoryStreamProvider);
+ RegisterSingleInstance(SystemEvents);
RegisterSingleInstance(LogManager);
RegisterSingleInstance(Logger);
@@ -492,12 +486,6 @@ namespace MediaBrowser.Common.Implementations
NetworkManager = CreateNetworkManager(LogManager.GetLogger("NetworkManager"));
RegisterSingleInstance(NetworkManager);
- SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager);
- RegisterSingleInstance(SecurityManager);
-
- InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager);
- RegisterSingleInstance(InstallationManager);
-
IsoManager = new IsoManager();
RegisterSingleInstance(IsoManager);
diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
index 7c1302ff65..943e6c5f88 100644
--- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
+++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs
@@ -79,7 +79,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
get
{
// Lazy load
- LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer));
+ LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer, FileSystem));
return _configuration;
}
protected set
@@ -126,7 +126,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
Logger.Info("Saving system configuration");
var path = CommonApplicationPaths.SystemConfigurationFilePath;
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ FileSystem.CreateDirectory(Path.GetDirectoryName(path));
lock (_configurationSyncLock)
{
@@ -196,9 +196,9 @@ namespace MediaBrowser.Common.Implementations.Configuration
&& !string.Equals(CommonConfiguration.CachePath ?? string.Empty, newPath))
{
// Validate
- if (!Directory.Exists(newPath))
+ if (!FileSystem.DirectoryExists(newPath))
{
- throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath));
+ throw new FileNotFoundException(string.Format("{0} does not exist.", newPath));
}
EnsureWriteAccess(newPath);
@@ -253,7 +253,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
{
return Activator.CreateInstance(configurationType);
}
- catch (DirectoryNotFoundException)
+ catch (IOException)
{
return Activator.CreateInstance(configurationType);
}
@@ -293,7 +293,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
_configurations.AddOrUpdate(key, configuration, (k, v) => configuration);
var path = GetConfigurationFile(key);
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ FileSystem.CreateDirectory(Path.GetDirectoryName(path));
lock (_configurationSyncLock)
{
diff --git a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
index 419b85fa73..0c1683f93e 100644
--- a/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
+++ b/MediaBrowser.Common.Implementations/Configuration/ConfigurationHelper.cs
@@ -2,6 +2,7 @@
using System;
using System.IO;
using System.Linq;
+using MediaBrowser.Model.IO;
namespace MediaBrowser.Common.Implementations.Configuration
{
@@ -18,7 +19,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
/// The path.
/// The XML serializer.
/// System.Object.
- public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer)
+ public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
{
object configuration;
@@ -27,7 +28,7 @@ namespace MediaBrowser.Common.Implementations.Configuration
// Use try/catch to avoid the extra file system lookup using File.Exists
try
{
- buffer = File.ReadAllBytes(path);
+ buffer = fileSystem.ReadAllBytes(path);
configuration = xmlSerializer.DeserializeFromBytes(type, buffer);
}
@@ -46,10 +47,10 @@ namespace MediaBrowser.Common.Implementations.Configuration
// If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !buffer.SequenceEqual(newBytes))
{
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ fileSystem.CreateDirectory(Path.GetDirectoryName(path));
// Save it after load in case we got new items
- File.WriteAllBytes(path, newBytes);
+ fileSystem.WriteAllBytes(path, newBytes);
}
return configuration;
diff --git a/MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs b/MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs
index 8b027d41ac..4f6c34cb7b 100644
--- a/MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs
+++ b/MediaBrowser.Common.Implementations/IO/ManagedFileSystem.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
-using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
@@ -660,6 +659,11 @@ namespace MediaBrowser.Common.Implementations.IO
return File.ReadAllText(path);
}
+ public byte[] ReadAllBytes(string path)
+ {
+ return File.ReadAllBytes(path);
+ }
+
public void WriteAllText(string path, string text, Encoding encoding)
{
File.WriteAllText(path, text, encoding);
@@ -670,6 +674,11 @@ namespace MediaBrowser.Common.Implementations.IO
File.WriteAllText(path, text);
}
+ public void WriteAllBytes(string path, byte[] bytes)
+ {
+ File.WriteAllBytes(path, bytes);
+ }
+
public string ReadAllText(string path, Encoding encoding)
{
return File.ReadAllText(path, encoding);
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index 4b3fe3dba9..89e9427ae4 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -79,14 +79,8 @@
-
-
-
-
-
-
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs
index 3d33e958de..ab1d8f02dc 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/DailyTrigger.cs
@@ -1,11 +1,11 @@
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Tasks;
-using System;
+using System;
using System.Globalization;
using System.Threading;
+using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
///
/// Represents a task trigger that fires everyday
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
index 8038d5551d..251e460cb1 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/IntervalTrigger.cs
@@ -1,11 +1,11 @@
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Tasks;
-using System;
+using System;
using System.Linq;
using System.Threading;
+using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
///
/// Represents a task trigger that runs repeatedly on an interval
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs
index 41f58a7ad5..c96a41ac80 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/StartupTrigger.cs
@@ -1,10 +1,10 @@
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Tasks;
-using System;
+using System;
using System.Threading.Tasks;
+using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
///
/// Class StartupTaskTrigger
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
index 9a0221deab..5c721d915e 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs
@@ -12,6 +12,7 @@ using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.System;
using Microsoft.Win32;
namespace MediaBrowser.Common.Implementations.ScheduledTasks
@@ -48,6 +49,8 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// The application paths.
private IApplicationPaths ApplicationPaths { get; set; }
+ private readonly ISystemEvents _systemEvents;
+
///
/// Gets the logger.
///
@@ -81,29 +84,23 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// The json serializer.
/// The logger.
/// kernel
- public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger, IFileSystem fileSystem)
+ public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger, IFileSystem fileSystem, ISystemEvents systemEvents)
{
ApplicationPaths = applicationPaths;
JsonSerializer = jsonSerializer;
Logger = logger;
_fileSystem = fileSystem;
+ _systemEvents = systemEvents;
ScheduledTasks = new IScheduledTaskWorker[] { };
}
private void BindToSystemEvent()
{
- try
- {
- SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
- }
- catch
- {
-
- }
+ _systemEvents.Resume += _systemEvents_Resume;
}
- void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
+ private void _systemEvents_Resume(object sender, EventArgs e)
{
foreach (var task in ScheduledTasks)
{
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
index 318802e07d..0d8af4e9c2 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/WeeklyTrigger.cs
@@ -4,7 +4,7 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Tasks;
-namespace MediaBrowser.Common.ScheduledTasks
+namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
///
/// Represents a task trigger that fires on a weekly basis
diff --git a/MediaBrowser.Common.Implementations/Security/MbAdmin.cs b/MediaBrowser.Common.Implementations/Security/MbAdmin.cs
deleted file mode 100644
index 76ff92c2eb..0000000000
--- a/MediaBrowser.Common.Implementations/Security/MbAdmin.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-
-namespace MediaBrowser.Common.Implementations.Security
-{
- public class MbAdmin
- {
- public const string HttpUrl = "https://www.mb3admin.com/admin/";
-
- ///
- /// Leaving as http for now until we get it squared away
- ///
- public const string HttpsUrl = "https://www.mb3admin.com/admin/";
- }
-}
diff --git a/MediaBrowser.Common.Implementations/Security/SuppporterInfoResponse.cs b/MediaBrowser.Common.Implementations/Security/SuppporterInfoResponse.cs
deleted file mode 100644
index 49c5af8d82..0000000000
--- a/MediaBrowser.Common.Implementations/Security/SuppporterInfoResponse.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-
-namespace MediaBrowser.Common.Implementations.Security
-{
- internal class SuppporterInfoResponse
- {
- public string email { get; set; }
- public string supporterKey { get; set; }
- public int totalRegs { get; set; }
- public int totalMachines { get; set; }
- public string expDate { get; set; }
- public string regDate { get; set; }
- public string planType { get; set; }
- }
-}
diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs
index b2ca6924f5..4f920c3b03 100644
--- a/MediaBrowser.Model/IO/IFileSystem.cs
+++ b/MediaBrowser.Model/IO/IFileSystem.cs
@@ -249,6 +249,10 @@ namespace MediaBrowser.Model.IO
/// System.String.
string ReadAllText(string path);
+ byte[] ReadAllBytes(string path);
+
+ void WriteAllBytes(string path, byte[] bytes);
+
///
/// Writes all text.
///
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 912decfa3f..75669b44f6 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -408,6 +408,7 @@
+
diff --git a/MediaBrowser.Model/System/ISystemEvents.cs b/MediaBrowser.Model/System/ISystemEvents.cs
new file mode 100644
index 0000000000..c50f8ce030
--- /dev/null
+++ b/MediaBrowser.Model/System/ISystemEvents.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace MediaBrowser.Model.System
+{
+ public interface ISystemEvents
+ {
+ event EventHandler Resume;
+ event EventHandler Suspend;
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index ec1fbb4796..24ce4097f1 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -287,6 +287,9 @@
+
+
+
@@ -296,6 +299,7 @@
+
diff --git a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs b/MediaBrowser.Server.Implementations/Security/MBLicenseFile.cs
similarity index 97%
rename from MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
rename to MediaBrowser.Server.Implementations/Security/MBLicenseFile.cs
index 78515cd141..7b37925ba5 100644
--- a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs
+++ b/MediaBrowser.Server.Implementations/Security/MBLicenseFile.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Configuration;
-using System;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
@@ -7,8 +6,9 @@ using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
+using MediaBrowser.Common.Configuration;
-namespace MediaBrowser.Common.Implementations.Security
+namespace MediaBrowser.Server.Implementations.Security
{
internal class MBLicenseFile
{
diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Server.Implementations/Security/PluginSecurityManager.cs
similarity index 93%
rename from MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
rename to MediaBrowser.Server.Implementations/Security/PluginSecurityManager.cs
index 5d440609ef..7dc78a3afd 100644
--- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
+++ b/MediaBrowser.Server.Implementations/Security/PluginSecurityManager.cs
@@ -1,26 +1,29 @@
-using System.IO;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Security;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using System;
+using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Security;
+using MediaBrowser.Controller;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Serialization;
-namespace MediaBrowser.Common.Implementations.Security
+namespace MediaBrowser.Server.Implementations.Security
{
///
/// Class PluginSecurityManager
///
public class PluginSecurityManager : ISecurityManager
{
- private const string MBValidateUrl = MbAdmin.HttpsUrl + "service/registration/validate";
+ private const string MBValidateUrl = "https://mb3admin.com/admin/service/registration/validate";
private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "https://mb3admin.com/admin/service/appstore/register";
///
@@ -57,9 +60,10 @@ namespace MediaBrowser.Common.Implementations.Security
private readonly IHttpClient _httpClient;
private readonly IJsonSerializer _jsonSerializer;
- private readonly IApplicationHost _appHost;
+ private readonly IServerApplicationHost _appHost;
private readonly ILogger _logger;
private readonly IApplicationPaths _appPaths;
+ private readonly IFileSystem _fileSystem;
private IEnumerable _registeredEntities;
protected IEnumerable RegisteredEntities
@@ -73,8 +77,8 @@ namespace MediaBrowser.Common.Implementations.Security
///
/// Initializes a new instance of the class.
///
- public PluginSecurityManager(IApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer,
- IApplicationPaths appPaths, ILogManager logManager)
+ public PluginSecurityManager(IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer,
+ IApplicationPaths appPaths, ILogManager logManager, IFileSystem fileSystem)
{
if (httpClient == null)
{
@@ -85,6 +89,7 @@ namespace MediaBrowser.Common.Implementations.Security
_httpClient = httpClient;
_jsonSerializer = jsonSerializer;
_appPaths = appPaths;
+ _fileSystem = fileSystem;
_logger = logManager.GetLogger("SecurityManager");
}
@@ -226,7 +231,7 @@ namespace MediaBrowser.Common.Implementations.Security
try
{
- File.WriteAllText(Path.Combine(_appPaths.ProgramDataPath, "apptrans-error.txt"), info);
+ _fileSystem.WriteAllText(Path.Combine(_appPaths.ProgramDataPath, "apptrans-error.txt"), info);
}
catch (IOException)
{
diff --git a/MediaBrowser.Common.Implementations/Security/RegRecord.cs b/MediaBrowser.Server.Implementations/Security/RegRecord.cs
similarity index 80%
rename from MediaBrowser.Common.Implementations/Security/RegRecord.cs
rename to MediaBrowser.Server.Implementations/Security/RegRecord.cs
index ece70b7726..947ec629f0 100644
--- a/MediaBrowser.Common.Implementations/Security/RegRecord.cs
+++ b/MediaBrowser.Server.Implementations/Security/RegRecord.cs
@@ -1,6 +1,6 @@
using System;
-namespace MediaBrowser.Common.Implementations.Security
+namespace MediaBrowser.Server.Implementations.Security
{
class RegRecord
{
diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Server.Implementations/Updates/InstallationManager.cs
similarity index 98%
rename from MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
rename to MediaBrowser.Server.Implementations/Updates/InstallationManager.cs
index 934898f778..c6930e4872 100644
--- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
+++ b/MediaBrowser.Server.Implementations/Updates/InstallationManager.cs
@@ -1,16 +1,4 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Implementations.Security;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Plugins;
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Common.Security;
-using MediaBrowser.Common.Updates;
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Updates;
-using System;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
@@ -18,10 +6,21 @@ using System.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Events;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Plugins;
+using MediaBrowser.Common.Progress;
+using MediaBrowser.Common.Security;
+using MediaBrowser.Common.Updates;
+using MediaBrowser.Model.Events;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Updates;
-namespace MediaBrowser.Common.Implementations.Updates
+namespace MediaBrowser.Server.Implementations.Updates
{
///
/// Manages all install, uninstall and update operations (both plugins and system)
@@ -164,7 +163,7 @@ namespace MediaBrowser.Common.Implementations.Updates
if (withRegistration)
{
- using (var json = await _httpClient.Post(MbAdmin.HttpsUrl + "service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
+ using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
{
cancellationToken.ThrowIfCancellationRequested();
@@ -237,7 +236,7 @@ namespace MediaBrowser.Common.Implementations.Updates
var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
{
- Url = MbAdmin.HttpUrl + "service/MB3Packages.json",
+ Url = "https://www.mb3admin.com/admin/service/MB3Packages.json",
CancellationToken = cancellationToken,
Progress = new Progress()
@@ -619,7 +618,7 @@ namespace MediaBrowser.Common.Implementations.Updates
//If it is an archive - write out a version file so we know what it is
if (isArchive)
{
- File.WriteAllText(target + ".ver", package.versionStr);
+ _fileSystem.WriteAllText(target + ".ver", package.versionStr);
}
}
catch (IOException e)
diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs
index f970f68db2..051b233dc0 100644
--- a/MediaBrowser.Server.Mono/Program.cs
+++ b/MediaBrowser.Server.Mono/Program.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Mono
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, StartupOptions options)
{
- SystemEvents.SessionEnding += SystemEvents_SessionEnding;
+ Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding;
// Allow all https requests
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 3ef63fd941..b26edb8953 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -104,6 +104,8 @@ using MediaBrowser.Common.Implementations.Serialization;
using MediaBrowser.Common.Implementations.Updates;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Plugins;
+using MediaBrowser.Common.Security;
+using MediaBrowser.Common.Updates;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
@@ -120,6 +122,7 @@ using MediaBrowser.Model.Xml;
using MediaBrowser.Server.Implementations.Archiving;
using MediaBrowser.Server.Implementations.Reflection;
using MediaBrowser.Server.Implementations.Serialization;
+using MediaBrowser.Server.Implementations.Updates;
using MediaBrowser.Server.Implementations.Xml;
using OpenSubtitlesHandler;
using ServiceStack;
@@ -226,6 +229,17 @@ namespace MediaBrowser.Server.Startup.Common
private IMediaSourceManager MediaSourceManager { get; set; }
private IPlaylistManager PlaylistManager { get; set; }
+ ///
+ /// Gets or sets the installation manager.
+ ///
+ /// The installation manager.
+ protected IInstallationManager InstallationManager { get; private set; }
+ ///
+ /// Gets the security manager.
+ ///
+ /// The security manager.
+ protected ISecurityManager SecurityManager { get; private set; }
+
///
/// Gets or sets the zip client.
///
@@ -405,6 +419,11 @@ namespace MediaBrowser.Server.Startup.Common
return new MemoryStreamProvider();
}
+ protected override ISystemEvents CreateSystemEvents()
+ {
+ return new SystemEvents(LogManager.GetLogger("SystemEvents"));
+ }
+
protected override IJsonSerializer CreateJsonSerializer()
{
try
@@ -636,7 +655,6 @@ namespace MediaBrowser.Server.Startup.Common
{
var migrations = new List
{
- new MovieDbEpisodeProviderMigration(ServerConfigurationManager),
new DbMigration(ServerConfigurationManager, TaskManager)
};
@@ -660,6 +678,12 @@ namespace MediaBrowser.Server.Startup.Common
{
await base.RegisterResources(progress).ConfigureAwait(false);
+ SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager);
+ RegisterSingleInstance(SecurityManager);
+
+ InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager);
+ RegisterSingleInstance(InstallationManager);
+
ZipClient = new ZipClient(FileSystemManager);
RegisterSingleInstance(ZipClient);
diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
index c0ef484c97..53dbac53f1 100644
--- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
+++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
@@ -77,11 +77,11 @@
-
+
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/MovieDbEpisodeProviderMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/MovieDbEpisodeProviderMigration.cs
deleted file mode 100644
index cd2122e57b..0000000000
--- a/MediaBrowser.Server.Startup.Common/Migrations/MovieDbEpisodeProviderMigration.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using MediaBrowser.Controller.Configuration;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Server.Startup.Common.Migrations
-{
- class MovieDbEpisodeProviderMigration : IVersionMigration
- {
- private readonly IServerConfigurationManager _config;
- private const string _providerName = "TheMovieDb";
-
- public MovieDbEpisodeProviderMigration(IServerConfigurationManager config)
- {
- _config = config;
- }
-
- public async Task Run()
- {
- var migrationKey = this.GetType().FullName;
- var migrationKeyList = _config.Configuration.Migrations.ToList();
-
- if (!migrationKeyList.Contains(migrationKey))
- {
- foreach (var metaDataOption in _config.Configuration.MetadataOptions)
- {
- if (metaDataOption.ItemType == "Episode")
- {
- var disabledFetchers = metaDataOption.DisabledMetadataFetchers.ToList();
- if (!disabledFetchers.Contains(_providerName))
- {
- disabledFetchers.Add(_providerName);
- metaDataOption.DisabledMetadataFetchers = disabledFetchers.ToArray();
- }
- }
- }
-
- migrationKeyList.Add(migrationKey);
- _config.Configuration.Migrations = migrationKeyList.ToArray();
- _config.SaveConfiguration();
- }
-
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/SystemEvents.cs b/MediaBrowser.Server.Startup.Common/SystemEvents.cs
new file mode 100644
index 0000000000..088d04a249
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/SystemEvents.cs
@@ -0,0 +1,34 @@
+using System;
+using MediaBrowser.Common.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.System;
+
+namespace MediaBrowser.Server.Startup.Common
+{
+ public class SystemEvents : ISystemEvents
+ {
+ public event EventHandler Resume;
+ public event EventHandler Suspend;
+
+ private readonly ILogger _logger;
+
+ public SystemEvents(ILogger logger)
+ {
+ _logger = logger;
+ Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
+ }
+
+ private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
+ {
+ switch (e.Mode)
+ {
+ case Microsoft.Win32.PowerModes.Resume:
+ EventHelper.FireEventIfNotNull(Resume, this, EventArgs.Empty, _logger);
+ break;
+ case Microsoft.Win32.PowerModes.Suspend:
+ EventHelper.FireEventIfNotNull(Suspend, this, EventArgs.Empty, _logger);
+ break;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index 9287be3e28..6296f01173 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -351,8 +351,8 @@ namespace MediaBrowser.ServerApplication
task = InstallVcredist2013IfNeeded(_appHost, _logger);
Task.WaitAll(task);
- SystemEvents.SessionEnding += SystemEvents_SessionEnding;
- SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
+ Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding;
+ Microsoft.Win32.SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
HideSplashScreen();