diff options
Diffstat (limited to 'Emby.Server.Implementations')
515 files changed, 71612 insertions, 2419 deletions
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index 567f139fd..4e448ac64 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Activity { @@ -127,7 +128,7 @@ namespace Emby.Server.Implementations.Activity { // Don't report theme song or local trailer playback return; - } + } if (e.Users.Count == 0) { @@ -159,8 +160,8 @@ namespace Emby.Server.Implementations.Activity { // Don't report theme song or local trailer playback return; - } - + } + if (e.Users.Count == 0) { return; @@ -415,7 +416,7 @@ namespace Emby.Server.Implementations.Activity { return; } - + var time = result.EndTimeUtc - result.StartTimeUtc; var runningTime = string.Format(_localization.GetLocalizedString("LabelRunningTimeValue"), ToUserFriendlyString(time)); @@ -436,18 +437,18 @@ namespace Emby.Server.Implementations.Activity { Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name), Type = "ScheduledTaskFailed", - Overview = string.Join(Environment.NewLine, vals.ToArray()), + Overview = string.Join(Environment.NewLine, vals.ToArray(vals.Count)), ShortOverview = runningTime, Severity = LogSeverity.Error }); } } - private async void CreateLogEntry(ActivityLogEntry entry) + private void CreateLogEntry(ActivityLogEntry entry) { try { - await _activityManager.Create(entry).ConfigureAwait(false); + _activityManager.Create(entry); } catch { @@ -490,6 +491,7 @@ namespace Emby.Server.Implementations.Activity //_logManager.LoggerLoaded -= _logManager_LoggerLoaded; _appHost.ApplicationUpdated -= _appHost_ApplicationUpdated; + GC.SuppressFinalize(this); } /// <summary> diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs index b6095f082..9a3f1ae47 100644 --- a/Emby.Server.Implementations/Activity/ActivityManager.cs +++ b/Emby.Server.Implementations/Activity/ActivityManager.cs @@ -13,7 +13,7 @@ namespace Emby.Server.Implementations.Activity public class ActivityManager : IActivityManager { public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated; - + private readonly IActivityRepository _repo; private readonly ILogger _logger; private readonly IUserManager _userManager; @@ -25,12 +25,12 @@ namespace Emby.Server.Implementations.Activity _userManager = userManager; } - public async Task Create(ActivityLogEntry entry) + public void Create(ActivityLogEntry entry) { entry.Id = Guid.NewGuid().ToString("N"); entry.Date = DateTime.UtcNow; - await _repo.Create(entry).ConfigureAwait(false); + _repo.Create(entry); EventHelper.FireEventIfNotNull(EntryCreated, this, new GenericEventArgs<ActivityLogEntry>(entry), _logger); } diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index e9b6f7a40..3dcc50ba3 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -3,13 +3,13 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using System.Threading.Tasks; using Emby.Server.Implementations.Data; using MediaBrowser.Controller; using MediaBrowser.Model.Activity; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using SQLitePCL.pretty; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Activity { @@ -40,12 +40,12 @@ namespace Emby.Server.Implementations.Activity private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLogEntries"; - public Task Create(ActivityLogEntry entry) + public void Create(ActivityLogEntry entry) { - return Update(entry); + Update(entry); } - public async Task Update(ActivityLogEntry entry) + public void Update(ActivityLogEntry entry) { if (entry == null) { @@ -94,13 +94,13 @@ namespace Emby.Server.Implementations.Activity var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); if (startIndex.HasValue && startIndex.Value > 0) { var pagingWhereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})", pagingWhereText, @@ -109,7 +109,7 @@ namespace Emby.Server.Implementations.Activity var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); commandText += whereText; @@ -154,7 +154,7 @@ namespace Emby.Server.Implementations.Activity result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First(); } - result.Items = list.ToArray(); + result.Items = list.ToArray(list.Count); return result; }, ReadTransactionMode); diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index 54d1d5302..1e63aa1a6 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -13,15 +13,12 @@ namespace Emby.Server.Implementations.AppBase /// <summary> /// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class. /// </summary> - protected BaseApplicationPaths(string programDataPath, string appFolderPath, Action<string> createDirectoryFn) + protected BaseApplicationPaths(string programDataPath, string appFolderPath) { ProgramDataPath = programDataPath; ProgramSystemPath = appFolderPath; - CreateDirectoryFn = createDirectoryFn; } - protected Action<string> CreateDirectoryFn; - public string ProgramDataPath { get; private set; } /// <summary> @@ -45,7 +42,7 @@ namespace Emby.Server.Implementations.AppBase { _dataDirectory = Path.Combine(ProgramDataPath, "data"); - CreateDirectoryFn(_dataDirectory); + Directory.CreateDirectory(_dataDirectory); } return _dataDirectory; @@ -152,7 +149,7 @@ namespace Emby.Server.Implementations.AppBase { _cachePath = Path.Combine(ProgramDataPath, "cache"); - CreateDirectoryFn(_cachePath); + Directory.CreateDirectory(_cachePath); } return _cachePath; diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs new file mode 100644 index 000000000..b3268b156 --- /dev/null +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -0,0 +1,2401 @@ +using Emby.Common.Implementations; +using Emby.Common.Implementations.Serialization; +using Emby.Dlna; +using Emby.Dlna.ConnectionManager; +using Emby.Dlna.ContentDirectory; +using Emby.Dlna.Main; +using Emby.Dlna.MediaReceiverRegistrar; +using Emby.Dlna.Ssdp; +using Emby.Drawing; +using Emby.Photos; +using Emby.Server.Implementations.Activity; +using Emby.Server.Implementations.Channels; +using Emby.Server.Implementations.Collections; +using Emby.Server.Implementations.Configuration; +using Emby.Server.Implementations.Data; +using Emby.Server.Implementations.Devices; +using Emby.Server.Implementations.Dto; +using Emby.Server.Implementations.FFMpeg; +using Emby.Server.Implementations.HttpServer; +using Emby.Server.Implementations.HttpServer.Security; +using Emby.Server.Implementations.IO; +using Emby.Server.Implementations.Library; +using Emby.Server.Implementations.LiveTv; +using Emby.Server.Implementations.Localization; +using Emby.Server.Implementations.MediaEncoder; +using Emby.Server.Implementations.Migrations; +using Emby.Server.Implementations.Notifications; +using Emby.Server.Implementations.Playlists; +using Emby.Server.Implementations.Security; +using Emby.Server.Implementations.Session; +using Emby.Server.Implementations.Social; +using Emby.Server.Implementations.TV; +using Emby.Server.Implementations.Updates; +using MediaBrowser.Api; +using MediaBrowser.Common; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Events; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Common.Plugins; +using MediaBrowser.Common.Progress; +using MediaBrowser.Common.Security; +using MediaBrowser.Common.Updates; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Chapters; +using MediaBrowser.Controller.Collections; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Connect; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Dlna; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Notifications; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Resolvers; +using MediaBrowser.Controller.Security; +using MediaBrowser.Controller.Session; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Controller.Subtitles; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Controller.TV; +using MediaBrowser.LocalMetadata.Savers; +using MediaBrowser.Model.Activity; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Diagnostics; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Net; +using MediaBrowser.Model.News; +using MediaBrowser.Model.Reflection; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Services; +using MediaBrowser.Model.Social; +using MediaBrowser.Model.System; +using MediaBrowser.Model.Text; +using MediaBrowser.Model.Updates; +using MediaBrowser.Model.Xml; +using MediaBrowser.Providers.Chapters; +using MediaBrowser.Providers.Manager; +using MediaBrowser.Providers.Subtitles; +using MediaBrowser.WebDashboard.Api; +using MediaBrowser.XbmcMetadata.Providers; +using OpenSubtitlesHandler; +using ServiceStack; +using SocketHttpListener.Primitives; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Emby.Server.Core.Cryptography; +using Emby.Server.Implementations.Archiving; +using Emby.Server.Implementations.Cryptography; +using Emby.Server.Implementations.Diagnostics; +using Emby.Server.Implementations.Net; +using Emby.Server.Implementations.Reflection; +using Emby.Server.Implementations.ScheduledTasks; +using Emby.Server.Implementations.Serialization; +using Emby.Server.Implementations.Threading; +using Emby.Server.Implementations.Xml; +using Emby.Server.MediaEncoding.Subtitles; +using MediaBrowser.MediaEncoding.BdInfo; +using MediaBrowser.Model.Cryptography; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Threading; +using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions; +using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate; + +namespace Emby.Server.Implementations +{ + /// <summary> + /// Class CompositionRoot + /// </summary> + public abstract class ApplicationHost : IServerApplicationHost, IDependencyContainer + { + /// <summary> + /// Gets a value indicating whether this instance can self restart. + /// </summary> + /// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value> + public abstract bool CanSelfRestart { get; } + + /// <summary> + /// Gets or sets a value indicating whether this instance can self update. + /// </summary> + /// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value> + public virtual bool CanSelfUpdate + { + get + { + return false; + } + } + + /// <summary> + /// Occurs when [has pending restart changed]. + /// </summary> + public event EventHandler HasPendingRestartChanged; + + /// <summary> + /// Occurs when [application updated]. + /// </summary> + public event EventHandler<GenericEventArgs<PackageVersionInfo>> ApplicationUpdated; + + /// <summary> + /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart. + /// </summary> + /// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value> + public bool HasPendingRestart { get; private set; } + + /// <summary> + /// Gets or sets the logger. + /// </summary> + /// <value>The logger.</value> + protected ILogger Logger { get; set; } + + /// <summary> + /// Gets or sets the plugins. + /// </summary> + /// <value>The plugins.</value> + public IPlugin[] Plugins { get; protected set; } + + /// <summary> + /// Gets or sets the log manager. + /// </summary> + /// <value>The log manager.</value> + public ILogManager LogManager { get; protected set; } + + /// <summary> + /// Gets the application paths. + /// </summary> + /// <value>The application paths.</value> + protected ServerApplicationPaths ApplicationPaths { get; set; } + + /// <summary> + /// Gets assemblies that failed to load + /// </summary> + /// <value>The failed assemblies.</value> + public List<string> FailedAssemblies { get; protected set; } + + /// <summary> + /// Gets all concrete types. + /// </summary> + /// <value>All concrete types.</value> + public Type[] AllConcreteTypes { get; protected set; } + + /// <summary> + /// The disposable parts + /// </summary> + protected readonly List<IDisposable> DisposableParts = new List<IDisposable>(); + + /// <summary> + /// Gets a value indicating whether this instance is first run. + /// </summary> + /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value> + public bool IsFirstRun { get; private set; } + + /// <summary> + /// Gets the configuration manager. + /// </summary> + /// <value>The configuration manager.</value> + protected IConfigurationManager ConfigurationManager { get; set; } + + public IFileSystem FileSystemManager { get; set; } + + protected IEnvironmentInfo EnvironmentInfo { get; set; } + + private IBlurayExaminer BlurayExaminer { get; set; } + + public PackageVersionClass SystemUpdateLevel + { + get + { + +#if BETA + return PackageVersionClass.Beta; +#endif + return PackageVersionClass.Release; + } + } + + public virtual string OperatingSystemDisplayName + { + get { return EnvironmentInfo.OperatingSystemName; } + } + + /// <summary> + /// The container + /// </summary> + protected readonly SimpleInjector.Container Container = new SimpleInjector.Container(); + + protected ISystemEvents SystemEvents { get; set; } + protected IMemoryStreamFactory MemoryStreamFactory { get; set; } + + /// <summary> + /// Gets the server configuration manager. + /// </summary> + /// <value>The server configuration manager.</value> + public IServerConfigurationManager ServerConfigurationManager + { + get { return (IServerConfigurationManager)ConfigurationManager; } + } + + /// <summary> + /// Gets the configuration manager. + /// </summary> + /// <returns>IConfigurationManager.</returns> + protected IConfigurationManager GetConfigurationManager() + { + return new ServerConfigurationManager(ApplicationPaths, LogManager, XmlSerializer, FileSystemManager); + } + + /// <summary> + /// Gets or sets the server manager. + /// </summary> + /// <value>The server manager.</value> + private IServerManager ServerManager { get; set; } + /// <summary> + /// Gets or sets the user manager. + /// </summary> + /// <value>The user manager.</value> + public IUserManager UserManager { get; set; } + /// <summary> + /// Gets or sets the library manager. + /// </summary> + /// <value>The library manager.</value> + internal ILibraryManager LibraryManager { get; set; } + /// <summary> + /// Gets or sets the directory watchers. + /// </summary> + /// <value>The directory watchers.</value> + private ILibraryMonitor LibraryMonitor { get; set; } + /// <summary> + /// Gets or sets the provider manager. + /// </summary> + /// <value>The provider manager.</value> + private IProviderManager ProviderManager { get; set; } + /// <summary> + /// Gets or sets the HTTP server. + /// </summary> + /// <value>The HTTP server.</value> + private IHttpServer HttpServer { get; set; } + private IDtoService DtoService { get; set; } + public IImageProcessor ImageProcessor { get; set; } + + /// <summary> + /// Gets or sets the media encoder. + /// </summary> + /// <value>The media encoder.</value> + private IMediaEncoder MediaEncoder { get; set; } + private ISubtitleEncoder SubtitleEncoder { get; set; } + + private IConnectManager ConnectManager { get; set; } + private ISessionManager SessionManager { get; set; } + + private ILiveTvManager LiveTvManager { get; set; } + + public ILocalizationManager LocalizationManager { get; set; } + + private IEncodingManager EncodingManager { get; set; } + private IChannelManager ChannelManager { get; set; } + private ISyncManager SyncManager { get; set; } + + /// <summary> + /// Gets or sets the user data repository. + /// </summary> + /// <value>The user data repository.</value> + private IUserDataManager UserDataManager { get; set; } + private IUserRepository UserRepository { get; set; } + internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; } + internal IItemRepository ItemRepository { get; set; } + private INotificationsRepository NotificationsRepository { get; set; } + + private INotificationManager NotificationManager { get; set; } + private ISubtitleManager SubtitleManager { get; set; } + private IChapterManager ChapterManager { get; set; } + private IDeviceManager DeviceManager { get; set; } + + internal IUserViewManager UserViewManager { get; set; } + + private IAuthenticationRepository AuthenticationRepository { get; set; } + private ITVSeriesManager TVSeriesManager { get; set; } + private ICollectionManager CollectionManager { get; set; } + private IMediaSourceManager MediaSourceManager { get; set; } + private IPlaylistManager PlaylistManager { get; set; } + + /// <summary> + /// Gets or sets the installation manager. + /// </summary> + /// <value>The installation manager.</value> + protected IInstallationManager InstallationManager { get; private set; } + /// <summary> + /// Gets the security manager. + /// </summary> + /// <value>The security manager.</value> + protected ISecurityManager SecurityManager { get; private set; } + + /// <summary> + /// Gets or sets the zip client. + /// </summary> + /// <value>The zip client.</value> + protected IZipClient ZipClient { get; private set; } + + protected IAuthService AuthService { get; private set; } + + protected readonly StartupOptions StartupOptions; + private readonly string _releaseAssetFilename; + + internal IPowerManagement PowerManagement { get; private set; } + internal IImageEncoder ImageEncoder { get; private set; } + + protected IProcessFactory ProcessFactory { get; private set; } + protected ITimerFactory TimerFactory { get; private set; } + protected ICryptoProvider CryptographyProvider = new CryptographyProvider(); + protected readonly IXmlSerializer XmlSerializer; + + protected ISocketFactory SocketFactory { get; private set; } + protected ITaskManager TaskManager { get; private set; } + public IHttpClient HttpClient { get; private set; } + protected INetworkManager NetworkManager { get; set; } + public IJsonSerializer JsonSerializer { get; private set; } + protected IIsoManager IsoManager { get; private set; } + + /// <summary> + /// Initializes a new instance of the <see cref="ApplicationHost" /> class. + /// </summary> + public ApplicationHost(ServerApplicationPaths applicationPaths, + ILogManager logManager, + StartupOptions options, + IFileSystem fileSystem, + IPowerManagement powerManagement, + string releaseAssetFilename, + IEnvironmentInfo environmentInfo, + IImageEncoder imageEncoder, + ISystemEvents systemEvents, + INetworkManager networkManager) + { + // hack alert, until common can target .net core + BaseExtensions.CryptographyProvider = CryptographyProvider; + + XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer")); + + NetworkManager = networkManager; + EnvironmentInfo = environmentInfo; + SystemEvents = systemEvents; + MemoryStreamFactory = new MemoryStreamProvider(); + + FailedAssemblies = new List<string>(); + + ApplicationPaths = applicationPaths; + LogManager = logManager; + FileSystemManager = fileSystem; + + ConfigurationManager = GetConfigurationManager(); + + // Initialize this early in case the -v command line option is used + Logger = LogManager.GetLogger("App"); + + StartupOptions = options; + _releaseAssetFilename = releaseAssetFilename; + PowerManagement = powerManagement; + + ImageEncoder = imageEncoder; + + SetBaseExceptionMessage(); + + fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); + } + + private Version _version; + /// <summary> + /// Gets the current application version + /// </summary> + /// <value>The application version.</value> + public Version ApplicationVersion + { + get + { + return _version ?? (_version = GetAssembly(GetType()).GetName().Version); + } + } + + public virtual bool SupportsRunningAsService + { + get + { + return false; + } + } + + private DeviceId _deviceId; + public string SystemId + { + get + { + if (_deviceId == null) + { + _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager); + } + + return _deviceId.Value; + } + } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name + { + get + { + return "Emby Server"; + } + } + + public virtual bool IsRunningAsService + { + get + { + return false; + } + } + + private Assembly GetAssembly(Type type) + { + return type.GetTypeInfo().Assembly; + } + + public virtual bool SupportsAutoRunAtStartup + { + get + { + return EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows; + } + } + + /// <summary> + /// Creates an instance of type and resolves all constructor dependancies + /// </summary> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + public object CreateInstance(Type type) + { + try + { + return Container.GetInstance(type); + } + catch (Exception ex) + { + Logger.ErrorException("Error creating {0}", ex, type.FullName); + + throw; + } + } + + /// <summary> + /// Creates the instance safe. + /// </summary> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + protected object CreateInstanceSafe(Type type) + { + try + { + return Container.GetInstance(type); + } + catch (Exception ex) + { + Logger.ErrorException("Error creating {0}", ex, type.FullName); + // Don't blow up in release mode + return null; + } + } + + /// <summary> + /// Registers the specified obj. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="obj">The obj.</param> + /// <param name="manageLifetime">if set to <c>true</c> [manage lifetime].</param> + protected void RegisterSingleInstance<T>(T obj, bool manageLifetime = true) + where T : class + { + Container.RegisterSingleton(obj); + + if (manageLifetime) + { + var disposable = obj as IDisposable; + + if (disposable != null) + { + DisposableParts.Add(disposable); + } + } + } + + /// <summary> + /// Registers the single instance. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="func">The func.</param> + protected void RegisterSingleInstance<T>(Func<T> func) + where T : class + { + Container.RegisterSingleton(func); + } + + /// <summary> + /// Resolves this instance. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns>``0.</returns> + public T Resolve<T>() + { + return (T)Container.GetRegistration(typeof(T), true).GetInstance(); + } + + /// <summary> + /// Resolves this instance. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns>``0.</returns> + public T TryResolve<T>() + { + var result = Container.GetRegistration(typeof(T), false); + + if (result == null) + { + return default(T); + } + return (T)result.GetInstance(); + } + + /// <summary> + /// Loads the assembly. + /// </summary> + /// <param name="file">The file.</param> + /// <returns>Assembly.</returns> + 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; + } + } + + /// <summary> + /// Gets the export types. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns>IEnumerable{Type}.</returns> + public IEnumerable<Type> GetExportTypes<T>() + { + var currentType = typeof(T); + + return AllConcreteTypes.Where(currentType.IsAssignableFrom); + } + + /// <summary> + /// Gets the exports. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param> + /// <returns>IEnumerable{``0}.</returns> + public IEnumerable<T> GetExports<T>(bool manageLiftime = true) + { + var parts = GetExportTypes<T>() + .Select(CreateInstanceSafe) + .Where(i => i != null) + .Cast<T>() + .ToList(); + + if (manageLiftime) + { + lock (DisposableParts) + { + DisposableParts.AddRange(parts.OfType<IDisposable>()); + } + } + + return parts; + } + + private void SetBaseExceptionMessage() + { + var builder = GetBaseExceptionMessage(ApplicationPaths); + + builder.Insert(0, string.Format("Version: {0}{1}", ApplicationVersion, Environment.NewLine)); + builder.Insert(0, "*** Error Report ***" + Environment.NewLine); + + LogManager.ExceptionMessagePrefix = builder.ToString(); + } + + /// <summary> + /// Runs the startup tasks. + /// </summary> + public async Task RunStartupTasks() + { + Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false)); + + ConfigureAutorun(); + + ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; + + await MediaEncoder.Init().ConfigureAwait(false); + + if (string.IsNullOrWhiteSpace(MediaEncoder.EncoderPath)) + { + if (ServerConfigurationManager.Configuration.IsStartupWizardCompleted) + { + ServerConfigurationManager.Configuration.IsStartupWizardCompleted = false; + ServerConfigurationManager.SaveConfiguration(); + } + } + + Logger.Info("ServerId: {0}", SystemId); + Logger.Info("Core startup complete"); + HttpServer.GlobalResponse = null; + + Logger.Info("Post-init migrations complete"); + + foreach (var entryPoint in GetExports<IServerEntryPoint>().ToList()) + { + var name = entryPoint.GetType().FullName; + Logger.Info("Starting entry point {0}", name); + var now = DateTime.UtcNow; + try + { + entryPoint.Run(); + } + catch (Exception ex) + { + Logger.ErrorException("Error in {0}", ex, name); + } + Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture), "ImageInfos"); + } + Logger.Info("All entry points have started"); + + LogManager.RemoveConsoleOutput(); + } + + /// <summary> + /// Configures the autorun. + /// </summary> + private void ConfigureAutorun() + { + try + { + ConfigureAutoRunAtStartup(ConfigurationManager.CommonConfiguration.RunAtStartup); + } + catch (Exception ex) + { + Logger.ErrorException("Error configuring autorun", ex); + } + } + + private IJsonSerializer CreateJsonSerializer() + { + try + { + // https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Web.config#L4 + Licensing.RegisterLicense("1001-e1JlZjoxMDAxLE5hbWU6VGVzdCBCdXNpbmVzcyxUeXBlOkJ1c2luZXNzLEhhc2g6UHVNTVRPclhvT2ZIbjQ5MG5LZE1mUTd5RUMzQnBucTFEbTE3TDczVEF4QUNMT1FhNXJMOWkzVjFGL2ZkVTE3Q2pDNENqTkQyUktRWmhvUVBhYTBiekJGUUZ3ZE5aZHFDYm9hL3lydGlwUHI5K1JsaTBYbzNsUC85cjVJNHE5QVhldDN6QkE4aTlvdldrdTgyTk1relY2eis2dFFqTThYN2lmc0JveHgycFdjPSxFeHBpcnk6MjAxMy0wMS0wMX0="); + } + catch + { + // Failing under mono + } + + return new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer")); + } + + public async Task Init(IProgress<double> progress) + { + HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; + HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; + + // Safeguard against invalid configuration + if (HttpPort == HttpsPort) + { + HttpPort = ServerConfiguration.DefaultHttpPort; + HttpsPort = ServerConfiguration.DefaultHttpsPort; + } + + progress.Report(1); + + JsonSerializer = CreateJsonSerializer(); + + 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<double>(); + 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 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); + } + } + + protected abstract IConnectManager CreateConnectManager(); + protected abstract ISyncManager CreateSyncManager(); + + /// <summary> + /// Registers resources that classes will depend on + /// </summary> + protected async Task RegisterResources(IProgress<double> progress) + { + RegisterSingleInstance(ConfigurationManager); + RegisterSingleInstance<IApplicationHost>(this); + + RegisterSingleInstance<IApplicationPaths>(ApplicationPaths); + + RegisterSingleInstance(JsonSerializer); + RegisterSingleInstance(MemoryStreamFactory); + RegisterSingleInstance(SystemEvents); + + RegisterSingleInstance(LogManager, false); + RegisterSingleInstance(Logger); + + RegisterSingleInstance(EnvironmentInfo); + + RegisterSingleInstance(FileSystemManager); + + HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamFactory, GetDefaultUserAgent); + RegisterSingleInstance(HttpClient); + + RegisterSingleInstance(NetworkManager); + + IsoManager = new IsoManager(); + RegisterSingleInstance(IsoManager); + + TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LogManager.GetLogger("TaskManager"), FileSystemManager, SystemEvents); + RegisterSingleInstance(TaskManager); + + RegisterSingleInstance(XmlSerializer); + + ProcessFactory = new ProcessFactory(); + RegisterSingleInstance(ProcessFactory); + + TimerFactory = new TimerFactory(); + RegisterSingleInstance(TimerFactory); + + RegisterSingleInstance(CryptographyProvider); + + SocketFactory = new SocketFactory(LogManager.GetLogger("SocketFactory")); + RegisterSingleInstance(SocketFactory); + + RegisterSingleInstance(PowerManagement); + + SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager, CryptographyProvider); + RegisterSingleInstance(SecurityManager); + + InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime); + RegisterSingleInstance(InstallationManager); + + ZipClient = new ZipClient(FileSystemManager); + RegisterSingleInstance(ZipClient); + + RegisterSingleInstance<IHttpResultFactory>(new HttpResultFactory(LogManager, FileSystemManager, JsonSerializer, MemoryStreamFactory)); + + RegisterSingleInstance<IServerApplicationHost>(this); + RegisterSingleInstance<IServerApplicationPaths>(ApplicationPaths); + + RegisterSingleInstance(ServerConfigurationManager); + + IAssemblyInfo assemblyInfo = new AssemblyInfo(); + RegisterSingleInstance<IAssemblyInfo>(assemblyInfo); + + LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LogManager.GetLogger("LocalizationManager"), assemblyInfo, new TextLocalizer()); + StringExtensions.LocalizationManager = LocalizationManager; + RegisterSingleInstance(LocalizationManager); + + ITextEncoding textEncoding = new TextEncoding.TextEncoding(FileSystemManager, LogManager.GetLogger("TextEncoding"), JsonSerializer); + RegisterSingleInstance(textEncoding); + Utilities.EncodingHelper = textEncoding; + BlurayExaminer = new BdInfoExaminer(FileSystemManager, textEncoding); + RegisterSingleInstance(BlurayExaminer); + + RegisterSingleInstance<IXmlReaderSettingsFactory>(new XmlReaderSettingsFactory()); + + UserDataManager = new UserDataManager(LogManager, ServerConfigurationManager); + RegisterSingleInstance(UserDataManager); + + UserRepository = GetUserRepository(); + // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it + RegisterSingleInstance(UserRepository); + + var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager.GetLogger("SqliteDisplayPreferencesRepository"), JsonSerializer, ApplicationPaths, MemoryStreamFactory); + DisplayPreferencesRepository = displayPreferencesRepo; + RegisterSingleInstance(DisplayPreferencesRepository); + + var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo, TimerFactory); + ItemRepository = itemRepo; + RegisterSingleInstance(ItemRepository); + + AuthenticationRepository = GetAuthenticationRepository(); + RegisterSingleInstance(AuthenticationRepository); + + UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, CryptographyProvider); + RegisterSingleInstance(UserManager); + + LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager); + RegisterSingleInstance(LibraryManager); + + var musicManager = new MusicManager(LibraryManager); + RegisterSingleInstance<IMusicManager>(new MusicManager(LibraryManager)); + + LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory, SystemEvents, EnvironmentInfo); + RegisterSingleInstance(LibraryMonitor); + + ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamFactory); + RegisterSingleInstance(ProviderManager); + + RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager)); + + CertificateInfo = GetCertificateInfo(true); + Certificate = GetCertificate(CertificateInfo); + + HttpServer = HttpServerFactory.CreateServer(this, LogManager, ServerConfigurationManager, NetworkManager, MemoryStreamFactory, "Emby", "web/index.html", textEncoding, SocketFactory, CryptographyProvider, JsonSerializer, XmlSerializer, EnvironmentInfo, Certificate, FileSystemManager, SupportsDualModeSockets); + HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading"); + RegisterSingleInstance(HttpServer, false); + progress.Report(10); + + ServerManager = new ServerManager.ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager, MemoryStreamFactory, textEncoding); + RegisterSingleInstance(ServerManager); + + var innerProgress = new ActionableProgress<double>(); + innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15)); + + ImageProcessor = GetImageProcessor(); + RegisterSingleInstance(ImageProcessor); + + TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager); + RegisterSingleInstance(TVSeriesManager); + + SyncManager = CreateSyncManager(); + RegisterSingleInstance(SyncManager); + + DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager); + RegisterSingleInstance(DtoService); + + var encryptionManager = new EncryptionManager(); + RegisterSingleInstance<IEncryptionManager>(encryptionManager); + + ConnectManager = CreateConnectManager(); + RegisterSingleInstance(ConnectManager); + + DeviceManager = new DeviceManager(new DeviceRepository(ApplicationPaths, JsonSerializer, LogManager.GetLogger("DeviceManager"), FileSystemManager), UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LogManager.GetLogger("DeviceManager"), NetworkManager); + RegisterSingleInstance(DeviceManager); + + var newsService = new Emby.Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer); + RegisterSingleInstance<INewsService>(newsService); + + progress.Report(15); + + ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LogManager.GetLogger("ChannelManager"), ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager); + RegisterSingleInstance(ChannelManager); + + MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer, FileSystemManager, UserDataManager, TimerFactory); + RegisterSingleInstance(MediaSourceManager); + + SessionManager = new SessionManager(UserDataManager, LogManager.GetLogger("SessionManager"), LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager, TimerFactory); + RegisterSingleInstance(SessionManager); + + var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("Dlna"), JsonSerializer, this, assemblyInfo); + RegisterSingleInstance<IDlnaManager>(dlnaManager); + + var connectionManager = new ConnectionManager(dlnaManager, ServerConfigurationManager, LogManager.GetLogger("UpnpConnectionManager"), HttpClient, new XmlReaderSettingsFactory()); + RegisterSingleInstance<IConnectionManager>(connectionManager); + + CollectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("CollectionManager"), ProviderManager); + RegisterSingleInstance(CollectionManager); + + PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("PlaylistManager"), UserManager, ProviderManager); + RegisterSingleInstance<IPlaylistManager>(PlaylistManager); + + LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager, FileSystemManager, SecurityManager); + RegisterSingleInstance(LiveTvManager); + + UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); + RegisterSingleInstance(UserViewManager); + + var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager, () => MediaEncoder, new XmlReaderSettingsFactory(), TVSeriesManager); + RegisterSingleInstance<IContentDirectory>(contentDirectory); + + var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager, new XmlReaderSettingsFactory()); + RegisterSingleInstance<IMediaReceiverRegistrar>(mediaRegistrar); + + NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager); + RegisterSingleInstance(NotificationManager); + + SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor, LibraryManager, MediaSourceManager); + RegisterSingleInstance(SubtitleManager); + + RegisterSingleInstance<IDeviceDiscovery>(new DeviceDiscovery(LogManager.GetLogger("IDeviceDiscovery"), ServerConfigurationManager, SocketFactory, TimerFactory)); + + ChapterManager = new ChapterManager(LibraryManager, LogManager.GetLogger("ChapterManager"), ServerConfigurationManager, ItemRepository); + RegisterSingleInstance(ChapterManager); + + await RegisterMediaEncoder(innerProgress).ConfigureAwait(false); + progress.Report(90); + + EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager, LibraryManager); + RegisterSingleInstance(EncodingManager); + + var sharingRepo = new SharingRepository(LogManager.GetLogger("SharingRepository"), ApplicationPaths); + sharingRepo.Initialize(); + // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it + RegisterSingleInstance<ISharingRepository>(sharingRepo); + RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); + + var activityLogRepo = GetActivityLogRepository(); + RegisterSingleInstance(activityLogRepo); + RegisterSingleInstance<IActivityManager>(new ActivityManager(LogManager.GetLogger("ActivityManager"), activityLogRepo, UserManager)); + + var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager); + RegisterSingleInstance<IAuthorizationContext>(authContext); + RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager)); + + AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager); + RegisterSingleInstance<IAuthService>(AuthService); + + SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, MemoryStreamFactory, ProcessFactory, textEncoding); + RegisterSingleInstance(SubtitleEncoder); + + displayPreferencesRepo.Initialize(); + + var userDataRepo = new SqliteUserDataRepository(LogManager.GetLogger("SqliteUserDataRepository"), ApplicationPaths, FileSystemManager); + + ((UserDataManager)UserDataManager).Repository = userDataRepo; + itemRepo.Initialize(userDataRepo); + ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; + ConfigureNotificationsRepository(); + progress.Report(100); + + SetStaticProperties(); + + ((UserManager)UserManager).Initialize(); + } + + protected virtual string PackageRuntime + { + get + { + return "netframework"; + } + } + + 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("64-Bit OS: {0}", Environment.Is64BitOperatingSystem)); + builder.AppendLine(string.Format("64-Bit Process: {0}", Environment.Is64BitProcess)); + builder.AppendLine(string.Format("User Interactive: {0}", Environment.UserInteractive)); + + 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("Processor count: {0}", Environment.ProcessorCount)); + builder.AppendLine(string.Format("Program data path: {0}", appPaths.ProgramDataPath)); + builder.AppendLine(string.Format("Application directory: {0}", appPaths.ProgramSystemPath)); + + return builder; + } + + 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); + } + } + + /// <summary> + /// Installs the iso mounters. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + private async Task InstallIsoMounters(CancellationToken cancellationToken) + { + var list = new List<IIsoMounter>(); + + foreach (var isoMounter in GetExports<IIsoMounter>()) + { + 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); + } + + private string GetDefaultUserAgent() + { + var name = FormatAttribute(Name); + + return name + "/" + ApplicationVersion; + } + + private string FormatAttribute(string str) + { + var arr = str.ToCharArray(); + + arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c) + || char.IsWhiteSpace(c)))); + + var result = new string(arr); + + if (string.IsNullOrWhiteSpace(result)) + { + result = "Emby"; + } + + return result; + } + + protected virtual bool SupportsDualModeSockets + { + get + { + return true; + } + } + + private X509Certificate GetCertificate(CertificateInfo info) + { + var certificateLocation = info == null ? null : info.Path; + + if (string.IsNullOrWhiteSpace(certificateLocation)) + { + return null; + } + + try + { + if (!FileSystemManager.FileExists(certificateLocation)) + { + return null; + } + + // Don't use an empty string password + var password = string.IsNullOrWhiteSpace(info.Password) ? null : info.Password; + + X509Certificate2 localCert = new X509Certificate2(certificateLocation, password); + //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA; + if (!localCert.HasPrivateKey) + { + //throw new FileNotFoundException("Secure requested, no private key included", certificateLocation); + return null; + } + + return localCert; + } + catch (Exception ex) + { + Logger.ErrorException("Error loading cert from {0}", ex, certificateLocation); + return null; + } + } + + private IImageProcessor GetImageProcessor() + { + return new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, ImageEncoder, () => LibraryManager, TimerFactory, () => MediaEncoder); + } + + protected virtual FFMpegInstallInfo GetFfmpegInstallInfo() + { + var info = new FFMpegInstallInfo(); + + // Windows builds: http://ffmpeg.zeranoe.com/builds/ + // Linux builds: http://johnvansickle.com/ffmpeg/ + // OS X builds: http://ffmpegmac.net/ + // OS X x64: http://www.evermeet.cx/ffmpeg/ + + if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Linux) + { + info.FFMpegFilename = "ffmpeg"; + info.FFProbeFilename = "ffprobe"; + info.ArchiveType = "7z"; + info.Version = "20170308"; + info.DownloadUrls = GetLinuxDownloadUrls(); + } + else if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + { + info.FFMpegFilename = "ffmpeg.exe"; + info.FFProbeFilename = "ffprobe.exe"; + info.Version = "20170308"; + info.ArchiveType = "7z"; + info.DownloadUrls = GetWindowsDownloadUrls(); + } + else if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX) + { + info.FFMpegFilename = "ffmpeg"; + info.FFProbeFilename = "ffprobe"; + info.ArchiveType = "7z"; + info.Version = "20170308"; + info.DownloadUrls = GetMacDownloadUrls(); + } + else + { + // No version available - user requirement + info.DownloadUrls = new string[] { }; + } + + return info; + } + + private string[] GetMacDownloadUrls() + { + switch (EnvironmentInfo.SystemArchitecture) + { + case MediaBrowser.Model.System.Architecture.X64: + return new[] + { + "https://embydata.com/downloads/ffmpeg/osx/ffmpeg-x64-20170308.7z" + }; + } + + return new string[] { }; + } + + private string[] GetWindowsDownloadUrls() + { + switch (EnvironmentInfo.SystemArchitecture) + { + case MediaBrowser.Model.System.Architecture.X64: + return new[] + { + "https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win64.7z" + }; + case MediaBrowser.Model.System.Architecture.X86: + return new[] + { + "https://embydata.com/downloads/ffmpeg/windows/ffmpeg-20170308-win32.7z" + }; + } + + return new string[] { }; + } + + private string[] GetLinuxDownloadUrls() + { + switch (EnvironmentInfo.SystemArchitecture) + { + case MediaBrowser.Model.System.Architecture.X64: + return new[] + { + "https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-64bit-static.7z" + }; + case MediaBrowser.Model.System.Architecture.X86: + return new[] + { + "https://embydata.com/downloads/ffmpeg/linux/ffmpeg-git-20170301-32bit-static.7z" + }; + } + + return new string[] { }; + } + + /// <summary> + /// Registers the media encoder. + /// </summary> + /// <returns>Task.</returns> + private async Task RegisterMediaEncoder(IProgress<double> progress) + { + string encoderPath = null; + string probePath = null; + + var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, GetFfmpegInstallInfo()) + .GetFFMpegInfo(StartupOptions, progress).ConfigureAwait(false); + + encoderPath = info.EncoderPath; + probePath = info.ProbePath; + var hasExternalEncoder = string.Equals(info.Version, "external", StringComparison.OrdinalIgnoreCase); + + var mediaEncoder = new MediaEncoding.Encoder.MediaEncoder(LogManager.GetLogger("MediaEncoder"), + JsonSerializer, + encoderPath, + probePath, + hasExternalEncoder, + ServerConfigurationManager, + FileSystemManager, + LiveTvManager, + IsoManager, + LibraryManager, + ChannelManager, + SessionManager, + () => SubtitleEncoder, + () => MediaSourceManager, + HttpClient, + ZipClient, + MemoryStreamFactory, + ProcessFactory, + (Environment.ProcessorCount > 2 ? 14000 : 40000), + EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows, + EnvironmentInfo, + BlurayExaminer); + + MediaEncoder = mediaEncoder; + RegisterSingleInstance(MediaEncoder); + } + + /// <summary> + /// Gets the user repository. + /// </summary> + /// <returns>Task{IUserRepository}.</returns> + private IUserRepository GetUserRepository() + { + var repo = new SqliteUserRepository(LogManager.GetLogger("SqliteUserRepository"), ApplicationPaths, JsonSerializer, MemoryStreamFactory); + + repo.Initialize(); + + return repo; + } + + private IAuthenticationRepository GetAuthenticationRepository() + { + var repo = new AuthenticationRepository(LogManager.GetLogger("AuthenticationRepository"), ServerConfigurationManager.ApplicationPaths); + + repo.Initialize(); + + return repo; + } + + private IActivityRepository GetActivityLogRepository() + { + var repo = new ActivityRepository(LogManager.GetLogger("ActivityRepository"), ServerConfigurationManager.ApplicationPaths); + + repo.Initialize(); + + return repo; + } + + /// <summary> + /// Configures the repositories. + /// </summary> + private void ConfigureNotificationsRepository() + { + var repo = new SqliteNotificationsRepository(LogManager.GetLogger("SqliteNotificationsRepository"), ServerConfigurationManager.ApplicationPaths, FileSystemManager); + + repo.Initialize(); + + NotificationsRepository = repo; + + RegisterSingleInstance(NotificationsRepository); + } + + /// <summary> + /// Dirty hacks + /// </summary> + private void SetStaticProperties() + { + // For now there's no real way to inject these properly + BaseItem.Logger = LogManager.GetLogger("BaseItem"); + BaseItem.ConfigurationManager = ServerConfigurationManager; + BaseItem.LibraryManager = LibraryManager; + BaseItem.ProviderManager = ProviderManager; + BaseItem.LocalizationManager = LocalizationManager; + BaseItem.ItemRepository = ItemRepository; + User.XmlSerializer = XmlSerializer; + User.UserManager = UserManager; + Folder.UserManager = UserManager; + BaseItem.FileSystem = FileSystemManager; + BaseItem.UserDataManager = UserDataManager; + BaseItem.ChannelManager = ChannelManager; + BaseItem.LiveTvManager = LiveTvManager; + Folder.UserViewManager = UserViewManager; + UserView.TVSeriesManager = TVSeriesManager; + UserView.PlaylistManager = PlaylistManager; + BaseItem.CollectionManager = CollectionManager; + BaseItem.MediaSourceManager = MediaSourceManager; + CollectionFolder.XmlSerializer = XmlSerializer; + Utilities.CryptographyProvider = CryptographyProvider; + AuthenticatedAttribute.AuthService = AuthService; + } + + /// <summary> + /// Finds the parts. + /// </summary> + protected void FindParts() + { + if (!ServerConfigurationManager.Configuration.IsPortAuthorized) + { + RegisterServerWithAdministratorAccess(); + ServerConfigurationManager.Configuration.IsPortAuthorized = true; + ConfigurationManager.SaveConfiguration(); + } + + RegisterModules(); + + ConfigurationManager.AddParts(GetExports<IConfigurationFactory>()); + Plugins = GetExports<IPlugin>().Select(LoadPlugin).Where(i => i != null).ToArray(); + + HttpServer.Init(GetExports<IService>(false)); + + ServerManager.AddWebSocketListeners(GetExports<IWebSocketListener>(false)); + + StartServer(); + + LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(), + GetExports<IVirtualFolderCreator>(), + GetExports<IItemResolver>(), + GetExports<IIntroProvider>(), + GetExports<IBaseItemComparer>(), + GetExports<ILibraryPostScanTask>()); + + ProviderManager.AddParts(GetExports<IImageProvider>(), + GetExports<IMetadataService>(), + GetExports<IMetadataProvider>(), + GetExports<IMetadataSaver>(), + GetExports<IExternalId>()); + + ImageProcessor.AddParts(GetExports<IImageEnhancer>()); + + LiveTvManager.AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>()); + + SubtitleManager.AddParts(GetExports<ISubtitleProvider>()); + + SessionManager.AddParts(GetExports<ISessionControllerFactory>()); + + ChannelManager.AddParts(GetExports<IChannel>()); + + MediaSourceManager.AddParts(GetExports<IMediaSourceProvider>()); + + NotificationManager.AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>()); + SyncManager.AddParts(GetExports<ISyncProvider>()); + } + + private IPlugin LoadPlugin(IPlugin plugin) + { + try + { + var assemblyPlugin = plugin as IPluginAssembly; + + if (assemblyPlugin != null) + { + var assembly = plugin.GetType().Assembly; + var assemblyName = assembly.GetName(); + + var assemblyFileName = assemblyName.Name + ".dll"; + var assemblyFilePath = Path.Combine(ApplicationPaths.PluginsPath, assemblyFileName); + + assemblyPlugin.SetAttributes(assemblyFilePath, assemblyFileName, assemblyName.Version); + + try + { + var idAttributes = assembly.GetCustomAttributes(typeof(GuidAttribute), true); + if (idAttributes.Length > 0) + { + var attribute = (GuidAttribute)idAttributes[0]; + var assemblyId = new Guid(attribute.Value); + + assemblyPlugin.SetId(assemblyId); + } + } + catch (Exception ex) + { + Logger.ErrorException("Error getting plugin Id from {0}.", ex, plugin.GetType().FullName); + } + } + + 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; + } + + /// <summary> + /// Discovers the types. + /// </summary> + 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(); + } + + /// <summary> + /// 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 + /// </summary> + /// <param name="assembly">The assembly.</param> + /// <returns>IEnumerable{Type}.</returns> + /// <exception cref="System.ArgumentNullException">assembly</exception> + protected List<Type> GetTypes(Assembly assembly) + { + if (assembly == null) + { + return new List<Type>(); + } + + try + { + // This null checking really shouldn't be needed but adding it due to some + // unhandled exceptions in mono 5.0 that are a little hard to hunt down + var types = assembly.GetTypes() ?? new Type[] { }; + return types.Where(t => t != null).ToList(); + } + catch (ReflectionTypeLoadException ex) + { + if (ex.LoaderExceptions != null) + { + foreach (var loaderException in ex.LoaderExceptions) + { + if (loaderException != null) + { + Logger.Error("LoaderException: " + loaderException.Message); + } + } + } + + // If it fails we can still get a list of the Types it was able to resolve + var types = ex.Types ?? new Type[] { }; + return types.Where(t => t != null).ToList(); + } + catch (Exception ex) + { + Logger.ErrorException("Error loading types from assembly", ex); + + return new List<Type>(); + } + } + + private CertificateInfo CertificateInfo { get; set; } + private X509Certificate Certificate { get; set; } + + private IEnumerable<string> GetUrlPrefixes() + { + var hosts = new List<string>(); + + hosts.Add("+"); + + return hosts.SelectMany(i => + { + var prefixes = new List<string> + { + "http://"+i+":" + HttpPort + "/" + }; + + if (CertificateInfo != null) + { + prefixes.Add("https://" + i + ":" + HttpsPort + "/"); + } + + return prefixes; + }); + } + + /// <summary> + /// Starts the server. + /// </summary> + private void StartServer() + { + try + { + ServerManager.Start(GetUrlPrefixes().ToArray()); + return; + } + catch (Exception ex) + { + Logger.ErrorException("Error starting http server", ex); + + if (HttpPort == ServerConfiguration.DefaultHttpPort) + { + throw; + } + } + + HttpPort = ServerConfiguration.DefaultHttpPort; + + try + { + ServerManager.Start(GetUrlPrefixes().ToArray()); + } + catch (Exception ex) + { + Logger.ErrorException("Error starting http server", ex); + + throw; + } + } + + private CertificateInfo GetCertificateInfo(bool generateCertificate) + { + if (!string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.CertificatePath)) + { + // Custom cert + return new CertificateInfo + { + Path = ServerConfigurationManager.Configuration.CertificatePath, + Password = ServerConfigurationManager.Configuration.CertificatePassword + }; + } + + // Generate self-signed cert + var certHost = GetHostnameFromExternalDns(ServerConfigurationManager.Configuration.WanDdns); + var certPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.ProgramDataPath, "ssl", "cert_" + (certHost + "2").GetMD5().ToString("N") + ".pfx"); + var password = "embycert"; + + if (generateCertificate) + { + if (!FileSystemManager.FileExists(certPath)) + { + FileSystemManager.CreateDirectory(FileSystemManager.GetDirectoryName(certPath)); + + try + { + CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, password, Logger); + } + catch (Exception ex) + { + Logger.ErrorException("Error creating ssl cert", ex); + return null; + } + } + } + + return new CertificateInfo + { + Path = certPath, + Password = password + }; + } + + /// <summary> + /// Called when [configuration updated]. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> + protected void OnConfigurationUpdated(object sender, EventArgs e) + { + ConfigureAutorun(); + + var requiresRestart = false; + + // Don't do anything if these haven't been set yet + if (HttpPort != 0 && HttpsPort != 0) + { + // Need to restart if ports have changed + if (ServerConfigurationManager.Configuration.HttpServerPortNumber != HttpPort || + ServerConfigurationManager.Configuration.HttpsPortNumber != HttpsPort) + { + if (ServerConfigurationManager.Configuration.IsPortAuthorized) + { + ServerConfigurationManager.Configuration.IsPortAuthorized = false; + ServerConfigurationManager.SaveConfiguration(); + + requiresRestart = true; + } + } + } + + if (!HttpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase)) + { + requiresRestart = true; + } + + var currentCertPath = CertificateInfo == null ? null : CertificateInfo.Path; + var newCertInfo = GetCertificateInfo(false); + var newCertPath = newCertInfo == null ? null : newCertInfo.Path; + + if (!string.Equals(currentCertPath, newCertPath, StringComparison.OrdinalIgnoreCase)) + { + requiresRestart = true; + } + + if (requiresRestart) + { + Logger.Info("App needs to be restarted due to configuration change."); + + NotifyPendingRestart(); + } + } + + /// <summary> + /// Notifies that the kernel that a change has been made that requires a restart + /// </summary> + public void NotifyPendingRestart() + { + Logger.Info("App needs to be restarted."); + + var changed = !HasPendingRestart; + + HasPendingRestart = true; + + if (changed) + { + EventHelper.QueueEventIfNotNull(HasPendingRestartChanged, this, EventArgs.Empty, Logger); + } + } + + /// <summary> + /// Restarts this instance. + /// </summary> + public async Task Restart() + { + if (!CanSelfRestart) + { + throw new PlatformNotSupportedException("The server is unable to self-restart. Please restart manually."); + } + + try + { + await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.ErrorException("Error sending server restart notification", ex); + } + + Logger.Info("Calling RestartInternal"); + + RestartInternal(); + } + + protected abstract void RestartInternal(); + + /// <summary> + /// Gets the composable part assemblies. + /// </summary> + /// <returns>IEnumerable{Assembly}.</returns> + protected IEnumerable<Assembly> GetComposablePartAssemblies() + { + var list = GetPluginAssemblies() + .ToList(); + + // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that + // This will prevent the .dll file from getting locked, and allow us to replace it when needed + + // Include composable parts in the Api assembly + list.Add(GetAssembly(typeof(ApiEntryPoint))); + + // Include composable parts in the Dashboard assembly + list.Add(GetAssembly(typeof(DashboardService))); + + // Include composable parts in the Model assembly + list.Add(GetAssembly(typeof(SystemInfo))); + + // Include composable parts in the Common assembly + list.Add(GetAssembly(typeof(IApplicationHost))); + + // Include composable parts in the Controller assembly + list.Add(GetAssembly(typeof(IServerApplicationHost))); + + // Include composable parts in the Providers assembly + list.Add(GetAssembly(typeof(ProviderUtils))); + + // Include composable parts in the Photos assembly + list.Add(GetAssembly(typeof(PhotoProvider))); + + // Emby.Server implementations + list.Add(GetAssembly(typeof(InstallationManager))); + + // MediaEncoding + list.Add(GetAssembly(typeof(MediaEncoding.Encoder.MediaEncoder))); + + // Dlna + list.Add(GetAssembly(typeof(DlnaEntryPoint))); + + // Local metadata + list.Add(GetAssembly(typeof(BoxSetXmlSaver))); + + // Xbmc + list.Add(GetAssembly(typeof(ArtistNfoProvider))); + + list.AddRange(GetAssembliesWithPartsInternal()); + + return list.ToList(); + } + + protected abstract List<Assembly> GetAssembliesWithPartsInternal(); + + /// <summary> + /// Gets the plugin assemblies. + /// </summary> + /// <returns>IEnumerable{Assembly}.</returns> + private IEnumerable<Assembly> GetPluginAssemblies() + { + try + { + return Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) + .Where(EnablePlugin) + .Select(LoadAssembly) + .Where(a => a != null) + .ToList(); + } + catch (DirectoryNotFoundException) + { + return new List<Assembly>(); + } + } + + private bool EnablePlugin(string path) + { + var filename = Path.GetFileName(path); + + var exclude = new[] + { + "mbplus.dll", + "mbintros.dll", + "embytv.dll" + }; + + return !exclude.Contains(filename ?? string.Empty, StringComparer.OrdinalIgnoreCase); + } + + /// <summary> + /// Gets the system status. + /// </summary> + /// <returns>SystemInfo.</returns> + public async Task<SystemInfo> GetSystemInfo() + { + var localAddress = await GetLocalApiUrl().ConfigureAwait(false); + + return new SystemInfo + { + HasPendingRestart = HasPendingRestart, + Version = ApplicationVersion.ToString(), + WebSocketPortNumber = HttpPort, + FailedPluginAssemblies = FailedAssemblies.ToArray(), + InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToArray(), + CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(), + Id = SystemId, + ProgramDataPath = ApplicationPaths.ProgramDataPath, + LogPath = ApplicationPaths.LogDirectoryPath, + ItemsByNamePath = ApplicationPaths.ItemsByNamePath, + InternalMetadataPath = ApplicationPaths.InternalMetadataPath, + CachePath = ApplicationPaths.CachePath, + MacAddress = GetMacAddress(), + HttpServerPortNumber = HttpPort, + SupportsHttps = SupportsHttps, + HttpsPortNumber = HttpsPort, + OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(), + OperatingSystemDisplayName = OperatingSystemDisplayName, + CanSelfRestart = CanSelfRestart, + CanSelfUpdate = CanSelfUpdate, + WanAddress = ConnectManager.WanApiAddress, + HasUpdateAvailable = HasUpdateAvailable, + SupportsAutoRunAtStartup = SupportsAutoRunAtStartup, + TranscodingTempPath = ApplicationPaths.TranscodingTempPath, + SupportsRunningAsService = SupportsRunningAsService, + ServerName = FriendlyName, + LocalAddress = localAddress, + SupportsLibraryMonitor = true, + EncoderLocationType = MediaEncoder.EncoderLocationType, + SystemArchitecture = EnvironmentInfo.SystemArchitecture, + SystemUpdateLevel = SystemUpdateLevel, + PackageName = StartupOptions.GetOption("-package") + }; + } + + public bool EnableHttps + { + get + { + return SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps; + } + } + + public bool SupportsHttps + { + get { return Certificate != null; } + } + + public async Task<string> GetLocalApiUrl() + { + try + { + // Return the first matched address, if found, or the first known local address + var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); + + if (address != null) + { + return GetLocalApiUrl(address); + } + + return null; + } + catch (Exception ex) + { + Logger.ErrorException("Error getting local Ip address information", ex); + } + + return null; + } + + public string GetLocalApiUrl(IpAddressInfo ipAddress) + { + if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) + { + return GetLocalApiUrl("[" + ipAddress.Address + "]"); + } + + return GetLocalApiUrl(ipAddress.Address); + } + + public string GetLocalApiUrl(string host) + { + return string.Format("http://{0}:{1}", + host, + HttpPort.ToString(CultureInfo.InvariantCulture)); + } + + public async Task<List<IpAddressInfo>> GetLocalIpAddresses() + { + var addresses = ServerConfigurationManager + .Configuration + .LocalNetworkAddresses + .Select(NormalizeConfiguredLocalAddress) + .Where(i => i != null) + .ToList(); + + if (addresses.Count == 0) + { + addresses.AddRange(NetworkManager.GetLocalIpAddresses()); + + var list = new List<IpAddressInfo>(); + + foreach (var address in addresses) + { + var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false); + if (valid) + { + list.Add(address); + } + } + + addresses = list; + } + + return addresses; + } + + private IpAddressInfo NormalizeConfiguredLocalAddress(string address) + { + var index = address.Trim('/').IndexOf('/'); + + if (index != -1) + { + address = address.Substring(index + 1); + } + + IpAddressInfo result; + if (NetworkManager.TryParseIpAddress(address.Trim('/'), out result)) + { + return result; + } + return null; + } + + private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase); + private DateTime _lastAddressCacheClear; + private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address) + { + if (address.Equals(IpAddressInfo.Loopback) || + address.Equals(IpAddressInfo.IPv6Loopback)) + { + return true; + } + + var apiUrl = GetLocalApiUrl(address); + apiUrl += "/system/ping"; + + if ((DateTime.UtcNow - _lastAddressCacheClear).TotalMinutes >= 15) + { + _lastAddressCacheClear = DateTime.UtcNow; + _validAddressResults.Clear(); + } + + bool cachedResult; + if (_validAddressResults.TryGetValue(apiUrl, out cachedResult)) + { + return cachedResult; + } + + try + { + using (var response = await HttpClient.SendAsync(new HttpRequestOptions + { + Url = apiUrl, + LogErrorResponseBody = false, + LogErrors = false, + LogRequest = false, + TimeoutMs = 30000, + BufferContent = false + + }, "POST").ConfigureAwait(false)) + { + using (var reader = new StreamReader(response.Content)) + { + var result = reader.ReadToEnd(); + var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase); + + _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid); + //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid); + return valid; + } + } + } + catch + { + //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); + + _validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false); + return false; + } + } + + public string FriendlyName + { + get + { + return string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.ServerName) + ? Environment.MachineName + : ServerConfigurationManager.Configuration.ServerName; + } + } + + public int HttpPort { get; private set; } + + public int HttpsPort { get; private set; } + + /// <summary> + /// Gets the mac address. + /// </summary> + /// <returns>System.String.</returns> + private string GetMacAddress() + { + try + { + return NetworkManager.GetMacAddress(); + } + catch (Exception ex) + { + Logger.ErrorException("Error getting mac address", ex); + return null; + } + } + + /// <summary> + /// Shuts down. + /// </summary> + public async Task Shutdown() + { + try + { + await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.ErrorException("Error sending server shutdown notification", ex); + } + + ShutdownInternal(); + } + + protected abstract void ShutdownInternal(); + + /// <summary> + /// Registers the server with administrator access. + /// </summary> + private void RegisterServerWithAdministratorAccess() + { + Logger.Info("Requesting administrative access to authorize http server"); + + try + { + AuthorizeServer(); + } + catch (NotImplementedException) + { + + } + catch (Exception ex) + { + Logger.ErrorException("Error authorizing server", ex); + } + } + + protected virtual void AuthorizeServer() + { + throw new NotImplementedException(); + } + + public event EventHandler HasUpdateAvailableChanged; + + private bool _hasUpdateAvailable; + public bool HasUpdateAvailable + { + get { return _hasUpdateAvailable; } + set + { + var fireEvent = value && !_hasUpdateAvailable; + + _hasUpdateAvailable = value; + + if (fireEvent) + { + EventHelper.FireEventIfNotNull(HasUpdateAvailableChanged, this, EventArgs.Empty, Logger); + } + } + } + + /// <summary> + /// Removes the plugin. + /// </summary> + /// <param name="plugin">The plugin.</param> + public void RemovePlugin(IPlugin plugin) + { + var list = Plugins.ToList(); + list.Remove(plugin); + Plugins = list.ToArray(); + } + + /// <summary> + /// Checks for update. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task{CheckForUpdateResult}.</returns> + public async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress) + { + var cacheLength = TimeSpan.FromHours(1); + var updateLevel = SystemUpdateLevel; + + if (updateLevel != PackageVersionClass.Release) + { + cacheLength = TimeSpan.FromMinutes(5); + } + + var result = await new GithubUpdater(HttpClient, JsonSerializer).CheckForUpdateResult("MediaBrowser", "Emby", ApplicationVersion, updateLevel, _releaseAssetFilename, + "MBServer", "Mbserver.zip", cacheLength, cancellationToken).ConfigureAwait(false); + + HasUpdateAvailable = result.IsUpdateAvailable; + + return result; + } + + /// <summary> + /// Updates the application. + /// </summary> + /// <param name="package">The package that contains the update</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + public async Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress<double> progress) + { + await InstallationManager.InstallPackage(package, false, progress, cancellationToken).ConfigureAwait(false); + + HasUpdateAvailable = false; + + OnApplicationUpdated(package); + } + + /// <summary> + /// Configures the automatic run at startup. + /// </summary> + /// <param name="autorun">if set to <c>true</c> [autorun].</param> + protected void ConfigureAutoRunAtStartup(bool autorun) + { + if (SupportsAutoRunAtStartup) + { + ConfigureAutoRunInternal(autorun); + } + } + + protected virtual void ConfigureAutoRunInternal(bool autorun) + { + throw new NotImplementedException(); + } + + /// <summary> + /// This returns localhost in the case of no external dns, and the hostname if the + /// dns is prefixed with a valid Uri prefix. + /// </summary> + /// <param name="externalDns">The external dns prefix to get the hostname of.</param> + /// <returns>The hostname in <paramref name="externalDns"/></returns> + private static string GetHostnameFromExternalDns(string externalDns) + { + if (string.IsNullOrWhiteSpace(externalDns)) + { + return "localhost"; + } + + try + { + return new Uri(externalDns).Host; + } + catch + { + return externalDns; + } + } + + public void LaunchUrl(string url) + { + if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows && + EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX) + { + throw new NotImplementedException(); + } + + var process = ProcessFactory.Create(new ProcessOptions + { + FileName = url, + //EnableRaisingEvents = true, + UseShellExecute = true, + ErrorDialog = false + }); + + process.Exited += ProcessExited; + + try + { + process.Start(); + } + catch (Exception ex) + { + Console.WriteLine("Error launching url: {0}", url); + Logger.ErrorException("Error launching url: {0}", ex, url); + + throw; + } + } + + private static void ProcessExited(object sender, EventArgs e) + { + ((IProcess)sender).Dispose(); + } + + public virtual void EnableLoopback(string appName) + { + } + + private void RegisterModules() + { + var moduleTypes = GetExportTypes<IDependencyModule>(); + + foreach (var type in moduleTypes) + { + try + { + var instance = Activator.CreateInstance(type) as IDependencyModule; + if (instance != null) + instance.BindDependencies(this); + } + catch (Exception ex) + { + Logger.ErrorException("Error setting up dependency bindings for " + type.Name, ex); + } + } + } + + /// <summary> + /// Called when [application updated]. + /// </summary> + /// <param name="package">The package.</param> + protected void OnApplicationUpdated(PackageVersionInfo package) + { + Logger.Info("Application has been updated to version {0}", package.versionStr); + + EventHelper.FireEventIfNotNull(ApplicationUpdated, this, new GenericEventArgs<PackageVersionInfo> + { + Argument = package + + }, Logger); + + NotifyPendingRestart(); + } + + private bool _disposed; + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + + Dispose(true); + GC.SuppressFinalize(this); + } + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + var type = GetType(); + + LogManager.AddConsoleOutput(); + 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); + } + } + } + } + + void IDependencyContainer.RegisterSingleInstance<T>(T obj, bool manageLifetime) + { + RegisterSingleInstance(obj, manageLifetime); + } + + void IDependencyContainer.RegisterSingleInstance<T>(Func<T> func) + { + RegisterSingleInstance(func); + } + + void IDependencyContainer.Register(Type typeInterface, Type typeImplementation) + { + Container.Register(typeInterface, typeImplementation); + } + } + + internal class CertificateInfo + { + public string Path { get; set; } + public string Password { get; set; } + } +} diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs new file mode 100644 index 000000000..3218d56c6 --- /dev/null +++ b/Emby.Server.Implementations/Archiving/ZipClient.cs @@ -0,0 +1,193 @@ +using System.IO; +using MediaBrowser.Model.IO; +using SharpCompress.Archives.Rar; +using SharpCompress.Archives.SevenZip; +using SharpCompress.Archives.Tar; +using SharpCompress.Readers; +using SharpCompress.Readers.Zip; + +namespace Emby.Server.Implementations.Archiving +{ + /// <summary> + /// Class DotNetZipClient + /// </summary> + public class ZipClient : IZipClient + { + private readonly IFileSystem _fileSystem; + + public ZipClient(IFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + + /// <summary> + /// Extracts all. + /// </summary> + /// <param name="sourceFile">The source file.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles) + { + using (var fileStream = _fileSystem.OpenRead(sourceFile)) + { + ExtractAll(fileStream, targetPath, overwriteExistingFiles); + } + } + + /// <summary> + /// Extracts all. + /// </summary> + /// <param name="source">The source.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var reader = ReaderFactory.Open(source)) + { + var options = new ExtractionOptions(); + options.ExtractFullPath = true; + + if (overwriteExistingFiles) + { + options.Overwrite = true; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + + public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var reader = ZipReader.Open(source)) + { + var options = new ExtractionOptions(); + options.ExtractFullPath = true; + + if (overwriteExistingFiles) + { + options.Overwrite = true; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + + /// <summary> + /// Extracts all from7z. + /// </summary> + /// <param name="sourceFile">The source file.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles) + { + using (var fileStream = _fileSystem.OpenRead(sourceFile)) + { + ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles); + } + } + + /// <summary> + /// Extracts all from7z. + /// </summary> + /// <param name="source">The source.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAllFrom7z(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var archive = SevenZipArchive.Open(source)) + { + using (var reader = archive.ExtractAllEntries()) + { + var options = new ExtractionOptions(); + options.ExtractFullPath = true; + + if (overwriteExistingFiles) + { + options.Overwrite = true; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + } + + + /// <summary> + /// Extracts all from tar. + /// </summary> + /// <param name="sourceFile">The source file.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles) + { + using (var fileStream = _fileSystem.OpenRead(sourceFile)) + { + ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles); + } + } + + /// <summary> + /// Extracts all from tar. + /// </summary> + /// <param name="source">The source.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAllFromTar(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var archive = TarArchive.Open(source)) + { + using (var reader = archive.ExtractAllEntries()) + { + var options = new ExtractionOptions(); + options.ExtractFullPath = true; + + if (overwriteExistingFiles) + { + options.Overwrite = true; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + } + + /// <summary> + /// Extracts all from rar. + /// </summary> + /// <param name="sourceFile">The source file.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAllFromRar(string sourceFile, string targetPath, bool overwriteExistingFiles) + { + using (var fileStream = _fileSystem.OpenRead(sourceFile)) + { + ExtractAllFromRar(fileStream, targetPath, overwriteExistingFiles); + } + } + + /// <summary> + /// Extracts all from rar. + /// </summary> + /// <param name="source">The source.</param> + /// <param name="targetPath">The target path.</param> + /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param> + public void ExtractAllFromRar(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var archive = RarArchive.Open(source)) + { + using (var reader = archive.ExtractAllEntries()) + { + var options = new ExtractionOptions(); + options.ExtractFullPath = true; + + if (overwriteExistingFiles) + { + options.Overwrite = true; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + } + } +} diff --git a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs index f892b1e62..0c363c585 100644 --- a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs +++ b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs @@ -18,12 +18,12 @@ namespace Emby.Server.Implementations.Channels _channelManager = channelManager; } - public IEnumerable<ImageType> GetSupportedImages(IHasImages item) + public IEnumerable<ImageType> GetSupportedImages(IHasMetadata item) { return GetChannel(item).GetSupportedChannelImages(); } - public Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken) + public Task<DynamicImageResponse> GetImage(IHasMetadata item, ImageType type, CancellationToken cancellationToken) { var channel = GetChannel(item); @@ -35,12 +35,12 @@ namespace Emby.Server.Implementations.Channels get { return "Channel Image Provider"; } } - public bool Supports(IHasImages item) + public bool Supports(IHasMetadata item) { return item is Channel; } - private IChannel GetChannel(IHasImages item) + private IChannel GetChannel(IHasMetadata item) { var channel = (Channel)item; diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 2adf6a37c..2f726f8ab 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -159,7 +159,7 @@ namespace Emby.Server.Implementations.Channels all = all.Take(query.Limit.Value).ToList(); } - var returnItems = all.ToArray(); + var returnItems = all.ToArray(all.Count); var result = new QueryResult<Channel> { @@ -182,8 +182,7 @@ namespace Emby.Server.Implementations.Channels { }; - var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false)) - .ToArray(); + var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user); var result = new QueryResult<BaseItemDto> { @@ -429,7 +428,7 @@ namespace Emby.Server.Implementations.Channels if (isNew) { - await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); + _libraryManager.CreateItem(item, cancellationToken); } else if (forceUpdate) { @@ -462,14 +461,14 @@ namespace Emby.Server.Implementations.Channels return _libraryManager.GetItemById(id) as Channel; } - public IEnumerable<ChannelFeatures> GetAllChannelFeatures() + public ChannelFeatures[] GetAllChannelFeatures() { return _libraryManager.GetItemIds(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Channel).Name }, - SortBy = new[] { ItemSortBy.SortName } + OrderBy = new Tuple<string, SortOrder>[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) } - }).Select(i => GetChannelFeatures(i.ToString("N"))); + }).Select(i => GetChannelFeatures(i.ToString("N"))).ToArray(); } public ChannelFeatures GetChannelFeatures(string id) @@ -509,10 +508,10 @@ namespace Emby.Server.Implementations.Channels { CanFilter = !features.MaxPageSize.HasValue, CanSearch = provider is ISearchableChannel, - ContentTypes = features.ContentTypes, - DefaultSortFields = features.DefaultSortFields, + ContentTypes = features.ContentTypes.ToArray(), + DefaultSortFields = features.DefaultSortFields.ToArray(), MaxPageSize = features.MaxPageSize, - MediaTypes = features.MediaTypes, + MediaTypes = features.MediaTypes.ToArray(), SupportsSortOrderToggle = features.SupportsSortOrderToggle, SupportsLatestMedia = supportsLatest, Name = channel.Name, @@ -564,11 +563,10 @@ namespace Emby.Server.Implementations.Channels var dtoOptions = new DtoOptions() { - Fields = query.Fields.ToList() + Fields = query.Fields }; - var returnItems = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false)) - .ToArray(); + var returnItems = _dtoService.GetBaseItemDtos(items, dtoOptions, user); var result = new QueryResult<BaseItemDto> { @@ -676,12 +674,10 @@ namespace Emby.Server.Implementations.Channels internalItems = internalItems.Take(query.Limit.Value).ToArray(); } - var returnItemArray = internalItems.ToArray(); - return new QueryResult<BaseItem> { TotalRecordCount = totalCount, - Items = returnItemArray + Items = internalItems }; } @@ -813,12 +809,10 @@ namespace Emby.Server.Implementations.Channels var internalItems = await Task.WhenAll(itemTasks).ConfigureAwait(false); - var returnItemArray = internalItems.ToArray(); - return new QueryResult<BaseItem> { TotalRecordCount = totalCount, - Items = returnItemArray + Items = internalItems }; } @@ -834,11 +828,10 @@ namespace Emby.Server.Implementations.Channels var dtoOptions = new DtoOptions() { - Fields = query.Fields.ToList() + Fields = query.Fields }; - var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false)) - .ToArray(); + var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user); var result = new QueryResult<BaseItemDto> { @@ -939,14 +932,15 @@ namespace Emby.Server.Implementations.Channels ChannelItemSortField? sortField = null; ChannelItemSortField parsedField; - if (query.SortBy.Length == 1 && - Enum.TryParse(query.SortBy[0], true, out parsedField)) + var sortDescending = false; + + if (query.OrderBy.Length == 1 && + Enum.TryParse(query.OrderBy[0].Item1, true, out parsedField)) { sortField = parsedField; + sortDescending = query.OrderBy[0].Item2 == SortOrder.Descending; } - var sortDescending = query.SortOrder.HasValue && query.SortOrder.Value == SortOrder.Descending; - var itemsResult = await GetChannelItems(channelProvider, user, query.FolderId, @@ -986,11 +980,10 @@ namespace Emby.Server.Implementations.Channels var dtoOptions = new DtoOptions() { - Fields = query.Fields.ToList() + Fields = query.Fields }; - var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false)) - .ToArray(); + var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user); var result = new QueryResult<BaseItemDto> { @@ -1174,7 +1167,7 @@ namespace Emby.Server.Implementations.Channels { items = ApplyFilters(items, query.Filters, user); - items = _libraryManager.Sort(items, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending); + items = _libraryManager.Sort(items, user, query.OrderBy); var all = items.ToList(); var totalCount = totalCountFromProvider ?? all.Count; @@ -1191,7 +1184,7 @@ namespace Emby.Server.Implementations.Channels } } - var returnItemArray = all.ToArray(); + var returnItemArray = all.ToArray(all.Count); RefreshIfNeeded(returnItemArray); return new QueryResult<BaseItem> @@ -1309,7 +1302,7 @@ namespace Emby.Server.Implementations.Channels { item.Name = info.Name; item.Genres = info.Genres; - item.Studios = info.Studios; + item.Studios = info.Studios.ToArray(info.Studios.Count); item.CommunityRating = info.CommunityRating; item.Overview = info.Overview; item.IndexNumber = info.IndexNumber; @@ -1319,7 +1312,7 @@ namespace Emby.Server.Implementations.Channels item.ProviderIds = info.ProviderIds; item.OfficialRating = info.OfficialRating; item.DateCreated = info.DateCreated ?? DateTime.UtcNow; - item.Tags = info.Tags; + item.Tags = info.Tags.ToArray(info.Tags.Count); item.HomePageUrl = info.HomePageUrl; } else if (info.Type == ChannelItemType.Folder && info.FolderType == ChannelFolderType.Container) @@ -1335,13 +1328,13 @@ namespace Emby.Server.Implementations.Channels var hasArtists = item as IHasArtist; if (hasArtists != null) { - hasArtists.Artists = info.Artists; + hasArtists.Artists = info.Artists.ToArray(); } var hasAlbumArtists = item as IHasAlbumArtist; if (hasAlbumArtists != null) { - hasAlbumArtists.AlbumArtists = info.AlbumArtists; + hasAlbumArtists.AlbumArtists = info.AlbumArtists.ToArray(info.AlbumArtists.Count); } var trailer = item as Trailer; @@ -1393,11 +1386,11 @@ namespace Emby.Server.Implementations.Channels if (isNew) { - await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); + _libraryManager.CreateItem(item, cancellationToken); if (info.People != null && info.People.Count > 0) { - await _libraryManager.UpdatePeople(item, info.People ?? new List<PersonInfo>()).ConfigureAwait(false); + _libraryManager.UpdatePeople(item, info.People ?? new List<PersonInfo>()); } } else if (forceUpdate) @@ -1631,6 +1624,7 @@ namespace Emby.Server.Implementations.Channels public void Dispose() { + GC.SuppressFinalize(this); } } }
\ No newline at end of file diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs index 463d276e5..c7378956d 100644 --- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs +++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs @@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.Collections { } - protected override bool Supports(IHasImages item) + protected override bool Supports(IHasMetadata item) { // Right now this is the only way to prevent this image from getting created ahead of internet image providers if (!item.IsLocked) @@ -32,7 +32,7 @@ namespace Emby.Server.Implementations.Collections return base.Supports(item); } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var playlist = (BoxSet)item; @@ -76,7 +76,7 @@ namespace Emby.Server.Implementations.Collections return GetFinalItems(items, 2); } - protected override string CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); } diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index 4e5d344a3..2e884e729 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Collections { @@ -83,15 +84,15 @@ namespace Emby.Server.Implementations.Collections ProviderIds = options.ProviderIds, Shares = options.UserIds.Select(i => new Share { - UserId = i.ToString("N"), + UserId = i, CanEdit = true }).ToList() }; - await parentFolder.AddChild(collection, CancellationToken.None).ConfigureAwait(false); + parentFolder.AddChild(collection, CancellationToken.None); - if (options.ItemIdList.Count > 0) + if (options.ItemIdList.Length > 0) { await AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(_fileSystem) { @@ -148,12 +149,17 @@ namespace Emby.Server.Implementations.Collections return GetCollectionsFolder(string.Empty); } - public Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids) + public Task AddToCollection(Guid collectionId, IEnumerable<string> ids) { return AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(_fileSystem)); } - private async Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids, bool fireEvent, MetadataRefreshOptions refreshOptions) + public Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids) + { + return AddToCollection(collectionId, ids.Select(i => i.ToString("N")), true, new MetadataRefreshOptions(_fileSystem)); + } + + private async Task AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions) { var collection = _libraryManager.GetItemById(collectionId) as BoxSet; @@ -164,11 +170,12 @@ namespace Emby.Server.Implementations.Collections var list = new List<LinkedChild>(); var itemList = new List<BaseItem>(); - var currentLinkedChildren = collection.GetLinkedChildren().ToList(); + var currentLinkedChildrenIds = collection.GetLinkedChildren().Select(i => i.Id).ToList(); - foreach (var itemId in ids) + foreach (var id in ids) { - var item = _libraryManager.GetItemById(itemId); + var guidId = new Guid(id); + var item = _libraryManager.GetItemById(guidId); if (string.IsNullOrWhiteSpace(item.Path)) { @@ -182,7 +189,7 @@ namespace Emby.Server.Implementations.Collections itemList.Add(item); - if (currentLinkedChildren.All(i => i.Id != itemId)) + if (!currentLinkedChildrenIds.Contains(guidId)) { list.Add(LinkedChild.Create(item)); } @@ -190,7 +197,9 @@ namespace Emby.Server.Implementations.Collections if (list.Count > 0) { - collection.LinkedChildren.AddRange(list); + var newList = collection.LinkedChildren.ToList(); + newList.AddRange(list); + collection.LinkedChildren = newList.ToArray(newList.Count); collection.UpdateRatingToContent(); @@ -210,6 +219,11 @@ namespace Emby.Server.Implementations.Collections } } + public Task RemoveFromCollection(Guid collectionId, IEnumerable<string> itemIds) + { + return RemoveFromCollection(collectionId, itemIds.Select(i => new Guid(i))); + } + public async Task RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds) { var collection = _libraryManager.GetItemById(collectionId) as BoxSet; @@ -222,11 +236,11 @@ namespace Emby.Server.Implementations.Collections var list = new List<LinkedChild>(); var itemList = new List<BaseItem>(); - foreach (var itemId in itemIds) + foreach (var guidId in itemIds) { - var childItem = _libraryManager.GetItemById(itemId); + var childItem = _libraryManager.GetItemById(guidId); - var child = collection.LinkedChildren.FirstOrDefault(i => (i.ItemId.HasValue && i.ItemId.Value == itemId) || (childItem != null && string.Equals(childItem.Path, i.Path, StringComparison.OrdinalIgnoreCase))); + var child = collection.LinkedChildren.FirstOrDefault(i => (i.ItemId.HasValue && i.ItemId.Value == guidId) || (childItem != null && string.Equals(childItem.Path, i.Path, StringComparison.OrdinalIgnoreCase))); if (child == null) { @@ -241,9 +255,9 @@ namespace Emby.Server.Implementations.Collections } } - foreach (var child in list) + if (list.Count > 0) { - collection.LinkedChildren.Remove(child); + collection.LinkedChildren = collection.LinkedChildren.Except(list).ToArray(); } collection.UpdateRatingToContent(); diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs index 2241e9377..4d9bf0624 100644 --- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -16,6 +16,7 @@ using MediaBrowser.Model.Events; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Configuration { @@ -216,7 +217,7 @@ namespace Emby.Server.Implementations.Configuration list.Add(service); - options.DisabledMetadataSavers = list.ToArray(); + options.DisabledMetadataSavers = list.ToArray(list.Count); } } @@ -236,7 +237,7 @@ namespace Emby.Server.Implementations.Configuration list.Add(options); - config.MetadataOptions = list.ToArray(); + config.MetadataOptions = list.ToArray(list.Count); } return options; diff --git a/Emby.Server.Implementations/Cryptography/ASN1.cs b/Emby.Server.Implementations/Cryptography/ASN1.cs new file mode 100644 index 000000000..f5c826436 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/ASN1.cs @@ -0,0 +1,340 @@ +// +// ASN1.cs: Abstract Syntax Notation 1 - micro-parser and generator +// +// Authors: +// Sebastien Pouliot <sebastien@ximian.com> +// Jesper Pedersen <jep@itplus.dk> +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// (C) 2004 IT+ A/S (http://www.itplus.dk) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.IO; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + + // References: + // a. ITU ASN.1 standards (free download) + // http://www.itu.int/ITU-T/studygroups/com17/languages/ + + public class ASN1 { + + private byte m_nTag; + private byte[] m_aValue; + private ArrayList elist; + + public ASN1 () : this (0x00, null) {} + + public ASN1 (byte tag) : this (tag, null) {} + + public ASN1 (byte tag, byte[] data) + { + m_nTag = tag; + m_aValue = data; + } + + public ASN1 (byte[] data) + { + m_nTag = data [0]; + + int nLenLength = 0; + int nLength = data [1]; + + if (nLength > 0x80) { + // composed length + nLenLength = nLength - 0x80; + nLength = 0; + for (int i = 0; i < nLenLength; i++) { + nLength *= 256; + nLength += data [i + 2]; + } + } + else if (nLength == 0x80) { + // undefined length encoding + throw new NotSupportedException ("Undefined length encoding."); + } + + m_aValue = new byte [nLength]; + Buffer.BlockCopy (data, (2 + nLenLength), m_aValue, 0, nLength); + + if ((m_nTag & 0x20) == 0x20) { + int nStart = (2 + nLenLength); + Decode (data, ref nStart, data.Length); + } + } + + public int Count { + get { + if (elist == null) + return 0; + return elist.Count; + } + } + + public byte Tag { + get { return m_nTag; } + } + + public int Length { + get { + if (m_aValue != null) + return m_aValue.Length; + else + return 0; + } + } + + public byte[] Value { + get { + if (m_aValue == null) + GetBytes (); + return (byte[]) m_aValue.Clone (); + } + set { + if (value != null) + m_aValue = (byte[]) value.Clone (); + } + } + + private bool CompareArray (byte[] array1, byte[] array2) + { + bool bResult = (array1.Length == array2.Length); + if (bResult) { + for (int i = 0; i < array1.Length; i++) { + if (array1[i] != array2[i]) + return false; + } + } + return bResult; + } + + public bool Equals (byte[] asn1) + { + return CompareArray (this.GetBytes (), asn1); + } + + public bool CompareValue (byte[] value) + { + return CompareArray (m_aValue, value); + } + + public ASN1 Add (ASN1 asn1) + { + if (asn1 != null) { + if (elist == null) + elist = new ArrayList (); + elist.Add (asn1); + } + return asn1; + } + + public virtual byte[] GetBytes () + { + byte[] val = null; + + if (Count > 0) { + int esize = 0; + ArrayList al = new ArrayList (); + foreach (ASN1 a in elist) { + byte[] item = a.GetBytes (); + al.Add (item); + esize += item.Length; + } + val = new byte [esize]; + int pos = 0; + for (int i=0; i < elist.Count; i++) { + byte[] item = (byte[]) al[i]; + Buffer.BlockCopy (item, 0, val, pos, item.Length); + pos += item.Length; + } + } else if (m_aValue != null) { + val = m_aValue; + } + + byte[] der; + int nLengthLen = 0; + + if (val != null) { + int nLength = val.Length; + // special for length > 127 + if (nLength > 127) { + if (nLength <= Byte.MaxValue) { + der = new byte [3 + nLength]; + Buffer.BlockCopy (val, 0, der, 3, nLength); + nLengthLen = 0x81; + der[2] = (byte)(nLength); + } + else if (nLength <= UInt16.MaxValue) { + der = new byte [4 + nLength]; + Buffer.BlockCopy (val, 0, der, 4, nLength); + nLengthLen = 0x82; + der[2] = (byte)(nLength >> 8); + der[3] = (byte)(nLength); + } + else if (nLength <= 0xFFFFFF) { + // 24 bits + der = new byte [5 + nLength]; + Buffer.BlockCopy (val, 0, der, 5, nLength); + nLengthLen = 0x83; + der [2] = (byte)(nLength >> 16); + der [3] = (byte)(nLength >> 8); + der [4] = (byte)(nLength); + } + else { + // max (Length is an integer) 32 bits + der = new byte [6 + nLength]; + Buffer.BlockCopy (val, 0, der, 6, nLength); + nLengthLen = 0x84; + der [2] = (byte)(nLength >> 24); + der [3] = (byte)(nLength >> 16); + der [4] = (byte)(nLength >> 8); + der [5] = (byte)(nLength); + } + } + else { + // basic case (no encoding) + der = new byte [2 + nLength]; + Buffer.BlockCopy (val, 0, der, 2, nLength); + nLengthLen = nLength; + } + if (m_aValue == null) + m_aValue = val; + } + else + der = new byte[2]; + + der[0] = m_nTag; + der[1] = (byte)nLengthLen; + + return der; + } + + // Note: Recursive + protected void Decode (byte[] asn1, ref int anPos, int anLength) + { + byte nTag; + int nLength; + byte[] aValue; + + // minimum is 2 bytes (tag + length of 0) + while (anPos < anLength - 1) { + DecodeTLV (asn1, ref anPos, out nTag, out nLength, out aValue); + // sometimes we get trailing 0 + if (nTag == 0) + continue; + + ASN1 elm = Add (new ASN1 (nTag, aValue)); + + if ((nTag & 0x20) == 0x20) { + int nConstructedPos = anPos; + elm.Decode (asn1, ref nConstructedPos, nConstructedPos + nLength); + } + anPos += nLength; // value length + } + } + + // TLV : Tag - Length - Value + protected void DecodeTLV (byte[] asn1, ref int pos, out byte tag, out int length, out byte[] content) + { + tag = asn1 [pos++]; + length = asn1 [pos++]; + + // special case where L contains the Length of the Length + 0x80 + if ((length & 0x80) == 0x80) { + int nLengthLen = length & 0x7F; + length = 0; + for (int i = 0; i < nLengthLen; i++) + length = length * 256 + asn1 [pos++]; + } + + content = new byte [length]; + Buffer.BlockCopy (asn1, pos, content, 0, length); + } + + public ASN1 this [int index] { + get { + try { + if ((elist == null) || (index >= elist.Count)) + return null; + return (ASN1) elist [index]; + } + catch (ArgumentOutOfRangeException) { + return null; + } + } + } + + public ASN1 Element (int index, byte anTag) + { + try { + if ((elist == null) || (index >= elist.Count)) + return null; + + ASN1 elm = (ASN1) elist [index]; + if (elm.Tag == anTag) + return elm; + else + return null; + } + catch (ArgumentOutOfRangeException) { + return null; + } + } + + public override string ToString() + { + StringBuilder hexLine = new StringBuilder (); + + // Add tag + hexLine.AppendFormat ("Tag: {0} {1}", m_nTag.ToString ("X2"), Environment.NewLine); + + // Add length + hexLine.AppendFormat ("Length: {0} {1}", Value.Length, Environment.NewLine); + + // Add value + hexLine.Append ("Value: "); + hexLine.Append (Environment.NewLine); + for (int i = 0; i < Value.Length; i++) { + hexLine.AppendFormat ("{0} ", Value [i].ToString ("X2")); + if ((i+1) % 16 == 0) + hexLine.AppendFormat (Environment.NewLine); + } + return hexLine.ToString (); + } + + public void SaveToFile (string filename) + { + if (filename == null) + throw new ArgumentNullException ("filename"); + + using (FileStream fs = File.Create (filename)) { + byte[] data = GetBytes (); + fs.Write (data, 0, data.Length); + } + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/ASN1Convert.cs b/Emby.Server.Implementations/Cryptography/ASN1Convert.cs new file mode 100644 index 000000000..851d36dc7 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/ASN1Convert.cs @@ -0,0 +1,207 @@ +// +// ASN1Convert.cs: Abstract Syntax Notation 1 convertion routines +// +// Authors: +// Sebastien Pouliot <sebastien@ximian.com> +// Jesper Pedersen <jep@itplus.dk> +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// (C) 2004 IT+ A/S (http://www.itplus.dk) +// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Globalization; +using System.Security.Cryptography; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + + // References: + // a. ITU ASN.1 standards (free download) + // http://www.itu.int/ITU-T/studygroups/com17/languages/ + + public static class ASN1Convert { + // RFC3280, section 4.2.1.5 + // CAs conforming to this profile MUST always encode certificate + // validity dates through the year 2049 as UTCTime; certificate validity + // dates in 2050 or later MUST be encoded as GeneralizedTime. + + // Under 1.x this API requires a Local datetime to be provided + // Under 2.0 it will also accept a Utc datetime + static public ASN1 FromDateTime (DateTime dt) + { + if (dt.Year < 2050) { + // UTCTIME + return new ASN1 (0x17, Encoding.ASCII.GetBytes ( + dt.ToUniversalTime ().ToString ("yyMMddHHmmss", + CultureInfo.InvariantCulture) + "Z")); + } + else { + // GENERALIZEDTIME + return new ASN1 (0x18, Encoding.ASCII.GetBytes ( + dt.ToUniversalTime ().ToString ("yyyyMMddHHmmss", + CultureInfo.InvariantCulture) + "Z")); + } + } + + static public ASN1 FromInt32 (Int32 value) + { + byte[] integer = BitConverterLE.GetBytes (value); + Array.Reverse (integer); + int x = 0; + while ((x < integer.Length) && (integer [x] == 0x00)) + x++; + ASN1 asn1 = new ASN1 (0x02); + switch (x) { + case 0: + asn1.Value = integer; + break; + case 4: + asn1.Value = new byte [1]; + break; + default: + byte[] smallerInt = new byte [4 - x]; + Buffer.BlockCopy (integer, x, smallerInt, 0, smallerInt.Length); + asn1.Value = smallerInt; + break; + } + return asn1; + } + + static public ASN1 FromOid (string oid) + { + if (oid == null) + throw new ArgumentNullException ("oid"); + + return new ASN1 (CryptoConfig.EncodeOID (oid)); + } + + static public ASN1 FromUnsignedBigInteger (byte[] big) + { + if (big == null) + throw new ArgumentNullException ("big"); + + // check for numbers that could be interpreted as negative (first bit) + if (big [0] >= 0x80) { + // in thie cas we add a new, empty, byte (position 0) so we're + // sure this will always be interpreted an unsigned integer. + // However we can't feed it into RSAParameters or DSAParameters + int length = big.Length + 1; + byte[] uinteger = new byte [length]; + Buffer.BlockCopy (big, 0, uinteger, 1, length - 1); + big = uinteger; + } + return new ASN1 (0x02, big); + } + + static public int ToInt32 (ASN1 asn1) + { + if (asn1 == null) + throw new ArgumentNullException ("asn1"); + if (asn1.Tag != 0x02) + throw new FormatException ("Only integer can be converted"); + + int x = 0; + for (int i=0; i < asn1.Value.Length; i++) + x = (x << 8) + asn1.Value [i]; + return x; + } + + // Convert a binary encoded OID to human readable string representation of + // an OID (IETF style). Based on DUMPASN1.C from Peter Gutmann. + static public string ToOid (ASN1 asn1) + { + if (asn1 == null) + throw new ArgumentNullException ("asn1"); + + byte[] aOID = asn1.Value; + StringBuilder sb = new StringBuilder (); + // Pick apart the OID + byte x = (byte) (aOID[0] / 40); + byte y = (byte) (aOID[0] % 40); + if (x > 2) { + // Handle special case for large y if x = 2 + y += (byte) ((x - 2) * 40); + x = 2; + } + sb.Append (x.ToString (CultureInfo.InvariantCulture)); + sb.Append ("."); + sb.Append (y.ToString (CultureInfo.InvariantCulture)); + ulong val = 0; + for (x = 1; x < aOID.Length; x++) { + val = ((val << 7) | ((byte) (aOID [x] & 0x7F))); + if ( !((aOID [x] & 0x80) == 0x80)) { + sb.Append ("."); + sb.Append (val.ToString (CultureInfo.InvariantCulture)); + val = 0; + } + } + return sb.ToString (); + } + + static public DateTime ToDateTime (ASN1 time) + { + if (time == null) + throw new ArgumentNullException ("time"); + + string t = Encoding.ASCII.GetString (time.Value); + // to support both UTCTime and GeneralizedTime (and not so common format) + string mask = null; + int year; + switch (t.Length) { + case 11: + // illegal format, still it's supported for compatibility + mask = "yyMMddHHmmZ"; + break; + case 13: + // RFC3280: 4.1.2.5.1 UTCTime + year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture); + // Where YY is greater than or equal to 50, the + // year SHALL be interpreted as 19YY; and + // Where YY is less than 50, the year SHALL be + // interpreted as 20YY. + if (year >= 50) + t = "19" + t; + else + t = "20" + t; + mask = "yyyyMMddHHmmssZ"; + break; + case 15: + mask = "yyyyMMddHHmmssZ"; // GeneralizedTime + break; + case 17: + // another illegal format (990630000000+1000), again supported for compatibility + year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture); + string century = (year >= 50) ? "19" : "20"; + // ASN.1 (see ITU X.680 section 43.3) deals with offset differently than .NET + char sign = (t[12] == '+') ? '-' : '+'; + t = String.Format ("{0}{1}{2}{3}{4}:{5}{6}", century, t.Substring (0, 12), sign, + t[13], t[14], t[15], t[16]); + mask = "yyyyMMddHHmmsszzz"; + break; + } + return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/BitConverterLE.cs b/Emby.Server.Implementations/Cryptography/BitConverterLE.cs new file mode 100644 index 000000000..34e6bf6dc --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/BitConverterLE.cs @@ -0,0 +1,239 @@ +// +// Mono.Security.BitConverterLE.cs +// Like System.BitConverter but always little endian +// +// Author: +// Bernie Solomon +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Emby.Server.Core.Cryptography +{ + internal sealed class BitConverterLE + { + private BitConverterLE () + { + } + + unsafe private static byte[] GetUShortBytes (byte *bytes) + { + if (BitConverter.IsLittleEndian) + return new byte [] { bytes [0], bytes [1] }; + else + return new byte [] { bytes [1], bytes [0] }; + } + + unsafe private static byte[] GetUIntBytes (byte *bytes) + { + if (BitConverter.IsLittleEndian) + return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3] }; + else + return new byte [] { bytes [3], bytes [2], bytes [1], bytes [0] }; + } + + unsafe private static byte[] GetULongBytes (byte *bytes) + { + if (BitConverter.IsLittleEndian) + return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3], + bytes [4], bytes [5], bytes [6], bytes [7] }; + else + return new byte [] { bytes [7], bytes [6], bytes [5], bytes [4], + bytes [3], bytes [2], bytes [1], bytes [0] }; + } + + unsafe internal static byte[] GetBytes (bool value) + { + return new byte [] { value ? (byte)1 : (byte)0 }; + } + + unsafe internal static byte[] GetBytes (char value) + { + return GetUShortBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (short value) + { + return GetUShortBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (int value) + { + return GetUIntBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (long value) + { + return GetULongBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (ushort value) + { + return GetUShortBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (uint value) + { + return GetUIntBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (ulong value) + { + return GetULongBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (float value) + { + return GetUIntBytes ((byte *) &value); + } + + unsafe internal static byte[] GetBytes (double value) + { + return GetULongBytes ((byte *) &value); + } + + unsafe private static void UShortFromBytes (byte *dst, byte[] src, int startIndex) + { + if (BitConverter.IsLittleEndian) { + dst [0] = src [startIndex]; + dst [1] = src [startIndex + 1]; + } else { + dst [0] = src [startIndex + 1]; + dst [1] = src [startIndex]; + } + } + + unsafe private static void UIntFromBytes (byte *dst, byte[] src, int startIndex) + { + if (BitConverter.IsLittleEndian) { + dst [0] = src [startIndex]; + dst [1] = src [startIndex + 1]; + dst [2] = src [startIndex + 2]; + dst [3] = src [startIndex + 3]; + } else { + dst [0] = src [startIndex + 3]; + dst [1] = src [startIndex + 2]; + dst [2] = src [startIndex + 1]; + dst [3] = src [startIndex]; + } + } + + unsafe private static void ULongFromBytes (byte *dst, byte[] src, int startIndex) + { + if (BitConverter.IsLittleEndian) { + for (int i = 0; i < 8; ++i) + dst [i] = src [startIndex + i]; + } else { + for (int i = 0; i < 8; ++i) + dst [i] = src [startIndex + (7 - i)]; + } + } + + unsafe internal static bool ToBoolean (byte[] value, int startIndex) + { + return value [startIndex] != 0; + } + + unsafe internal static char ToChar (byte[] value, int startIndex) + { + char ret; + + UShortFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static short ToInt16 (byte[] value, int startIndex) + { + short ret; + + UShortFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static int ToInt32 (byte[] value, int startIndex) + { + int ret; + + UIntFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static long ToInt64 (byte[] value, int startIndex) + { + long ret; + + ULongFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static ushort ToUInt16 (byte[] value, int startIndex) + { + ushort ret; + + UShortFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static uint ToUInt32 (byte[] value, int startIndex) + { + uint ret; + + UIntFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static ulong ToUInt64 (byte[] value, int startIndex) + { + ulong ret; + + ULongFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static float ToSingle (byte[] value, int startIndex) + { + float ret; + + UIntFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + + unsafe internal static double ToDouble (byte[] value, int startIndex) + { + double ret; + + ULongFromBytes ((byte *) &ret, value, startIndex); + + return ret; + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/CertificateGenerator.cs b/Emby.Server.Implementations/Cryptography/CertificateGenerator.cs new file mode 100644 index 000000000..b4c84a600 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/CertificateGenerator.cs @@ -0,0 +1,109 @@ +using MediaBrowser.Model.Logging; +using System; +using System.Collections; +using System.Security.Cryptography; +using System.Xml; + +namespace Emby.Server.Core.Cryptography +{ + public class CertificateGenerator + { + private const string MonoTestRootAgency = "<RSAKeyValue><Modulus>v/4nALBxCE+9JgEC0LnDUvKh6e96PwTpN4Rj+vWnqKT7IAp1iK/JjuqvAg6DQ2vTfv0dTlqffmHH51OyioprcT5nzxcSTsZb/9jcHScG0s3/FRIWnXeLk/fgm7mSYhjUaHNI0m1/NTTktipicjKxo71hGIg9qucCWnDum+Krh/k=</Modulus><Exponent>AQAB</Exponent><P>9jbKxMXEruW2CfZrzhxtull4O8P47+mNsEL+9gf9QsRO1jJ77C+jmzfU6zbzjf8+ViK+q62tCMdC1ZzulwdpXQ==</P><Q>x5+p198l1PkK0Ga2mRh0SIYSykENpY2aLXoyZD/iUpKYAvATm0/wvKNrE4dKJyPCA+y3hfTdgVag+SP9avvDTQ==</Q><DP>ISSjCvXsUfbOGG05eddN1gXxL2pj+jegQRfjpk7RAsnWKvNExzhqd5x+ZuNQyc6QH5wxun54inP4RTUI0P/IaQ==</DP><DQ>R815VQmR3RIbPqzDXzv5j6CSH6fYlcTiQRtkBsUnzhWmkd/y3XmamO+a8zJFjOCCx9CcjpVuGziivBqi65lVPQ==</DQ><InverseQ>iYiu0KwMWI/dyqN3RJYUzuuLj02/oTD1pYpwo2rvNCXU1Q5VscOeu2DpNg1gWqI+1RrRCsEoaTNzXB1xtKNlSw==</InverseQ><D>nIfh1LYF8fjRBgMdAH/zt9UKHWiaCnc+jXzq5tkR8HVSKTVdzitD8bl1JgAfFQD8VjSXiCJqluexy/B5SGrCXQ49c78NIQj0hD+J13Y8/E0fUbW1QYbhj6Ff7oHyhaYe1WOQfkp2t/h+llHOdt1HRf7bt7dUknYp7m8bQKGxoYE=</D></RSAKeyValue>"; + + public static void CreateSelfSignCertificatePfx( + string fileName, + string hostname, + string password, + ILogger logger) + { + if (string.IsNullOrWhiteSpace(fileName)) + { + throw new ArgumentNullException("fileName"); + } + + byte[] sn = Guid.NewGuid().ToByteArray(); + string subject = string.Format("CN={0}", hostname); + string issuer = subject; + DateTime notBefore = DateTime.Now.AddDays(-2); + DateTime notAfter = DateTime.Now.AddYears(10); + + RSA issuerKey = RSA.Create(); +#if NET46 + issuerKey.FromXmlString(MonoTestRootAgency); +#else + RSACryptoServiceProviderExtensions.FromXmlString(issuerKey, MonoTestRootAgency); +#endif + RSA subjectKey = RSA.Create(); + + // serial number MUST be positive + if ((sn[0] & 0x80) == 0x80) + sn[0] -= 0x80; + + issuer = subject; + issuerKey = subjectKey; + + X509CertificateBuilder cb = new X509CertificateBuilder(3); + cb.SerialNumber = sn; + cb.IssuerName = issuer; + cb.NotBefore = notBefore; + cb.NotAfter = notAfter; + cb.SubjectName = subject; + cb.SubjectPublicKey = subjectKey; + + // signature + cb.Hash = "SHA256"; + byte[] rawcert = cb.Sign(issuerKey); + + PKCS12 p12 = new PKCS12(); + + + ArrayList list = new ArrayList(); + // we use a fixed array to avoid endianess issues + // (in case some tools requires the ID to be 1). + list.Add(new byte[4] { 1, 0, 0, 0 }); + Hashtable attributes = new Hashtable(1); + attributes.Add(PKCS9.localKeyId, list); + + p12.AddCertificate(new X509Certificate(rawcert), attributes); + p12.Password = password; + + p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes); + p12.SaveToFile(fileName); + } + } + + public static class RSACryptoServiceProviderExtensions + { + public static void FromXmlString(RSA rsa, string xmlString) + { + RSAParameters parameters = new RSAParameters(); + + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(xmlString); + + if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue")) + { + foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes) + { + switch (node.Name) + { + case "Modulus": parameters.Modulus = Convert.FromBase64String(node.InnerText); break; + case "Exponent": parameters.Exponent = Convert.FromBase64String(node.InnerText); break; + case "P": parameters.P = Convert.FromBase64String(node.InnerText); break; + case "Q": parameters.Q = Convert.FromBase64String(node.InnerText); break; + case "DP": parameters.DP = Convert.FromBase64String(node.InnerText); break; + case "DQ": parameters.DQ = Convert.FromBase64String(node.InnerText); break; + case "InverseQ": parameters.InverseQ = Convert.FromBase64String(node.InnerText); break; + case "D": parameters.D = Convert.FromBase64String(node.InnerText); break; + } + } + } + else + { + throw new Exception("Invalid XML RSA key."); + } + + rsa.ImportParameters(parameters); + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/CryptoConvert.cs b/Emby.Server.Implementations/Cryptography/CryptoConvert.cs new file mode 100644 index 000000000..70a91bfff --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/CryptoConvert.cs @@ -0,0 +1,745 @@ +// +// CryptoConvert.cs - Crypto Convertion Routines +// +// Author: +// Sebastien Pouliot <sebastien@ximian.com> +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Globalization; +using System.Security.Cryptography; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + + public sealed class CryptoConvert { + + private CryptoConvert () + { + } + + static private int ToInt32LE (byte [] bytes, int offset) + { + return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]; + } + + static private uint ToUInt32LE (byte [] bytes, int offset) + { + return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]); + } + + static private byte [] GetBytesLE (int val) + { + return new byte [] { + (byte) (val & 0xff), + (byte) ((val >> 8) & 0xff), + (byte) ((val >> 16) & 0xff), + (byte) ((val >> 24) & 0xff) + }; + } + + static private byte[] Trim (byte[] array) + { + for (int i=0; i < array.Length; i++) { + if (array [i] != 0x00) { + byte[] result = new byte [array.Length - i]; + Buffer.BlockCopy (array, i, result, 0, result.Length); + return result; + } + } + return null; + } + + // convert the key from PRIVATEKEYBLOB to RSA + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp + // e.g. SNK files, PVK files + static public RSA FromCapiPrivateKeyBlob (byte[] blob) + { + return FromCapiPrivateKeyBlob (blob, 0); + } + + static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + RSAParameters rsap = new RSAParameters (); + try { + if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) + (blob [offset+1] != 0x02) || // Version (0x02) + (blob [offset+2] != 0x00) || // Reserved (word) + (blob [offset+3] != 0x00) || + (ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2 + throw new CryptographicException ("Invalid blob header"); + + // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) + // int algId = ToInt32LE (blob, offset+4); + + // DWORD bitlen + int bitLen = ToInt32LE (blob, offset+12); + + // DWORD public exponent + byte[] exp = new byte [4]; + Buffer.BlockCopy (blob, offset+16, exp, 0, 4); + Array.Reverse (exp); + rsap.Exponent = Trim (exp); + + int pos = offset+20; + // BYTE modulus[rsapubkey.bitlen/8]; + int byteLen = (bitLen >> 3); + rsap.Modulus = new byte [byteLen]; + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); + Array.Reverse (rsap.Modulus); + pos += byteLen; + + // BYTE prime1[rsapubkey.bitlen/16]; + int byteHalfLen = (byteLen >> 1); + rsap.P = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen); + Array.Reverse (rsap.P); + pos += byteHalfLen; + + // BYTE prime2[rsapubkey.bitlen/16]; + rsap.Q = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen); + Array.Reverse (rsap.Q); + pos += byteHalfLen; + + // BYTE exponent1[rsapubkey.bitlen/16]; + rsap.DP = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen); + Array.Reverse (rsap.DP); + pos += byteHalfLen; + + // BYTE exponent2[rsapubkey.bitlen/16]; + rsap.DQ = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen); + Array.Reverse (rsap.DQ); + pos += byteHalfLen; + + // BYTE coefficient[rsapubkey.bitlen/16]; + rsap.InverseQ = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen); + Array.Reverse (rsap.InverseQ); + pos += byteHalfLen; + + // ok, this is hackish but CryptoAPI support it so... + // note: only works because CRT is used by default + // http://bugzilla.ximian.com/show_bug.cgi?id=57941 + rsap.D = new byte [byteLen]; // must be allocated + if (pos + byteLen + offset <= blob.Length) { + // BYTE privateExponent[rsapubkey.bitlen/8]; + Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen); + Array.Reverse (rsap.D); + } + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + + RSA rsa = null; + try + { + rsa = RSA.Create(); + rsa.ImportParameters(rsap); + } + catch (CryptographicException ce) + { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + try + { + CspParameters csp = new CspParameters(); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + rsa = new RSACryptoServiceProvider(csp); + rsa.ImportParameters(rsap); + } + catch + { + // rethrow original, not the later, exception if this fails + throw ce; + } + } + return rsa; + } + + static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob) + { + return FromCapiPrivateKeyBlobDSA (blob, 0); + } + + static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + DSAParameters dsap = new DSAParameters (); + try { + if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) + (blob [offset + 1] != 0x02) || // Version (0x02) + (blob [offset + 2] != 0x00) || // Reserved (word) + (blob [offset + 3] != 0x00) || + (ToUInt32LE (blob, offset + 8) != 0x32535344)) // DWORD magic + throw new CryptographicException ("Invalid blob header"); + + int bitlen = ToInt32LE (blob, offset + 12); + int bytelen = bitlen >> 3; + int pos = offset + 16; + + dsap.P = new byte [bytelen]; + Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen); + Array.Reverse (dsap.P); + pos += bytelen; + + dsap.Q = new byte [20]; + Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20); + Array.Reverse (dsap.Q); + pos += 20; + + dsap.G = new byte [bytelen]; + Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen); + Array.Reverse (dsap.G); + pos += bytelen; + + dsap.X = new byte [20]; + Buffer.BlockCopy (blob, pos, dsap.X, 0, 20); + Array.Reverse (dsap.X); + pos += 20; + + dsap.Counter = ToInt32LE (blob, pos); + pos += 4; + + dsap.Seed = new byte [20]; + Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20); + Array.Reverse (dsap.Seed); + pos += 20; + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + + DSA dsa = null; + try + { + dsa = (DSA)DSA.Create(); + dsa.ImportParameters(dsap); + } + catch (CryptographicException ce) + { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + try + { + CspParameters csp = new CspParameters(); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + dsa = new DSACryptoServiceProvider(csp); + dsa.ImportParameters(dsap); + } + catch + { + // rethrow original, not the later, exception if this fails + throw ce; + } + } + return dsa; + } + + static public byte[] ToCapiPrivateKeyBlob (RSA rsa) + { + RSAParameters p = rsa.ExportParameters (true); + int keyLength = p.Modulus.Length; // in bytes + byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)]; + + blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07) + blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) + // [2], [3] // RESERVED - Always 0 + blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) + blob [8] = 0x52; // Magic - RSA2 (ASCII in hex) + blob [9] = 0x53; + blob [10] = 0x41; + blob [11] = 0x32; + + byte[] bitlen = GetBytesLE (keyLength << 3); + blob [12] = bitlen [0]; // bitlen + blob [13] = bitlen [1]; + blob [14] = bitlen [2]; + blob [15] = bitlen [3]; + + // public exponent (DWORD) + int pos = 16; + int n = p.Exponent.Length; + while (n > 0) + blob [pos++] = p.Exponent [--n]; + // modulus + pos = 20; + byte[] part = p.Modulus; + int len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + // private key + part = p.P; + len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + + part = p.Q; + len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + + part = p.DP; + len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + + part = p.DQ; + len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + + part = p.InverseQ; + len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + + part = p.D; + len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + + return blob; + } + + static public byte[] ToCapiPrivateKeyBlob (DSA dsa) + { + DSAParameters p = dsa.ExportParameters (true); + int keyLength = p.P.Length; // in bytes + + // header + P + Q + G + X + count + seed + byte[] blob = new byte [16 + keyLength + 20 + keyLength + 20 + 4 + 20]; + + blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07) + blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) + // [2], [3] // RESERVED - Always 0 + blob [5] = 0x22; // ALGID + blob [8] = 0x44; // Magic + blob [9] = 0x53; + blob [10] = 0x53; + blob [11] = 0x32; + + byte[] bitlen = GetBytesLE (keyLength << 3); + blob [12] = bitlen [0]; + blob [13] = bitlen [1]; + blob [14] = bitlen [2]; + blob [15] = bitlen [3]; + + int pos = 16; + byte[] part = p.P; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, keyLength); + pos += keyLength; + + part = p.Q; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, 20); + pos += 20; + + part = p.G; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, keyLength); + pos += keyLength; + + part = p.X; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, 20); + pos += 20; + + Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4); + pos += 4; + + part = p.Seed; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, 20); + + return blob; + } + + static public RSA FromCapiPublicKeyBlob (byte[] blob) + { + return FromCapiPublicKeyBlob (blob, 0); + } + + static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + try { + if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) + (blob [offset+1] != 0x02) || // Version (0x02) + (blob [offset+2] != 0x00) || // Reserved (word) + (blob [offset+3] != 0x00) || + (ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1 + throw new CryptographicException ("Invalid blob header"); + + // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) + // int algId = ToInt32LE (blob, offset+4); + + // DWORD bitlen + int bitLen = ToInt32LE (blob, offset+12); + + // DWORD public exponent + RSAParameters rsap = new RSAParameters (); + rsap.Exponent = new byte [3]; + rsap.Exponent [0] = blob [offset+18]; + rsap.Exponent [1] = blob [offset+17]; + rsap.Exponent [2] = blob [offset+16]; + + int pos = offset+20; + // BYTE modulus[rsapubkey.bitlen/8]; + int byteLen = (bitLen >> 3); + rsap.Modulus = new byte [byteLen]; + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); + Array.Reverse (rsap.Modulus); + RSA rsa = null; + try + { + rsa = RSA.Create(); + rsa.ImportParameters(rsap); + } + catch (CryptographicException) + { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + CspParameters csp = new CspParameters(); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + rsa = new RSACryptoServiceProvider(csp); + rsa.ImportParameters(rsap); + } + return rsa; + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + } + + static public DSA FromCapiPublicKeyBlobDSA (byte[] blob) + { + return FromCapiPublicKeyBlobDSA (blob, 0); + } + + static public DSA FromCapiPublicKeyBlobDSA (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + try { + if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) + (blob [offset + 1] != 0x02) || // Version (0x02) + (blob [offset + 2] != 0x00) || // Reserved (word) + (blob [offset + 3] != 0x00) || + (ToUInt32LE (blob, offset + 8) != 0x31535344)) // DWORD magic + throw new CryptographicException ("Invalid blob header"); + + int bitlen = ToInt32LE (blob, offset + 12); + DSAParameters dsap = new DSAParameters (); + int bytelen = bitlen >> 3; + int pos = offset + 16; + + dsap.P = new byte [bytelen]; + Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen); + Array.Reverse (dsap.P); + pos += bytelen; + + dsap.Q = new byte [20]; + Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20); + Array.Reverse (dsap.Q); + pos += 20; + + dsap.G = new byte [bytelen]; + Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen); + Array.Reverse (dsap.G); + pos += bytelen; + + dsap.Y = new byte [bytelen]; + Buffer.BlockCopy (blob, pos, dsap.Y, 0, bytelen); + Array.Reverse (dsap.Y); + pos += bytelen; + + dsap.Counter = ToInt32LE (blob, pos); + pos += 4; + + dsap.Seed = new byte [20]; + Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20); + Array.Reverse (dsap.Seed); + pos += 20; + + DSA dsa = (DSA)DSA.Create (); + dsa.ImportParameters (dsap); + return dsa; + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + } + + static public byte[] ToCapiPublicKeyBlob (RSA rsa) + { + RSAParameters p = rsa.ExportParameters (false); + int keyLength = p.Modulus.Length; // in bytes + byte[] blob = new byte [20 + keyLength]; + + blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06) + blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) + // [2], [3] // RESERVED - Always 0 + blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) + blob [8] = 0x52; // Magic - RSA1 (ASCII in hex) + blob [9] = 0x53; + blob [10] = 0x41; + blob [11] = 0x31; + + byte[] bitlen = GetBytesLE (keyLength << 3); + blob [12] = bitlen [0]; // bitlen + blob [13] = bitlen [1]; + blob [14] = bitlen [2]; + blob [15] = bitlen [3]; + + // public exponent (DWORD) + int pos = 16; + int n = p.Exponent.Length; + while (n > 0) + blob [pos++] = p.Exponent [--n]; + // modulus + pos = 20; + byte[] part = p.Modulus; + int len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + return blob; + } + + static public byte[] ToCapiPublicKeyBlob (DSA dsa) + { + DSAParameters p = dsa.ExportParameters (false); + int keyLength = p.P.Length; // in bytes + + // header + P + Q + G + Y + count + seed + byte[] blob = new byte [16 + keyLength + 20 + keyLength + keyLength + 4 + 20]; + + blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06) + blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) + // [2], [3] // RESERVED - Always 0 + blob [5] = 0x22; // ALGID + blob [8] = 0x44; // Magic + blob [9] = 0x53; + blob [10] = 0x53; + blob [11] = 0x31; + + byte[] bitlen = GetBytesLE (keyLength << 3); + blob [12] = bitlen [0]; + blob [13] = bitlen [1]; + blob [14] = bitlen [2]; + blob [15] = bitlen [3]; + + int pos = 16; + byte[] part; + + part = p.P; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, keyLength); + pos += keyLength; + + part = p.Q; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, 20); + pos += 20; + + part = p.G; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, keyLength); + pos += keyLength; + + part = p.Y; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, keyLength); + pos += keyLength; + + Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4); + pos += 4; + + part = p.Seed; + Array.Reverse (part); + Buffer.BlockCopy (part, 0, blob, pos, 20); + + return blob; + } + + // PRIVATEKEYBLOB + // PUBLICKEYBLOB + static public RSA FromCapiKeyBlob (byte[] blob) + { + return FromCapiKeyBlob (blob, 0); + } + + static public RSA FromCapiKeyBlob (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + switch (blob [offset]) { + case 0x00: + // this could be a public key inside an header + // like "sn -e" would produce + if (blob [offset + 12] == 0x06) { + return FromCapiPublicKeyBlob (blob, offset + 12); + } + break; + case 0x06: + return FromCapiPublicKeyBlob (blob, offset); + case 0x07: + return FromCapiPrivateKeyBlob (blob, offset); + } + throw new CryptographicException ("Unknown blob format."); + } + + static public DSA FromCapiKeyBlobDSA (byte[] blob) + { + return FromCapiKeyBlobDSA (blob, 0); + } + + static public DSA FromCapiKeyBlobDSA (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + switch (blob [offset]) { + case 0x06: + return FromCapiPublicKeyBlobDSA (blob, offset); + case 0x07: + return FromCapiPrivateKeyBlobDSA (blob, offset); + } + throw new CryptographicException ("Unknown blob format."); + } + + static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey) + { + if (keypair == null) + throw new ArgumentNullException ("keypair"); + + // check between RSA and DSA (and potentially others like DH) + if (keypair is RSA) + return ToCapiKeyBlob ((RSA)keypair, includePrivateKey); + else if (keypair is DSA) + return ToCapiKeyBlob ((DSA)keypair, includePrivateKey); + else + return null; // TODO + } + + static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey) + { + if (rsa == null) + throw new ArgumentNullException ("rsa"); + + if (includePrivateKey) + return ToCapiPrivateKeyBlob (rsa); + else + return ToCapiPublicKeyBlob (rsa); + } + + static public byte[] ToCapiKeyBlob (DSA dsa, bool includePrivateKey) + { + if (dsa == null) + throw new ArgumentNullException ("dsa"); + + if (includePrivateKey) + return ToCapiPrivateKeyBlob (dsa); + else + return ToCapiPublicKeyBlob (dsa); + } + + static public string ToHex (byte[] input) + { + if (input == null) + return null; + + StringBuilder sb = new StringBuilder (input.Length * 2); + foreach (byte b in input) { + sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture)); + } + return sb.ToString (); + } + + static private byte FromHexChar (char c) + { + if ((c >= 'a') && (c <= 'f')) + return (byte) (c - 'a' + 10); + if ((c >= 'A') && (c <= 'F')) + return (byte) (c - 'A' + 10); + if ((c >= '0') && (c <= '9')) + return (byte) (c - '0'); + throw new ArgumentException ("invalid hex char"); + } + + static public byte[] FromHex (string hex) + { + if (hex == null) + return null; + if ((hex.Length & 0x1) == 0x1) + throw new ArgumentException ("Length must be a multiple of 2"); + + byte[] result = new byte [hex.Length >> 1]; + int n = 0; + int i = 0; + while (n < result.Length) { + result [n] = (byte) (FromHexChar (hex [i++]) << 4); + result [n++] += FromHexChar (hex [i++]); + } + return result; + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs new file mode 100644 index 000000000..6402da0c9 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using MediaBrowser.Model.Cryptography; + +namespace Emby.Server.Implementations.Cryptography +{ + public class CryptographyProvider : ICryptoProvider + { + public Guid GetMD5(string str) + { + return new Guid(ComputeMD5(Encoding.Unicode.GetBytes(str))); + } + + public byte[] ComputeSHA1(byte[] bytes) + { + using (var provider = SHA1.Create()) + { + return provider.ComputeHash(bytes); + } + } + + public byte[] ComputeMD5(Stream str) + { + using (var provider = MD5.Create()) + { + return provider.ComputeHash(str); + } + } + + public byte[] ComputeMD5(byte[] bytes) + { + using (var provider = MD5.Create()) + { + return provider.ComputeHash(bytes); + } + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/PKCS1.cs b/Emby.Server.Implementations/Cryptography/PKCS1.cs new file mode 100644 index 000000000..24c0708c5 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/PKCS1.cs @@ -0,0 +1,491 @@ +// +// PKCS1.cs - Implements PKCS#1 primitives. +// +// Author: +// Sebastien Pouliot <sebastien@xamarin.com> +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// Copyright 2013 Xamarin Inc. (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Security.Cryptography; + +namespace Emby.Server.Core.Cryptography +{ + + // References: + // a. PKCS#1: RSA Cryptography Standard + // http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/index.html + + public sealed class PKCS1 { + + private PKCS1 () + { + } + + private static bool Compare (byte[] array1, byte[] array2) + { + bool result = (array1.Length == array2.Length); + if (result) { + for (int i=0; i < array1.Length; i++) + if (array1[i] != array2[i]) + return false; + } + return result; + } + + private static byte[] xor (byte[] array1, byte[] array2) + { + byte[] result = new byte [array1.Length]; + for (int i=0; i < result.Length; i++) + result[i] = (byte) (array1[i] ^ array2[i]); + return result; + } + + private static byte[] emptySHA1 = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 }; + private static byte[] emptySHA256 = { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 }; + private static byte[] emptySHA384 = { 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b }; + private static byte[] emptySHA512 = { 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e }; + + private static byte[] GetEmptyHash (HashAlgorithm hash) + { + if (hash is SHA1) + return emptySHA1; + else if (hash is SHA256) + return emptySHA256; + else if (hash is SHA384) + return emptySHA384; + else if (hash is SHA512) + return emptySHA512; + else + return hash.ComputeHash ((byte[])null); + } + + // PKCS #1 v.2.1, Section 4.1 + // I2OSP converts a non-negative integer to an octet string of a specified length. + public static byte[] I2OSP (int x, int size) + { + byte[] array = BitConverterLE.GetBytes (x); + Array.Reverse (array, 0, array.Length); + return I2OSP (array, size); + } + + public static byte[] I2OSP (byte[] x, int size) + { + byte[] result = new byte [size]; + Buffer.BlockCopy (x, 0, result, (result.Length - x.Length), x.Length); + return result; + } + + // PKCS #1 v.2.1, Section 4.2 + // OS2IP converts an octet string to a nonnegative integer. + public static byte[] OS2IP (byte[] x) + { + int i = 0; + while ((x [i++] == 0x00) && (i < x.Length)) { + // confuse compiler into reporting a warning with {} + } + i--; + if (i > 0) { + byte[] result = new byte [x.Length - i]; + Buffer.BlockCopy (x, i, result, 0, result.Length); + return result; + } + else + return x; + } + + // PKCS #1 v.2.1, Section 5.1.1 + public static byte[] RSAEP (RSA rsa, byte[] m) + { + // c = m^e mod n + return rsa.EncryptValue (m); + } + + // PKCS #1 v.2.1, Section 5.1.2 + public static byte[] RSADP (RSA rsa, byte[] c) + { + // m = c^d mod n + // Decrypt value may apply CRT optimizations + return rsa.DecryptValue (c); + } + + // PKCS #1 v.2.1, Section 5.2.1 + public static byte[] RSASP1 (RSA rsa, byte[] m) + { + // first form: s = m^d mod n + // Decrypt value may apply CRT optimizations + return rsa.DecryptValue (m); + } + + // PKCS #1 v.2.1, Section 5.2.2 + public static byte[] RSAVP1 (RSA rsa, byte[] s) + { + // m = s^e mod n + return rsa.EncryptValue (s); + } + + // PKCS #1 v.2.1, Section 7.1.1 + // RSAES-OAEP-ENCRYPT ((n, e), M, L) + public static byte[] Encrypt_OAEP (RSA rsa, HashAlgorithm hash, RandomNumberGenerator rng, byte[] M) + { + int size = rsa.KeySize / 8; + int hLen = hash.HashSize / 8; + if (M.Length > size - 2 * hLen - 2) + throw new CryptographicException ("message too long"); + // empty label L SHA1 hash + byte[] lHash = GetEmptyHash (hash); + int PSLength = (size - M.Length - 2 * hLen - 2); + // DB = lHash || PS || 0x01 || M + byte[] DB = new byte [lHash.Length + PSLength + 1 + M.Length]; + Buffer.BlockCopy (lHash, 0, DB, 0, lHash.Length); + DB [(lHash.Length + PSLength)] = 0x01; + Buffer.BlockCopy (M, 0, DB, (DB.Length - M.Length), M.Length); + + byte[] seed = new byte [hLen]; + rng.GetBytes (seed); + + byte[] dbMask = MGF1 (hash, seed, size - hLen - 1); + byte[] maskedDB = xor (DB, dbMask); + byte[] seedMask = MGF1 (hash, maskedDB, hLen); + byte[] maskedSeed = xor (seed, seedMask); + // EM = 0x00 || maskedSeed || maskedDB + byte[] EM = new byte [maskedSeed.Length + maskedDB.Length + 1]; + Buffer.BlockCopy (maskedSeed, 0, EM, 1, maskedSeed.Length); + Buffer.BlockCopy (maskedDB, 0, EM, maskedSeed.Length + 1, maskedDB.Length); + + byte[] m = OS2IP (EM); + byte[] c = RSAEP (rsa, m); + return I2OSP (c, size); + } + + // PKCS #1 v.2.1, Section 7.1.2 + // RSAES-OAEP-DECRYPT (K, C, L) + public static byte[] Decrypt_OAEP (RSA rsa, HashAlgorithm hash, byte[] C) + { + int size = rsa.KeySize / 8; + int hLen = hash.HashSize / 8; + if ((size < (2 * hLen + 2)) || (C.Length != size)) + throw new CryptographicException ("decryption error"); + + byte[] c = OS2IP (C); + byte[] m = RSADP (rsa, c); + byte[] EM = I2OSP (m, size); + + // split EM = Y || maskedSeed || maskedDB + byte[] maskedSeed = new byte [hLen]; + Buffer.BlockCopy (EM, 1, maskedSeed, 0, maskedSeed.Length); + byte[] maskedDB = new byte [size - hLen - 1]; + Buffer.BlockCopy (EM, (EM.Length - maskedDB.Length), maskedDB, 0, maskedDB.Length); + + byte[] seedMask = MGF1 (hash, maskedDB, hLen); + byte[] seed = xor (maskedSeed, seedMask); + byte[] dbMask = MGF1 (hash, seed, size - hLen - 1); + byte[] DB = xor (maskedDB, dbMask); + + byte[] lHash = GetEmptyHash (hash); + // split DB = lHash' || PS || 0x01 || M + byte[] dbHash = new byte [lHash.Length]; + Buffer.BlockCopy (DB, 0, dbHash, 0, dbHash.Length); + bool h = Compare (lHash, dbHash); + + // find separator 0x01 + int nPos = lHash.Length; + while (DB[nPos] == 0) + nPos++; + + int Msize = DB.Length - nPos - 1; + byte[] M = new byte [Msize]; + Buffer.BlockCopy (DB, (nPos + 1), M, 0, Msize); + + // we could have returned EM[0] sooner but would be helping a timing attack + if ((EM[0] != 0) || (!h) || (DB[nPos] != 0x01)) + return null; + return M; + } + + // PKCS #1 v.2.1, Section 7.2.1 + // RSAES-PKCS1-V1_5-ENCRYPT ((n, e), M) + public static byte[] Encrypt_v15 (RSA rsa, RandomNumberGenerator rng, byte[] M) + { + int size = rsa.KeySize / 8; + if (M.Length > size - 11) + throw new CryptographicException ("message too long"); + int PSLength = System.Math.Max (8, (size - M.Length - 3)); + byte[] PS = new byte [PSLength]; + rng.GetNonZeroBytes (PS); + byte[] EM = new byte [size]; + EM [1] = 0x02; + Buffer.BlockCopy (PS, 0, EM, 2, PSLength); + Buffer.BlockCopy (M, 0, EM, (size - M.Length), M.Length); + + byte[] m = OS2IP (EM); + byte[] c = RSAEP (rsa, m); + byte[] C = I2OSP (c, size); + return C; + } + + // PKCS #1 v.2.1, Section 7.2.2 + // RSAES-PKCS1-V1_5-DECRYPT (K, C) + public static byte[] Decrypt_v15 (RSA rsa, byte[] C) + { + int size = rsa.KeySize >> 3; // div by 8 + if ((size < 11) || (C.Length > size)) + throw new CryptographicException ("decryption error"); + byte[] c = OS2IP (C); + byte[] m = RSADP (rsa, c); + byte[] EM = I2OSP (m, size); + + if ((EM [0] != 0x00) || (EM [1] != 0x02)) + return null; + + int mPos = 10; + // PS is a minimum of 8 bytes + 2 bytes for header + while ((EM [mPos] != 0x00) && (mPos < EM.Length)) + mPos++; + if (EM [mPos] != 0x00) + return null; + mPos++; + byte[] M = new byte [EM.Length - mPos]; + Buffer.BlockCopy (EM, mPos, M, 0, M.Length); + return M; + } + + // PKCS #1 v.2.1, Section 8.2.1 + // RSASSA-PKCS1-V1_5-SIGN (K, M) + public static byte[] Sign_v15 (RSA rsa, HashAlgorithm hash, byte[] hashValue) + { + int size = (rsa.KeySize >> 3); // div 8 + byte[] EM = Encode_v15 (hash, hashValue, size); + byte[] m = OS2IP (EM); + byte[] s = RSASP1 (rsa, m); + byte[] S = I2OSP (s, size); + return S; + } + + internal static byte[] Sign_v15 (RSA rsa, string hashName, byte[] hashValue) + { + using (var hash = CreateFromName (hashName)) + return Sign_v15 (rsa, hash, hashValue); + } + + // PKCS #1 v.2.1, Section 8.2.2 + // RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S) + public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte[] hashValue, byte[] signature) + { + return Verify_v15 (rsa, hash, hashValue, signature, false); + } + + internal static bool Verify_v15 (RSA rsa, string hashName, byte[] hashValue, byte[] signature) + { + using (var hash = CreateFromName (hashName)) + return Verify_v15 (rsa, hash, hashValue, signature, false); + } + + // DO NOT USE WITHOUT A VERY GOOD REASON + public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte [] hashValue, byte [] signature, bool tryNonStandardEncoding) + { + int size = (rsa.KeySize >> 3); // div 8 + byte[] s = OS2IP (signature); + byte[] m = RSAVP1 (rsa, s); + byte[] EM2 = I2OSP (m, size); + byte[] EM = Encode_v15 (hash, hashValue, size); + bool result = Compare (EM, EM2); + if (result || !tryNonStandardEncoding) + return result; + + // NOTE: some signatures don't include the hash OID (pretty lame but real) + // and compatible with MS implementation. E.g. Verisign Authenticode Timestamps + + // we're making this "as safe as possible" + if ((EM2 [0] != 0x00) || (EM2 [1] != 0x01)) + return false; + int i; + for (i = 2; i < EM2.Length - hashValue.Length - 1; i++) { + if (EM2 [i] != 0xFF) + return false; + } + if (EM2 [i++] != 0x00) + return false; + + byte [] decryptedHash = new byte [hashValue.Length]; + Buffer.BlockCopy (EM2, i, decryptedHash, 0, decryptedHash.Length); + return Compare (decryptedHash, hashValue); + } + + // PKCS #1 v.2.1, Section 9.2 + // EMSA-PKCS1-v1_5-Encode + public static byte[] Encode_v15 (HashAlgorithm hash, byte[] hashValue, int emLength) + { + if (hashValue.Length != (hash.HashSize >> 3)) + throw new CryptographicException ("bad hash length for " + hash.ToString ()); + + // DigestInfo ::= SEQUENCE { + // digestAlgorithm AlgorithmIdentifier, + // digest OCTET STRING + // } + + byte[] t = null; + + string oid = CryptoConfig.MapNameToOID (hash.ToString ()); + if (oid != null) + { + ASN1 digestAlgorithm = new ASN1 (0x30); + digestAlgorithm.Add (new ASN1 (CryptoConfig.EncodeOID (oid))); + digestAlgorithm.Add (new ASN1 (0x05)); // NULL + ASN1 digest = new ASN1 (0x04, hashValue); + ASN1 digestInfo = new ASN1 (0x30); + digestInfo.Add (digestAlgorithm); + digestInfo.Add (digest); + + t = digestInfo.GetBytes (); + } + else + { + // There are no valid OID, in this case t = hashValue + // This is the case of the MD5SHA hash algorithm + t = hashValue; + } + + Buffer.BlockCopy (hashValue, 0, t, t.Length - hashValue.Length, hashValue.Length); + + int PSLength = System.Math.Max (8, emLength - t.Length - 3); + // PS = PSLength of 0xff + + // EM = 0x00 | 0x01 | PS | 0x00 | T + byte[] EM = new byte [PSLength + t.Length + 3]; + EM [1] = 0x01; + for (int i=2; i < PSLength + 2; i++) + EM[i] = 0xff; + Buffer.BlockCopy (t, 0, EM, PSLength + 3, t.Length); + + return EM; + } + + // PKCS #1 v.2.1, Section B.2.1 + public static byte[] MGF1 (HashAlgorithm hash, byte[] mgfSeed, int maskLen) + { + // 1. If maskLen > 2^32 hLen, output "mask too long" and stop. + // easy - this is impossible by using a int (31bits) as parameter ;-) + // BUT with a signed int we do have to check for negative values! + if (maskLen < 0) + throw new OverflowException(); + + int mgfSeedLength = mgfSeed.Length; + int hLen = (hash.HashSize >> 3); // from bits to bytes + int iterations = (maskLen / hLen); + if (maskLen % hLen != 0) + iterations++; + // 2. Let T be the empty octet string. + byte[] T = new byte [iterations * hLen]; + + byte[] toBeHashed = new byte [mgfSeedLength + 4]; + int pos = 0; + // 3. For counter from 0 to \ceil (maskLen / hLen) - 1, do the following: + for (int counter = 0; counter < iterations; counter++) { + // a. Convert counter to an octet string C of length 4 octets + byte[] C = I2OSP (counter, 4); + + // b. Concatenate the hash of the seed mgfSeed and C to the octet string T: + // T = T || Hash (mgfSeed || C) + Buffer.BlockCopy (mgfSeed, 0, toBeHashed, 0, mgfSeedLength); + Buffer.BlockCopy (C, 0, toBeHashed, mgfSeedLength, 4); + byte[] output = hash.ComputeHash (toBeHashed); + Buffer.BlockCopy (output, 0, T, pos, hLen); + pos += hLen; + } + + // 4. Output the leading maskLen octets of T as the octet string mask. + byte[] mask = new byte [maskLen]; + Buffer.BlockCopy (T, 0, mask, 0, maskLen); + return mask; + } + + static internal string HashNameFromOid (string oid, bool throwOnError = true) + { + switch (oid) { + case "1.2.840.113549.1.1.2": // MD2 with RSA encryption + return "MD2"; + case "1.2.840.113549.1.1.3": // MD4 with RSA encryption + return "MD4"; + case "1.2.840.113549.1.1.4": // MD5 with RSA encryption + return "MD5"; + case "1.2.840.113549.1.1.5": // SHA-1 with RSA Encryption + case "1.3.14.3.2.29": // SHA1 with RSA signature + case "1.2.840.10040.4.3": // SHA1-1 with DSA + return "SHA1"; + case "1.2.840.113549.1.1.11": // SHA-256 with RSA Encryption + return "SHA256"; + case "1.2.840.113549.1.1.12": // SHA-384 with RSA Encryption + return "SHA384"; + case "1.2.840.113549.1.1.13": // SHA-512 with RSA Encryption + return "SHA512"; + case "1.3.36.3.3.1.2": + return "RIPEMD160"; + default: + if (throwOnError) + throw new CryptographicException ("Unsupported hash algorithm: " + oid); + return null; + } + } + + static internal HashAlgorithm CreateFromOid (string oid) + { + return CreateFromName (HashNameFromOid (oid)); + } + + static internal HashAlgorithm CreateFromName (string name) + { +#if FULL_AOT_RUNTIME + switch (name) { + case "MD2": + return MD2.Create (); + case "MD4": + return MD4.Create (); + case "MD5": + return MD5.Create (); + case "SHA1": + return SHA1.Create (); + case "SHA256": + return SHA256.Create (); + case "SHA384": + return SHA384.Create (); + case "SHA512": + return SHA512.Create (); + case "RIPEMD160": + return RIPEMD160.Create (); + default: + try { + return (HashAlgorithm) Activator.CreateInstance (Type.GetType (name)); + } + catch { + throw new CryptographicException ("Unsupported hash algorithm: " + name); + } + } +#else + return HashAlgorithm.Create (name); +#endif + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/PKCS12.cs b/Emby.Server.Implementations/Cryptography/PKCS12.cs new file mode 100644 index 000000000..50f3776d9 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/PKCS12.cs @@ -0,0 +1,1934 @@ +// +// PKCS12.cs: PKCS 12 - Personal Information Exchange Syntax +// +// Author: +// Sebastien Pouliot <sebastien@xamarin.com> +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004,2005,2006 Novell Inc. (http://www.novell.com) +// Copyright 2013 Xamarin Inc. (http://www.xamarin.com) +// +// Key derivation translated from Bouncy Castle JCE (http://www.bouncycastle.org/) +// See bouncycastle.txt for license. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + + public class PKCS5 { + + public const string pbeWithMD2AndDESCBC = "1.2.840.113549.1.5.1"; + public const string pbeWithMD5AndDESCBC = "1.2.840.113549.1.5.3"; + public const string pbeWithMD2AndRC2CBC = "1.2.840.113549.1.5.4"; + public const string pbeWithMD5AndRC2CBC = "1.2.840.113549.1.5.6"; + public const string pbeWithSHA1AndDESCBC = "1.2.840.113549.1.5.10"; + public const string pbeWithSHA1AndRC2CBC = "1.2.840.113549.1.5.11"; + + public PKCS5 () {} + } + + public class PKCS9 { + + public const string friendlyName = "1.2.840.113549.1.9.20"; + public const string localKeyId = "1.2.840.113549.1.9.21"; + + public PKCS9 () {} + } + + + internal class SafeBag { + private string _bagOID; + private ASN1 _asn1; + + public SafeBag(string bagOID, ASN1 asn1) { + _bagOID = bagOID; + _asn1 = asn1; + } + + public string BagOID { + get { return _bagOID; } + } + + public ASN1 ASN1 { + get { return _asn1; } + } + } + + + public class PKCS12 : ICloneable { + + public const string pbeWithSHAAnd128BitRC4 = "1.2.840.113549.1.12.1.1"; + public const string pbeWithSHAAnd40BitRC4 = "1.2.840.113549.1.12.1.2"; + public const string pbeWithSHAAnd3KeyTripleDESCBC = "1.2.840.113549.1.12.1.3"; + public const string pbeWithSHAAnd2KeyTripleDESCBC = "1.2.840.113549.1.12.1.4"; + public const string pbeWithSHAAnd128BitRC2CBC = "1.2.840.113549.1.12.1.5"; + public const string pbeWithSHAAnd40BitRC2CBC = "1.2.840.113549.1.12.1.6"; + + // bags + public const string keyBag = "1.2.840.113549.1.12.10.1.1"; + public const string pkcs8ShroudedKeyBag = "1.2.840.113549.1.12.10.1.2"; + public const string certBag = "1.2.840.113549.1.12.10.1.3"; + public const string crlBag = "1.2.840.113549.1.12.10.1.4"; + public const string secretBag = "1.2.840.113549.1.12.10.1.5"; + public const string safeContentsBag = "1.2.840.113549.1.12.10.1.6"; + + // types + public const string x509Certificate = "1.2.840.113549.1.9.22.1"; + public const string sdsiCertificate = "1.2.840.113549.1.9.22.2"; + public const string x509Crl = "1.2.840.113549.1.9.23.1"; + + // Adapted from BouncyCastle PKCS12ParametersGenerator.java + public class DeriveBytes { + + public enum Purpose { + Key, + IV, + MAC + } + + static private byte[] keyDiversifier = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; + static private byte[] ivDiversifier = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }; + static private byte[] macDiversifier = { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }; + + private string _hashName; + private int _iterations; + private byte[] _password; + private byte[] _salt; + + public DeriveBytes () {} + + public string HashName { + get { return _hashName; } + set { _hashName = value; } + } + + public int IterationCount { + get { return _iterations; } + set { _iterations = value; } + } + + public byte[] Password { + get { return (byte[]) _password.Clone (); } + set { + if (value == null) + _password = new byte [0]; + else + _password = (byte[]) value.Clone (); + } + } + + public byte[] Salt { + get { return (byte[]) _salt.Clone (); } + set { + if (value != null) + _salt = (byte[]) value.Clone (); + else + _salt = null; + } + } + + private void Adjust (byte[] a, int aOff, byte[] b) + { + int x = (b[b.Length - 1] & 0xff) + (a [aOff + b.Length - 1] & 0xff) + 1; + + a [aOff + b.Length - 1] = (byte) x; + x >>= 8; + + for (int i = b.Length - 2; i >= 0; i--) { + x += (b [i] & 0xff) + (a [aOff + i] & 0xff); + a [aOff + i] = (byte) x; + x >>= 8; + } + } + + private byte[] Derive (byte[] diversifier, int n) + { + HashAlgorithm digest = PKCS1.CreateFromName (_hashName); + int u = (digest.HashSize >> 3); // div 8 + int v = 64; + byte[] dKey = new byte [n]; + + byte[] S; + if ((_salt != null) && (_salt.Length != 0)) { + S = new byte[v * ((_salt.Length + v - 1) / v)]; + + for (int i = 0; i != S.Length; i++) { + S[i] = _salt[i % _salt.Length]; + } + } + else { + S = new byte[0]; + } + + byte[] P; + if ((_password != null) && (_password.Length != 0)) { + P = new byte[v * ((_password.Length + v - 1) / v)]; + + for (int i = 0; i != P.Length; i++) { + P[i] = _password[i % _password.Length]; + } + } + else { + P = new byte[0]; + } + + byte[] I = new byte [S.Length + P.Length]; + + Buffer.BlockCopy (S, 0, I, 0, S.Length); + Buffer.BlockCopy (P, 0, I, S.Length, P.Length); + + byte[] B = new byte[v]; + int c = (n + u - 1) / u; + + for (int i = 1; i <= c; i++) { + digest.TransformBlock (diversifier, 0, diversifier.Length, diversifier, 0); + digest.TransformFinalBlock (I, 0, I.Length); + byte[] A = digest.Hash; + digest.Initialize (); + for (int j = 1; j != _iterations; j++) { + A = digest.ComputeHash (A, 0, A.Length); + } + + for (int j = 0; j != B.Length; j++) { + B [j] = A [j % A.Length]; + } + + for (int j = 0; j != I.Length / v; j++) { + Adjust (I, j * v, B); + } + + if (i == c) { + Buffer.BlockCopy(A, 0, dKey, (i - 1) * u, dKey.Length - ((i - 1) * u)); + } + else { + Buffer.BlockCopy(A, 0, dKey, (i - 1) * u, A.Length); + } + } + + return dKey; + } + + public byte[] DeriveKey (int size) + { + return Derive (keyDiversifier, size); + } + + public byte[] DeriveIV (int size) + { + return Derive (ivDiversifier, size); + } + + public byte[] DeriveMAC (int size) + { + return Derive (macDiversifier, size); + } + } + + const int recommendedIterationCount = 2000; + + //private int _version; + private byte[] _password; + private ArrayList _keyBags; + private ArrayList _secretBags; + private X509CertificateCollection _certs; + private bool _keyBagsChanged; + private bool _secretBagsChanged; + private bool _certsChanged; + private int _iterations; + private ArrayList _safeBags; + private RandomNumberGenerator _rng; + + // constructors + + public PKCS12 () + { + _iterations = recommendedIterationCount; + _keyBags = new ArrayList (); + _secretBags = new ArrayList (); + _certs = new X509CertificateCollection (); + _keyBagsChanged = false; + _secretBagsChanged = false; + _certsChanged = false; + _safeBags = new ArrayList (); + } + + public PKCS12 (byte[] data) + : this () + { + Password = null; + Decode (data); + } + + /* + * PFX ::= SEQUENCE { + * version INTEGER {v3(3)}(v3,...), + * authSafe ContentInfo, + * macData MacData OPTIONAL + * } + * + * MacData ::= SEQUENCE { + * mac DigestInfo, + * macSalt OCTET STRING, + * iterations INTEGER DEFAULT 1 + * -- Note: The default is for historical reasons and its use is deprecated. A higher + * -- value, like 1024 is recommended. + * } + * + * SafeContents ::= SEQUENCE OF SafeBag + * + * SafeBag ::= SEQUENCE { + * bagId BAG-TYPE.&id ({PKCS12BagSet}), + * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), + * bagAttributes SET OF PKCS12Attribute OPTIONAL + * } + */ + public PKCS12 (byte[] data, string password) + : this () + { + Password = password; + Decode (data); + } + + public PKCS12 (byte[] data, byte[] password) + : this () + { + _password = password; + Decode (data); + } + + private void Decode (byte[] data) + { + ASN1 pfx = new ASN1 (data); + if (pfx.Tag != 0x30) + throw new ArgumentException ("invalid data"); + + ASN1 version = pfx [0]; + if (version.Tag != 0x02) + throw new ArgumentException ("invalid PFX version"); + //_version = version.Value [0]; + + PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (pfx [1]); + if (authSafe.ContentType != PKCS7.Oid.data) + throw new ArgumentException ("invalid authenticated safe"); + + // now that we know it's a PKCS#12 file, check the (optional) MAC + // before decoding anything else in the file + if (pfx.Count > 2) { + ASN1 macData = pfx [2]; + if (macData.Tag != 0x30) + throw new ArgumentException ("invalid MAC"); + + ASN1 mac = macData [0]; + if (mac.Tag != 0x30) + throw new ArgumentException ("invalid MAC"); + ASN1 macAlgorithm = mac [0]; + string macOid = ASN1Convert.ToOid (macAlgorithm [0]); + if (macOid != "1.3.14.3.2.26") + throw new ArgumentException ("unsupported HMAC"); + byte[] macValue = mac [1].Value; + + ASN1 macSalt = macData [1]; + if (macSalt.Tag != 0x04) + throw new ArgumentException ("missing MAC salt"); + + _iterations = 1; // default value + if (macData.Count > 2) { + ASN1 iters = macData [2]; + if (iters.Tag != 0x02) + throw new ArgumentException ("invalid MAC iteration"); + _iterations = ASN1Convert.ToInt32 (iters); + } + + byte[] authSafeData = authSafe.Content [0].Value; + byte[] calculatedMac = MAC (_password, macSalt.Value, _iterations, authSafeData); + if (!Compare (macValue, calculatedMac)) { + byte[] nullPassword = {0, 0}; + calculatedMac = MAC(nullPassword, macSalt.Value, _iterations, authSafeData); + if (!Compare (macValue, calculatedMac)) + throw new CryptographicException ("Invalid MAC - file may have been tampe red!"); + _password = nullPassword; + } + } + + // we now returns to our original presentation - PFX + ASN1 authenticatedSafe = new ASN1 (authSafe.Content [0].Value); + for (int i=0; i < authenticatedSafe.Count; i++) { + PKCS7.ContentInfo ci = new PKCS7.ContentInfo (authenticatedSafe [i]); + switch (ci.ContentType) { + case PKCS7.Oid.data: + // unencrypted (by PKCS#12) + ASN1 safeContents = new ASN1 (ci.Content [0].Value); + for (int j=0; j < safeContents.Count; j++) { + ASN1 safeBag = safeContents [j]; + ReadSafeBag (safeBag); + } + break; + case PKCS7.Oid.encryptedData: + // password encrypted + PKCS7.EncryptedData ed = new PKCS7.EncryptedData (ci.Content [0]); + ASN1 decrypted = new ASN1 (Decrypt (ed)); + for (int j=0; j < decrypted.Count; j++) { + ASN1 safeBag = decrypted [j]; + ReadSafeBag (safeBag); + } + break; + case PKCS7.Oid.envelopedData: + // public key encrypted + throw new NotImplementedException ("public key encrypted"); + default: + throw new ArgumentException ("unknown authenticatedSafe"); + } + } + } + + ~PKCS12 () + { + if (_password != null) { + Array.Clear (_password, 0, _password.Length); + } + _password = null; + } + + // properties + + public string Password { + set { + // Clear old password. + if (_password != null) + Array.Clear (_password, 0, _password.Length); + _password = null; + if (value != null) { + if (value.Length > 0) { + int size = value.Length; + int nul = 0; + if (size < MaximumPasswordLength) { + // if not present, add space for a NULL (0x00) character + if (value[size - 1] != 0x00) + nul = 1; + } else { + size = MaximumPasswordLength; + } + _password = new byte[(size + nul) << 1]; // double for unicode + Encoding.BigEndianUnicode.GetBytes (value, 0, size, _password, 0); + } else { + // double-byte (Unicode) NULL (0x00) - see bug #79617 + _password = new byte[2]; + } + } + } + } + + public int IterationCount { + get { return _iterations; } + set { _iterations = value; } + } + + public ArrayList Keys { + get { + if (_keyBagsChanged) { + _keyBags.Clear (); + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (keyBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); + byte[] privateKey = pki.PrivateKey; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p)); + break; + case 0x30: + _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey)); + break; + default: + break; + } + Array.Clear (privateKey, 0, privateKey.Length); + + } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); + byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); + byte[] privateKey = pki.PrivateKey; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p)); + break; + case 0x30: + _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey)); + break; + default: + break; + } + Array.Clear (privateKey, 0, privateKey.Length); + Array.Clear (decrypted, 0, decrypted.Length); + } + } + _keyBagsChanged = false; + } + return ArrayList.ReadOnly(_keyBags); + } + } + + public ArrayList Secrets { + get { + if (_secretBagsChanged) { + _secretBags.Clear (); + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (secretBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + byte[] secret = bagValue.Value; + _secretBags.Add(secret); + } + } + _secretBagsChanged = false; + } + return ArrayList.ReadOnly(_secretBags); + } + } + + public X509CertificateCollection Certificates { + get { + if (_certsChanged) { + _certs.Clear (); + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (certBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); + _certs.Add (new X509Certificate (cert.Content [0].Value)); + } + } + _certsChanged = false; + } + return _certs; + } + } + + internal RandomNumberGenerator RNG { + get { + if (_rng == null) + _rng = RandomNumberGenerator.Create (); + return _rng; + } + } + + // private methods + + private bool Compare (byte[] expected, byte[] actual) + { + bool compare = false; + if (expected.Length == actual.Length) { + for (int i=0; i < expected.Length; i++) { + if (expected [i] != actual [i]) + return false; + } + compare = true; + } + return compare; + } + + private SymmetricAlgorithm GetSymmetricAlgorithm (string algorithmOid, byte[] salt, int iterationCount) + { + string algorithm = null; + int keyLength = 8; // 64 bits (default) + int ivLength = 8; // 64 bits (default) + + PKCS12.DeriveBytes pd = new PKCS12.DeriveBytes (); + pd.Password = _password; + pd.Salt = salt; + pd.IterationCount = iterationCount; + + switch (algorithmOid) { + case PKCS5.pbeWithMD2AndDESCBC: // no unit test available + pd.HashName = "MD2"; + algorithm = "DES"; + break; + case PKCS5.pbeWithMD5AndDESCBC: // no unit test available + pd.HashName = "MD5"; + algorithm = "DES"; + break; + case PKCS5.pbeWithMD2AndRC2CBC: // no unit test available + // TODO - RC2-CBC-Parameter (PKCS5) + // if missing default to 32 bits !!! + pd.HashName = "MD2"; + algorithm = "RC2"; + keyLength = 4; // default + break; + case PKCS5.pbeWithMD5AndRC2CBC: // no unit test available + // TODO - RC2-CBC-Parameter (PKCS5) + // if missing default to 32 bits !!! + pd.HashName = "MD5"; + algorithm = "RC2"; + keyLength = 4; // default + break; + case PKCS5.pbeWithSHA1AndDESCBC: // no unit test available + pd.HashName = "SHA1"; + algorithm = "DES"; + break; + case PKCS5.pbeWithSHA1AndRC2CBC: // no unit test available + // TODO - RC2-CBC-Parameter (PKCS5) + // if missing default to 32 bits !!! + pd.HashName = "SHA1"; + algorithm = "RC2"; + keyLength = 4; // default + break; + case PKCS12.pbeWithSHAAnd128BitRC4: // no unit test available + pd.HashName = "SHA1"; + algorithm = "RC4"; + keyLength = 16; + ivLength = 0; // N/A + break; + case PKCS12.pbeWithSHAAnd40BitRC4: // no unit test available + pd.HashName = "SHA1"; + algorithm = "RC4"; + keyLength = 5; + ivLength = 0; // N/A + break; + case PKCS12.pbeWithSHAAnd3KeyTripleDESCBC: + pd.HashName = "SHA1"; + algorithm = "TripleDES"; + keyLength = 24; + break; + case PKCS12.pbeWithSHAAnd2KeyTripleDESCBC: // no unit test available + pd.HashName = "SHA1"; + algorithm = "TripleDES"; + keyLength = 16; + break; + case PKCS12.pbeWithSHAAnd128BitRC2CBC: // no unit test available + pd.HashName = "SHA1"; + algorithm = "RC2"; + keyLength = 16; + break; + case PKCS12.pbeWithSHAAnd40BitRC2CBC: + pd.HashName = "SHA1"; + algorithm = "RC2"; + keyLength = 5; + break; + default: + throw new NotSupportedException ("unknown oid " + algorithm); + } + + SymmetricAlgorithm sa = null; + sa = SymmetricAlgorithm.Create(algorithm); + sa.Key = pd.DeriveKey (keyLength); + // IV required only for block ciphers (not stream ciphers) + if (ivLength > 0) { + sa.IV = pd.DeriveIV (ivLength); + sa.Mode = CipherMode.CBC; + } + return sa; + } + + public byte[] Decrypt (string algorithmOid, byte[] salt, int iterationCount, byte[] encryptedData) + { + SymmetricAlgorithm sa = null; + byte[] result = null; + try { + sa = GetSymmetricAlgorithm (algorithmOid, salt, iterationCount); + ICryptoTransform ct = sa.CreateDecryptor (); + result = ct.TransformFinalBlock (encryptedData, 0, encryptedData.Length); + } + finally { + if (sa != null) + sa.Clear (); + } + return result; + } + + public byte[] Decrypt (PKCS7.EncryptedData ed) + { + return Decrypt (ed.EncryptionAlgorithm.ContentType, + ed.EncryptionAlgorithm.Content [0].Value, + ASN1Convert.ToInt32 (ed.EncryptionAlgorithm.Content [1]), + ed.EncryptedContent); + } + + public byte[] Encrypt (string algorithmOid, byte[] salt, int iterationCount, byte[] data) + { + byte[] result = null; + using (SymmetricAlgorithm sa = GetSymmetricAlgorithm (algorithmOid, salt, iterationCount)) { + ICryptoTransform ct = sa.CreateEncryptor (); + result = ct.TransformFinalBlock (data, 0, data.Length); + } + return result; + } + + private DSAParameters GetExistingParameters (out bool found) + { + foreach (X509Certificate cert in Certificates) { + // FIXME: that won't work if parts of the parameters are missing + if (cert.KeyAlgorithmParameters != null) { + DSA dsa = cert.DSA; + if (dsa != null) { + found = true; + return dsa.ExportParameters (false); + } + } + } + found = false; + return new DSAParameters (); + } + + private void AddPrivateKey (PKCS8.PrivateKeyInfo pki) + { + byte[] privateKey = pki.PrivateKey; + switch (privateKey [0]) { + case 0x02: + bool found; + DSAParameters p = GetExistingParameters (out found); + if (found) { + _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p)); + } + break; + case 0x30: + _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey)); + break; + default: + Array.Clear (privateKey, 0, privateKey.Length); + throw new CryptographicException ("Unknown private key format"); + } + Array.Clear (privateKey, 0, privateKey.Length); + } + + private void ReadSafeBag (ASN1 safeBag) + { + if (safeBag.Tag != 0x30) + throw new ArgumentException ("invalid safeBag"); + + ASN1 bagId = safeBag [0]; + if (bagId.Tag != 0x06) + throw new ArgumentException ("invalid safeBag id"); + + ASN1 bagValue = safeBag [1]; + string oid = ASN1Convert.ToOid (bagId); + switch (oid) { + case keyBag: + // NEED UNIT TEST + AddPrivateKey (new PKCS8.PrivateKeyInfo (bagValue.Value)); + break; + case pkcs8ShroudedKeyBag: + PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); + byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); + AddPrivateKey (new PKCS8.PrivateKeyInfo (decrypted)); + Array.Clear (decrypted, 0, decrypted.Length); + break; + case certBag: + PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); + if (cert.ContentType != x509Certificate) + throw new NotSupportedException ("unsupport certificate type"); + X509Certificate x509 = new X509Certificate (cert.Content [0].Value); + _certs.Add (x509); + break; + case crlBag: + // TODO + break; + case secretBag: + byte[] secret = bagValue.Value; + _secretBags.Add(secret); + break; + case safeContentsBag: + // TODO - ? recurse ? + break; + default: + throw new ArgumentException ("unknown safeBag oid"); + } + + if (safeBag.Count > 2) { + ASN1 bagAttributes = safeBag [2]; + if (bagAttributes.Tag != 0x31) + throw new ArgumentException ("invalid safeBag attributes id"); + + for (int i = 0; i < bagAttributes.Count; i++) { + ASN1 pkcs12Attribute = bagAttributes[i]; + + if (pkcs12Attribute.Tag != 0x30) + throw new ArgumentException ("invalid PKCS12 attributes id"); + + ASN1 attrId = pkcs12Attribute [0]; + if (attrId.Tag != 0x06) + throw new ArgumentException ("invalid attribute id"); + + string attrOid = ASN1Convert.ToOid (attrId); + + ASN1 attrValues = pkcs12Attribute[1]; + for (int j = 0; j < attrValues.Count; j++) { + ASN1 attrValue = attrValues[j]; + + switch (attrOid) { + case PKCS9.friendlyName: + if (attrValue.Tag != 0x1e) + throw new ArgumentException ("invalid attribute value id"); + break; + case PKCS9.localKeyId: + if (attrValue.Tag != 0x04) + throw new ArgumentException ("invalid attribute value id"); + break; + default: + // Unknown OID -- don't check Tag + break; + } + } + } + } + + _safeBags.Add (new SafeBag(oid, safeBag)); + } + + private ASN1 Pkcs8ShroudedKeyBagSafeBag (AsymmetricAlgorithm aa, IDictionary attributes) + { + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (); + if (aa is RSA) { + pki.Algorithm = "1.2.840.113549.1.1.1"; + pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((RSA)aa); + } + else if (aa is DSA) { + pki.Algorithm = null; + pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((DSA)aa); + } + else + throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ()); + + PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (); + epki.Algorithm = pbeWithSHAAnd3KeyTripleDESCBC; + epki.IterationCount = _iterations; + epki.EncryptedData = Encrypt (pbeWithSHAAnd3KeyTripleDESCBC, epki.Salt, _iterations, pki.GetBytes ()); + + ASN1 safeBag = new ASN1 (0x30); + safeBag.Add (ASN1Convert.FromOid (pkcs8ShroudedKeyBag)); + ASN1 bagValue = new ASN1 (0xA0); + bagValue.Add (new ASN1 (epki.GetBytes ())); + safeBag.Add (bagValue); + + if (attributes != null) { + ASN1 bagAttributes = new ASN1 (0x31); + IDictionaryEnumerator de = attributes.GetEnumerator (); + + while (de.MoveNext ()) { + string oid = (string)de.Key; + switch (oid) { + case PKCS9.friendlyName: + ArrayList names = (ArrayList)de.Value; + if (names.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] name in names) { + ASN1 attrValue = new ASN1 (0x1e); + attrValue.Value = name; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + case PKCS9.localKeyId: + ArrayList keys = (ArrayList)de.Value; + if (keys.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] key in keys) { + ASN1 attrValue = new ASN1 (0x04); + attrValue.Value = key; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + default: + break; + } + } + + if (bagAttributes.Count > 0) { + safeBag.Add (bagAttributes); + } + } + + return safeBag; + } + + private ASN1 KeyBagSafeBag (AsymmetricAlgorithm aa, IDictionary attributes) + { + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (); + if (aa is RSA) { + pki.Algorithm = "1.2.840.113549.1.1.1"; + pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((RSA)aa); + } + else if (aa is DSA) { + pki.Algorithm = null; + pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((DSA)aa); + } + else + throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ()); + + ASN1 safeBag = new ASN1 (0x30); + safeBag.Add (ASN1Convert.FromOid (keyBag)); + ASN1 bagValue = new ASN1 (0xA0); + bagValue.Add (new ASN1 (pki.GetBytes ())); + safeBag.Add (bagValue); + + if (attributes != null) { + ASN1 bagAttributes = new ASN1 (0x31); + IDictionaryEnumerator de = attributes.GetEnumerator (); + + while (de.MoveNext ()) { + string oid = (string)de.Key; + switch (oid) { + case PKCS9.friendlyName: + ArrayList names = (ArrayList)de.Value; + if (names.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] name in names) { + ASN1 attrValue = new ASN1 (0x1e); + attrValue.Value = name; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + case PKCS9.localKeyId: + ArrayList keys = (ArrayList)de.Value; + if (keys.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] key in keys) { + ASN1 attrValue = new ASN1 (0x04); + attrValue.Value = key; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + default: + break; + } + } + + if (bagAttributes.Count > 0) { + safeBag.Add (bagAttributes); + } + } + + return safeBag; + } + + private ASN1 SecretBagSafeBag (byte[] secret, IDictionary attributes) + { + ASN1 safeBag = new ASN1 (0x30); + safeBag.Add (ASN1Convert.FromOid (secretBag)); + ASN1 bagValue = new ASN1 (0x80, secret); + safeBag.Add (bagValue); + + if (attributes != null) { + ASN1 bagAttributes = new ASN1 (0x31); + IDictionaryEnumerator de = attributes.GetEnumerator (); + + while (de.MoveNext ()) { + string oid = (string)de.Key; + switch (oid) { + case PKCS9.friendlyName: + ArrayList names = (ArrayList)de.Value; + if (names.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] name in names) { + ASN1 attrValue = new ASN1 (0x1e); + attrValue.Value = name; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + case PKCS9.localKeyId: + ArrayList keys = (ArrayList)de.Value; + if (keys.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] key in keys) { + ASN1 attrValue = new ASN1 (0x04); + attrValue.Value = key; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + default: + break; + } + } + + if (bagAttributes.Count > 0) { + safeBag.Add (bagAttributes); + } + } + + return safeBag; + } + + private ASN1 CertificateSafeBag (X509Certificate x509, IDictionary attributes) + { + ASN1 encapsulatedCertificate = new ASN1 (0x04, x509.RawData); + + PKCS7.ContentInfo ci = new PKCS7.ContentInfo (); + ci.ContentType = x509Certificate; + ci.Content.Add (encapsulatedCertificate); + + ASN1 bagValue = new ASN1 (0xA0); + bagValue.Add (ci.ASN1); + + ASN1 safeBag = new ASN1 (0x30); + safeBag.Add (ASN1Convert.FromOid (certBag)); + safeBag.Add (bagValue); + + if (attributes != null) { + ASN1 bagAttributes = new ASN1 (0x31); + IDictionaryEnumerator de = attributes.GetEnumerator (); + + while (de.MoveNext ()) { + string oid = (string)de.Key; + switch (oid) { + case PKCS9.friendlyName: + ArrayList names = (ArrayList)de.Value; + if (names.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] name in names) { + ASN1 attrValue = new ASN1 (0x1e); + attrValue.Value = name; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + case PKCS9.localKeyId: + ArrayList keys = (ArrayList)de.Value; + if (keys.Count > 0) { + ASN1 pkcs12Attribute = new ASN1 (0x30); + pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); + ASN1 attrValues = new ASN1 (0x31); + foreach (byte[] key in keys) { + ASN1 attrValue = new ASN1 (0x04); + attrValue.Value = key; + attrValues.Add (attrValue); + } + pkcs12Attribute.Add (attrValues); + bagAttributes.Add (pkcs12Attribute); + } + break; + default: + break; + } + } + + if (bagAttributes.Count > 0) { + safeBag.Add (bagAttributes); + } + } + + return safeBag; + } + + private byte[] MAC (byte[] password, byte[] salt, int iterations, byte[] data) + { + PKCS12.DeriveBytes pd = new PKCS12.DeriveBytes (); + pd.HashName = "SHA1"; + pd.Password = password; + pd.Salt = salt; + pd.IterationCount = iterations; + + HMACSHA1 hmac = (HMACSHA1) HMACSHA1.Create (); + hmac.Key = pd.DeriveMAC (20); + return hmac.ComputeHash (data, 0, data.Length); + } + + /* + * SafeContents ::= SEQUENCE OF SafeBag + * + * SafeBag ::= SEQUENCE { + * bagId BAG-TYPE.&id ({PKCS12BagSet}), + * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), + * bagAttributes SET OF PKCS12Attribute OPTIONAL + * } + */ + public byte[] GetBytes () + { + // TODO (incomplete) + ASN1 safeBagSequence = new ASN1 (0x30); + + // Sync Safe Bag list since X509CertificateCollection may be updated + ArrayList scs = new ArrayList (); + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (certBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); + scs.Add (new X509Certificate (cert.Content [0].Value)); + } + } + + ArrayList addcerts = new ArrayList (); + ArrayList removecerts = new ArrayList (); + + foreach (X509Certificate c in Certificates) { + bool found = false; + + foreach (X509Certificate lc in scs) { + if (Compare (c.RawData, lc.RawData)) { + found = true; + } + } + + if (!found) { + addcerts.Add (c); + } + } + foreach (X509Certificate c in scs) { + bool found = false; + + foreach (X509Certificate lc in Certificates) { + if (Compare (c.RawData, lc.RawData)) { + found = true; + } + } + + if (!found) { + removecerts.Add (c); + } + } + + foreach (X509Certificate c in removecerts) { + RemoveCertificate (c); + } + + foreach (X509Certificate c in addcerts) { + AddCertificate (c); + } + // Sync done + + if (_safeBags.Count > 0) { + ASN1 certsSafeBag = new ASN1 (0x30); + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (certBag)) { + certsSafeBag.Add (sb.ASN1); + } + } + + if (certsSafeBag.Count > 0) { + PKCS7.ContentInfo contentInfo = EncryptedContentInfo (certsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC); + safeBagSequence.Add (contentInfo.ASN1); + } + } + + if (_safeBags.Count > 0) { + ASN1 safeContents = new ASN1 (0x30); + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (keyBag) || + sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + safeContents.Add (sb.ASN1); + } + } + if (safeContents.Count > 0) { + ASN1 content = new ASN1 (0xA0); + content.Add (new ASN1 (0x04, safeContents.GetBytes ())); + + PKCS7.ContentInfo keyBag = new PKCS7.ContentInfo (PKCS7.Oid.data); + keyBag.Content = content; + safeBagSequence.Add (keyBag.ASN1); + } + } + + // Doing SecretBags separately in case we want to change their encryption independently. + if (_safeBags.Count > 0) { + ASN1 secretsSafeBag = new ASN1 (0x30); + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (secretBag)) { + secretsSafeBag.Add (sb.ASN1); + } + } + + if (secretsSafeBag.Count > 0) { + PKCS7.ContentInfo contentInfo = EncryptedContentInfo (secretsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC); + safeBagSequence.Add (contentInfo.ASN1); + } + } + + + ASN1 encapsulates = new ASN1 (0x04, safeBagSequence.GetBytes ()); + ASN1 ci = new ASN1 (0xA0); + ci.Add (encapsulates); + PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (PKCS7.Oid.data); + authSafe.Content = ci; + + ASN1 macData = new ASN1 (0x30); + if (_password != null) { + // only for password based encryption + byte[] salt = new byte [20]; + RNG.GetBytes (salt); + byte[] macValue = MAC (_password, salt, _iterations, authSafe.Content [0].Value); + ASN1 oidSeq = new ASN1 (0x30); + oidSeq.Add (ASN1Convert.FromOid ("1.3.14.3.2.26")); // SHA1 + oidSeq.Add (new ASN1 (0x05)); + + ASN1 mac = new ASN1 (0x30); + mac.Add (oidSeq); + mac.Add (new ASN1 (0x04, macValue)); + + macData.Add (mac); + macData.Add (new ASN1 (0x04, salt)); + macData.Add (ASN1Convert.FromInt32 (_iterations)); + } + + ASN1 version = new ASN1 (0x02, new byte [1] { 0x03 }); + + ASN1 pfx = new ASN1 (0x30); + pfx.Add (version); + pfx.Add (authSafe.ASN1); + if (macData.Count > 0) { + // only for password based encryption + pfx.Add (macData); + } + + return pfx.GetBytes (); + } + + // Creates an encrypted PKCS#7 ContentInfo with safeBags as its SafeContents. Used in GetBytes(), above. + private PKCS7.ContentInfo EncryptedContentInfo(ASN1 safeBags, string algorithmOid) + { + byte[] salt = new byte [8]; + RNG.GetBytes (salt); + + ASN1 seqParams = new ASN1 (0x30); + seqParams.Add (new ASN1 (0x04, salt)); + seqParams.Add (ASN1Convert.FromInt32 (_iterations)); + + ASN1 seqPbe = new ASN1 (0x30); + seqPbe.Add (ASN1Convert.FromOid (algorithmOid)); + seqPbe.Add (seqParams); + + byte[] encrypted = Encrypt (algorithmOid, salt, _iterations, safeBags.GetBytes ()); + ASN1 encryptedContent = new ASN1 (0x80, encrypted); + + ASN1 seq = new ASN1 (0x30); + seq.Add (ASN1Convert.FromOid (PKCS7.Oid.data)); + seq.Add (seqPbe); + seq.Add (encryptedContent); + + ASN1 version = new ASN1 (0x02, new byte [1] { 0x00 }); + ASN1 encData = new ASN1 (0x30); + encData.Add (version); + encData.Add (seq); + + ASN1 finalContent = new ASN1 (0xA0); + finalContent.Add (encData); + + PKCS7.ContentInfo bag = new PKCS7.ContentInfo (PKCS7.Oid.encryptedData); + bag.Content = finalContent; + return bag; + } + + public void AddCertificate (X509Certificate cert) + { + AddCertificate (cert, null); + } + + public void AddCertificate (X509Certificate cert, IDictionary attributes) + { + bool found = false; + + for (int i = 0; !found && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (certBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); + X509Certificate c = new X509Certificate (crt.Content [0].Value); + if (Compare (cert.RawData, c.RawData)) { + found = true; + } + } + } + + if (!found) { + _safeBags.Add (new SafeBag (certBag, CertificateSafeBag (cert, attributes))); + _certsChanged = true; + } + } + + public void RemoveCertificate (X509Certificate cert) + { + RemoveCertificate (cert, null); + } + + public void RemoveCertificate (X509Certificate cert, IDictionary attrs) + { + int certIndex = -1; + + for (int i = 0; certIndex == -1 && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (certBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); + X509Certificate c = new X509Certificate (crt.Content [0].Value); + if (Compare (cert.RawData, c.RawData)) { + if (attrs != null) { + if (safeBag.Count == 3) { + ASN1 bagAttributes = safeBag [2]; + int bagAttributesFound = 0; + for (int j = 0; j < bagAttributes.Count; j++) { + ASN1 pkcs12Attribute = bagAttributes [j]; + ASN1 attrId = pkcs12Attribute [0]; + string ao = ASN1Convert.ToOid (attrId); + ArrayList dattrValues = (ArrayList)attrs [ao]; + + if (dattrValues != null) { + ASN1 attrValues = pkcs12Attribute [1]; + + if (dattrValues.Count == attrValues.Count) { + int attrValuesFound = 0; + for (int k = 0; k < attrValues.Count; k++) { + ASN1 attrValue = attrValues [k]; + byte[] value = (byte[])dattrValues [k]; + + if (Compare (value, attrValue.Value)) { + attrValuesFound += 1; + } + } + if (attrValuesFound == attrValues.Count) { + bagAttributesFound += 1; + } + } + } + } + if (bagAttributesFound == bagAttributes.Count) { + certIndex = i; + } + } + } else { + certIndex = i; + } + } + } + } + + if (certIndex != -1) { + _safeBags.RemoveAt (certIndex); + _certsChanged = true; + } + } + + private bool CompareAsymmetricAlgorithm (AsymmetricAlgorithm a1, AsymmetricAlgorithm a2) + { + // fast path + if (a1.KeySize != a2.KeySize) + return false; + // compare public keys - if they match we can assume the private match too + return (a1.ToXmlString (false) == a2.ToXmlString (false)); + } + + public void AddPkcs8ShroudedKeyBag (AsymmetricAlgorithm aa) + { + AddPkcs8ShroudedKeyBag (aa, null); + } + + public void AddPkcs8ShroudedKeyBag (AsymmetricAlgorithm aa, IDictionary attributes) + { + bool found = false; + + for (int i = 0; !found && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + ASN1 bagValue = sb.ASN1 [1]; + PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); + byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); + byte[] privateKey = pki.PrivateKey; + + AsymmetricAlgorithm saa = null; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + Array.Clear (decrypted, 0, decrypted.Length); + Array.Clear (privateKey, 0, privateKey.Length); + throw new CryptographicException ("Unknown private key format"); + } + + Array.Clear (decrypted, 0, decrypted.Length); + Array.Clear (privateKey, 0, privateKey.Length); + + if (CompareAsymmetricAlgorithm (aa , saa)) { + found = true; + } + } + } + + if (!found) { + _safeBags.Add (new SafeBag (pkcs8ShroudedKeyBag, Pkcs8ShroudedKeyBagSafeBag (aa, attributes))); + _keyBagsChanged = true; + } + } + + public void RemovePkcs8ShroudedKeyBag (AsymmetricAlgorithm aa) + { + int aaIndex = -1; + + for (int i = 0; aaIndex == -1 && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + ASN1 bagValue = sb.ASN1 [1]; + PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); + byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); + byte[] privateKey = pki.PrivateKey; + + AsymmetricAlgorithm saa = null; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + Array.Clear (decrypted, 0, decrypted.Length); + Array.Clear (privateKey, 0, privateKey.Length); + throw new CryptographicException ("Unknown private key format"); + } + + Array.Clear (decrypted, 0, decrypted.Length); + Array.Clear (privateKey, 0, privateKey.Length); + + if (CompareAsymmetricAlgorithm (aa, saa)) { + aaIndex = i; + } + } + } + + if (aaIndex != -1) { + _safeBags.RemoveAt (aaIndex); + _keyBagsChanged = true; + } + } + + public void AddKeyBag (AsymmetricAlgorithm aa) + { + AddKeyBag (aa, null); + } + + public void AddKeyBag (AsymmetricAlgorithm aa, IDictionary attributes) + { + bool found = false; + + for (int i = 0; !found && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (keyBag)) { + ASN1 bagValue = sb.ASN1 [1]; + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); + byte[] privateKey = pki.PrivateKey; + + AsymmetricAlgorithm saa = null; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + Array.Clear (privateKey, 0, privateKey.Length); + throw new CryptographicException ("Unknown private key format"); + } + + Array.Clear (privateKey, 0, privateKey.Length); + + if (CompareAsymmetricAlgorithm (aa, saa)) { + found = true; + } + } + } + + if (!found) { + _safeBags.Add (new SafeBag (keyBag, KeyBagSafeBag (aa, attributes))); + _keyBagsChanged = true; + } + } + + public void RemoveKeyBag (AsymmetricAlgorithm aa) + { + int aaIndex = -1; + + for (int i = 0; aaIndex == -1 && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (keyBag)) { + ASN1 bagValue = sb.ASN1 [1]; + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); + byte[] privateKey = pki.PrivateKey; + + AsymmetricAlgorithm saa = null; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + Array.Clear (privateKey, 0, privateKey.Length); + throw new CryptographicException ("Unknown private key format"); + } + + Array.Clear (privateKey, 0, privateKey.Length); + + if (CompareAsymmetricAlgorithm (aa, saa)) { + aaIndex = i; + } + } + } + + if (aaIndex != -1) { + _safeBags.RemoveAt (aaIndex); + _keyBagsChanged = true; + } + } + + public void AddSecretBag (byte[] secret) + { + AddSecretBag (secret, null); + } + + public void AddSecretBag (byte[] secret, IDictionary attributes) + { + bool found = false; + + for (int i = 0; !found && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (secretBag)) { + ASN1 bagValue = sb.ASN1 [1]; + byte[] ssecret = bagValue.Value; + + if (Compare (secret, ssecret)) { + found = true; + } + } + } + + if (!found) { + _safeBags.Add (new SafeBag (secretBag, SecretBagSafeBag (secret, attributes))); + _secretBagsChanged = true; + } + } + + public void RemoveSecretBag (byte[] secret) + { + int sIndex = -1; + + for (int i = 0; sIndex == -1 && i < _safeBags.Count; i++) { + SafeBag sb = (SafeBag)_safeBags [i]; + + if (sb.BagOID.Equals (secretBag)) { + ASN1 bagValue = sb.ASN1 [1]; + byte[] ssecret = bagValue.Value; + + if (Compare (secret, ssecret)) { + sIndex = i; + } + } + } + + if (sIndex != -1) { + _safeBags.RemoveAt (sIndex); + _secretBagsChanged = true; + } + } + + public AsymmetricAlgorithm GetAsymmetricAlgorithm (IDictionary attrs) + { + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (keyBag) || sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + ASN1 safeBag = sb.ASN1; + + if (safeBag.Count == 3) { + ASN1 bagAttributes = safeBag [2]; + + int bagAttributesFound = 0; + for (int i = 0; i < bagAttributes.Count; i++) { + ASN1 pkcs12Attribute = bagAttributes [i]; + ASN1 attrId = pkcs12Attribute [0]; + string ao = ASN1Convert.ToOid (attrId); + ArrayList dattrValues = (ArrayList)attrs [ao]; + + if (dattrValues != null) { + ASN1 attrValues = pkcs12Attribute [1]; + + if (dattrValues.Count == attrValues.Count) { + int attrValuesFound = 0; + for (int j = 0; j < attrValues.Count; j++) { + ASN1 attrValue = attrValues [j]; + byte[] value = (byte[])dattrValues [j]; + + if (Compare (value, attrValue.Value)) { + attrValuesFound += 1; + } + } + if (attrValuesFound == attrValues.Count) { + bagAttributesFound += 1; + } + } + } + } + if (bagAttributesFound == bagAttributes.Count) { + ASN1 bagValue = safeBag [1]; + AsymmetricAlgorithm aa = null; + if (sb.BagOID.Equals (keyBag)) { + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); + byte[] privateKey = pki.PrivateKey; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + aa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + aa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + break; + } + Array.Clear (privateKey, 0, privateKey.Length); + } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); + byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); + byte[] privateKey = pki.PrivateKey; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + aa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + aa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + break; + } + Array.Clear (privateKey, 0, privateKey.Length); + Array.Clear (decrypted, 0, decrypted.Length); + } + return aa; + } + } + } + } + + return null; + } + + public byte[] GetSecret (IDictionary attrs) + { + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (secretBag)) { + ASN1 safeBag = sb.ASN1; + + if (safeBag.Count == 3) { + ASN1 bagAttributes = safeBag [2]; + + int bagAttributesFound = 0; + for (int i = 0; i < bagAttributes.Count; i++) { + ASN1 pkcs12Attribute = bagAttributes [i]; + ASN1 attrId = pkcs12Attribute [0]; + string ao = ASN1Convert.ToOid (attrId); + ArrayList dattrValues = (ArrayList)attrs [ao]; + + if (dattrValues != null) { + ASN1 attrValues = pkcs12Attribute [1]; + + if (dattrValues.Count == attrValues.Count) { + int attrValuesFound = 0; + for (int j = 0; j < attrValues.Count; j++) { + ASN1 attrValue = attrValues [j]; + byte[] value = (byte[])dattrValues [j]; + + if (Compare (value, attrValue.Value)) { + attrValuesFound += 1; + } + } + if (attrValuesFound == attrValues.Count) { + bagAttributesFound += 1; + } + } + } + } + if (bagAttributesFound == bagAttributes.Count) { + ASN1 bagValue = safeBag [1]; + return bagValue.Value; + } + } + } + } + + return null; + } + + public X509Certificate GetCertificate (IDictionary attrs) + { + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (certBag)) { + ASN1 safeBag = sb.ASN1; + + if (safeBag.Count == 3) { + ASN1 bagAttributes = safeBag [2]; + + int bagAttributesFound = 0; + for (int i = 0; i < bagAttributes.Count; i++) { + ASN1 pkcs12Attribute = bagAttributes [i]; + ASN1 attrId = pkcs12Attribute [0]; + string ao = ASN1Convert.ToOid (attrId); + ArrayList dattrValues = (ArrayList)attrs [ao]; + + if (dattrValues != null) { + ASN1 attrValues = pkcs12Attribute [1]; + + if (dattrValues.Count == attrValues.Count) { + int attrValuesFound = 0; + for (int j = 0; j < attrValues.Count; j++) { + ASN1 attrValue = attrValues [j]; + byte[] value = (byte[])dattrValues [j]; + + if (Compare (value, attrValue.Value)) { + attrValuesFound += 1; + } + } + if (attrValuesFound == attrValues.Count) { + bagAttributesFound += 1; + } + } + } + } + if (bagAttributesFound == bagAttributes.Count) { + ASN1 bagValue = safeBag [1]; + PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); + return new X509Certificate (crt.Content [0].Value); + } + } + } + } + + return null; + } + + public IDictionary GetAttributes (AsymmetricAlgorithm aa) + { + IDictionary result = new Hashtable (); + + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (keyBag) || sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + ASN1 safeBag = sb.ASN1; + + ASN1 bagValue = safeBag [1]; + AsymmetricAlgorithm saa = null; + if (sb.BagOID.Equals (keyBag)) { + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value); + byte[] privateKey = pki.PrivateKey; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + break; + } + Array.Clear (privateKey, 0, privateKey.Length); + } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { + PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); + byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); + PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted); + byte[] privateKey = pki.PrivateKey; + switch (privateKey [0]) { + case 0x02: + DSAParameters p = new DSAParameters (); // FIXME + saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p); + break; + case 0x30: + saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey); + break; + default: + break; + } + Array.Clear (privateKey, 0, privateKey.Length); + Array.Clear (decrypted, 0, decrypted.Length); + } + + if (saa != null && CompareAsymmetricAlgorithm (saa, aa)) { + if (safeBag.Count == 3) { + ASN1 bagAttributes = safeBag [2]; + + for (int i = 0; i < bagAttributes.Count; i++) { + ASN1 pkcs12Attribute = bagAttributes [i]; + ASN1 attrId = pkcs12Attribute [0]; + string aOid = ASN1Convert.ToOid (attrId); + ArrayList aValues = new ArrayList (); + + ASN1 attrValues = pkcs12Attribute [1]; + + for (int j = 0; j < attrValues.Count; j++) { + ASN1 attrValue = attrValues [j]; + aValues.Add (attrValue.Value); + } + result.Add (aOid, aValues); + } + } + } + } + } + + return result; + } + + public IDictionary GetAttributes (X509Certificate cert) + { + IDictionary result = new Hashtable (); + + foreach (SafeBag sb in _safeBags) { + if (sb.BagOID.Equals (certBag)) { + ASN1 safeBag = sb.ASN1; + ASN1 bagValue = safeBag [1]; + PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); + X509Certificate xc = new X509Certificate (crt.Content [0].Value); + + if (Compare (cert.RawData, xc.RawData)) { + if (safeBag.Count == 3) { + ASN1 bagAttributes = safeBag [2]; + + for (int i = 0; i < bagAttributes.Count; i++) { + ASN1 pkcs12Attribute = bagAttributes [i]; + ASN1 attrId = pkcs12Attribute [0]; + + string aOid = ASN1Convert.ToOid (attrId); + ArrayList aValues = new ArrayList (); + + ASN1 attrValues = pkcs12Attribute [1]; + + for (int j = 0; j < attrValues.Count; j++) { + ASN1 attrValue = attrValues [j]; + aValues.Add (attrValue.Value); + } + result.Add (aOid, aValues); + } + } + } + } + } + + return result; + } + + public void SaveToFile (string filename) + { + if (filename == null) + throw new ArgumentNullException ("filename"); + + using (FileStream fs = File.Create (filename)) { + byte[] data = GetBytes (); + fs.Write (data, 0, data.Length); + } + } + + public object Clone () + { + PKCS12 clone = null; + if (_password != null) { + clone = new PKCS12 (GetBytes (), Encoding.BigEndianUnicode.GetString (_password)); + } else { + clone = new PKCS12 (GetBytes ()); + } + clone.IterationCount = this.IterationCount; + + return clone; + } + + // static + + public const int CryptoApiPasswordLimit = 32; + + static private int password_max_length = Int32.MaxValue; + + // static properties + + // MS CryptoAPI limits the password to a maximum of 31 characters + // other implementations, like OpenSSL, have no such limitation. + // Setting a maximum value will truncate the password length to + // ensure compatibility with MS's PFXImportCertStore API. + static public int MaximumPasswordLength { + get { return password_max_length; } + set { + if (value < CryptoApiPasswordLimit) { + string msg = string.Format ("Maximum password length cannot be less than {0}.", CryptoApiPasswordLimit); + throw new ArgumentOutOfRangeException (msg); + } + password_max_length = value; + } + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/PKCS7.cs b/Emby.Server.Implementations/Cryptography/PKCS7.cs new file mode 100644 index 000000000..475854500 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/PKCS7.cs @@ -0,0 +1,1012 @@ +// +// PKCS7.cs: PKCS #7 - Cryptographic Message Syntax Standard +// http://www.rsasecurity.com/rsalabs/pkcs/pkcs-7/index.html +// +// Authors: +// Sebastien Pouliot <sebastien@ximian.com> +// Daniel Granath <dgranath#gmail.com> +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Security.Cryptography; + +namespace Emby.Server.Core.Cryptography +{ + + public sealed class PKCS7 { + + public class Oid { + // pkcs 1 + public const string rsaEncryption = "1.2.840.113549.1.1.1"; + // pkcs 7 + public const string data = "1.2.840.113549.1.7.1"; + public const string signedData = "1.2.840.113549.1.7.2"; + public const string envelopedData = "1.2.840.113549.1.7.3"; + public const string signedAndEnvelopedData = "1.2.840.113549.1.7.4"; + public const string digestedData = "1.2.840.113549.1.7.5"; + public const string encryptedData = "1.2.840.113549.1.7.6"; + // pkcs 9 + public const string contentType = "1.2.840.113549.1.9.3"; + public const string messageDigest = "1.2.840.113549.1.9.4"; + public const string signingTime = "1.2.840.113549.1.9.5"; + public const string countersignature = "1.2.840.113549.1.9.6"; + + public Oid () + { + } + } + + private PKCS7 () + { + } + + static public ASN1 Attribute (string oid, ASN1 value) + { + ASN1 attr = new ASN1 (0x30); + attr.Add (ASN1Convert.FromOid (oid)); + ASN1 aset = attr.Add (new ASN1 (0x31)); + aset.Add (value); + return attr; + } + + static public ASN1 AlgorithmIdentifier (string oid) + { + ASN1 ai = new ASN1 (0x30); + ai.Add (ASN1Convert.FromOid (oid)); + ai.Add (new ASN1 (0x05)); // NULL + return ai; + } + + static public ASN1 AlgorithmIdentifier (string oid, ASN1 parameters) + { + ASN1 ai = new ASN1 (0x30); + ai.Add (ASN1Convert.FromOid (oid)); + ai.Add (parameters); + return ai; + } + + /* + * IssuerAndSerialNumber ::= SEQUENCE { + * issuer Name, + * serialNumber CertificateSerialNumber + * } + */ + static public ASN1 IssuerAndSerialNumber (X509Certificate x509) + { + ASN1 issuer = null; + ASN1 serial = null; + ASN1 cert = new ASN1 (x509.RawData); + int tbs = 0; + bool flag = false; + while (tbs < cert[0].Count) { + ASN1 e = cert[0][tbs++]; + if (e.Tag == 0x02) + serial = e; + else if (e.Tag == 0x30) { + if (flag) { + issuer = e; + break; + } + flag = true; + } + } + ASN1 iasn = new ASN1 (0x30); + iasn.Add (issuer); + iasn.Add (serial); + return iasn; + } + + /* + * ContentInfo ::= SEQUENCE { + * contentType ContentType, + * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL + * } + * ContentType ::= OBJECT IDENTIFIER + */ + public class ContentInfo { + + private string contentType; + private ASN1 content; + + public ContentInfo () + { + content = new ASN1 (0xA0); + } + + public ContentInfo (string oid) : this () + { + contentType = oid; + } + + public ContentInfo (byte[] data) + : this (new ASN1 (data)) {} + + public ContentInfo (ASN1 asn1) + { + // SEQUENCE with 1 or 2 elements + if ((asn1.Tag != 0x30) || ((asn1.Count < 1) && (asn1.Count > 2))) + throw new ArgumentException ("Invalid ASN1"); + if (asn1[0].Tag != 0x06) + throw new ArgumentException ("Invalid contentType"); + contentType = ASN1Convert.ToOid (asn1[0]); + if (asn1.Count > 1) { + if (asn1[1].Tag != 0xA0) + throw new ArgumentException ("Invalid content"); + content = asn1[1]; + } + } + + public ASN1 ASN1 { + get { return GetASN1(); } + } + + public ASN1 Content { + get { return content; } + set { content = value; } + } + + public string ContentType { + get { return contentType; } + set { contentType = value; } + } + + internal ASN1 GetASN1 () + { + // ContentInfo ::= SEQUENCE { + ASN1 contentInfo = new ASN1 (0x30); + // contentType ContentType, -> ContentType ::= OBJECT IDENTIFIER + contentInfo.Add (ASN1Convert.FromOid (contentType)); + // content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL + if ((content != null) && (content.Count > 0)) + contentInfo.Add (content); + return contentInfo; + } + + public byte[] GetBytes () + { + return GetASN1 ().GetBytes (); + } + } + + /* + * EncryptedData ::= SEQUENCE { + * version INTEGER {edVer0(0)} (edVer0), + * encryptedContentInfo EncryptedContentInfo + * } + */ + public class EncryptedData { + private byte _version; + private ContentInfo _content; + private ContentInfo _encryptionAlgorithm; + private byte[] _encrypted; + + public EncryptedData () + { + _version = 0; + } + + public EncryptedData (byte[] data) + : this (new ASN1 (data)) + { + } + + public EncryptedData (ASN1 asn1) : this () + { + if ((asn1.Tag != 0x30) || (asn1.Count < 2)) + throw new ArgumentException ("Invalid EncryptedData"); + + if (asn1 [0].Tag != 0x02) + throw new ArgumentException ("Invalid version"); + _version = asn1 [0].Value [0]; + + ASN1 encryptedContentInfo = asn1 [1]; + if (encryptedContentInfo.Tag != 0x30) + throw new ArgumentException ("missing EncryptedContentInfo"); + + ASN1 contentType = encryptedContentInfo [0]; + if (contentType.Tag != 0x06) + throw new ArgumentException ("missing EncryptedContentInfo.ContentType"); + _content = new ContentInfo (ASN1Convert.ToOid (contentType)); + + ASN1 contentEncryptionAlgorithm = encryptedContentInfo [1]; + if (contentEncryptionAlgorithm.Tag != 0x30) + throw new ArgumentException ("missing EncryptedContentInfo.ContentEncryptionAlgorithmIdentifier"); + _encryptionAlgorithm = new ContentInfo (ASN1Convert.ToOid (contentEncryptionAlgorithm [0])); + _encryptionAlgorithm.Content = contentEncryptionAlgorithm [1]; + + ASN1 encryptedContent = encryptedContentInfo [2]; + if (encryptedContent.Tag != 0x80) + throw new ArgumentException ("missing EncryptedContentInfo.EncryptedContent"); + _encrypted = encryptedContent.Value; + } + + public ASN1 ASN1 { + get { return GetASN1(); } + } + + public ContentInfo ContentInfo { + get { return _content; } + } + + public ContentInfo EncryptionAlgorithm { + get { return _encryptionAlgorithm; } + } + + public byte[] EncryptedContent { + get { + if (_encrypted == null) + return null; + return (byte[]) _encrypted.Clone (); + } + } + + public byte Version { + get { return _version; } + set { _version = value; } + } + + // methods + + internal ASN1 GetASN1 () + { + return null; + } + + public byte[] GetBytes () + { + return GetASN1 ().GetBytes (); + } + } + + /* + * EnvelopedData ::= SEQUENCE { + * version Version, + * recipientInfos RecipientInfos, + * encryptedContentInfo EncryptedContentInfo + * } + * + * RecipientInfos ::= SET OF RecipientInfo + * + * EncryptedContentInfo ::= SEQUENCE { + * contentType ContentType, + * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, + * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL + * } + * + * EncryptedContent ::= OCTET STRING + * + */ + public class EnvelopedData { + private byte _version; + private ContentInfo _content; + private ContentInfo _encryptionAlgorithm; + private ArrayList _recipientInfos; + private byte[] _encrypted; + + public EnvelopedData () + { + _version = 0; + _content = new ContentInfo (); + _encryptionAlgorithm = new ContentInfo (); + _recipientInfos = new ArrayList (); + } + + public EnvelopedData (byte[] data) + : this (new ASN1 (data)) + { + } + + public EnvelopedData (ASN1 asn1) : this () + { + if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 3)) + throw new ArgumentException ("Invalid EnvelopedData"); + + if (asn1[0][0].Tag != 0x02) + throw new ArgumentException ("Invalid version"); + _version = asn1[0][0].Value[0]; + + // recipientInfos + + ASN1 recipientInfos = asn1 [0][1]; + if (recipientInfos.Tag != 0x31) + throw new ArgumentException ("missing RecipientInfos"); + for (int i=0; i < recipientInfos.Count; i++) { + ASN1 recipientInfo = recipientInfos [i]; + _recipientInfos.Add (new RecipientInfo (recipientInfo)); + } + + ASN1 encryptedContentInfo = asn1[0][2]; + if (encryptedContentInfo.Tag != 0x30) + throw new ArgumentException ("missing EncryptedContentInfo"); + + ASN1 contentType = encryptedContentInfo [0]; + if (contentType.Tag != 0x06) + throw new ArgumentException ("missing EncryptedContentInfo.ContentType"); + _content = new ContentInfo (ASN1Convert.ToOid (contentType)); + + ASN1 contentEncryptionAlgorithm = encryptedContentInfo [1]; + if (contentEncryptionAlgorithm.Tag != 0x30) + throw new ArgumentException ("missing EncryptedContentInfo.ContentEncryptionAlgorithmIdentifier"); + _encryptionAlgorithm = new ContentInfo (ASN1Convert.ToOid (contentEncryptionAlgorithm [0])); + _encryptionAlgorithm.Content = contentEncryptionAlgorithm [1]; + + ASN1 encryptedContent = encryptedContentInfo [2]; + if (encryptedContent.Tag != 0x80) + throw new ArgumentException ("missing EncryptedContentInfo.EncryptedContent"); + _encrypted = encryptedContent.Value; + } + + public ArrayList RecipientInfos { + get { return _recipientInfos; } + } + + public ASN1 ASN1 { + get { return GetASN1(); } + } + + public ContentInfo ContentInfo { + get { return _content; } + } + + public ContentInfo EncryptionAlgorithm { + get { return _encryptionAlgorithm; } + } + + public byte[] EncryptedContent { + get { + if (_encrypted == null) + return null; + return (byte[]) _encrypted.Clone (); + } + } + + public byte Version { + get { return _version; } + set { _version = value; } + } + + internal ASN1 GetASN1 () + { + // SignedData ::= SEQUENCE { + ASN1 signedData = new ASN1 (0x30); + // version Version -> Version ::= INTEGER +/* byte[] ver = { _version }; + signedData.Add (new ASN1 (0x02, ver)); + // digestAlgorithms DigestAlgorithmIdentifiers -> DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier + ASN1 digestAlgorithms = signedData.Add (new ASN1 (0x31)); + if (hashAlgorithm != null) { + string hashOid = CryptoConfig.MapNameToOid (hashAlgorithm); + digestAlgorithms.Add (AlgorithmIdentifier (hashOid)); + } + + // contentInfo ContentInfo, + ASN1 ci = contentInfo.ASN1; + signedData.Add (ci); + if ((mda == null) && (hashAlgorithm != null)) { + // automatically add the messageDigest authenticated attribute + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + byte[] idcHash = ha.ComputeHash (ci[1][0].Value); + ASN1 md = new ASN1 (0x30); + mda = Attribute (messageDigest, md.Add (new ASN1 (0x04, idcHash))); + signerInfo.AuthenticatedAttributes.Add (mda); + } + + // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, + if (certs.Count > 0) { + ASN1 a0 = signedData.Add (new ASN1 (0xA0)); + foreach (X509Certificate x in certs) + a0.Add (new ASN1 (x.RawData)); + } + // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, + if (crls.Count > 0) { + ASN1 a1 = signedData.Add (new ASN1 (0xA1)); + foreach (byte[] crl in crls) + a1.Add (new ASN1 (crl)); + } + // signerInfos SignerInfos -> SignerInfos ::= SET OF SignerInfo + ASN1 signerInfos = signedData.Add (new ASN1 (0x31)); + if (signerInfo.Key != null) + signerInfos.Add (signerInfo.ASN1);*/ + return signedData; + } + + public byte[] GetBytes () { + return GetASN1 ().GetBytes (); + } + } + + /* RecipientInfo ::= SEQUENCE { + * version Version, + * issuerAndSerialNumber IssuerAndSerialNumber, + * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, + * encryptedKey EncryptedKey + * } + * + * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier + * + * EncryptedKey ::= OCTET STRING + */ + public class RecipientInfo { + + private int _version; + private string _oid; + private byte[] _key; + private byte[] _ski; + private string _issuer; + private byte[] _serial; + + public RecipientInfo () {} + + public RecipientInfo (ASN1 data) + { + if (data.Tag != 0x30) + throw new ArgumentException ("Invalid RecipientInfo"); + + ASN1 version = data [0]; + if (version.Tag != 0x02) + throw new ArgumentException ("missing Version"); + _version = version.Value [0]; + + // issuerAndSerialNumber IssuerAndSerialNumber + ASN1 subjectIdentifierType = data [1]; + if ((subjectIdentifierType.Tag == 0x80) && (_version == 3)) { + _ski = subjectIdentifierType.Value; + } + else { + _issuer = X501.ToString (subjectIdentifierType [0]); + _serial = subjectIdentifierType [1].Value; + } + + ASN1 keyEncryptionAlgorithm = data [2]; + _oid = ASN1Convert.ToOid (keyEncryptionAlgorithm [0]); + + ASN1 encryptedKey = data [3]; + _key = encryptedKey.Value; + } + + public string Oid { + get { return _oid; } + } + + public byte[] Key { + get { + if (_key == null) + return null; + return (byte[]) _key.Clone (); + } + } + + public byte[] SubjectKeyIdentifier { + get { + if (_ski == null) + return null; + return (byte[]) _ski.Clone (); + } + } + + public string Issuer { + get { return _issuer; } + } + + public byte[] Serial { + get { + if (_serial == null) + return null; + return (byte[]) _serial.Clone (); + } + } + + public int Version { + get { return _version; } + } + } + + /* + * SignedData ::= SEQUENCE { + * version Version, + * digestAlgorithms DigestAlgorithmIdentifiers, + * contentInfo ContentInfo, + * certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, + * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, + * signerInfos SignerInfos + * } + */ + public class SignedData { + private byte version; + private string hashAlgorithm; + private ContentInfo contentInfo; + private X509CertificateCollection certs; + private ArrayList crls; + private SignerInfo signerInfo; + private bool mda; + private bool signed; + + public SignedData () + { + version = 1; + contentInfo = new ContentInfo (); + certs = new X509CertificateCollection (); + crls = new ArrayList (); + signerInfo = new SignerInfo (); + mda = true; + signed = false; + } + + public SignedData (byte[] data) + : this (new ASN1 (data)) + { + } + + public SignedData (ASN1 asn1) + { + if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 4)) + throw new ArgumentException ("Invalid SignedData"); + + if (asn1[0][0].Tag != 0x02) + throw new ArgumentException ("Invalid version"); + version = asn1[0][0].Value[0]; + + contentInfo = new ContentInfo (asn1[0][2]); + + int n = 3; + certs = new X509CertificateCollection (); + if (asn1[0][n].Tag == 0xA0) { + for (int i=0; i < asn1[0][n].Count; i++) + certs.Add (new X509Certificate (asn1[0][n][i].GetBytes ())); + n++; + } + + crls = new ArrayList (); + if (asn1[0][n].Tag == 0xA1) { + for (int i=0; i < asn1[0][n].Count; i++) + crls.Add (asn1[0][n][i].GetBytes ()); + n++; + } + + if (asn1[0][n].Count > 0) + signerInfo = new SignerInfo (asn1[0][n]); + else + signerInfo = new SignerInfo (); + + // Exchange hash algorithm Oid from SignerInfo + if (signerInfo.HashName != null) { + HashName = OidToName(signerInfo.HashName); + } + + // Check if SignerInfo has authenticated attributes + mda = (signerInfo.AuthenticatedAttributes.Count > 0); + } + + public ASN1 ASN1 { + get { return GetASN1(); } + } + + public X509CertificateCollection Certificates { + get { return certs; } + } + + public ContentInfo ContentInfo { + get { return contentInfo; } + } + + public ArrayList Crls { + get { return crls; } + } + + public string HashName { + get { return hashAlgorithm; } + // todo add validation + set { + hashAlgorithm = value; + signerInfo.HashName = value; + } + } + + public SignerInfo SignerInfo { + get { return signerInfo; } + } + + public byte Version { + get { return version; } + set { version = value; } + } + + public bool UseAuthenticatedAttributes { + get { return mda; } + set { mda = value; } + } + + public bool VerifySignature (AsymmetricAlgorithm aa) + { + if (aa == null) { + return false; + } + + RSAPKCS1SignatureDeformatter r = new RSAPKCS1SignatureDeformatter (aa); + r.SetHashAlgorithm (hashAlgorithm); + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + + byte[] signature = signerInfo.Signature; + byte[] hash = null; + + if (mda) { + ASN1 asn = new ASN1 (0x31); + foreach (ASN1 attr in signerInfo.AuthenticatedAttributes) + asn.Add (attr); + + hash = ha.ComputeHash (asn.GetBytes ()); + } else { + hash = ha.ComputeHash (contentInfo.Content[0].Value); + } + + if (hash != null && signature != null) { + return r.VerifySignature (hash, signature); + } + return false; + } + + internal string OidToName (string oid) + { + switch (oid) { + case "1.3.14.3.2.26" : + return "SHA1"; + case "1.2.840.113549.2.2" : + return "MD2"; + case "1.2.840.113549.2.5" : + return "MD5"; + case "2.16.840.1.101.3.4.1" : + return "SHA256"; + case "2.16.840.1.101.3.4.2" : + return "SHA384"; + case "2.16.840.1.101.3.4.3" : + return "SHA512"; + default : + break; + } + // Unknown Oid + return oid; + } + + internal ASN1 GetASN1 () + { + // SignedData ::= SEQUENCE { + ASN1 signedData = new ASN1 (0x30); + // version Version -> Version ::= INTEGER + byte[] ver = { version }; + signedData.Add (new ASN1 (0x02, ver)); + // digestAlgorithms DigestAlgorithmIdentifiers -> DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier + ASN1 digestAlgorithms = signedData.Add (new ASN1 (0x31)); + if (hashAlgorithm != null) { + string hashOid = CryptoConfig.MapNameToOID (hashAlgorithm); + digestAlgorithms.Add (AlgorithmIdentifier (hashOid)); + } + + // contentInfo ContentInfo, + ASN1 ci = contentInfo.ASN1; + signedData.Add (ci); + if (!signed && (hashAlgorithm != null)) { + if (mda) { + // Use authenticated attributes for signature + + // Automatically add the contentType authenticated attribute + ASN1 ctattr = Attribute (Oid.contentType, ci[0]); + signerInfo.AuthenticatedAttributes.Add (ctattr); + + // Automatically add the messageDigest authenticated attribute + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + byte[] idcHash = ha.ComputeHash (ci[1][0].Value); + ASN1 md = new ASN1 (0x30); + ASN1 mdattr = Attribute (Oid.messageDigest, md.Add (new ASN1 (0x04, idcHash))); + signerInfo.AuthenticatedAttributes.Add (mdattr); + } else { + // Don't use authenticated attributes for signature -- signature is content + RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (signerInfo.Key); + r.SetHashAlgorithm (hashAlgorithm); + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + byte[] sig = ha.ComputeHash (ci[1][0].Value); + signerInfo.Signature = r.CreateSignature (sig); + } + signed = true; + } + + // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, + if (certs.Count > 0) { + ASN1 a0 = signedData.Add (new ASN1 (0xA0)); + foreach (X509Certificate x in certs) + a0.Add (new ASN1 (x.RawData)); + } + // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, + if (crls.Count > 0) { + ASN1 a1 = signedData.Add (new ASN1 (0xA1)); + foreach (byte[] crl in crls) + a1.Add (new ASN1 (crl)); + } + // signerInfos SignerInfos -> SignerInfos ::= SET OF SignerInfo + ASN1 signerInfos = signedData.Add (new ASN1 (0x31)); + if (signerInfo.Key != null) + signerInfos.Add (signerInfo.ASN1); + return signedData; + } + + public byte[] GetBytes () + { + return GetASN1 ().GetBytes (); + } + } + + /* + * SignerInfo ::= SEQUENCE { + * version Version, + * issuerAndSerialNumber IssuerAndSerialNumber, + * digestAlgorithm DigestAlgorithmIdentifier, + * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, + * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, + * encryptedDigest EncryptedDigest, + * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL + * } + * + * For version == 3 issuerAndSerialNumber may be replaced by ... + */ + public class SignerInfo { + + private byte version; + private X509Certificate x509; + private string hashAlgorithm; + private AsymmetricAlgorithm key; + private ArrayList authenticatedAttributes; + private ArrayList unauthenticatedAttributes; + private byte[] signature; + private string issuer; + private byte[] serial; + private byte[] ski; + + public SignerInfo () + { + version = 1; + authenticatedAttributes = new ArrayList (); + unauthenticatedAttributes = new ArrayList (); + } + + public SignerInfo (byte[] data) + : this (new ASN1 (data)) {} + + // TODO: INCOMPLETE + public SignerInfo (ASN1 asn1) : this () + { + if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 5)) + throw new ArgumentException ("Invalid SignedData"); + + // version Version + if (asn1[0][0].Tag != 0x02) + throw new ArgumentException ("Invalid version"); + version = asn1[0][0].Value[0]; + + // issuerAndSerialNumber IssuerAndSerialNumber + ASN1 subjectIdentifierType = asn1 [0][1]; + if ((subjectIdentifierType.Tag == 0x80) && (version == 3)) { + ski = subjectIdentifierType.Value; + } + else { + issuer = X501.ToString (subjectIdentifierType [0]); + serial = subjectIdentifierType [1].Value; + } + + // digestAlgorithm DigestAlgorithmIdentifier + ASN1 digestAlgorithm = asn1 [0][2]; + hashAlgorithm = ASN1Convert.ToOid (digestAlgorithm [0]); + + // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL + int n = 3; + ASN1 authAttributes = asn1 [0][n]; + if (authAttributes.Tag == 0xA0) { + n++; + for (int i=0; i < authAttributes.Count; i++) + authenticatedAttributes.Add (authAttributes [i]); + } + + // digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier + n++; + // ASN1 digestEncryptionAlgorithm = asn1 [0][n++]; + // string digestEncryptionAlgorithmOid = ASN1Convert.ToOid (digestEncryptionAlgorithm [0]); + + // encryptedDigest EncryptedDigest + ASN1 encryptedDigest = asn1 [0][n++]; + if (encryptedDigest.Tag == 0x04) + signature = encryptedDigest.Value; + + // unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL + ASN1 unauthAttributes = asn1 [0][n]; + if ((unauthAttributes != null) && (unauthAttributes.Tag == 0xA1)) { + for (int i=0; i < unauthAttributes.Count; i++) + unauthenticatedAttributes.Add (unauthAttributes [i]); + } + } + + public string IssuerName { + get { return issuer; } + } + + public byte[] SerialNumber { + get { + if (serial == null) + return null; + return (byte[]) serial.Clone (); + } + } + + public byte[] SubjectKeyIdentifier { + get { + if (ski == null) + return null; + return (byte[]) ski.Clone (); + } + } + + public ASN1 ASN1 { + get { return GetASN1(); } + } + + public ArrayList AuthenticatedAttributes { + get { return authenticatedAttributes; } + } + + public X509Certificate Certificate { + get { return x509; } + set { x509 = value; } + } + + public string HashName { + get { return hashAlgorithm; } + set { hashAlgorithm = value; } + } + + public AsymmetricAlgorithm Key { + get { return key; } + set { key = value; } + } + + public byte[] Signature { + get { + if (signature == null) + return null; + return (byte[]) signature.Clone (); + } + + set { + if (value != null) { + signature = (byte[]) value.Clone (); + } + } + } + + public ArrayList UnauthenticatedAttributes { + get { return unauthenticatedAttributes; } + } + + public byte Version { + get { return version; } + set { version = value; } + } + + internal ASN1 GetASN1 () + { + if ((key == null) || (hashAlgorithm == null)) + return null; + byte[] ver = { version }; + ASN1 signerInfo = new ASN1 (0x30); + // version Version -> Version ::= INTEGER + signerInfo.Add (new ASN1 (0x02, ver)); + // issuerAndSerialNumber IssuerAndSerialNumber, + signerInfo.Add (PKCS7.IssuerAndSerialNumber (x509)); + // digestAlgorithm DigestAlgorithmIdentifier, + string hashOid = CryptoConfig.MapNameToOID (hashAlgorithm); + signerInfo.Add (AlgorithmIdentifier (hashOid)); + // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, + ASN1 aa = null; + if (authenticatedAttributes.Count > 0) { + aa = signerInfo.Add (new ASN1 (0xA0)); + authenticatedAttributes.Sort(new SortedSet ()); + foreach (ASN1 attr in authenticatedAttributes) + aa.Add (attr); + } + // digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, + if (key is RSA) { + signerInfo.Add (AlgorithmIdentifier (PKCS7.Oid.rsaEncryption)); + + if (aa != null) { + // Calculate the signature here; otherwise it must be set from SignedData + RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (key); + r.SetHashAlgorithm (hashAlgorithm); + byte[] tbs = aa.GetBytes (); + tbs [0] = 0x31; // not 0xA0 for signature + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + byte[] tbsHash = ha.ComputeHash (tbs); + signature = r.CreateSignature (tbsHash); + } + } + else if (key is DSA) { + throw new NotImplementedException ("not yet"); + } + else + throw new CryptographicException ("Unknown assymetric algorithm"); + // encryptedDigest EncryptedDigest, + signerInfo.Add (new ASN1 (0x04, signature)); + // unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL + if (unauthenticatedAttributes.Count > 0) { + ASN1 ua = signerInfo.Add (new ASN1 (0xA1)); + unauthenticatedAttributes.Sort(new SortedSet ()); + foreach (ASN1 attr in unauthenticatedAttributes) + ua.Add (attr); + } + return signerInfo; + } + + public byte[] GetBytes () + { + return GetASN1 ().GetBytes (); + } + } + + internal class SortedSet : IComparer { + + public int Compare (object x, object y) + { + if (x == null) + return (y == null) ? 0 : -1; + else if (y == null) + return 1; + + ASN1 xx = x as ASN1; + ASN1 yy = y as ASN1; + + if ((xx == null) || (yy == null)) { + throw new ArgumentException (("Invalid objects.")); + } + + byte[] xb = xx.GetBytes (); + byte[] yb = yy.GetBytes (); + + for (int i = 0; i < xb.Length; i++) { + if (i == yb.Length) + break; + + if (xb[i] == yb[i]) + continue; + + return (xb[i] < yb[i]) ? -1 : 1; + } + + // The arrays are equal up to the shortest of them. + if (xb.Length > yb.Length) + return 1; + else if (xb.Length < yb.Length) + return -1; + + return 0; + } + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/PKCS8.cs b/Emby.Server.Implementations/Cryptography/PKCS8.cs new file mode 100644 index 000000000..7e9a27298 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/PKCS8.cs @@ -0,0 +1,495 @@ +// +// PKCS8.cs: PKCS #8 - Private-Key Information Syntax Standard +// ftp://ftp.rsasecurity.com/pub/pkcs/doc/pkcs-8.doc +// +// Author: +// Sebastien Pouliot <sebastien@xamarin.com> +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com) +// Copyright 2013 Xamarin Inc. (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Security.Cryptography; + +namespace Emby.Server.Core.Cryptography +{ + + public sealed class PKCS8 { + + public enum KeyInfo { + PrivateKey, + EncryptedPrivateKey, + Unknown + } + + private PKCS8 () + { + } + + static public KeyInfo GetType (byte[] data) + { + if (data == null) + throw new ArgumentNullException ("data"); + + KeyInfo ki = KeyInfo.Unknown; + try { + ASN1 top = new ASN1 (data); + if ((top.Tag == 0x30) && (top.Count > 0)) { + ASN1 firstLevel = top [0]; + switch (firstLevel.Tag) { + case 0x02: + ki = KeyInfo.PrivateKey; + break; + case 0x30: + ki = KeyInfo.EncryptedPrivateKey; + break; + } + } + } + catch { + throw new CryptographicException ("invalid ASN.1 data"); + } + return ki; + } + + /* + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL + * } + * + * Version ::= INTEGER + * + * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + * + * PrivateKey ::= OCTET STRING + * + * Attributes ::= SET OF Attribute + */ + public class PrivateKeyInfo { + + private int _version; + private string _algorithm; + private byte[] _key; + private ArrayList _list; + + public PrivateKeyInfo () + { + _version = 0; + _list = new ArrayList (); + } + + public PrivateKeyInfo (byte[] data) : this () + { + Decode (data); + } + + // properties + + public string Algorithm { + get { return _algorithm; } + set { _algorithm = value; } + } + + public ArrayList Attributes { + get { return _list; } + } + + public byte[] PrivateKey { + get { + if (_key == null) + return null; + return (byte[]) _key.Clone (); + } + set { + if (value == null) + throw new ArgumentNullException ("PrivateKey"); + _key = (byte[]) value.Clone (); + } + } + + public int Version { + get { return _version; } + set { + if (value < 0) + throw new ArgumentOutOfRangeException ("negative version"); + _version = value; + } + } + + // methods + + private void Decode (byte[] data) + { + ASN1 privateKeyInfo = new ASN1 (data); + if (privateKeyInfo.Tag != 0x30) + throw new CryptographicException ("invalid PrivateKeyInfo"); + + ASN1 version = privateKeyInfo [0]; + if (version.Tag != 0x02) + throw new CryptographicException ("invalid version"); + _version = version.Value [0]; + + ASN1 privateKeyAlgorithm = privateKeyInfo [1]; + if (privateKeyAlgorithm.Tag != 0x30) + throw new CryptographicException ("invalid algorithm"); + + ASN1 algorithm = privateKeyAlgorithm [0]; + if (algorithm.Tag != 0x06) + throw new CryptographicException ("missing algorithm OID"); + _algorithm = ASN1Convert.ToOid (algorithm); + + ASN1 privateKey = privateKeyInfo [2]; + _key = privateKey.Value; + + // attributes [0] IMPLICIT Attributes OPTIONAL + if (privateKeyInfo.Count > 3) { + ASN1 attributes = privateKeyInfo [3]; + for (int i=0; i < attributes.Count; i++) { + _list.Add (attributes [i]); + } + } + } + + public byte[] GetBytes () + { + ASN1 privateKeyAlgorithm = new ASN1 (0x30); + privateKeyAlgorithm.Add (ASN1Convert.FromOid (_algorithm)); + privateKeyAlgorithm.Add (new ASN1 (0x05)); // ASN.1 NULL + + ASN1 pki = new ASN1 (0x30); + pki.Add (new ASN1 (0x02, new byte [1] { (byte) _version })); + pki.Add (privateKeyAlgorithm); + pki.Add (new ASN1 (0x04, _key)); + + if (_list.Count > 0) { + ASN1 attributes = new ASN1 (0xA0); + foreach (ASN1 attribute in _list) { + attributes.Add (attribute); + } + pki.Add (attributes); + } + + return pki.GetBytes (); + } + + // static methods + + static private byte[] RemoveLeadingZero (byte[] bigInt) + { + int start = 0; + int length = bigInt.Length; + if (bigInt [0] == 0x00) { + start = 1; + length--; + } + byte[] bi = new byte [length]; + Buffer.BlockCopy (bigInt, start, bi, 0, length); + return bi; + } + + static private byte[] Normalize (byte[] bigInt, int length) + { + if (bigInt.Length == length) + return bigInt; + else if (bigInt.Length > length) + return RemoveLeadingZero (bigInt); + else { + // pad with 0 + byte[] bi = new byte [length]; + Buffer.BlockCopy (bigInt, 0, bi, (length - bigInt.Length), bigInt.Length); + return bi; + } + } + + /* + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + */ + static public RSA DecodeRSA (byte[] keypair) + { + ASN1 privateKey = new ASN1 (keypair); + if (privateKey.Tag != 0x30) + throw new CryptographicException ("invalid private key format"); + + ASN1 version = privateKey [0]; + if (version.Tag != 0x02) + throw new CryptographicException ("missing version"); + + if (privateKey.Count < 9) + throw new CryptographicException ("not enough key parameters"); + + RSAParameters param = new RSAParameters (); + // note: MUST remove leading 0 - else MS wont import the key + param.Modulus = RemoveLeadingZero (privateKey [1].Value); + int keysize = param.Modulus.Length; + int keysize2 = (keysize >> 1); // half-size + // size must be normalized - else MS wont import the key + param.D = Normalize (privateKey [3].Value, keysize); + param.DP = Normalize (privateKey [6].Value, keysize2); + param.DQ = Normalize (privateKey [7].Value, keysize2); + param.Exponent = RemoveLeadingZero (privateKey [2].Value); + param.InverseQ = Normalize (privateKey [8].Value, keysize2); + param.P = Normalize (privateKey [4].Value, keysize2); + param.Q = Normalize (privateKey [5].Value, keysize2); + + RSA rsa = null; + try { + rsa = RSA.Create (); + rsa.ImportParameters (param); + } + catch (CryptographicException) { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + CspParameters csp = new CspParameters(); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + rsa = new RSACryptoServiceProvider(csp); + rsa.ImportParameters(param); + } + return rsa; + } + + /* + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + */ + static public byte[] Encode (RSA rsa) + { + RSAParameters param = rsa.ExportParameters (true); + + ASN1 rsaPrivateKey = new ASN1 (0x30); + rsaPrivateKey.Add (new ASN1 (0x02, new byte [1] { 0x00 })); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Modulus)); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Exponent)); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.D)); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.P)); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Q)); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DP)); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DQ)); + rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.InverseQ)); + + return rsaPrivateKey.GetBytes (); + } + + // DSA only encode it's X private key inside an ASN.1 INTEGER (Hint: Tag == 0x02) + // which isn't enough for rebuilding the keypair. The other parameters + // can be found (98% of the time) in the X.509 certificate associated + // with the private key or (2% of the time) the parameters are in it's + // issuer X.509 certificate (not supported in the .NET framework). + static public DSA DecodeDSA (byte[] privateKey, DSAParameters dsaParameters) + { + ASN1 pvk = new ASN1 (privateKey); + if (pvk.Tag != 0x02) + throw new CryptographicException ("invalid private key format"); + + // X is ALWAYS 20 bytes (no matter if the key length is 512 or 1024 bits) + dsaParameters.X = Normalize (pvk.Value, 20); + DSA dsa = DSA.Create (); + dsa.ImportParameters (dsaParameters); + return dsa; + } + + static public byte[] Encode (DSA dsa) + { + DSAParameters param = dsa.ExportParameters (true); + return ASN1Convert.FromUnsignedBigInteger (param.X).GetBytes (); + } + + static public byte[] Encode (AsymmetricAlgorithm aa) + { + if (aa is RSA) + return Encode ((RSA)aa); + else if (aa is DSA) + return Encode ((DSA)aa); + else + throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ()); + } + } + + /* + * EncryptedPrivateKeyInfo ::= SEQUENCE { + * encryptionAlgorithm EncryptionAlgorithmIdentifier, + * encryptedData EncryptedData + * } + * + * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier + * + * EncryptedData ::= OCTET STRING + * + * -- + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * -- from PKCS#5 + * PBEParameter ::= SEQUENCE { + * salt OCTET STRING SIZE(8), + * iterationCount INTEGER + * } + */ + public class EncryptedPrivateKeyInfo { + + private string _algorithm; + private byte[] _salt; + private int _iterations; + private byte[] _data; + + public EncryptedPrivateKeyInfo () {} + + public EncryptedPrivateKeyInfo (byte[] data) : this () + { + Decode (data); + } + + // properties + + public string Algorithm { + get { return _algorithm; } + set { _algorithm = value; } + } + + public byte[] EncryptedData { + get { return (_data == null) ? null : (byte[]) _data.Clone (); } + set { _data = (value == null) ? null : (byte[]) value.Clone (); } + } + + public byte[] Salt { + get { + if (_salt == null) { + RandomNumberGenerator rng = RandomNumberGenerator.Create (); + _salt = new byte [8]; + rng.GetBytes (_salt); + } + return (byte[]) _salt.Clone (); + } + set { _salt = (byte[]) value.Clone (); } + } + + public int IterationCount { + get { return _iterations; } + set { + if (value < 0) + throw new ArgumentOutOfRangeException ("IterationCount", "Negative"); + _iterations = value; + } + } + + // methods + + private void Decode (byte[] data) + { + ASN1 encryptedPrivateKeyInfo = new ASN1 (data); + if (encryptedPrivateKeyInfo.Tag != 0x30) + throw new CryptographicException ("invalid EncryptedPrivateKeyInfo"); + + ASN1 encryptionAlgorithm = encryptedPrivateKeyInfo [0]; + if (encryptionAlgorithm.Tag != 0x30) + throw new CryptographicException ("invalid encryptionAlgorithm"); + ASN1 algorithm = encryptionAlgorithm [0]; + if (algorithm.Tag != 0x06) + throw new CryptographicException ("invalid algorithm"); + _algorithm = ASN1Convert.ToOid (algorithm); + // parameters ANY DEFINED BY algorithm OPTIONAL + if (encryptionAlgorithm.Count > 1) { + ASN1 parameters = encryptionAlgorithm [1]; + if (parameters.Tag != 0x30) + throw new CryptographicException ("invalid parameters"); + + ASN1 salt = parameters [0]; + if (salt.Tag != 0x04) + throw new CryptographicException ("invalid salt"); + _salt = salt.Value; + + ASN1 iterationCount = parameters [1]; + if (iterationCount.Tag != 0x02) + throw new CryptographicException ("invalid iterationCount"); + _iterations = ASN1Convert.ToInt32 (iterationCount); + } + + ASN1 encryptedData = encryptedPrivateKeyInfo [1]; + if (encryptedData.Tag != 0x04) + throw new CryptographicException ("invalid EncryptedData"); + _data = encryptedData.Value; + } + + // Note: PKCS#8 doesn't define how to generate the key required for encryption + // so you're on your own. Just don't try to copy the big guys too much ;) + // Netscape: http://www.cs.auckland.ac.nz/~pgut001/pubs/netscape.txt + // Microsoft: http://www.cs.auckland.ac.nz/~pgut001/pubs/breakms.txt + public byte[] GetBytes () + { + if (_algorithm == null) + throw new CryptographicException ("No algorithm OID specified"); + + ASN1 encryptionAlgorithm = new ASN1 (0x30); + encryptionAlgorithm.Add (ASN1Convert.FromOid (_algorithm)); + + // parameters ANY DEFINED BY algorithm OPTIONAL + if ((_iterations > 0) || (_salt != null)) { + ASN1 salt = new ASN1 (0x04, _salt); + ASN1 iterations = ASN1Convert.FromInt32 (_iterations); + + ASN1 parameters = new ASN1 (0x30); + parameters.Add (salt); + parameters.Add (iterations); + encryptionAlgorithm.Add (parameters); + } + + // encapsulates EncryptedData into an OCTET STRING + ASN1 encryptedData = new ASN1 (0x04, _data); + + ASN1 encryptedPrivateKeyInfo = new ASN1 (0x30); + encryptedPrivateKeyInfo.Add (encryptionAlgorithm); + encryptedPrivateKeyInfo.Add (encryptedData); + + return encryptedPrivateKeyInfo.GetBytes (); + } + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/PfxGenerator.cs b/Emby.Server.Implementations/Cryptography/PfxGenerator.cs new file mode 100644 index 000000000..2d1dd649e --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/PfxGenerator.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections; +using System.Security.Cryptography; + +namespace Emby.Server.Core.Cryptography +{ + public class PFXGenerator + { + // http://www.freekpaans.nl/2015/04/creating-self-signed-x-509-certificates-using-mono-security/ + public static byte[] GeneratePfx(string certificateName, string password) + { + byte[] sn = GenerateSerialNumber(); + string subject = string.Format("CN={0}", certificateName); + + DateTime notBefore = DateTime.Now; + DateTime notAfter = DateTime.Now.AddYears(20); + + RSA subjectKey = new RSACryptoServiceProvider(2048); + + + string hashName = "SHA256"; + + X509CertificateBuilder cb = new X509CertificateBuilder(3); + cb.SerialNumber = sn; + cb.IssuerName = subject; + cb.NotBefore = notBefore; + cb.NotAfter = notAfter; + cb.SubjectName = subject; + cb.SubjectPublicKey = subjectKey; + cb.Hash = hashName; + + byte[] rawcert = cb.Sign(subjectKey); + + + PKCS12 p12 = new PKCS12(); + p12.Password = password; + + Hashtable attributes = GetAttributes(); + + p12.AddCertificate(new X509Certificate(rawcert), attributes); + p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes); + + return p12.GetBytes(); + } + + private static Hashtable GetAttributes() + { + ArrayList list = new ArrayList(); + // we use a fixed array to avoid endianess issues + // (in case some tools requires the ID to be 1). + list.Add(new byte[4] { 1, 0, 0, 0 }); + Hashtable attributes = new Hashtable(1); + attributes.Add(PKCS9.localKeyId, list); + return attributes; + } + + private static byte[] GenerateSerialNumber() + { + byte[] sn = Guid.NewGuid().ToByteArray(); + + //must be positive + if ((sn[0] & 0x80) == 0x80) + sn[0] -= 0x80; + return sn; + } + + public static byte[] GetCertificateForBytes(byte[] pfx, string password) + { + var pkcs = new PKCS12(pfx, password); + var cert = pkcs.GetCertificate(GetAttributes()); + + return cert.RawData; + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X501Name.cs b/Emby.Server.Implementations/Cryptography/X501Name.cs new file mode 100644 index 000000000..3318f95e2 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X501Name.cs @@ -0,0 +1,393 @@ +// +// X501Name.cs: X.501 Distinguished Names stuff +// +// Author: +// Sebastien Pouliot <sebastien@ximian.com> +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Globalization; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + + // References: + // 1. Information technology - Open Systems Interconnection - The Directory: Models + // http://www.itu.int/rec/recommendation.asp?type=items&lang=e&parent=T-REC-X.501-200102-I + // 2. RFC2253: Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names + // http://www.ietf.org/rfc/rfc2253.txt + + /* + * Name ::= CHOICE { RDNSequence } + * + * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + * + * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue + */ + public sealed class X501 { + + static byte[] countryName = { 0x55, 0x04, 0x06 }; + static byte[] organizationName = { 0x55, 0x04, 0x0A }; + static byte[] organizationalUnitName = { 0x55, 0x04, 0x0B }; + static byte[] commonName = { 0x55, 0x04, 0x03 }; + static byte[] localityName = { 0x55, 0x04, 0x07 }; + static byte[] stateOrProvinceName = { 0x55, 0x04, 0x08 }; + static byte[] streetAddress = { 0x55, 0x04, 0x09 }; + //static byte[] serialNumber = { 0x55, 0x04, 0x05 }; + static byte[] domainComponent = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 }; + static byte[] userid = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01 }; + static byte[] email = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 }; + static byte[] dnQualifier = { 0x55, 0x04, 0x2E }; + static byte[] title = { 0x55, 0x04, 0x0C }; + static byte[] surname = { 0x55, 0x04, 0x04 }; + static byte[] givenName = { 0x55, 0x04, 0x2A }; + static byte[] initial = { 0x55, 0x04, 0x2B }; + + private X501 () + { + } + + static public string ToString (ASN1 seq) + { + StringBuilder sb = new StringBuilder (); + for (int i = 0; i < seq.Count; i++) { + ASN1 entry = seq [i]; + AppendEntry (sb, entry, true); + + // separator (not on last iteration) + if (i < seq.Count - 1) + sb.Append (", "); + } + return sb.ToString (); + } + + static public string ToString (ASN1 seq, bool reversed, string separator, bool quotes) + { + StringBuilder sb = new StringBuilder (); + + if (reversed) { + for (int i = seq.Count - 1; i >= 0; i--) { + ASN1 entry = seq [i]; + AppendEntry (sb, entry, quotes); + + // separator (not on last iteration) + if (i > 0) + sb.Append (separator); + } + } else { + for (int i = 0; i < seq.Count; i++) { + ASN1 entry = seq [i]; + AppendEntry (sb, entry, quotes); + + // separator (not on last iteration) + if (i < seq.Count - 1) + sb.Append (separator); + } + } + return sb.ToString (); + } + + static private void AppendEntry (StringBuilder sb, ASN1 entry, bool quotes) + { + // multiple entries are valid + for (int k = 0; k < entry.Count; k++) { + ASN1 pair = entry [k]; + ASN1 s = pair [1]; + if (s == null) + continue; + + ASN1 poid = pair [0]; + if (poid == null) + continue; + + if (poid.CompareValue (countryName)) + sb.Append ("C="); + else if (poid.CompareValue (organizationName)) + sb.Append ("O="); + else if (poid.CompareValue (organizationalUnitName)) + sb.Append ("OU="); + else if (poid.CompareValue (commonName)) + sb.Append ("CN="); + else if (poid.CompareValue (localityName)) + sb.Append ("L="); + else if (poid.CompareValue (stateOrProvinceName)) + sb.Append ("S="); // NOTE: RFC2253 uses ST= + else if (poid.CompareValue (streetAddress)) + sb.Append ("STREET="); + else if (poid.CompareValue (domainComponent)) + sb.Append ("DC="); + else if (poid.CompareValue (userid)) + sb.Append ("UID="); + else if (poid.CompareValue (email)) + sb.Append ("E="); // NOTE: Not part of RFC2253 + else if (poid.CompareValue (dnQualifier)) + sb.Append ("dnQualifier="); + else if (poid.CompareValue (title)) + sb.Append ("T="); + else if (poid.CompareValue (surname)) + sb.Append ("SN="); + else if (poid.CompareValue (givenName)) + sb.Append ("G="); + else if (poid.CompareValue (initial)) + sb.Append ("I="); + else { + // unknown OID + sb.Append ("OID."); // NOTE: Not present as RFC2253 + sb.Append (ASN1Convert.ToOid (poid)); + sb.Append ("="); + } + + string sValue = null; + // 16bits or 8bits string ? TODO not complete (+special chars!) + if (s.Tag == 0x1E) { + // BMPSTRING + StringBuilder sb2 = new StringBuilder (); + for (int j = 1; j < s.Value.Length; j += 2) + sb2.Append ((char)s.Value[j]); + sValue = sb2.ToString (); + } else { + if (s.Tag == 0x14) + sValue = Encoding.UTF7.GetString (s.Value); + else + sValue = Encoding.UTF8.GetString (s.Value); + // in some cases we must quote (") the value + // Note: this doesn't seems to conform to RFC2253 + char[] specials = { ',', '+', '"', '\\', '<', '>', ';' }; + if (quotes) { + if ((sValue.IndexOfAny (specials, 0, sValue.Length) > 0) || + sValue.StartsWith (" ") || (sValue.EndsWith (" "))) + sValue = "\"" + sValue + "\""; + } + } + + sb.Append (sValue); + + // separator (not on last iteration) + if (k < entry.Count - 1) + sb.Append (", "); + } + } + + static private X520.AttributeTypeAndValue GetAttributeFromOid (string attributeType) + { + string s = attributeType.ToUpper (CultureInfo.InvariantCulture).Trim (); + switch (s) { + case "C": + return new X520.CountryName (); + case "O": + return new X520.OrganizationName (); + case "OU": + return new X520.OrganizationalUnitName (); + case "CN": + return new X520.CommonName (); + case "L": + return new X520.LocalityName (); + case "S": // Microsoft + case "ST": // RFC2253 + return new X520.StateOrProvinceName (); + case "E": // NOTE: Not part of RFC2253 + return new X520.EmailAddress (); + case "DC": // RFC2247 + return new X520.DomainComponent (); + case "UID": // RFC1274 + return new X520.UserId (); + case "DNQUALIFIER": + return new X520.DnQualifier (); + case "T": + return new X520.Title (); + case "SN": + return new X520.Surname (); + case "G": + return new X520.GivenName (); + case "I": + return new X520.Initial (); + default: + if (s.StartsWith ("OID.")) { + // MUST support it but it OID may be without it + return new X520.Oid (s.Substring (4)); + } else { + if (IsOid (s)) + return new X520.Oid (s); + else + return null; + } + } + } + + static private bool IsOid (string oid) + { + try { + ASN1 asn = ASN1Convert.FromOid (oid); + return (asn.Tag == 0x06); + } + catch { + return false; + } + } + + // no quote processing + static private X520.AttributeTypeAndValue ReadAttribute (string value, ref int pos) + { + while ((value[pos] == ' ') && (pos < value.Length)) + pos++; + + // get '=' position in substring + int equal = value.IndexOf ('=', pos); + if (equal == -1) { + string msg = ("No attribute found."); + throw new FormatException (msg); + } + + string s = value.Substring (pos, equal - pos); + X520.AttributeTypeAndValue atv = GetAttributeFromOid (s); + if (atv == null) { + string msg = ("Unknown attribute '{0}'."); + throw new FormatException (String.Format (msg, s)); + } + pos = equal + 1; // skip the '=' + return atv; + } + + static private bool IsHex (char c) + { + if (Char.IsDigit (c)) + return true; + char up = Char.ToUpper (c, CultureInfo.InvariantCulture); + return ((up >= 'A') && (up <= 'F')); + } + + static string ReadHex (string value, ref int pos) + { + StringBuilder sb = new StringBuilder (); + // it is (at least an) 8 bits char + sb.Append (value[pos++]); + sb.Append (value[pos]); + // look ahead for a 16 bits char + if ((pos < value.Length - 4) && (value[pos+1] == '\\') && IsHex (value[pos+2])) { + pos += 2; // pass last char and skip \ + sb.Append (value[pos++]); + sb.Append (value[pos]); + } + byte[] data = CryptoConvert.FromHex (sb.ToString ()); + return Encoding.UTF8.GetString (data); + } + + static private int ReadEscaped (StringBuilder sb, string value, int pos) + { + switch (value[pos]) { + case '\\': + case '"': + case '=': + case ';': + case '<': + case '>': + case '+': + case '#': + case ',': + sb.Append (value[pos]); + return pos; + default: + if (pos >= value.Length - 2) { + string msg = ("Malformed escaped value '{0}'."); + throw new FormatException (string.Format (msg, value.Substring (pos))); + } + // it's either a 8 bits or 16 bits char + sb.Append (ReadHex (value, ref pos)); + return pos; + } + } + + static private int ReadQuoted (StringBuilder sb, string value, int pos) + { + int original = pos; + while (pos <= value.Length) { + switch (value[pos]) { + case '"': + return pos; + case '\\': + return ReadEscaped (sb, value, pos); + default: + sb.Append (value[pos]); + pos++; + break; + } + } + string msg = ("Malformed quoted value '{0}'."); + throw new FormatException (string.Format (msg, value.Substring (original))); + } + + static private string ReadValue (string value, ref int pos) + { + int original = pos; + StringBuilder sb = new StringBuilder (); + while (pos < value.Length) { + switch (value [pos]) { + case '\\': + pos = ReadEscaped (sb, value, ++pos); + break; + case '"': + pos = ReadQuoted (sb, value, ++pos); + break; + case '=': + case ';': + case '<': + case '>': + string msg =("Malformed value '{0}' contains '{1}' outside quotes."); + throw new FormatException (string.Format (msg, value.Substring (original), value[pos])); + case '+': + case '#': + throw new NotImplementedException (); + case ',': + pos++; + return sb.ToString (); + default: + sb.Append (value[pos]); + break; + } + pos++; + } + return sb.ToString (); + } + + static public ASN1 FromString (string rdn) + { + if (rdn == null) + throw new ArgumentNullException ("rdn"); + + int pos = 0; + ASN1 asn1 = new ASN1 (0x30); + while (pos < rdn.Length) { + X520.AttributeTypeAndValue atv = ReadAttribute (rdn, ref pos); + atv.Value = ReadValue (rdn, ref pos); + + ASN1 sequence = new ASN1 (0x31); + sequence.Add (atv.GetASN1 ()); + asn1.Add (sequence); + } + return asn1; + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X509Builder.cs b/Emby.Server.Implementations/Cryptography/X509Builder.cs new file mode 100644 index 000000000..a2e292350 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X509Builder.cs @@ -0,0 +1,153 @@ +// +// X509Builder.cs: Abstract builder class for X509 objects +// +// Author: +// Sebastien Pouliot <sebastien@ximian.com> +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// (C) 2004 Novell (http://www.novell.com) +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Globalization; +using System.Security.Cryptography; + +namespace Emby.Server.Core.Cryptography +{ + + public abstract class X509Builder { + + private const string defaultHash = "SHA1"; + private string hashName; + + protected X509Builder () + { + hashName = defaultHash; + } + + protected abstract ASN1 ToBeSigned (string hashName); + + // move to PKCS1 + protected string GetOid (string hashName) + { + switch (hashName.ToLower (CultureInfo.InvariantCulture)) { + case "md2": + // md2withRSAEncryption (1 2 840 113549 1 1 2) + return "1.2.840.113549.1.1.2"; + case "md4": + // md4withRSAEncryption (1 2 840 113549 1 1 3) + return "1.2.840.113549.1.1.3"; + case "md5": + // md5withRSAEncryption (1 2 840 113549 1 1 4) + return "1.2.840.113549.1.1.4"; + case "sha1": + // sha1withRSAEncryption (1 2 840 113549 1 1 5) + return "1.2.840.113549.1.1.5"; + case "sha256": + // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } + return "1.2.840.113549.1.1.11"; + case "sha384": + // sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } + return "1.2.840.113549.1.1.12"; + case "sha512": + // sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } + return "1.2.840.113549.1.1.13"; + default: + throw new NotSupportedException ("Unknown hash algorithm " + hashName); + } + } + + public string Hash { + get { return hashName; } + set { + if (hashName == null) + hashName = defaultHash; + else + hashName = value; + } + } + + public virtual byte[] Sign (AsymmetricAlgorithm aa) + { + if (aa is RSA) + return Sign (aa as RSA); + else if (aa is DSA) + return Sign (aa as DSA); + else + throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString()); + } + + private byte[] Build (ASN1 tbs, string hashoid, byte[] signature) + { + ASN1 builder = new ASN1 (0x30); + builder.Add (tbs); + builder.Add (PKCS7.AlgorithmIdentifier (hashoid)); + // first byte of BITSTRING is the number of unused bits in the first byte + byte[] bitstring = new byte [signature.Length + 1]; + Buffer.BlockCopy (signature, 0, bitstring, 1, signature.Length); + builder.Add (new ASN1 (0x03, bitstring)); + return builder.GetBytes (); + } + + public virtual byte[] Sign (RSA key) + { + string oid = GetOid (hashName); + ASN1 tbs = ToBeSigned (oid); + HashAlgorithm ha = HashAlgorithm.Create (hashName); + byte[] hash = ha.ComputeHash (tbs.GetBytes ()); + + RSAPKCS1SignatureFormatter pkcs1 = new RSAPKCS1SignatureFormatter (key); + pkcs1.SetHashAlgorithm (hashName); + byte[] signature = pkcs1.CreateSignature (hash); + + return Build (tbs, oid, signature); + } + + public virtual byte[] Sign (DSA key) + { + string oid = "1.2.840.10040.4.3"; + ASN1 tbs = ToBeSigned (oid); + HashAlgorithm ha = HashAlgorithm.Create (hashName); + if (!(ha is SHA1)) + throw new NotSupportedException ("Only SHA-1 is supported for DSA"); + byte[] hash = ha.ComputeHash (tbs.GetBytes ()); + + DSASignatureFormatter dsa = new DSASignatureFormatter (key); + dsa.SetHashAlgorithm (hashName); + byte[] rs = dsa.CreateSignature (hash); + + // split R and S + byte[] r = new byte [20]; + Buffer.BlockCopy (rs, 0, r, 0, 20); + byte[] s = new byte [20]; + Buffer.BlockCopy (rs, 20, s, 0, 20); + ASN1 signature = new ASN1 (0x30); + signature.Add (new ASN1 (0x02, r)); + signature.Add (new ASN1 (0x02, s)); + + // dsaWithSha1 (1 2 840 10040 4 3) + return Build (tbs, oid, signature.GetBytes ()); + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X509Certificate.cs b/Emby.Server.Implementations/Cryptography/X509Certificate.cs new file mode 100644 index 000000000..3de58cfee --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X509Certificate.cs @@ -0,0 +1,563 @@ +// +// X509Certificates.cs: Handles X.509 certificates. +// +// Author: +// Sebastien Pouliot <sebastien@xamarin.com> +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) +// Copyright 2013 Xamarin Inc. (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Runtime.Serialization; +using System.Security.Cryptography; +using System.Security.Permissions; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + + // References: + // a. Internet X.509 Public Key Infrastructure Certificate and CRL Profile + // http://www.ietf.org/rfc/rfc3280.txt + // b. ITU ASN.1 standards (free download) + // http://www.itu.int/ITU-T/studygroups/com17/languages/ + + public class X509Certificate : ISerializable + { + + private ASN1 decoder; + + private byte[] m_encodedcert; + private DateTime m_from; + private DateTime m_until; + private ASN1 issuer; + private string m_issuername; + private string m_keyalgo; + private byte[] m_keyalgoparams; + private ASN1 subject; + private string m_subject; + private byte[] m_publickey; + private byte[] signature; + private string m_signaturealgo; + private byte[] m_signaturealgoparams; + private byte[] certhash; + private RSA _rsa; + private DSA _dsa; + + // from http://msdn.microsoft.com/en-gb/library/ff635835.aspx + private const string OID_DSA = "1.2.840.10040.4.1"; + private const string OID_RSA = "1.2.840.113549.1.1.1"; + + // from http://www.ietf.org/rfc/rfc2459.txt + // + //Certificate ::= SEQUENCE { + // tbsCertificate TBSCertificate, + // signatureAlgorithm AlgorithmIdentifier, + // signature BIT STRING } + // + //TBSCertificate ::= SEQUENCE { + // version [0] Version DEFAULT v1, + // serialNumber CertificateSerialNumber, + // signature AlgorithmIdentifier, + // issuer Name, + // validity Validity, + // subject Name, + // subjectPublicKeyInfo SubjectPublicKeyInfo, + // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + // -- If present, version shall be v2 or v3 + // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + // -- If present, version shall be v2 or v3 + // extensions [3] Extensions OPTIONAL + // -- If present, version shall be v3 -- } + private int version; + private byte[] serialnumber; + + private byte[] issuerUniqueID; + private byte[] subjectUniqueID; + private X509ExtensionCollection extensions; + + private static string encoding_error = ("Input data cannot be coded as a valid certificate."); + + + // that's were the real job is! + private void Parse (byte[] data) + { + try { + decoder = new ASN1 (data); + // Certificate + if (decoder.Tag != 0x30) + throw new CryptographicException (encoding_error); + // Certificate / TBSCertificate + if (decoder [0].Tag != 0x30) + throw new CryptographicException (encoding_error); + + ASN1 tbsCertificate = decoder [0]; + + int tbs = 0; + // Certificate / TBSCertificate / Version + ASN1 v = decoder [0][tbs]; + version = 1; // DEFAULT v1 + if ((v.Tag == 0xA0) && (v.Count > 0)) { + // version (optional) is present only in v2+ certs + version += v [0].Value [0]; // zero based + tbs++; + } + + // Certificate / TBSCertificate / CertificateSerialNumber + ASN1 sn = decoder [0][tbs++]; + if (sn.Tag != 0x02) + throw new CryptographicException (encoding_error); + serialnumber = sn.Value; + Array.Reverse (serialnumber, 0, serialnumber.Length); + + // Certificate / TBSCertificate / AlgorithmIdentifier + tbs++; + // ASN1 signatureAlgo = tbsCertificate.Element (tbs++, 0x30); + + issuer = tbsCertificate.Element (tbs++, 0x30); + m_issuername = X501.ToString (issuer); + + ASN1 validity = tbsCertificate.Element (tbs++, 0x30); + ASN1 notBefore = validity [0]; + m_from = ASN1Convert.ToDateTime (notBefore); + ASN1 notAfter = validity [1]; + m_until = ASN1Convert.ToDateTime (notAfter); + + subject = tbsCertificate.Element (tbs++, 0x30); + m_subject = X501.ToString (subject); + + ASN1 subjectPublicKeyInfo = tbsCertificate.Element (tbs++, 0x30); + + ASN1 algorithm = subjectPublicKeyInfo.Element (0, 0x30); + ASN1 algo = algorithm.Element (0, 0x06); + m_keyalgo = ASN1Convert.ToOid (algo); + // parameters ANY DEFINED BY algorithm OPTIONAL + // so we dont ask for a specific (Element) type and return DER + ASN1 parameters = algorithm [1]; + m_keyalgoparams = ((algorithm.Count > 1) ? parameters.GetBytes () : null); + + ASN1 subjectPublicKey = subjectPublicKeyInfo.Element (1, 0x03); + // we must drop th first byte (which is the number of unused bits + // in the BITSTRING) + int n = subjectPublicKey.Length - 1; + m_publickey = new byte [n]; + Buffer.BlockCopy (subjectPublicKey.Value, 1, m_publickey, 0, n); + + // signature processing + byte[] bitstring = decoder [2].Value; + // first byte contains unused bits in first byte + signature = new byte [bitstring.Length - 1]; + Buffer.BlockCopy (bitstring, 1, signature, 0, signature.Length); + + algorithm = decoder [1]; + algo = algorithm.Element (0, 0x06); + m_signaturealgo = ASN1Convert.ToOid (algo); + parameters = algorithm [1]; + if (parameters != null) + m_signaturealgoparams = parameters.GetBytes (); + else + m_signaturealgoparams = null; + + // Certificate / TBSCertificate / issuerUniqueID + ASN1 issuerUID = tbsCertificate.Element (tbs, 0x81); + if (issuerUID != null) { + tbs++; + issuerUniqueID = issuerUID.Value; + } + + // Certificate / TBSCertificate / subjectUniqueID + ASN1 subjectUID = tbsCertificate.Element (tbs, 0x82); + if (subjectUID != null) { + tbs++; + subjectUniqueID = subjectUID.Value; + } + + // Certificate / TBSCertificate / Extensions + ASN1 extns = tbsCertificate.Element (tbs, 0xA3); + if ((extns != null) && (extns.Count == 1)) + extensions = new X509ExtensionCollection (extns [0]); + else + extensions = new X509ExtensionCollection (null); + + // keep a copy of the original data + m_encodedcert = (byte[]) data.Clone (); + } + catch (Exception ex) { + throw new CryptographicException (encoding_error, ex); + } + } + + // constructors + + public X509Certificate (byte[] data) + { + if (data != null) { + // does it looks like PEM ? + if ((data.Length > 0) && (data [0] != 0x30)) { + try { + data = PEM ("CERTIFICATE", data); + } + catch (Exception ex) { + throw new CryptographicException (encoding_error, ex); + } + } + Parse (data); + } + } + + private byte[] GetUnsignedBigInteger (byte[] integer) + { + if (integer [0] == 0x00) { + // this first byte is added so we're sure it's an unsigned integer + // however we can't feed it into RSAParameters or DSAParameters + int length = integer.Length - 1; + byte[] uinteger = new byte [length]; + Buffer.BlockCopy (integer, 1, uinteger, 0, length); + return uinteger; + } + else + return integer; + } + + // public methods + + public DSA DSA { + get { + if (m_keyalgoparams == null) + throw new CryptographicException ("Missing key algorithm parameters."); + + if (_dsa == null && m_keyalgo == OID_DSA) { + DSAParameters dsaParams = new DSAParameters (); + // for DSA m_publickey contains 1 ASN.1 integer - Y + ASN1 pubkey = new ASN1 (m_publickey); + if ((pubkey == null) || (pubkey.Tag != 0x02)) + return null; + dsaParams.Y = GetUnsignedBigInteger (pubkey.Value); + + ASN1 param = new ASN1 (m_keyalgoparams); + if ((param == null) || (param.Tag != 0x30) || (param.Count < 3)) + return null; + if ((param [0].Tag != 0x02) || (param [1].Tag != 0x02) || (param [2].Tag != 0x02)) + return null; + dsaParams.P = GetUnsignedBigInteger (param [0].Value); + dsaParams.Q = GetUnsignedBigInteger (param [1].Value); + dsaParams.G = GetUnsignedBigInteger (param [2].Value); + + // BUG: MS BCL 1.0 can't import a key which + // isn't the same size as the one present in + // the container. + _dsa = (DSA) new DSACryptoServiceProvider (dsaParams.Y.Length << 3); + _dsa.ImportParameters (dsaParams); + } + return _dsa; + } + + set { + _dsa = value; + if (value != null) + _rsa = null; + } + } + + public X509ExtensionCollection Extensions { + get { return extensions; } + } + + public byte[] Hash { + get { + if (certhash == null) { + if ((decoder == null) || (decoder.Count < 1)) + return null; + string algo = PKCS1.HashNameFromOid (m_signaturealgo, false); + if (algo == null) + return null; + byte[] toBeSigned = decoder [0].GetBytes (); + using (var hash = PKCS1.CreateFromName (algo)) + certhash = hash.ComputeHash (toBeSigned, 0, toBeSigned.Length); + } + return (byte[]) certhash.Clone (); + } + } + + public virtual string IssuerName { + get { return m_issuername; } + } + + public virtual string KeyAlgorithm { + get { return m_keyalgo; } + } + + public virtual byte[] KeyAlgorithmParameters { + get { + if (m_keyalgoparams == null) + return null; + return (byte[]) m_keyalgoparams.Clone (); + } + set { m_keyalgoparams = value; } + } + + public virtual byte[] PublicKey { + get { + if (m_publickey == null) + return null; + return (byte[]) m_publickey.Clone (); + } + } + + public virtual RSA RSA { + get { + if (_rsa == null && m_keyalgo == OID_RSA) { + RSAParameters rsaParams = new RSAParameters (); + // for RSA m_publickey contains 2 ASN.1 integers + // the modulus and the public exponent + ASN1 pubkey = new ASN1 (m_publickey); + ASN1 modulus = pubkey [0]; + if ((modulus == null) || (modulus.Tag != 0x02)) + return null; + ASN1 exponent = pubkey [1]; + if (exponent.Tag != 0x02) + return null; + + rsaParams.Modulus = GetUnsignedBigInteger (modulus.Value); + rsaParams.Exponent = exponent.Value; + + // BUG: MS BCL 1.0 can't import a key which + // isn't the same size as the one present in + // the container. + int keySize = (rsaParams.Modulus.Length << 3); + _rsa = (RSA) new RSACryptoServiceProvider (keySize); + _rsa.ImportParameters (rsaParams); + } + return _rsa; + } + + set { + if (value != null) + _dsa = null; + _rsa = value; + } + } + + public virtual byte[] RawData { + get { + if (m_encodedcert == null) + return null; + return (byte[]) m_encodedcert.Clone (); + } + } + + public virtual byte[] SerialNumber { + get { + if (serialnumber == null) + return null; + return (byte[]) serialnumber.Clone (); + } + } + + public virtual byte[] Signature { + get { + if (signature == null) + return null; + + switch (m_signaturealgo) { + case "1.2.840.113549.1.1.2": // MD2 with RSA encryption + case "1.2.840.113549.1.1.3": // MD4 with RSA encryption + case "1.2.840.113549.1.1.4": // MD5 with RSA encryption + case "1.2.840.113549.1.1.5": // SHA-1 with RSA Encryption + case "1.3.14.3.2.29": // SHA1 with RSA signature + case "1.2.840.113549.1.1.11": // SHA-256 with RSA Encryption + case "1.2.840.113549.1.1.12": // SHA-384 with RSA Encryption + case "1.2.840.113549.1.1.13": // SHA-512 with RSA Encryption + case "1.3.36.3.3.1.2": // RIPEMD160 with RSA Encryption + return (byte[]) signature.Clone (); + + case "1.2.840.10040.4.3": // SHA-1 with DSA + ASN1 sign = new ASN1 (signature); + if ((sign == null) || (sign.Count != 2)) + return null; + byte[] part1 = sign [0].Value; + byte[] part2 = sign [1].Value; + byte[] sig = new byte [40]; + // parts may be less than 20 bytes (i.e. first bytes were 0x00) + // parts may be more than 20 bytes (i.e. first byte > 0x80, negative) + int s1 = System.Math.Max (0, part1.Length - 20); + int e1 = System.Math.Max (0, 20 - part1.Length); + Buffer.BlockCopy (part1, s1, sig, e1, part1.Length - s1); + int s2 = System.Math.Max (0, part2.Length - 20); + int e2 = System.Math.Max (20, 40 - part2.Length); + Buffer.BlockCopy (part2, s2, sig, e2, part2.Length - s2); + return sig; + + default: + throw new CryptographicException ("Unsupported hash algorithm: " + m_signaturealgo); + } + } + } + + public virtual string SignatureAlgorithm { + get { return m_signaturealgo; } + } + + public virtual byte[] SignatureAlgorithmParameters { + get { + if (m_signaturealgoparams == null) + return m_signaturealgoparams; + return (byte[]) m_signaturealgoparams.Clone (); + } + } + + public virtual string SubjectName { + get { return m_subject; } + } + + public virtual DateTime ValidFrom { + get { return m_from; } + } + + public virtual DateTime ValidUntil { + get { return m_until; } + } + + public int Version { + get { return version; } + } + + public bool IsCurrent { + get { return WasCurrent (DateTime.UtcNow); } + } + + public bool WasCurrent (DateTime instant) + { + return ((instant > ValidFrom) && (instant <= ValidUntil)); + } + + // uncommon v2 "extension" + public byte[] IssuerUniqueIdentifier { + get { + if (issuerUniqueID == null) + return null; + return (byte[]) issuerUniqueID.Clone (); + } + } + + // uncommon v2 "extension" + public byte[] SubjectUniqueIdentifier { + get { + if (subjectUniqueID == null) + return null; + return (byte[]) subjectUniqueID.Clone (); + } + } + + internal bool VerifySignature (DSA dsa) + { + // signatureOID is check by both this.Hash and this.Signature + DSASignatureDeformatter v = new DSASignatureDeformatter (dsa); + // only SHA-1 is supported + v.SetHashAlgorithm ("SHA1"); + return v.VerifySignature (this.Hash, this.Signature); + } + + internal bool VerifySignature (RSA rsa) + { + // SHA1-1 with DSA + if (m_signaturealgo == "1.2.840.10040.4.3") + return false; + RSAPKCS1SignatureDeformatter v = new RSAPKCS1SignatureDeformatter (rsa); + v.SetHashAlgorithm (PKCS1.HashNameFromOid (m_signaturealgo)); + return v.VerifySignature (this.Hash, this.Signature); + } + + public bool VerifySignature (AsymmetricAlgorithm aa) + { + if (aa == null) + throw new ArgumentNullException ("aa"); + + if (aa is RSA) + return VerifySignature (aa as RSA); + else if (aa is DSA) + return VerifySignature (aa as DSA); + else + throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString ()); + } + + public bool CheckSignature (byte[] hash, string hashAlgorithm, byte[] signature) + { + RSACryptoServiceProvider r = (RSACryptoServiceProvider) RSA; + return r.VerifyHash (hash, hashAlgorithm, signature); + } + + public bool IsSelfSigned { + get { + if (m_issuername != m_subject) + return false; + + try { + if (RSA != null) + return VerifySignature (RSA); + else if (DSA != null) + return VerifySignature (DSA); + else + return false; // e.g. a certificate with only DSA parameters + } + catch (CryptographicException) { + return false; + } + } + } + + public ASN1 GetIssuerName () + { + return issuer; + } + + public ASN1 GetSubjectName () + { + return subject; + } + + protected X509Certificate (SerializationInfo info, StreamingContext context) + { + Parse ((byte[]) info.GetValue ("raw", typeof (byte[]))); + } + + [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)] + public virtual void GetObjectData (SerializationInfo info, StreamingContext context) + { + info.AddValue ("raw", m_encodedcert); + // note: we NEVER serialize the private key + } + + static byte[] PEM (string type, byte[] data) + { + string pem = Encoding.ASCII.GetString (data); + string header = String.Format ("-----BEGIN {0}-----", type); + string footer = String.Format ("-----END {0}-----", type); + int start = pem.IndexOf (header) + header.Length; + int end = pem.IndexOf (footer, start); + string base64 = pem.Substring (start, (end - start)); + return Convert.FromBase64String (base64); + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X509CertificateBuilder.cs b/Emby.Server.Implementations/Cryptography/X509CertificateBuilder.cs new file mode 100644 index 000000000..cecff6578 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X509CertificateBuilder.cs @@ -0,0 +1,245 @@ +// +// X509CertificateBuilder.cs: Handles building of X.509 certificates. +// +// Author: +// Sebastien Pouliot <sebastien@ximian.com> +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// (C) 2004 Novell (http://www.novell.com) +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Security.Cryptography; + +namespace Emby.Server.Core.Cryptography +{ + // From RFC3280 + /* + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING + * } + * TBSCertificate ::= SEQUENCE { + * version [0] Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * extensions [3] Extensions OPTIONAL + * -- If present, version MUST be v3 -- + * } + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + * CertificateSerialNumber ::= INTEGER + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time + * } + * Time ::= CHOICE { + * utcTime UTCTime, + * generalTime GeneralizedTime + * } + */ + public class X509CertificateBuilder : X509Builder { + + private byte version; + private byte[] sn; + private string issuer; + private DateTime notBefore; + private DateTime notAfter; + private string subject; + private AsymmetricAlgorithm aa; + private byte[] issuerUniqueID; + private byte[] subjectUniqueID; + private X509ExtensionCollection extensions; + + public X509CertificateBuilder () : this (3) {} + + public X509CertificateBuilder (byte version) + { + if (version > 3) + throw new ArgumentException ("Invalid certificate version"); + this.version = version; + extensions = new X509ExtensionCollection (); + } + + public byte Version { + get { return version; } + set { version = value; } + } + + public byte[] SerialNumber { + get { return sn; } + set { sn = value; } + } + + public string IssuerName { + get { return issuer; } + set { issuer = value; } + } + + public DateTime NotBefore { + get { return notBefore; } + set { notBefore = value; } + } + + public DateTime NotAfter { + get { return notAfter; } + set { notAfter = value; } + } + + public string SubjectName { + get { return subject; } + set { subject = value; } + } + + public AsymmetricAlgorithm SubjectPublicKey { + get { return aa; } + set { aa = value; } + } + + public byte[] IssuerUniqueId { + get { return issuerUniqueID; } + set { issuerUniqueID = value; } + } + + public byte[] SubjectUniqueId { + get { return subjectUniqueID; } + set { subjectUniqueID = value; } + } + + public X509ExtensionCollection Extensions { + get { return extensions; } + } + + + /* SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ + private ASN1 SubjectPublicKeyInfo () + { + ASN1 keyInfo = new ASN1 (0x30); + if (aa is RSA) { + keyInfo.Add (PKCS7.AlgorithmIdentifier ("1.2.840.113549.1.1.1")); + RSAParameters p = (aa as RSA).ExportParameters (false); + /* RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER } -- e + */ + ASN1 key = new ASN1 (0x30); + key.Add (ASN1Convert.FromUnsignedBigInteger (p.Modulus)); + key.Add (ASN1Convert.FromUnsignedBigInteger (p.Exponent)); + keyInfo.Add (new ASN1 (UniqueIdentifier (key.GetBytes ()))); + } + else if (aa is DSA) { + DSAParameters p = (aa as DSA).ExportParameters (false); + /* Dss-Parms ::= SEQUENCE { + * p INTEGER, + * q INTEGER, + * g INTEGER } + */ + ASN1 param = new ASN1 (0x30); + param.Add (ASN1Convert.FromUnsignedBigInteger (p.P)); + param.Add (ASN1Convert.FromUnsignedBigInteger (p.Q)); + param.Add (ASN1Convert.FromUnsignedBigInteger (p.G)); + keyInfo.Add (PKCS7.AlgorithmIdentifier ("1.2.840.10040.4.1", param)); + ASN1 key = keyInfo.Add (new ASN1 (0x03)); + // DSAPublicKey ::= INTEGER -- public key, y + key.Add (ASN1Convert.FromUnsignedBigInteger (p.Y)); + } + else + throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString ()); + return keyInfo; + } + + private byte[] UniqueIdentifier (byte[] id) + { + // UniqueIdentifier ::= BIT STRING + ASN1 uid = new ASN1 (0x03); + // first byte in a BITSTRING is the number of unused bits in the first byte + byte[] v = new byte [id.Length + 1]; + Buffer.BlockCopy (id, 0, v, 1, id.Length); + uid.Value = v; + return uid.GetBytes (); + } + + protected override ASN1 ToBeSigned (string oid) + { + // TBSCertificate + ASN1 tbsCert = new ASN1 (0x30); + + if (version > 1) { + // TBSCertificate / [0] Version DEFAULT v1, + byte[] ver = { (byte)(version - 1) }; + ASN1 v = tbsCert.Add (new ASN1 (0xA0)); + v.Add (new ASN1 (0x02, ver)); + } + + // TBSCertificate / CertificateSerialNumber, + tbsCert.Add (new ASN1 (0x02, sn)); + + // TBSCertificate / AlgorithmIdentifier, + tbsCert.Add (PKCS7.AlgorithmIdentifier (oid)); + + // TBSCertificate / Name + tbsCert.Add (X501.FromString (issuer)); + + // TBSCertificate / Validity + ASN1 validity = tbsCert.Add (new ASN1 (0x30)); + // TBSCertificate / Validity / Time + validity.Add (ASN1Convert.FromDateTime (notBefore)); + // TBSCertificate / Validity / Time + validity.Add (ASN1Convert.FromDateTime (notAfter)); + + // TBSCertificate / Name + tbsCert.Add (X501.FromString (subject)); + + // TBSCertificate / SubjectPublicKeyInfo + tbsCert.Add (SubjectPublicKeyInfo ()); + + if (version > 1) { + // TBSCertificate / [1] IMPLICIT UniqueIdentifier OPTIONAL + if (issuerUniqueID != null) + tbsCert.Add (new ASN1 (0xA1, UniqueIdentifier (issuerUniqueID))); + + // TBSCertificate / [2] IMPLICIT UniqueIdentifier OPTIONAL + if (subjectUniqueID != null) + tbsCert.Add (new ASN1 (0xA1, UniqueIdentifier (subjectUniqueID))); + + // TBSCertificate / [3] Extensions OPTIONAL + if ((version > 2) && (extensions.Count > 0)) + tbsCert.Add (new ASN1 (0xA3, extensions.GetBytes ())); + } + + return tbsCert; + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X509CertificateCollection.cs b/Emby.Server.Implementations/Cryptography/X509CertificateCollection.cs new file mode 100644 index 000000000..a129bfc1a --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X509CertificateCollection.cs @@ -0,0 +1,201 @@ +// +// Based on System.Security.Cryptography.X509Certificates.X509CertificateCollection +// in System assembly +// +// Authors: +// Lawrence Pit (loz@cable.a2000.nl) +// Sebastien Pouliot <sebastien@ximian.com> +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; + +namespace Emby.Server.Core.Cryptography +{ + + [Serializable] + public class X509CertificateCollection : CollectionBase, IEnumerable { + + public X509CertificateCollection () + { + } + + public X509CertificateCollection (X509Certificate [] value) + { + AddRange (value); + } + + public X509CertificateCollection (X509CertificateCollection value) + { + AddRange (value); + } + + // Properties + + public X509Certificate this [int index] { + get { return (X509Certificate) InnerList [index]; } + set { InnerList [index] = value; } + } + + // Methods + + public int Add (X509Certificate value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + return InnerList.Add (value); + } + + public void AddRange (X509Certificate [] value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + for (int i = 0; i < value.Length; i++) + InnerList.Add (value [i]); + } + + public void AddRange (X509CertificateCollection value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + for (int i = 0; i < value.InnerList.Count; i++) + InnerList.Add (value [i]); + } + + public bool Contains (X509Certificate value) + { + return (IndexOf (value) != -1); + } + + public void CopyTo (X509Certificate[] array, int index) + { + InnerList.CopyTo (array, index); + } + + public new X509CertificateEnumerator GetEnumerator () + { + return new X509CertificateEnumerator (this); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return InnerList.GetEnumerator (); + } + + public override int GetHashCode () + { + return InnerList.GetHashCode (); + } + + public int IndexOf (X509Certificate value) + { + if (value == null) + throw new ArgumentNullException ("value"); + + byte[] hash = value.Hash; + for (int i=0; i < InnerList.Count; i++) { + X509Certificate x509 = (X509Certificate) InnerList [i]; + if (Compare (x509.Hash, hash)) + return i; + } + return -1; + } + + public void Insert (int index, X509Certificate value) + { + InnerList.Insert (index, value); + } + + public void Remove (X509Certificate value) + { + InnerList.Remove (value); + } + + // private stuff + + private bool Compare (byte[] array1, byte[] array2) + { + if ((array1 == null) && (array2 == null)) + return true; + if ((array1 == null) || (array2 == null)) + return false; + if (array1.Length != array2.Length) + return false; + for (int i=0; i < array1.Length; i++) { + if (array1 [i] != array2 [i]) + return false; + } + return true; + } + + // Inner Class + + public class X509CertificateEnumerator : IEnumerator { + + private IEnumerator enumerator; + + // Constructors + + public X509CertificateEnumerator (X509CertificateCollection mappings) + { + enumerator = ((IEnumerable) mappings).GetEnumerator (); + } + + // Properties + + public X509Certificate Current { + get { return (X509Certificate) enumerator.Current; } + } + + object IEnumerator.Current { + get { return enumerator.Current; } + } + + // Methods + + bool IEnumerator.MoveNext () + { + return enumerator.MoveNext (); + } + + void IEnumerator.Reset () + { + enumerator.Reset (); + } + + public bool MoveNext () + { + return enumerator.MoveNext (); + } + + public void Reset () + { + enumerator.Reset (); + } + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X509Extension.cs b/Emby.Server.Implementations/Cryptography/X509Extension.cs new file mode 100644 index 000000000..36b17deba --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X509Extension.cs @@ -0,0 +1,208 @@ +// +// X509Extension.cs: Base class for all X.509 extensions. +// +// Author: +// Sebastien Pouliot <sebastien@ximian.com> +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Globalization; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING + * } + */ + public class X509Extension { + + protected string extnOid; + protected bool extnCritical; + protected ASN1 extnValue; + + protected X509Extension () + { + extnCritical = false; + } + + public X509Extension (ASN1 asn1) + { + if ((asn1.Tag != 0x30) || (asn1.Count < 2)) + throw new ArgumentException (("Invalid X.509 extension.")); + if (asn1[0].Tag != 0x06) + throw new ArgumentException (("Invalid X.509 extension.")); + + extnOid = ASN1Convert.ToOid (asn1[0]); + extnCritical = ((asn1[1].Tag == 0x01) && (asn1[1].Value[0] == 0xFF)); + // last element is an octet string which may need to be decoded + extnValue = asn1 [asn1.Count - 1]; + if ((extnValue.Tag == 0x04) && (extnValue.Length > 0) && (extnValue.Count == 0)) { + try { + ASN1 encapsulated = new ASN1 (extnValue.Value); + extnValue.Value = null; + extnValue.Add (encapsulated); + } + catch { + // data isn't ASN.1 + } + } + Decode (); + } + + public X509Extension (X509Extension extension) + { + if (extension == null) + throw new ArgumentNullException ("extension"); + if ((extension.Value == null) || (extension.Value.Tag != 0x04) || (extension.Value.Count != 1)) + throw new ArgumentException (("Invalid X.509 extension.")); + + extnOid = extension.Oid; + extnCritical = extension.Critical; + extnValue = extension.Value; + Decode (); + } + + // encode the extension *into* an OCTET STRING + protected virtual void Decode () + { + } + + // decode the extension from *inside* an OCTET STRING + protected virtual void Encode () + { + } + + public ASN1 ASN1 { + get { + ASN1 extension = new ASN1 (0x30); + extension.Add (ASN1Convert.FromOid (extnOid)); + if (extnCritical) + extension.Add (new ASN1 (0x01, new byte [1] { 0xFF })); + Encode (); + extension.Add (extnValue); + return extension; + } + } + + public string Oid { + get { return extnOid; } + } + + public bool Critical { + get { return extnCritical; } + set { extnCritical = value; } + } + + // this gets overrided with more meaningful names + public virtual string Name { + get { return extnOid; } + } + + public ASN1 Value { + get { + if (extnValue == null) { + Encode (); + } + return extnValue; + } + } + + public override bool Equals (object obj) + { + if (obj == null) + return false; + + X509Extension ex = (obj as X509Extension); + if (ex == null) + return false; + + if (extnCritical != ex.extnCritical) + return false; + if (extnOid != ex.extnOid) + return false; + if (extnValue.Length != ex.extnValue.Length) + return false; + + for (int i=0; i < extnValue.Length; i++) { + if (extnValue [i] != ex.extnValue [i]) + return false; + } + return true; + } + + public byte[] GetBytes () + { + return ASN1.GetBytes (); + } + + public override int GetHashCode () + { + // OID should be unique in a collection of extensions + return extnOid.GetHashCode (); + } + + private void WriteLine (StringBuilder sb, int n, int pos) + { + byte[] value = extnValue.Value; + int p = pos; + for (int j=0; j < 8; j++) { + if (j < n) { + sb.Append (value [p++].ToString ("X2", CultureInfo.InvariantCulture)); + sb.Append (" "); + } + else + sb.Append (" "); + } + sb.Append (" "); + p = pos; + for (int j=0; j < n; j++) { + byte b = value [p++]; + if (b < 0x20) + sb.Append ("."); + else + sb.Append (Convert.ToChar (b)); + } + sb.Append (Environment.NewLine); + } + + public override string ToString () + { + StringBuilder sb = new StringBuilder (); + int div = (extnValue.Length >> 3); + int rem = (extnValue.Length - (div << 3)); + int x = 0; + for (int i=0; i < div; i++) { + WriteLine (sb, 8, x); + x += 8; + } + WriteLine (sb, rem, x); + return sb.ToString (); + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X509Extensions.cs b/Emby.Server.Implementations/Cryptography/X509Extensions.cs new file mode 100644 index 000000000..018a04d79 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X509Extensions.cs @@ -0,0 +1,195 @@ +// +// X509Extensions.cs: Handles X.509 extensions. +// +// Author: +// Sebastien Pouliot <sebastien@ximian.com> +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// (C) 2004 Novell (http://www.novell.com) +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; + +namespace Emby.Server.Core.Cryptography +{ + /* + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + * + * Note: 1..MAX -> There shouldn't be 0 Extensions in the ASN1 structure + */ + public sealed class X509ExtensionCollection : CollectionBase, IEnumerable { + + private bool readOnly; + + public X509ExtensionCollection () : base () + { + } + + public X509ExtensionCollection (ASN1 asn1) : this () + { + readOnly = true; + if (asn1 == null) + return; + if (asn1.Tag != 0x30) + throw new Exception ("Invalid extensions format"); + for (int i=0; i < asn1.Count; i++) { + X509Extension extension = new X509Extension (asn1 [i]); + InnerList.Add (extension); + } + } + + public int Add (X509Extension extension) + { + if (extension == null) + throw new ArgumentNullException ("extension"); + if (readOnly) + throw new NotSupportedException ("Extensions are read only"); + + return InnerList.Add (extension); + } + + public void AddRange (X509Extension[] extension) + { + if (extension == null) + throw new ArgumentNullException ("extension"); + if (readOnly) + throw new NotSupportedException ("Extensions are read only"); + + for (int i = 0; i < extension.Length; i++) + InnerList.Add (extension [i]); + } + + public void AddRange (X509ExtensionCollection collection) + { + if (collection == null) + throw new ArgumentNullException ("collection"); + if (readOnly) + throw new NotSupportedException ("Extensions are read only"); + + for (int i = 0; i < collection.InnerList.Count; i++) + InnerList.Add (collection [i]); + } + + public bool Contains (X509Extension extension) + { + return (IndexOf (extension) != -1); + } + + public bool Contains (string oid) + { + return (IndexOf (oid) != -1); + } + + public void CopyTo (X509Extension[] extensions, int index) + { + if (extensions == null) + throw new ArgumentNullException ("extensions"); + + InnerList.CopyTo (extensions, index); + } + + public int IndexOf (X509Extension extension) + { + if (extension == null) + throw new ArgumentNullException ("extension"); + + for (int i=0; i < InnerList.Count; i++) { + X509Extension ex = (X509Extension) InnerList [i]; + if (ex.Equals (extension)) + return i; + } + return -1; + } + + public int IndexOf (string oid) + { + if (oid == null) + throw new ArgumentNullException ("oid"); + + for (int i=0; i < InnerList.Count; i++) { + X509Extension ex = (X509Extension) InnerList [i]; + if (ex.Oid == oid) + return i; + } + return -1; + } + + public void Insert (int index, X509Extension extension) + { + if (extension == null) + throw new ArgumentNullException ("extension"); + + InnerList.Insert (index, extension); + } + + public void Remove (X509Extension extension) + { + if (extension == null) + throw new ArgumentNullException ("extension"); + + InnerList.Remove (extension); + } + + public void Remove (string oid) + { + if (oid == null) + throw new ArgumentNullException ("oid"); + + int index = IndexOf (oid); + if (index != -1) + InnerList.RemoveAt (index); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return InnerList.GetEnumerator (); + } + + public X509Extension this [int index] { + get { return (X509Extension) InnerList [index]; } + } + + public X509Extension this [string oid] { + get { + int index = IndexOf (oid); + if (index == -1) + return null; + return (X509Extension) InnerList [index]; + } + } + + public byte[] GetBytes () + { + if (InnerList.Count < 1) + return null; + ASN1 sequence = new ASN1 (0x30); + for (int i=0; i < InnerList.Count; i++) { + X509Extension x = (X509Extension) InnerList [i]; + sequence.Add (x.ASN1); + } + return sequence.GetBytes (); + } + } +} diff --git a/Emby.Server.Implementations/Cryptography/X520Attributes.cs b/Emby.Server.Implementations/Cryptography/X520Attributes.cs new file mode 100644 index 000000000..da7fd2b82 --- /dev/null +++ b/Emby.Server.Implementations/Cryptography/X520Attributes.cs @@ -0,0 +1,346 @@ +// +// X520.cs: X.520 related stuff (attributes, RDN) +// +// Author: +// Sebastien Pouliot <sebastien@ximian.com> +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +namespace Emby.Server.Core.Cryptography +{ + + // References: + // 1. Information technology - Open Systems Interconnection - The Directory: Selected attribute types + // http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.520 + // 2. Internet X.509 Public Key Infrastructure Certificate and CRL Profile + // http://www.ietf.org/rfc/rfc3280.txt + // 3. A Summary of the X.500(96) User Schema for use with LDAPv3 + // http://www.faqs.org/rfcs/rfc2256.html + // 4. RFC 2247 - Using Domains in LDAP/X.500 Distinguished Names + // http://www.faqs.org/rfcs/rfc2247.html + + /* + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue + * } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + */ + public class X520 { + + public abstract class AttributeTypeAndValue { + private string oid; + private string attrValue; + private int upperBound; + private byte encoding; + + protected AttributeTypeAndValue (string oid, int upperBound) + { + this.oid = oid; + this.upperBound = upperBound; + this.encoding = 0xFF; + } + + protected AttributeTypeAndValue (string oid, int upperBound, byte encoding) + { + this.oid = oid; + this.upperBound = upperBound; + this.encoding = encoding; + } + + public string Value { + get { return attrValue; } + set { + if ((attrValue != null) && (attrValue.Length > upperBound)) { + string msg = ("Value length bigger than upperbound ({0})."); + throw new FormatException (String.Format (msg, upperBound)); + } + attrValue = value; + } + } + + public ASN1 ASN1 { + get { return GetASN1 (); } + } + + internal ASN1 GetASN1 (byte encoding) + { + byte encode = encoding; + if (encode == 0xFF) + encode = SelectBestEncoding (); + + ASN1 asn1 = new ASN1 (0x30); + asn1.Add (ASN1Convert.FromOid (oid)); + switch (encode) { + case 0x13: + // PRINTABLESTRING + asn1.Add (new ASN1 (0x13, Encoding.ASCII.GetBytes (attrValue))); + break; + case 0x16: + // IA5STRING + asn1.Add (new ASN1 (0x16, Encoding.ASCII.GetBytes (attrValue))); + break; + case 0x1E: + // BMPSTRING + asn1.Add (new ASN1 (0x1E, Encoding.BigEndianUnicode.GetBytes (attrValue))); + break; + } + return asn1; + } + + internal ASN1 GetASN1 () + { + return GetASN1 (encoding); + } + + public byte[] GetBytes (byte encoding) + { + return GetASN1 (encoding) .GetBytes (); + } + + public byte[] GetBytes () + { + return GetASN1 () .GetBytes (); + } + + private byte SelectBestEncoding () + { + foreach (char c in attrValue) { + switch (c) { + case '@': + case '_': + return 0x1E; // BMPSTRING + default: + if (c > 127) + return 0x1E; // BMPSTRING + break; + } + } + return 0x13; // PRINTABLESTRING + } + } + + public class Name : AttributeTypeAndValue { + + public Name () : base ("2.5.4.41", 32768) + { + } + } + + public class CommonName : AttributeTypeAndValue { + + public CommonName () : base ("2.5.4.3", 64) + { + } + } + + // RFC2256, Section 5.6 + public class SerialNumber : AttributeTypeAndValue { + + // max length 64 bytes, Printable String only + public SerialNumber () + : base ("2.5.4.5", 64, 0x13) + { + } + } + + public class LocalityName : AttributeTypeAndValue { + + public LocalityName () : base ("2.5.4.7", 128) + { + } + } + + public class StateOrProvinceName : AttributeTypeAndValue { + + public StateOrProvinceName () : base ("2.5.4.8", 128) + { + } + } + + public class OrganizationName : AttributeTypeAndValue { + + public OrganizationName () : base ("2.5.4.10", 64) + { + } + } + + public class OrganizationalUnitName : AttributeTypeAndValue { + + public OrganizationalUnitName () : base ("2.5.4.11", 64) + { + } + } + + // NOTE: Not part of RFC2253 + public class EmailAddress : AttributeTypeAndValue { + + public EmailAddress () : base ("1.2.840.113549.1.9.1", 128, 0x16) + { + } + } + + // RFC2247, Section 4 + public class DomainComponent : AttributeTypeAndValue { + + // no maximum length defined + public DomainComponent () + : base ("0.9.2342.19200300.100.1.25", Int32.MaxValue, 0x16) + { + } + } + + // RFC1274, Section 9.3.1 + public class UserId : AttributeTypeAndValue { + + public UserId () + : base ("0.9.2342.19200300.100.1.1", 256) + { + } + } + + public class Oid : AttributeTypeAndValue { + + public Oid (string oid) + : base (oid, Int32.MaxValue) + { + } + } + + /* -- Naming attributes of type X520Title + * id-at-title AttributeType ::= { id-at 12 } + * + * X520Title ::= CHOICE { + * teletexString TeletexString (SIZE (1..ub-title)), + * printableString PrintableString (SIZE (1..ub-title)), + * universalString UniversalString (SIZE (1..ub-title)), + * utf8String UTF8String (SIZE (1..ub-title)), + * bmpString BMPString (SIZE (1..ub-title)) + * } + */ + public class Title : AttributeTypeAndValue { + + public Title () : base ("2.5.4.12", 64) + { + } + } + + public class CountryName : AttributeTypeAndValue { + + // (0x13) PRINTABLESTRING + public CountryName () : base ("2.5.4.6", 2, 0x13) + { + } + } + + public class DnQualifier : AttributeTypeAndValue { + + // (0x13) PRINTABLESTRING + public DnQualifier () : base ("2.5.4.46", 2, 0x13) + { + } + } + + public class Surname : AttributeTypeAndValue { + + public Surname () : base ("2.5.4.4", 32768) + { + } + } + + public class GivenName : AttributeTypeAndValue { + + public GivenName () : base ("2.5.4.42", 16) + { + } + } + + public class Initial : AttributeTypeAndValue { + + public Initial () : base ("2.5.4.43", 5) + { + } + } + + } + + /* From RFC3280 + * -- specifications of Upper Bounds MUST be regarded as mandatory + * -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter + * + * -- Upper Bounds + * + * ub-name INTEGER ::= 32768 + * ub-common-name INTEGER ::= 64 + * ub-locality-name INTEGER ::= 128 + * ub-state-name INTEGER ::= 128 + * ub-organization-name INTEGER ::= 64 + * ub-organizational-unit-name INTEGER ::= 64 + * ub-title INTEGER ::= 64 + * ub-serial-number INTEGER ::= 64 + * ub-match INTEGER ::= 128 + * ub-emailaddress-length INTEGER ::= 128 + * ub-common-name-length INTEGER ::= 64 + * ub-country-name-alpha-length INTEGER ::= 2 + * ub-country-name-numeric-length INTEGER ::= 3 + * ub-domain-defined-attributes INTEGER ::= 4 + * ub-domain-defined-attribute-type-length INTEGER ::= 8 + * ub-domain-defined-attribute-value-length INTEGER ::= 128 + * ub-domain-name-length INTEGER ::= 16 + * ub-extension-attributes INTEGER ::= 256 + * ub-e163-4-number-length INTEGER ::= 15 + * ub-e163-4-sub-address-length INTEGER ::= 40 + * ub-generation-qualifier-length INTEGER ::= 3 + * ub-given-name-length INTEGER ::= 16 + * ub-initials-length INTEGER ::= 5 + * ub-integer-options INTEGER ::= 256 + * ub-numeric-user-id-length INTEGER ::= 32 + * ub-organization-name-length INTEGER ::= 64 + * ub-organizational-unit-name-length INTEGER ::= 32 + * ub-organizational-units INTEGER ::= 4 + * ub-pds-name-length INTEGER ::= 16 + * ub-pds-parameter-length INTEGER ::= 30 + * ub-pds-physical-address-lines INTEGER ::= 6 + * ub-postal-code-length INTEGER ::= 16 + * ub-pseudonym INTEGER ::= 128 + * ub-surname-length INTEGER ::= 40 + * ub-terminal-id-length INTEGER ::= 24 + * ub-unformatted-address-length INTEGER ::= 180 + * ub-x121-address-length INTEGER ::= 16 + * + * -- Note - upper bounds on string types, such as TeletexString, are + * -- measured in characters. Excepting PrintableString or IA5String, a + * -- significantly greater number of octets will be required to hold + * -- such a value. As a minimum, 16 octets, or twice the specified + * -- upper bound, whichever is the larger, should be allowed for + * -- TeletexString. For UTF8String or UniversalString at least four + * -- times the upper bound should be allowed. + */ +} diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs index 462ff3e47..a34c90cb4 100644 --- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs +++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs @@ -131,25 +131,11 @@ namespace Emby.Server.Implementations.Data { queries.Add("PRAGMA temp_store = memory"); } - - ////foreach (var query in queries) - ////{ - //// db.Execute(query); - ////} - - //Logger.Info("synchronous: " + db.Query("PRAGMA synchronous").SelectScalarString().First()); - //Logger.Info("temp_store: " + db.Query("PRAGMA temp_store").SelectScalarString().First()); - - /*if (!string.Equals(_defaultWal, "wal", StringComparison.OrdinalIgnoreCase)) + else { - queries.Add("PRAGMA journal_mode=WAL"); - - using (WriteLock.Write()) - { - db.ExecuteAll(string.Join(";", queries.ToArray())); - } + queries.Add("PRAGMA temp_store = file"); } - else*/ + foreach (var query in queries) { db.Execute(query); @@ -208,6 +194,13 @@ namespace Emby.Server.Implementations.Data "pragma temp_store = memory" }); } + else + { + queries.AddRange(new List<string> + { + "pragma temp_store = file" + }); + } db.ExecuteAll(string.Join(";", queries.ToArray())); Logger.Info("PRAGMA synchronous=" + db.Query("PRAGMA synchronous").SelectScalarString().First()); diff --git a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs index f43e45441..37ba2eb5f 100644 --- a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs +++ b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs @@ -11,9 +11,6 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Model.IO; -using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Model.Tasks; namespace Emby.Server.Implementations.Data { @@ -34,31 +31,9 @@ namespace Emby.Server.Implementations.Data _appPaths = appPaths; } - public string Name + public Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - get { return "Clean Database"; } - } - - public string Description - { - get { return "Deletes obsolete content from the database."; } - } - - public string Category - { - get { return "Library"; } - } - - public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) - { - // Ensure these objects are lazy loaded. - // Without this there is a deadlock that will need to be investigated - var rootChildren = _libraryManager.RootFolder.Children.ToList(); - rootChildren = _libraryManager.GetUserRootFolder().Children.ToList(); - - await CleanDeadItems(cancellationToken, progress).ConfigureAwait(false); - - //await _itemRepo.UpdateInheritedValues(cancellationToken).ConfigureAwait(false); + return CleanDeadItems(cancellationToken, progress); } private async Task CleanDeadItems(CancellationToken cancellationToken, IProgress<double> progress) @@ -98,23 +73,5 @@ namespace Emby.Server.Implementations.Data progress.Report(100); } - - /// <summary> - /// Creates the triggers that define when the task will run - /// </summary> - /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() - { - return new[] { - - // Every so often - new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks} - }; - } - - public string Key - { - get { return "CleanDatabase"; } - } } }
\ No newline at end of file diff --git a/Emby.Server.Implementations/Data/ManagedConnection.cs b/Emby.Server.Implementations/Data/ManagedConnection.cs index 91a2dfdf6..5d0fc8ebc 100644 --- a/Emby.Server.Implementations/Data/ManagedConnection.cs +++ b/Emby.Server.Implementations/Data/ManagedConnection.cs @@ -77,6 +77,7 @@ namespace Emby.Server.Implementations.Data { Close(); } + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index 4118bd1b2..89664d158 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Threading; -using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Persistence; @@ -75,7 +74,7 @@ namespace Emby.Server.Implementations.Data /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public async Task SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, CancellationToken cancellationToken) + public void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid userId, string client, CancellationToken cancellationToken) { if (displayPreferences == null) { @@ -123,7 +122,7 @@ namespace Emby.Server.Implementations.Data /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public async Task SaveAllDisplayPreferences(IEnumerable<DisplayPreferences> displayPreferences, Guid userId, CancellationToken cancellationToken) + public void SaveAllDisplayPreferences(IEnumerable<DisplayPreferences> displayPreferences, Guid userId, CancellationToken cancellationToken) { if (displayPreferences == null) { @@ -226,9 +225,9 @@ namespace Emby.Server.Implementations.Data } } - public Task SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken) + public void SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken) { - return SaveDisplayPreferences(displayPreferences, new Guid(userId), client, cancellationToken); + SaveDisplayPreferences(displayPreferences, new Guid(userId), client, cancellationToken); } public DisplayPreferences GetDisplayPreferences(string displayPreferencesId, string userId, string client) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 528acd069..165d17a57 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -7,6 +7,8 @@ using System.Runtime.Serialization; using System.Text; using System.Threading; using System.Threading.Tasks; +using Emby.Server.Implementations.Devices; +using Emby.Server.Implementations.Playlists; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Configuration; @@ -25,12 +27,11 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Serialization; -using MediaBrowser.Server.Implementations.Devices; -using MediaBrowser.Server.Implementations.Playlists; using MediaBrowser.Model.Reflection; using SQLitePCL.pretty; using MediaBrowser.Model.System; using MediaBrowser.Model.Threading; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Data { @@ -131,8 +132,7 @@ namespace Emby.Server.Implementations.Data /// <summary> /// Opens the connection to the database /// </summary> - /// <returns>Task.</returns> - public async Task Initialize(SqliteUserDataRepository userDataRepo) + public void Initialize(SqliteUserDataRepository userDataRepo) { using (var connection = CreateConnection()) { @@ -148,7 +148,7 @@ namespace Emby.Server.Implementations.Data "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))", "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)", - "create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)", + "create index if not exists idx_AncestorIds5 on AncestorIds(AncestorIdText,ItemId)", "create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT, CleanValue TEXT)", @@ -190,7 +190,6 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "IsLocked", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "Name", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "OfficialRating", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "MediaType", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "Overview", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "ParentIndexNumber", "INT", existingColumnNames); @@ -200,28 +199,21 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames); - AddColumn(db, "TypedBaseItems", "HomePageUrl", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "DisplayMediaType", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateCreated", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames); - AddColumn(db, "TypedBaseItems", "IsSeries", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsLive", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsNews", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsPremiere", "BIT", existingColumnNames); - AddColumn(db, "TypedBaseItems", "EpisodeTitle", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsRepeat", "BIT", existingColumnNames); - AddColumn(db, "TypedBaseItems", "PreferredMetadataLanguage", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "PreferredMetadataCountryCode", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsHD", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "ExternalEtag", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateLastRefreshed", "DATETIME", existingColumnNames); - AddColumn(db, "TypedBaseItems", "DateLastSaved", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsInMixedFolder", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "LockedFields", "Text", existingColumnNames); @@ -235,7 +227,6 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "TopParentId", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "TrailerTypes", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "CriticRating", "Float", existingColumnNames); - AddColumn(db, "TypedBaseItems", "InheritedTags", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "CleanName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "PresentationUniqueKey", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "OriginalTitle", "Text", existingColumnNames); @@ -314,6 +305,9 @@ namespace Emby.Server.Implementations.Data "drop index if exists idx_TypeSeriesPresentationUniqueKey", "drop index if exists idx_SeriesPresentationUniqueKey", "drop index if exists idx_TypeSeriesPresentationUniqueKey2", + "drop index if exists idx_AncestorIds3", + "drop index if exists idx_AncestorIds4", + "drop index if exists idx_AncestorIds2", "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", @@ -352,7 +346,10 @@ namespace Emby.Server.Implementations.Data // items by name "create index if not exists idx_ItemValues6 on ItemValues(ItemId,Type,CleanValue)", - "create index if not exists idx_ItemValues7 on ItemValues(Type,CleanValue,ItemId)" + "create index if not exists idx_ItemValues7 on ItemValues(Type,CleanValue,ItemId)", + + // Used to update inherited tags + "create index if not exists idx_ItemValues8 on ItemValues(Type, ItemId, Value)", }; connection.RunQueries(postQueries); @@ -421,7 +418,6 @@ namespace Emby.Server.Implementations.Data "ProductionYear", "OfficialRating", "HomePageUrl", - "DisplayMediaType", "ForcedSortName", "RunTimeTicks", "DateCreated", @@ -449,7 +445,6 @@ namespace Emby.Server.Implementations.Data "SeriesId", "PresentationUniqueKey", "InheritedParentalRatingValue", - "InheritedTags", "ExternalSeriesId", "Tagline", "ProviderIds", @@ -539,7 +534,6 @@ namespace Emby.Server.Implementations.Data "ForcedSortName", "RunTimeTicks", "HomePageUrl", - "DisplayMediaType", "DateCreated", "DateModified", "PreferredMetadataLanguage", @@ -559,7 +553,6 @@ namespace Emby.Server.Implementations.Data "TopParentId", "TrailerTypes", "CriticRating", - "InheritedTags", "CleanName", "PresentationUniqueKey", "OriginalTitle", @@ -606,16 +599,15 @@ namespace Emby.Server.Implementations.Data /// </summary> /// <param name="item">The item.</param> /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public Task SaveItem(BaseItem item, CancellationToken cancellationToken) + public void SaveItem(BaseItem item, CancellationToken cancellationToken) { if (item == null) { throw new ArgumentNullException("item"); } - return SaveItems(new List<BaseItem> { item }, cancellationToken); + SaveItems(new List<BaseItem> { item }, cancellationToken); } /// <summary> @@ -623,13 +615,12 @@ namespace Emby.Server.Implementations.Data /// </summary> /// <param name="items">The items.</param> /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException"> /// items /// or /// cancellationToken /// </exception> - public async Task SaveItems(List<BaseItem> items, CancellationToken cancellationToken) + public void SaveItems(List<BaseItem> items, CancellationToken cancellationToken) { if (items == null) { @@ -640,7 +631,7 @@ namespace Emby.Server.Implementations.Data CheckDisposed(); - var tuples = new List<Tuple<BaseItem, List<Guid>, BaseItem, string>>(); + var tuples = new List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>>(); foreach (var item in items) { var ancestorIds = item.SupportsAncestors ? @@ -650,8 +641,9 @@ namespace Emby.Server.Implementations.Data var topParent = item.GetTopParent(); var userdataKey = item.GetUserDataKeys().FirstOrDefault(); + var inheritedTags = item.GetInheritedTags(); - tuples.Add(new Tuple<BaseItem, List<Guid>, BaseItem, string>(item, ancestorIds, topParent, userdataKey)); + tuples.Add(new Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>(item, ancestorIds, topParent, userdataKey, inheritedTags)); } using (WriteLock.Write()) @@ -661,12 +653,13 @@ namespace Emby.Server.Implementations.Data connection.RunInTransaction(db => { SaveItemsInTranscation(db, tuples); + }, TransactionMode); } } } - private void SaveItemsInTranscation(IDatabaseConnection db, List<Tuple<BaseItem, List<Guid>, BaseItem, string>> tuples) + private void SaveItemsInTranscation(IDatabaseConnection db, List<Tuple<BaseItem, List<Guid>, BaseItem, string, List<string>>> tuples) { var requiresReset = false; @@ -697,12 +690,14 @@ namespace Emby.Server.Implementations.Data SaveItem(item, topParent, userDataKey, saveItemStatement); //Logger.Debug(_saveItemCommand.CommandText); + var inheritedTags = tuple.Item5; + if (item.SupportsAncestors) { UpdateAncestors(item.Id, tuple.Item2, db, deleteAncestorsStatement, updateAncestorsStatement); } - UpdateItemValues(item.Id, GetItemValuesToSave(item), db); + UpdateItemValues(item.Id, GetItemValuesToSave(item, inheritedTags), db); requiresReset = true; } @@ -813,7 +808,6 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks); saveItemStatement.TryBind("@HomePageUrl", item.HomePageUrl); - saveItemStatement.TryBind("@DisplayMediaType", item.DisplayMediaType); saveItemStatement.TryBind("@DateCreated", item.DateCreated); saveItemStatement.TryBind("@DateModified", item.DateModified); @@ -842,7 +836,7 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@IsInMixedFolder", item.IsInMixedFolder); - if (item.LockedFields.Count > 0) + if (item.LockedFields.Length > 0) { saveItemStatement.TryBind("@LockedFields", string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray())); } @@ -851,7 +845,7 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBindNull("@LockedFields"); } - if (item.Studios.Count > 0) + if (item.Studios.Length > 0) { saveItemStatement.TryBind("@Studios", string.Join("|", item.Studios.ToArray())); } @@ -871,9 +865,9 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@ExternalServiceId", item.ServiceName); - if (item.Tags.Count > 0) + if (item.Tags.Length > 0) { - saveItemStatement.TryBind("@Tags", string.Join("|", item.Tags.ToArray())); + saveItemStatement.TryBind("@Tags", string.Join("|", item.Tags)); } else { @@ -907,16 +901,6 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@CriticRating", item.CriticRating); - var inheritedTags = item.InheritedTags; - if (inheritedTags.Count > 0) - { - saveItemStatement.TryBind("@InheritedTags", string.Join("|", inheritedTags.ToArray())); - } - else - { - saveItemStatement.TryBindNull("@InheritedTags"); - } - if (string.IsNullOrWhiteSpace(item.Name)) { saveItemStatement.TryBindNull("@CleanName"); @@ -1000,16 +984,16 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@ProviderIds", SerializeProviderIds(item)); saveItemStatement.TryBind("@Images", SerializeImages(item)); - if (item.ProductionLocations.Count > 0) + if (item.ProductionLocations.Length > 0) { - saveItemStatement.TryBind("@ProductionLocations", string.Join("|", item.ProductionLocations.ToArray())); + saveItemStatement.TryBind("@ProductionLocations", string.Join("|", item.ProductionLocations)); } else { saveItemStatement.TryBindNull("@ProductionLocations"); } - if (item.ThemeSongIds.Count > 0) + if (item.ThemeSongIds.Length > 0) { saveItemStatement.TryBind("@ThemeSongIds", string.Join("|", item.ThemeSongIds.ToArray())); } @@ -1018,7 +1002,7 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBindNull("@ThemeSongIds"); } - if (item.ThemeVideoIds.Count > 0) + if (item.ThemeVideoIds.Length > 0) { saveItemStatement.TryBind("@ThemeVideoIds", string.Join("|", item.ThemeVideoIds.ToArray())); } @@ -1041,9 +1025,9 @@ namespace Emby.Server.Implementations.Data var hasArtists = item as IHasArtist; if (hasArtists != null) { - if (hasArtists.Artists.Count > 0) + if (hasArtists.Artists.Length > 0) { - artists = string.Join("|", hasArtists.Artists.ToArray()); + artists = string.Join("|", hasArtists.Artists); } } saveItemStatement.TryBind("@Artists", artists); @@ -1052,9 +1036,9 @@ namespace Emby.Server.Implementations.Data var hasAlbumArtists = item as IHasAlbumArtist; if (hasAlbumArtists != null) { - if (hasAlbumArtists.AlbumArtists.Count > 0) + if (hasAlbumArtists.AlbumArtists.Length > 0) { - albumArtists = string.Join("|", hasAlbumArtists.AlbumArtists.ToArray()); + albumArtists = string.Join("|", hasAlbumArtists.AlbumArtists); } } saveItemStatement.TryBind("@AlbumArtists", albumArtists); @@ -1105,9 +1089,9 @@ namespace Emby.Server.Implementations.Data private string SerializeImages(BaseItem item) { - var images = item.ImageInfos.ToList(); + var images = item.ImageInfos; - if (images.Count == 0) + if (images.Length == 0) { return null; } @@ -1124,22 +1108,24 @@ namespace Emby.Server.Implementations.Data return; } - if (item.ImageInfos.Count > 0) + if (item.ImageInfos.Length > 0) { return; } var parts = value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); - + var list = new List<ItemImageInfo>(); foreach (var part in parts) { var image = ItemImageInfoFromValueString(part); if (image != null) { - item.ImageInfos.Add(image); + list.Add(image); } } + + item.ImageInfos = list.ToArray(list.Count); } public string ToValueString(ItemImageInfo image) @@ -1228,14 +1214,15 @@ namespace Emby.Server.Implementations.Data { return false; } - if (type == typeof(Season)) - { - return false; - } - if (type == typeof(MusicArtist)) - { - return false; - } + } + + if (type == typeof(Season)) + { + return false; + } + if (type == typeof(MusicArtist)) + { + return false; } if (type == typeof(Person)) @@ -1306,16 +1293,13 @@ namespace Emby.Server.Implementations.Data return false; } - if (_config.Configuration.SkipDeserializationForAudio) + if (type == typeof(Audio)) { - if (type == typeof(Audio)) - { - return false; - } - if (type == typeof(MusicAlbum)) - { - return false; - } + return false; + } + if (type == typeof(MusicAlbum)) + { + return false; } return true; @@ -1586,15 +1570,6 @@ namespace Emby.Server.Implementations.Data index++; } - if (HasField(query, ItemFields.DisplayMediaType)) - { - if (!reader.IsDBNull(index)) - { - item.DisplayMediaType = reader.GetString(index); - } - index++; - } - if (HasField(query, ItemFields.SortName)) { if (!reader.IsDBNull(index)) @@ -1690,7 +1665,7 @@ namespace Emby.Server.Implementations.Data return parsedValue; } return (MetadataFields?)null; - }).Where(i => i.HasValue).Select(i => i.Value).ToList(); + }).Where(i => i.HasValue).Select(i => i.Value).ToArray(); } index++; } @@ -1699,7 +1674,7 @@ namespace Emby.Server.Implementations.Data { if (!reader.IsDBNull(index)) { - item.Studios = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + item.Studios = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); } index++; } @@ -1708,7 +1683,7 @@ namespace Emby.Server.Implementations.Data { if (!reader.IsDBNull(index)) { - item.Tags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + item.Tags = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); } index++; } @@ -1849,15 +1824,6 @@ namespace Emby.Server.Implementations.Data index++; } - if (HasField(query, ItemFields.Tags)) - { - if (!reader.IsDBNull(index)) - { - item.InheritedTags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); - } - index++; - } - if (HasField(query, ItemFields.ExternalSeriesId)) { if (!reader.IsDBNull(index)) @@ -1895,7 +1861,7 @@ namespace Emby.Server.Implementations.Data { if (!reader.IsDBNull(index)) { - item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(); } index++; } @@ -1904,7 +1870,7 @@ namespace Emby.Server.Implementations.Data { if (!reader.IsDBNull(index)) { - item.ThemeSongIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(); + item.ThemeSongIds = SplitToGuids(reader.GetString(index)); } index++; } @@ -1913,7 +1879,7 @@ namespace Emby.Server.Implementations.Data { if (!reader.IsDBNull(index)) { - item.ThemeVideoIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(); + item.ThemeVideoIds = SplitToGuids(reader.GetString(index)); } index++; } @@ -1939,14 +1905,14 @@ namespace Emby.Server.Implementations.Data var hasArtists = item as IHasArtist; if (hasArtists != null && !reader.IsDBNull(index)) { - hasArtists.Artists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + hasArtists.Artists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); } index++; var hasAlbumArtists = item as IHasAlbumArtist; if (hasAlbumArtists != null && !reader.IsDBNull(index)) { - hasAlbumArtists.AlbumArtists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + hasAlbumArtists.AlbumArtists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); } index++; } @@ -1972,45 +1938,36 @@ namespace Emby.Server.Implementations.Data return item; } + private Guid[] SplitToGuids(string value) + { + var ids = value.Split('|'); + + var result = new Guid[ids.Length]; + + for (var i = 0; i < result.Length; i++) + { + result[i] = new Guid(ids[i]); + } + + return result; + } + /// <summary> /// Gets the critic reviews. /// </summary> /// <param name="itemId">The item id.</param> - /// <returns>Task{IEnumerable{ItemReview}}.</returns> - public IEnumerable<ItemReview> GetCriticReviews(Guid itemId) + public List<ItemReview> GetCriticReviews(Guid itemId) { - try - { - var path = Path.Combine(_criticReviewsPath, itemId + ".json"); - - return _jsonSerializer.DeserializeFromFile<List<ItemReview>>(path); - } - catch (FileNotFoundException) - { - return new List<ItemReview>(); - } - catch (IOException) - { - return new List<ItemReview>(); - } + return new List<ItemReview>(); } - private readonly Task _cachedTask = Task.FromResult(true); /// <summary> /// Saves the critic reviews. /// </summary> /// <param name="itemId">The item id.</param> /// <param name="criticReviews">The critic reviews.</param> - /// <returns>Task.</returns> - public Task SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews) + public void SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews) { - _fileSystem.CreateDirectory(_criticReviewsPath); - - var path = Path.Combine(_criticReviewsPath, itemId + ".json"); - - _jsonSerializer.SerializeToFile(criticReviews.ToList(), path); - - return _cachedTask; } /// <summary> @@ -2019,7 +1976,7 @@ namespace Emby.Server.Implementations.Data /// <param name="id">The id.</param> /// <returns>IEnumerable{ChapterInfo}.</returns> /// <exception cref="System.ArgumentNullException">id</exception> - public IEnumerable<ChapterInfo> GetChapters(Guid id) + public List<ChapterInfo> GetChapters(Guid id) { CheckDisposed(); if (id == Guid.Empty) @@ -2115,18 +2072,7 @@ namespace Emby.Server.Implementations.Data /// <summary> /// Saves the chapters. /// </summary> - /// <param name="id">The id.</param> - /// <param name="chapters">The chapters.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - /// <exception cref="System.ArgumentNullException"> - /// id - /// or - /// chapters - /// or - /// cancellationToken - /// </exception> - public async Task SaveChapters(Guid id, List<ChapterInfo> chapters, CancellationToken cancellationToken) + public void SaveChapters(Guid id, List<ChapterInfo> chapters) { CheckDisposed(); @@ -2140,8 +2086,6 @@ namespace Emby.Server.Implementations.Data throw new ArgumentNullException("chapters"); } - cancellationToken.ThrowIfCancellationRequested(); - var index = 0; using (WriteLock.Write()) @@ -2191,8 +2135,7 @@ namespace Emby.Server.Implementations.Data //return true; } - var sortingFields = query.SortBy.ToList(); - sortingFields.AddRange(query.OrderBy.Select(i => i.Item1)); + var sortingFields = query.OrderBy.Select(i => i.Item1).ToList(); if (sortingFields.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase)) { @@ -2247,7 +2190,7 @@ namespace Emby.Server.Implementations.Data return false; } - private List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields)) + private readonly List<ItemFields> allFields = Enum.GetNames(typeof(ItemFields)) .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) .ToList(); @@ -2271,7 +2214,7 @@ namespace Emby.Server.Implementations.Data } if (field == ItemFields.Tags) { - return new[] { "Tags", "InheritedTags" }; + return new[] { "Tags" }; } return new[] { field.ToString() }; @@ -2284,7 +2227,6 @@ namespace Emby.Server.Implementations.Data switch (name) { case ItemFields.HomePageUrl: - case ItemFields.DisplayMediaType: case ItemFields.CustomRating: case ItemFields.ProductionLocations: case ItemFields.Settings: @@ -2589,11 +2531,11 @@ namespace Emby.Server.Implementations.Data } } - query.ExcludeItemIds = excludeIds.ToArray(); + query.ExcludeItemIds = excludeIds.ToArray(excludeIds.Count); query.ExcludeProviderIds = item.ProviderIds; } - return list.ToArray(); + return list.ToArray(list.Count); } private void BindSimilarParams(InternalItemsQuery query, IStatement statement) @@ -2629,9 +2571,14 @@ namespace Emby.Server.Implementations.Data groups.Add("PresentationUniqueKey"); } + if (query.GroupBySeriesPresentationUniqueKey) + { + groups.Add("SeriesPresentationUniqueKey"); + } + if (groups.Count > 0) { - return " Group by " + string.Join(",", groups.ToArray()); + return " Group by " + string.Join(",", groups.ToArray(groups.Count)); } return string.Empty; @@ -2668,7 +2615,7 @@ namespace Emby.Server.Implementations.Data var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); commandText += whereText; @@ -2725,7 +2672,7 @@ namespace Emby.Server.Implementations.Data var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); commandText += whereText; @@ -2845,7 +2792,7 @@ namespace Emby.Server.Implementations.Data var slowThreshold = 1000; #if DEBUG - slowThreshold = 2; + slowThreshold = 10; #endif if (elapsed >= slowThreshold) @@ -2878,7 +2825,7 @@ namespace Emby.Server.Implementations.Data var returnList = GetItemList(query); return new QueryResult<BaseItem> { - Items = returnList.ToArray(), + Items = returnList.ToArray(returnList.Count), TotalRecordCount = returnList.Count }; } @@ -2901,7 +2848,7 @@ namespace Emby.Server.Implementations.Data var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); var whereTextWithoutPaging = whereText; @@ -2941,6 +2888,10 @@ namespace Emby.Server.Implementations.Data { commandText += " select count (distinct PresentationUniqueKey)" + GetFromText(); } + else if (query.GroupBySeriesPresentationUniqueKey) + { + commandText += " select count (distinct SeriesPresentationUniqueKey)" + GetFromText(); + } else { commandText += " select count (guid)" + GetFromText(); @@ -2958,8 +2909,7 @@ namespace Emby.Server.Implementations.Data return connection.RunInTransaction(db => { var result = new QueryResult<BaseItem>(); - var statements = PrepareAllSafe(db, statementTexts) - .ToList(); + var statements = PrepareAllSafe(db, statementTexts); if (!isReturningZeroItems) { @@ -3013,7 +2963,7 @@ namespace Emby.Server.Implementations.Data LogQueryTime("GetItems", commandText, now); - result.Items = list.ToArray(); + result.Items = list.ToArray(list.Count); return result; }, ReadTransactionMode); @@ -3024,16 +2974,7 @@ namespace Emby.Server.Implementations.Data private string GetOrderByText(InternalItemsQuery query) { var orderBy = query.OrderBy.ToList(); - var enableOrderInversion = true; - - if (orderBy.Count == 0) - { - orderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder))); - } - else - { - enableOrderInversion = false; - } + var enableOrderInversion = false; if (query.SimilarTo != null) { @@ -3042,12 +2983,10 @@ namespace Emby.Server.Implementations.Data orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending)); orderBy.Add(new Tuple<string, SortOrder>("SimilarityScore", SortOrder.Descending)); //orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending)); - query.SortOrder = SortOrder.Descending; - enableOrderInversion = false; } } - query.OrderBy = orderBy; + query.OrderBy = orderBy.ToArray(); if (orderBy.Count == 0) { @@ -3086,6 +3025,11 @@ namespace Emby.Server.Implementations.Data } if (string.Equals(name, ItemSortBy.DatePlayed, StringComparison.OrdinalIgnoreCase)) { + if (query.GroupBySeriesPresentationUniqueKey) + { + return new Tuple<string, bool>("MAX(LastPlayedDate)", false); + } + return new Tuple<string, bool>("LastPlayedDate", false); } if (string.Equals(name, ItemSortBy.PlayCount, StringComparison.OrdinalIgnoreCase)) @@ -3160,7 +3104,7 @@ namespace Emby.Server.Implementations.Data var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); commandText += whereText; @@ -3231,7 +3175,7 @@ namespace Emby.Server.Implementations.Data var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); commandText += whereText; @@ -3304,7 +3248,7 @@ namespace Emby.Server.Implementations.Data var returnList = GetItemIdsList(query); return new QueryResult<Guid> { - Items = returnList.ToArray(), + Items = returnList.ToArray(returnList.Count), TotalRecordCount = returnList.Count }; } @@ -3319,7 +3263,7 @@ namespace Emby.Server.Implementations.Data var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); var whereTextWithoutPaging = whereText; @@ -3360,6 +3304,10 @@ namespace Emby.Server.Implementations.Data { commandText += " select count (distinct PresentationUniqueKey)" + GetFromText(); } + else if (query.GroupBySeriesPresentationUniqueKey) + { + commandText += " select count (distinct SeriesPresentationUniqueKey)" + GetFromText(); + } else { commandText += " select count (guid)" + GetFromText(); @@ -3378,8 +3326,7 @@ namespace Emby.Server.Implementations.Data { var result = new QueryResult<Guid>(); - var statements = PrepareAllSafe(db, statementTexts) - .ToList(); + var statements = PrepareAllSafe(db, statementTexts); if (!isReturningZeroItems) { @@ -3422,7 +3369,7 @@ namespace Emby.Server.Implementations.Data LogQueryTime("GetItemIds", commandText, now); - result.Items = list.ToArray(); + result.Items = list.ToArray(list.Count); return result; }, ReadTransactionMode); @@ -3627,7 +3574,7 @@ namespace Emby.Server.Implementations.Data } if (programAttribtues.Count > 0) { - whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray()) + ")"); + whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray(programAttribtues.Count)) + ")"); } } @@ -4296,12 +4243,13 @@ namespace Emby.Server.Implementations.Data whereClauses.Add("ProductionYear in (" + val + ")"); } - if (query.IsVirtualItem.HasValue) + var isVirtualItem = query.IsVirtualItem ?? query.IsMissing; + if (isVirtualItem.HasValue) { whereClauses.Add("IsVirtualItem=@IsVirtualItem"); if (statement != null) { - statement.TryBind("@IsVirtualItem", query.IsVirtualItem.Value); + statement.TryBind("@IsVirtualItem", isVirtualItem.Value); } } if (query.IsSpecialSeason.HasValue) @@ -4326,28 +4274,6 @@ namespace Emby.Server.Implementations.Data whereClauses.Add("PremiereDate < DATETIME('now')"); } } - if (query.IsMissing.HasValue) - { - if (query.IsMissing.Value) - { - whereClauses.Add("(IsVirtualItem=1 AND PremiereDate < DATETIME('now'))"); - } - else - { - whereClauses.Add("(IsVirtualItem=0 OR PremiereDate >= DATETIME('now'))"); - } - } - if (query.IsVirtualUnaired.HasValue) - { - if (query.IsVirtualUnaired.Value) - { - whereClauses.Add("(IsVirtualItem=1 AND PremiereDate >= DATETIME('now'))"); - } - else - { - whereClauses.Add("(IsVirtualItem=0 OR PremiereDate < DATETIME('now'))"); - } - } var queryMediaTypes = query.MediaTypes.Where(IsValidMediaType).ToArray(); if (queryMediaTypes.Length == 1) { @@ -4563,26 +4489,12 @@ namespace Emby.Server.Implementations.Data whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause)); } - var excludeTagIndex = 0; - foreach (var excludeTag in query.ExcludeTags) + if (query.ExcludeInheritedTags.Length > 0) { - whereClauses.Add("(Tags is null OR Tags not like @excludeTag" + excludeTagIndex + ")"); - if (statement != null) - { - statement.TryBind("@excludeTag" + excludeTagIndex, "%" + excludeTag + "%"); - } - excludeTagIndex++; - } + var tagValues = query.ExcludeInheritedTags.Select(i => "'" + GetCleanValue(i) + "'").ToArray(); + var tagValuesList = string.Join(",", tagValues); - excludeTagIndex = 0; - foreach (var excludeTag in query.ExcludeInheritedTags) - { - whereClauses.Add("(InheritedTags is null OR InheritedTags not like @excludeInheritedTag" + excludeTagIndex + ")"); - if (statement != null) - { - statement.TryBind("@excludeInheritedTag" + excludeTagIndex, "%" + excludeTag + "%"); - } - excludeTagIndex++; + whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + tagValuesList + ")) is null)"); } return whereClauses; @@ -4647,6 +4559,11 @@ namespace Emby.Server.Implementations.Data return false; } + if (query.GroupBySeriesPresentationUniqueKey) + { + return false; + } + if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey)) { return false; @@ -4718,48 +4635,72 @@ namespace Emby.Server.Implementations.Data typeof(AggregateFolder) }; - public async Task UpdateInheritedValues(CancellationToken cancellationToken) + public void UpdateInheritedValues(CancellationToken cancellationToken) { - await UpdateInheritedTags(cancellationToken).ConfigureAwait(false); + UpdateInheritedTags(cancellationToken); } - private async Task UpdateInheritedTags(CancellationToken cancellationToken) + private void UpdateInheritedTags(CancellationToken cancellationToken) { - var newValues = new List<Tuple<Guid, string>>(); + var newValues = new List<Tuple<Guid, string[]>>(); - var commandText = "select Guid,InheritedTags,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer where NewInheritedTags <> InheritedTags"; + var commandText = @"select guid, +(select group_concat(Value, '|') from ItemValues where (ItemValues.ItemId = Outer.Guid OR ItemValues.ItemId in ((Select AncestorId from AncestorIds where AncestorIds.ItemId=Outer.guid))) and ItemValues.Type = 4) NewInheritedTags, +(select group_concat(Value, '|') from ItemValues where ItemValues.ItemId = Outer.Guid and ItemValues.Type = 6) CurrentInheritedTags +from typedbaseitems as Outer +where (NewInheritedTags <> CurrentInheritedTags or (NewInheritedTags is null) <> (CurrentInheritedTags is null)) +limit 100"; using (WriteLock.Write()) { using (var connection = CreateConnection()) { - foreach (var row in connection.Query(commandText)) + connection.RunInTransaction(db => { - var id = row.GetGuid(0); - string value = row.IsDBNull(2) ? null : row.GetString(2); + foreach (var row in connection.Query(commandText)) + { + var id = row.GetGuid(0); + string value = row.IsDBNull(1) ? null : row.GetString(1); - newValues.Add(new Tuple<Guid, string>(id, value)); - } + var valuesArray = string.IsNullOrWhiteSpace(value) ? new string[] { } : value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); - Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count); - if (newValues.Count == 0) - { - return; - } + newValues.Add(new Tuple<Guid, string[]>(id, valuesArray)); + } - // write lock here - using (var statement = PrepareStatement(connection, "Update TypedBaseItems set InheritedTags=@InheritedTags where Guid=@Guid")) - { - foreach (var item in newValues) + Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count); + if (newValues.Count == 0) { - var paramList = new List<object>(); + return; + } - paramList.Add(item.Item1); - paramList.Add(item.Item2); + using (var insertStatement = PrepareStatement(connection, "insert into ItemValues (ItemId, Type, Value, CleanValue) values (@ItemId, 6, @Value, @CleanValue)")) + { + using (var deleteStatement = PrepareStatement(connection, "delete from ItemValues where ItemId=@ItemId and Type=6")) + { + foreach (var item in newValues) + { + var guidBlob = item.Item1.ToGuidBlob(); - statement.Execute(paramList.ToArray()); + deleteStatement.Reset(); + deleteStatement.TryBind("@ItemId", guidBlob); + deleteStatement.MoveNext(); + + foreach (var itemValue in item.Item2) + { + insertStatement.Reset(); + + insertStatement.TryBind("@ItemId", guidBlob); + insertStatement.TryBind("@Value", itemValue); + + insertStatement.TryBind("@CleanValue", GetCleanValue(itemValue)); + + insertStatement.MoveNext(); + } + } + } } - } + + }, TransactionMode); } } } @@ -4794,7 +4735,7 @@ namespace Emby.Server.Implementations.Data return new[] { value }.Where(IsValidType); } - public async Task DeleteItem(Guid id, CancellationToken cancellationToken) + public void DeleteItem(Guid id, CancellationToken cancellationToken) { if (id == Guid.Empty) { @@ -5161,9 +5102,9 @@ namespace Emby.Server.Implementations.Data var itemCountColumns = new List<Tuple<string, string>>(); - var typesToCount = query.IncludeItemTypes.ToList(); + var typesToCount = query.IncludeItemTypes; - if (typesToCount.Count > 0) + if (typesToCount.Length > 0) { var itemCountColumnQuery = "select group_concat(type, '|')" + GetFromText("B"); @@ -5223,7 +5164,7 @@ namespace Emby.Server.Implementations.Data var whereText = " where Type=@SelectType"; - if (typesToCount.Count == 0) + if (typesToCount.Length == 0) { whereText += " And CleanName In (Select CleanValue from ItemValues where " + typeClause + " AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))"; } @@ -5301,8 +5242,7 @@ namespace Emby.Server.Implementations.Data var list = new List<Tuple<BaseItem, ItemCounts>>(); var result = new QueryResult<Tuple<BaseItem, ItemCounts>>(); - var statements = PrepareAllSafe(db, statementTexts) - .ToList(); + var statements = PrepareAllSafe(db, statementTexts); if (!isReturningZeroItems) { @@ -5377,7 +5317,7 @@ namespace Emby.Server.Implementations.Data { result.TotalRecordCount = list.Count; } - result.Items = list.ToArray(); + result.Items = list.ToArray(list.Count); return result; @@ -5386,11 +5326,11 @@ namespace Emby.Server.Implementations.Data } } - private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, List<string> typesToCount) + private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, string[] typesToCount) { var counts = new ItemCounts(); - if (typesToCount.Count == 0) + if (typesToCount.Length == 0) { return counts; } @@ -5448,7 +5388,7 @@ namespace Emby.Server.Implementations.Data return counts; } - private List<Tuple<int, string>> GetItemValuesToSave(BaseItem item) + private List<Tuple<int, string>> GetItemValuesToSave(BaseItem item, List<string> inheritedTags) { var list = new List<Tuple<int, string>>(); @@ -5468,6 +5408,10 @@ namespace Emby.Server.Implementations.Data list.AddRange(item.Studios.Select(i => new Tuple<int, string>(3, i))); list.AddRange(item.Tags.Select(i => new Tuple<int, string>(4, i))); + // keywords was 5 + + list.AddRange(inheritedTags.Select(i => new Tuple<int, string>(6, i))); + return list; } @@ -5485,8 +5429,10 @@ namespace Emby.Server.Implementations.Data CheckDisposed(); + var guidBlob = itemId.ToGuidBlob(); + // First delete - db.Execute("delete from ItemValues where ItemId=@Id", itemId.ToGuidBlob()); + db.Execute("delete from ItemValues where ItemId=@Id", guidBlob); using (var statement = PrepareStatement(db, "insert into ItemValues (ItemId, Type, Value, CleanValue) values (@ItemId, @Type, @Value, @CleanValue)")) { @@ -5502,7 +5448,7 @@ namespace Emby.Server.Implementations.Data statement.Reset(); - statement.TryBind("@ItemId", itemId.ToGuidBlob()); + statement.TryBind("@ItemId", guidBlob); statement.TryBind("@Type", pair.Item1); statement.TryBind("@Value", itemValue); @@ -5520,7 +5466,7 @@ namespace Emby.Server.Implementations.Data } } - public async Task UpdatePeople(Guid itemId, List<PersonInfo> people) + public void UpdatePeople(Guid itemId, List<PersonInfo> people) { if (itemId == Guid.Empty) { @@ -5594,7 +5540,7 @@ namespace Emby.Server.Implementations.Data return item; } - public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query) + public List<MediaStream> GetMediaStreams(MediaStreamQuery query) { CheckDisposed(); @@ -5650,7 +5596,7 @@ namespace Emby.Server.Implementations.Data } } - public async Task SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken) + public void SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken) { CheckDisposed(); diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs index bf6388f5d..ef1d7ba44 100644 --- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; -using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; @@ -153,7 +152,7 @@ namespace Emby.Server.Implementations.Data /// userId /// or /// userDataId</exception> - public Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken) + public void SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken) { if (userData == null) { @@ -168,10 +167,10 @@ namespace Emby.Server.Implementations.Data throw new ArgumentNullException("key"); } - return PersistUserData(userId, key, userData, cancellationToken); + PersistUserData(userId, key, userData, cancellationToken); } - public Task SaveAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken) + public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken) { if (userData == null) { @@ -182,7 +181,7 @@ namespace Emby.Server.Implementations.Data throw new ArgumentNullException("userId"); } - return PersistAllUserData(userId, userData.ToList(), cancellationToken); + PersistAllUserData(userId, userData, cancellationToken); } /// <summary> @@ -193,7 +192,7 @@ namespace Emby.Server.Implementations.Data /// <param name="userData">The user data.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public async Task PersistUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken) + public void PersistUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -264,7 +263,7 @@ namespace Emby.Server.Implementations.Data /// <summary> /// Persist all user data for the specified user /// </summary> - private async Task PersistAllUserData(Guid userId, List<UserItemData> userDataList, CancellationToken cancellationToken) + private void PersistAllUserData(Guid userId, UserItemData[] userDataList, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -349,7 +348,7 @@ namespace Emby.Server.Implementations.Data /// </summary> /// <param name="userId"></param> /// <returns></returns> - public IEnumerable<UserItemData> GetAllUserData(Guid userId) + public List<UserItemData> GetAllUserData(Guid userId) { if (userId == Guid.Empty) { diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs index 29959bcab..b65996e40 100644 --- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Threading; -using System.Threading.Tasks; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; @@ -72,7 +71,7 @@ namespace Emby.Server.Implementations.Data /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">user</exception> - public async Task SaveUser(User user, CancellationToken cancellationToken) + public void SaveUser(User user, CancellationToken cancellationToken) { if (user == null) { @@ -139,7 +138,7 @@ namespace Emby.Server.Implementations.Data /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">user</exception> - public async Task DeleteUser(User user, CancellationToken cancellationToken) + public void DeleteUser(User user, CancellationToken cancellationToken) { if (user == null) { diff --git a/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs b/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs index 52979f085..bb9ef157c 100644 --- a/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs +++ b/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs @@ -10,7 +10,6 @@ using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Serialization; -using MediaBrowser.Server.Implementations.Devices; namespace Emby.Server.Implementations.Devices { diff --git a/Emby.Server.Implementations/Devices/CameraUploadsFolder.cs b/Emby.Server.Implementations/Devices/CameraUploadsFolder.cs new file mode 100644 index 000000000..55063872c --- /dev/null +++ b/Emby.Server.Implementations/Devices/CameraUploadsFolder.cs @@ -0,0 +1,71 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Serialization; + +namespace Emby.Server.Implementations.Devices +{ + public class CameraUploadsFolder : BasePluginFolder, ISupportsUserSpecificView + { + public CameraUploadsFolder() + { + Name = "Camera Uploads"; + } + + public override bool IsVisible(User user) + { + if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + return base.IsVisible(user) && HasChildren(); + } + + [IgnoreDataMember] + public override string CollectionType + { + get { return MediaBrowser.Model.Entities.CollectionType.Photos; } + } + + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + public override string GetClientTypeName() + { + return typeof(CollectionFolder).Name; + } + + private bool? _hasChildren; + private bool HasChildren() + { + if (!_hasChildren.HasValue) + { + _hasChildren = LibraryManager.GetItemIds(new InternalItemsQuery { Parent = this }).Count > 0; + } + + return _hasChildren.Value; + } + + protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) + { + _hasChildren = null; + return base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService); + } + + [IgnoreDataMember] + public bool EnableUserSpecificView + { + get { return true; } + } + } +} diff --git a/Emby.Server.Implementations/Devices/DeviceId.cs b/Emby.Server.Implementations/Devices/DeviceId.cs new file mode 100644 index 000000000..5e0323ddb --- /dev/null +++ b/Emby.Server.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.Server.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(_fileSystem.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.Server.Implementations/Devices/DeviceRepository.cs b/Emby.Server.Implementations/Devices/DeviceRepository.cs index de0dfda2e..b286a3bb0 100644 --- a/Emby.Server.Implementations/Devices/DeviceRepository.cs +++ b/Emby.Server.Implementations/Devices/DeviceRepository.cs @@ -11,6 +11,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Session; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Devices { @@ -199,7 +200,10 @@ namespace Emby.Server.Implementations.Devices } history.DeviceId = deviceId; - history.FilesUploaded.Add(file); + + var list = history.FilesUploaded.ToList(); + list.Add(file); + history.FilesUploaded = list.ToArray(list.Count); _json.SerializeToFile(history, path); } diff --git a/Emby.Server.Implementations/Diagnostics/CommonProcess.cs b/Emby.Server.Implementations/Diagnostics/CommonProcess.cs new file mode 100644 index 000000000..a0a5f32ef --- /dev/null +++ b/Emby.Server.Implementations/Diagnostics/CommonProcess.cs @@ -0,0 +1,110 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using MediaBrowser.Model.Diagnostics; + +namespace Emby.Server.Implementations.Diagnostics +{ + public class CommonProcess : IProcess + { + public event EventHandler Exited; + + private readonly ProcessOptions _options; + private readonly Process _process; + + public CommonProcess(ProcessOptions options) + { + _options = options; + + var startInfo = new ProcessStartInfo + { + Arguments = options.Arguments, + FileName = options.FileName, + WorkingDirectory = options.WorkingDirectory, + UseShellExecute = options.UseShellExecute, + CreateNoWindow = options.CreateNoWindow, + RedirectStandardError = options.RedirectStandardError, + RedirectStandardInput = options.RedirectStandardInput, + RedirectStandardOutput = options.RedirectStandardOutput + }; + + startInfo.ErrorDialog = options.ErrorDialog; + + if (options.IsHidden) + { + startInfo.WindowStyle = ProcessWindowStyle.Hidden; + } + + _process = new Process + { + StartInfo = startInfo + }; + + if (options.EnableRaisingEvents) + { + _process.EnableRaisingEvents = true; + _process.Exited += _process_Exited; + } + } + + private void _process_Exited(object sender, EventArgs e) + { + if (Exited != null) + { + Exited(this, e); + } + } + + public ProcessOptions StartInfo + { + get { return _options; } + } + + public StreamWriter StandardInput + { + get { return _process.StandardInput; } + } + + public StreamReader StandardError + { + get { return _process.StandardError; } + } + + public StreamReader StandardOutput + { + get { return _process.StandardOutput; } + } + + public int ExitCode + { + get { return _process.ExitCode; } + } + + public void Start() + { + _process.Start(); + } + + public void Kill() + { + _process.Kill(); + } + + public bool WaitForExit(int timeMs) + { + return _process.WaitForExit(timeMs); + } + + public Task<bool> WaitForExitAsync(int timeMs) + { + return Task.FromResult(_process.WaitForExit(timeMs)); + } + + public void Dispose() + { + _process.Dispose(); + GC.SuppressFinalize(this); + } + } +} diff --git a/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs b/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs new file mode 100644 index 000000000..a2c511cb9 --- /dev/null +++ b/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs @@ -0,0 +1,12 @@ +using MediaBrowser.Model.Diagnostics; + +namespace Emby.Server.Implementations.Diagnostics +{ + public class ProcessFactory : IProcessFactory + { + public IProcess Create(ProcessOptions options) + { + return new CommonProcess(options); + } + } +} diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index a57ee0b9b..a0bbd171f 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.Dto /// <param name="owner">The owner.</param> /// <returns>Task{DtoBaseItem}.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null) + public BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null) { var options = new DtoOptions { @@ -87,7 +87,17 @@ namespace Emby.Server.Implementations.Dto return GetBaseItemDto(item, options, user, owner); } - public async Task<List<BaseItemDto>> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null) + public BaseItemDto[] GetBaseItemDtos(List<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null) + { + return GetBaseItemDtos(items, items.Count, options, user, owner); + } + + public BaseItemDto[] GetBaseItemDtos(BaseItem[] items, DtoOptions options, User user = null, BaseItem owner = null) + { + return GetBaseItemDtos(items, items.Length, options, user, owner); + } + + public BaseItemDto[] GetBaseItemDtos(IEnumerable<BaseItem> items, int itemCount, DtoOptions options, User user = null, BaseItem owner = null) { if (items == null) { @@ -101,17 +111,14 @@ namespace Emby.Server.Implementations.Dto var syncDictionary = GetSyncedItemProgress(options); - var list = new List<BaseItemDto>(); + var returnItems = new BaseItemDto[itemCount]; var programTuples = new List<Tuple<BaseItem, BaseItemDto>>(); var channelTuples = new List<Tuple<BaseItemDto, LiveTvChannel>>(); - var refreshQueue = options.Fields.Contains(ItemFields.RefreshState) - ? _providerManager.GetRefreshQueue() - : null; - + var index = 0; foreach (var item in items) { - var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user, owner); + var dto = GetBaseItemDtoInternal(item, options, user, owner); var tvChannel = item as LiveTvChannel; if (tvChannel != null) @@ -144,37 +151,34 @@ namespace Emby.Server.Implementations.Dto FillSyncInfo(dto, item, options, user, syncDictionary); - list.Add(dto); + returnItems[index] = dto; + index++; } if (programTuples.Count > 0) { - await _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user).ConfigureAwait(false); + var task = _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user); + Task.WaitAll(task); } if (channelTuples.Count > 0) { - await _livetvManager().AddChannelInfo(channelTuples, options, user).ConfigureAwait(false); + _livetvManager().AddChannelInfo(channelTuples, options, user); } - return list; + return returnItems; } public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { var syncDictionary = GetSyncedItemProgress(options); - var refreshQueue = options.Fields.Contains(ItemFields.RefreshState) - ? _providerManager.GetRefreshQueue() - : null; - - var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user, owner); + var dto = GetBaseItemDtoInternal(item, options, user, owner); var tvChannel = item as LiveTvChannel; if (tvChannel != null) { var list = new List<Tuple<BaseItemDto, LiveTvChannel>> { new Tuple<BaseItemDto, LiveTvChannel>(dto, tvChannel) }; - var task = _livetvManager().AddChannelInfo(list, options, user); - Task.WaitAll(task); + _livetvManager().AddChannelInfo(list, options, user); } else if (item is LiveTvProgram) { @@ -300,7 +304,7 @@ namespace Emby.Server.Implementations.Dto } } - private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Dictionary<Guid, Guid> currentRefreshQueue, User user = null, BaseItem owner = null) + private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) { var fields = options.Fields; @@ -359,12 +363,14 @@ namespace Emby.Server.Implementations.Dto { if (user == null) { - dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true).ToList(); + dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true); } else { - dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user).ToList(); + dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user); } + + NormalizeMediaSourceContainers(dto); } } @@ -400,25 +406,74 @@ namespace Emby.Server.Implementations.Dto dto.Etag = item.GetEtag(user); } - if (currentRefreshQueue != null) + var liveTvManager = _livetvManager(); + if (item is ILiveTvRecording) { - //dto.RefreshState = item.GetRefreshState(currentRefreshQueue); + liveTvManager.AddInfoToRecordingDto(item, dto, user); } - - if (item is ILiveTvRecording) + else { - _livetvManager().AddInfoToRecordingDto(item, dto, user); + var activeRecording = liveTvManager.GetActiveRecordingInfo(item.Path); + if (activeRecording != null) + { + dto.Type = "Recording"; + dto.CanDownload = false; + dto.RunTimeTicks = null; + + if (!string.IsNullOrWhiteSpace(dto.SeriesName)) + { + dto.EpisodeTitle = dto.Name; + dto.Name = dto.SeriesName; + } + liveTvManager.AddInfoToRecordingDto(item, dto, activeRecording, user); + } } return dto; } + private void NormalizeMediaSourceContainers(BaseItemDto dto) + { + foreach (var mediaSource in dto.MediaSources) + { + var container = mediaSource.Container; + if (string.IsNullOrWhiteSpace(container)) + { + continue; + } + var containers = container.Split(new[] { ',' }); + if (containers.Length < 2) + { + continue; + } + + var path = mediaSource.Path; + string fileExtensionContainer = null; + + if (!string.IsNullOrWhiteSpace(path)) + { + path = Path.GetExtension(path); + if (!string.IsNullOrWhiteSpace(path)) + { + path = Path.GetExtension(path); + if (!string.IsNullOrWhiteSpace(path)) + { + path = path.TrimStart('.'); + } + if (!string.IsNullOrWhiteSpace(path) && containers.Contains(path, StringComparer.OrdinalIgnoreCase)) + { + fileExtensionContainer = path; + } + } + } + + mediaSource.Container = fileExtensionContainer ?? containers[0]; + } + } + public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List<BaseItem> taggedItems, Dictionary<string, SyncedItemProgress> syncProgress, User user = null) { - var refreshQueue = options.Fields.Contains(ItemFields.RefreshState) - ? _providerManager.GetRefreshQueue() - : null; - var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user); + var dto = GetBaseItemDtoInternal(item, options, user); if (taggedItems != null && options.Fields.Contains(ItemFields.ItemCounts)) { @@ -517,7 +572,7 @@ namespace Emby.Server.Implementations.Dto } } - if (!(item is LiveTvProgram) || fields.Contains(ItemFields.PlayAccess)) + if (/*!(item is LiveTvProgram) ||*/ fields.Contains(ItemFields.PlayAccess)) { dto.PlayAccess = item.GetPlayAccess(user); } @@ -639,7 +694,6 @@ namespace Emby.Server.Implementations.Dto private void SetGameProperties(BaseItemDto dto, Game item) { - dto.Players = item.PlayersSupported; dto.GameSystem = item.GameSystem; dto.MultiPartGameFiles = item.MultiPartGameFiles; } @@ -649,12 +703,12 @@ namespace Emby.Server.Implementations.Dto dto.GameSystem = item.GameSystemName; } - private List<string> GetImageTags(BaseItem item, List<ItemImageInfo> images) + private string[] GetImageTags(BaseItem item, List<ItemImageInfo> images) { return images .Select(p => GetImageCacheTag(item, p)) .Where(i => i != null) - .ToList(); + .ToArray(); } private string GetImageCacheTag(BaseItem item, ImageType type) @@ -766,7 +820,7 @@ namespace Emby.Server.Implementations.Dto } } - dto.People = list.ToArray(); + dto.People = list.ToArray(list.Count); } /// <summary> @@ -864,11 +918,6 @@ namespace Emby.Server.Implementations.Dto dto.DateCreated = item.DateCreated; } - if (fields.Contains(ItemFields.DisplayMediaType)) - { - dto.DisplayMediaType = item.DisplayMediaType; - } - if (fields.Contains(ItemFields.Settings)) { dto.LockedFields = item.LockedFields; @@ -998,7 +1047,7 @@ namespace Emby.Server.Implementations.Dto { dto.RemoteTrailers = hasTrailers != null ? hasTrailers.RemoteTrailers : - new List<MediaUrl>(); + new MediaUrl[] { }; } dto.Name = item.Name; @@ -1054,12 +1103,12 @@ namespace Emby.Server.Implementations.Dto { if (!string.IsNullOrWhiteSpace(item.Tagline)) { - dto.Taglines = new List<string> { item.Tagline }; + dto.Taglines = new string[] { item.Tagline }; } if (dto.Taglines == null) { - dto.Taglines = new List<string>(); + dto.Taglines = new string[] { }; } } @@ -1125,8 +1174,7 @@ namespace Emby.Server.Implementations.Dto // Include artists that are not in the database yet, e.g., just added via metadata editor //var foundArtists = artistItems.Items.Select(i => i.Item1.Name).ToList(); - dto.ArtistItems = new List<NameIdPair>(); - dto.ArtistItems.AddRange(hasArtist.Artists + dto.ArtistItems = hasArtist.Artists //.Except(foundArtists, new DistinctNameComparer()) .Select(i => { @@ -1151,7 +1199,7 @@ namespace Emby.Server.Implementations.Dto return null; - }).Where(i => i != null)); + }).Where(i => i != null).ToArray(); } var hasAlbumArtist = item as IHasAlbumArtist; @@ -1177,8 +1225,7 @@ namespace Emby.Server.Implementations.Dto // }) // .ToList(); - dto.AlbumArtists = new List<NameIdPair>(); - dto.AlbumArtists.AddRange(hasAlbumArtist.AlbumArtists + dto.AlbumArtists = hasAlbumArtist.AlbumArtists //.Except(foundArtists, new DistinctNameComparer()) .Select(i => { @@ -1203,7 +1250,7 @@ namespace Emby.Server.Implementations.Dto return null; - }).Where(i => i != null)); + }).Where(i => i != null).ToArray(); } // Add video info @@ -1219,9 +1266,9 @@ namespace Emby.Server.Implementations.Dto dto.HasSubtitles = video.HasSubtitles; } - if (video.AdditionalParts.Count != 0) + if (video.AdditionalParts.Length != 0) { - dto.PartCount = video.AdditionalParts.Count + 1; + dto.PartCount = video.AdditionalParts.Length + 1; } if (fields.Contains(ItemFields.MediaSourceCount)) @@ -1251,17 +1298,17 @@ namespace Emby.Server.Implementations.Dto if (iHasMediaSources != null) { - List<MediaStream> mediaStreams; + MediaStream[] mediaStreams; if (dto.MediaSources != null && dto.MediaSources.Count > 0) { mediaStreams = dto.MediaSources.Where(i => new Guid(i.Id) == item.Id) .SelectMany(i => i.MediaStreams) - .ToList(); + .ToArray(); } else { - mediaStreams = _mediaSourceManager().GetStaticMediaSources(iHasMediaSources, true).First().MediaStreams; + mediaStreams = _mediaSourceManager().GetStaticMediaSources(iHasMediaSources, true).First().MediaStreams.ToArray(); } dto.MediaStreams = mediaStreams; @@ -1271,7 +1318,7 @@ namespace Emby.Server.Implementations.Dto var hasSpecialFeatures = item as IHasSpecialFeatures; if (hasSpecialFeatures != null) { - var specialFeatureCount = hasSpecialFeatures.SpecialFeatureIds.Count; + var specialFeatureCount = hasSpecialFeatures.SpecialFeatureIds.Length; if (specialFeatureCount > 0) { @@ -1316,15 +1363,6 @@ namespace Emby.Server.Implementations.Dto Series episodeSeries = null; - if (fields.Contains(ItemFields.SeriesGenres)) - { - episodeSeries = episodeSeries ?? episode.Series; - if (episodeSeries != null) - { - dto.SeriesGenres = episodeSeries.Genres.ToList(); - } - } - //if (fields.Contains(ItemFields.SeriesPrimaryImage)) { episodeSeries = episodeSeries ?? episode.Series; @@ -1340,27 +1378,6 @@ namespace Emby.Server.Implementations.Dto if (episodeSeries != null) { dto.SeriesStudio = episodeSeries.Studios.FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(dto.SeriesStudio)) - { - try - { - var studio = _libraryManager.GetStudio(dto.SeriesStudio); - - if (studio != null) - { - dto.SeriesStudioInfo = new StudioDto - { - Name = dto.SeriesStudio, - Id = studio.Id.ToString("N"), - PrimaryImageTag = GetImageCacheTag(studio, ImageType.Primary) - }; - } - } - catch (Exception ex) - { - - } - } } } } @@ -1435,9 +1452,9 @@ namespace Emby.Server.Implementations.Dto if (fields.Contains(ItemFields.ProductionLocations)) { - if (item.ProductionLocations.Count > 0 || item is Movie) + if (item.ProductionLocations.Length > 0 || item is Movie) { - dto.ProductionLocations = item.ProductionLocations.ToArray(); + dto.ProductionLocations = item.ProductionLocations; } } @@ -1504,7 +1521,9 @@ namespace Emby.Server.Implementations.Dto BaseItem parent = null; var isFirst = true; - while (((!dto.HasLogo && logoLimit > 0) || (!dto.HasArtImage && artLimit > 0) || (!dto.HasThumb && thumbLimit > 0) || parent is Series) && + var imageTags = dto.ImageTags; + + while (((!(imageTags != null && imageTags.ContainsKey(ImageType.Logo)) && logoLimit > 0) || (!(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && artLimit > 0) || (!(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && thumbLimit > 0) || parent is Series) && (parent = parent ?? (isFirst ? GetImageDisplayParent(item, item) ?? owner : parent)) != null) { if (parent == null) @@ -1514,7 +1533,7 @@ namespace Emby.Server.Implementations.Dto var allImages = parent.ImageInfos; - if (logoLimit > 0 && !dto.HasLogo && dto.ParentLogoItemId == null) + if (logoLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Logo)) && dto.ParentLogoItemId == null) { var image = allImages.FirstOrDefault(i => i.Type == ImageType.Logo); @@ -1524,7 +1543,7 @@ namespace Emby.Server.Implementations.Dto dto.ParentLogoImageTag = GetImageCacheTag(parent, image); } } - if (artLimit > 0 && !dto.HasArtImage && dto.ParentArtItemId == null) + if (artLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && dto.ParentArtItemId == null) { var image = allImages.FirstOrDefault(i => i.Type == ImageType.Art); @@ -1534,7 +1553,7 @@ namespace Emby.Server.Implementations.Dto dto.ParentArtImageTag = GetImageCacheTag(parent, image); } } - if (thumbLimit > 0 && !dto.HasThumb && (dto.ParentThumbItemId == null || parent is Series) && !(parent is ICollectionFolder) && !(parent is UserView)) + if (thumbLimit > 0 && !(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && (dto.ParentThumbItemId == null || parent is Series) && !(parent is ICollectionFolder) && !(parent is UserView)) { var image = allImages.FirstOrDefault(i => i.Type == ImageType.Thumb); @@ -1544,7 +1563,7 @@ namespace Emby.Server.Implementations.Dto dto.ParentThumbImageTag = GetImageCacheTag(parent, image); } } - if (backdropLimit > 0 && !dto.HasBackdrop) + if (backdropLimit > 0 && !((dto.BackdropImageTags != null && dto.BackdropImageTags.Length > 0) || (dto.ParentBackdropImageTags != null && dto.ParentBackdropImageTags.Length > 0))) { var images = allImages.Where(i => i.Type == ImageType.Backdrop).Take(backdropLimit).ToList(); @@ -1586,12 +1605,12 @@ namespace Emby.Server.Implementations.Dto /// <param name="dto">The dto.</param> /// <param name="item">The item.</param> /// <returns>Task.</returns> - public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item) + public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasMetadata item) { dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item); } - public double? GetPrimaryImageAspectRatio(IHasImages item) + public double? GetPrimaryImageAspectRatio(IHasMetadata item) { var imageInfo = item.GetImageInfo(ImageType.Primary, 0); @@ -1600,7 +1619,7 @@ namespace Emby.Server.Implementations.Dto return null; } - var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList(); + var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary); ImageSize size; diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 3d6e02816..75a9d8588 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -21,6 +21,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -29,6 +30,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> </PropertyGroup> <ItemGroup> <Compile Include="..\SharedVersion.cs"> @@ -40,6 +42,8 @@ <Compile Include="AppBase\BaseApplicationPaths.cs" /> <Compile Include="AppBase\BaseConfigurationManager.cs" /> <Compile Include="AppBase\ConfigurationHelper.cs" /> + <Compile Include="ApplicationHost.cs" /> + <Compile Include="Archiving\ZipClient.cs" /> <Compile Include="Branding\BrandingConfigurationFactory.cs" /> <Compile Include="Browser\BrowserLauncher.cs" /> <Compile Include="Channels\ChannelConfigurations.cs" /> @@ -52,6 +56,25 @@ <Compile Include="Collections\CollectionManager.cs" /> <Compile Include="Collections\CollectionsDynamicFolder.cs" /> <Compile Include="Configuration\ServerConfigurationManager.cs" /> + <Compile Include="Cryptography\ASN1.cs" /> + <Compile Include="Cryptography\ASN1Convert.cs" /> + <Compile Include="Cryptography\BitConverterLE.cs" /> + <Compile Include="Cryptography\CertificateGenerator.cs" /> + <Compile Include="Cryptography\CryptoConvert.cs" /> + <Compile Include="Cryptography\CryptographyProvider.cs" /> + <Compile Include="Cryptography\PfxGenerator.cs" /> + <Compile Include="Cryptography\PKCS1.cs" /> + <Compile Include="Cryptography\PKCS12.cs" /> + <Compile Include="Cryptography\PKCS7.cs" /> + <Compile Include="Cryptography\PKCS8.cs" /> + <Compile Include="Cryptography\X501Name.cs" /> + <Compile Include="Cryptography\X509Builder.cs" /> + <Compile Include="Cryptography\X509Certificate.cs" /> + <Compile Include="Cryptography\X509CertificateBuilder.cs" /> + <Compile Include="Cryptography\X509CertificateCollection.cs" /> + <Compile Include="Cryptography\X509Extension.cs" /> + <Compile Include="Cryptography\X509Extensions.cs" /> + <Compile Include="Cryptography\X520Attributes.cs" /> <Compile Include="Data\ManagedConnection.cs" /> <Compile Include="Data\SqliteDisplayPreferencesRepository.cs" /> <Compile Include="Data\SqliteItemRepository.cs" /> @@ -59,10 +82,15 @@ <Compile Include="Data\SqliteUserRepository.cs" /> <Compile Include="Data\TypeMapper.cs" /> <Compile Include="Devices\CameraUploadsDynamicFolder.cs" /> + <Compile Include="Devices\CameraUploadsFolder.cs" /> + <Compile Include="Devices\DeviceId.cs" /> <Compile Include="Devices\DeviceManager.cs" /> <Compile Include="Devices\DeviceRepository.cs" /> + <Compile Include="Diagnostics\CommonProcess.cs" /> + <Compile Include="Diagnostics\ProcessFactory.cs" /> <Compile Include="Dto\DtoService.cs" /> <Compile Include="EntryPoints\AutomaticRestartEntryPoint.cs" /> + <Compile Include="EntryPoints\ExternalPortForwarding.cs" /> <Compile Include="EntryPoints\KeepServerAwake.cs" /> <Compile Include="EntryPoints\LibraryChangedNotifier.cs" /> <Compile Include="EntryPoints\LoadRegistrations.cs" /> @@ -75,9 +103,13 @@ <Compile Include="EntryPoints\UsageEntryPoint.cs" /> <Compile Include="EntryPoints\UsageReporter.cs" /> <Compile Include="EntryPoints\UserDataChangeNotifier.cs" /> + <Compile Include="EnvironmentInfo\EnvironmentInfo.cs" /> <Compile Include="FFMpeg\FFMpegInfo.cs" /> <Compile Include="FFMpeg\FFMpegInstallInfo.cs" /> <Compile Include="FFMpeg\FFMpegLoader.cs" /> + <Compile Include="HttpClientManager\HttpClientInfo.cs" /> + <Compile Include="HttpClientManager\HttpClientManager.cs" /> + <Compile Include="HttpServerFactory.cs" /> <Compile Include="HttpServer\FileWriter.cs" /> <Compile Include="HttpServer\HttpListenerHost.cs" /> <Compile Include="HttpServer\HttpResultFactory.cs" /> @@ -99,7 +131,236 @@ <Compile Include="Images\BaseDynamicImageProvider.cs" /> <Compile Include="IO\AsyncStreamCopier.cs" /> <Compile Include="IO\FileRefresher.cs" /> + <Compile Include="IO\IsoManager.cs" /> + <Compile Include="IO\LibraryMonitor.cs" /> + <Compile Include="IO\ManagedFileSystem.cs" /> <Compile Include="IO\MbLinkShortcutHandler.cs" /> + <Compile Include="IO\MemoryStreamProvider.cs" /> + <Compile Include="IO\ProgressStream.cs" /> + <Compile Include="IO\SharpCifsFileSystem.cs" /> + <Compile Include="IO\SharpCifs\Config.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcBind.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcBinding.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcConstants.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcError.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcException.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcHandle.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcMessage.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcPipeHandle.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\DcerpcSecurityProvider.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\LsaPolicyHandle.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\Lsarpc.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\LsarSidArrayX.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcDfsRootEnum.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcEnumerateAliasesInDomain.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcGetMembersInAlias.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcLookupSids.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcLsarOpenPolicy2.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcQueryInformationPolicy.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcSamrConnect2.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcSamrConnect4.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcSamrOpenAlias.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcSamrOpenDomain.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcShareEnum.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\MsrpcShareGetInfo.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\Netdfs.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\Samr.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\SamrAliasHandle.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\SamrDomainHandle.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\SamrPolicyHandle.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Msrpc\Srvsvc.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Ndr\NdrBuffer.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Ndr\NdrException.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Ndr\NdrHyper.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Ndr\NdrLong.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Ndr\NdrObject.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Ndr\NdrShort.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Ndr\NdrSmall.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\Rpc.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\UnicodeString.cs" /> + <Compile Include="IO\SharpCifs\Dcerpc\UUID.cs" /> + <Compile Include="IO\SharpCifs\Netbios\Lmhosts.cs" /> + <Compile Include="IO\SharpCifs\Netbios\Name.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NameQueryRequest.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NameQueryResponse.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NameServiceClient.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NameServicePacket.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NbtAddress.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NbtException.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NodeStatusRequest.cs" /> + <Compile Include="IO\SharpCifs\Netbios\NodeStatusResponse.cs" /> + <Compile Include="IO\SharpCifs\Netbios\SessionRequestPacket.cs" /> + <Compile Include="IO\SharpCifs\Netbios\SessionRetargetResponsePacket.cs" /> + <Compile Include="IO\SharpCifs\Netbios\SessionServicePacket.cs" /> + <Compile Include="IO\SharpCifs\Ntlmssp\NtlmFlags.cs" /> + <Compile Include="IO\SharpCifs\Ntlmssp\NtlmMessage.cs" /> + <Compile Include="IO\SharpCifs\Ntlmssp\Type1Message.cs" /> + <Compile Include="IO\SharpCifs\Ntlmssp\Type2Message.cs" /> + <Compile Include="IO\SharpCifs\Ntlmssp\Type3Message.cs" /> + <Compile Include="IO\SharpCifs\Smb\ACE.cs" /> + <Compile Include="IO\SharpCifs\Smb\AllocInfo.cs" /> + <Compile Include="IO\SharpCifs\Smb\AndXServerMessageBlock.cs" /> + <Compile Include="IO\SharpCifs\Smb\BufferCache.cs" /> + <Compile Include="IO\SharpCifs\Smb\Dfs.cs" /> + <Compile Include="IO\SharpCifs\Smb\DfsReferral.cs" /> + <Compile Include="IO\SharpCifs\Smb\DosError.cs" /> + <Compile Include="IO\SharpCifs\Smb\DosFileFilter.cs" /> + <Compile Include="IO\SharpCifs\Smb\FileEntry.cs" /> + <Compile Include="IO\SharpCifs\Smb\IInfo.cs" /> + <Compile Include="IO\SharpCifs\Smb\NetServerEnum2.cs" /> + <Compile Include="IO\SharpCifs\Smb\NetServerEnum2Response.cs" /> + <Compile Include="IO\SharpCifs\Smb\NetShareEnum.cs" /> + <Compile Include="IO\SharpCifs\Smb\NetShareEnumResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\NtlmAuthenticator.cs" /> + <Compile Include="IO\SharpCifs\Smb\NtlmChallenge.cs" /> + <Compile Include="IO\SharpCifs\Smb\NtlmContext.cs" /> + <Compile Include="IO\SharpCifs\Smb\NtlmPasswordAuthentication.cs" /> + <Compile Include="IO\SharpCifs\Smb\NtStatus.cs" /> + <Compile Include="IO\SharpCifs\Smb\NtTransQuerySecurityDesc.cs" /> + <Compile Include="IO\SharpCifs\Smb\NtTransQuerySecurityDescResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\Principal.cs" /> + <Compile Include="IO\SharpCifs\Smb\SecurityDescriptor.cs" /> + <Compile Include="IO\SharpCifs\Smb\ServerMessageBlock.cs" /> + <Compile Include="IO\SharpCifs\Smb\SID.cs" /> + <Compile Include="IO\SharpCifs\Smb\SigningDigest.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbAuthException.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComBlankResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComClose.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComCreateDirectory.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComDelete.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComDeleteDirectory.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComFindClose2.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComLogoffAndX.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComNegotiate.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComNegotiateResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComNTCreateAndX.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComNTCreateAndXResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComNtTransaction.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComNtTransactionResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComOpenAndX.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComOpenAndXResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComQueryInformation.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComQueryInformationResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComReadAndX.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComReadAndXResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComRename.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComSessionSetupAndX.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComSessionSetupAndXResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComTransaction.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComTransactionResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComTreeConnectAndX.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComTreeConnectAndXResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComTreeDisconnect.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComWrite.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComWriteAndX.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComWriteAndXResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbComWriteResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbConstants.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbException.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbFile.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbFileExtensions.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbFileFilter.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbFileInputStream.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbFilenameFilter.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbFileOutputStream.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbNamedPipe.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbRandomAccessFile.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbSession.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbShareInfo.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbTransport.cs" /> + <Compile Include="IO\SharpCifs\Smb\SmbTree.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2FindFirst2.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2FindFirst2Response.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2FindNext2.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2GetDfsReferral.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2GetDfsReferralResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2QueryFSInformation.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2QueryFSInformationResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2QueryPathInformation.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2QueryPathInformationResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2SetFileInformation.cs" /> + <Compile Include="IO\SharpCifs\Smb\Trans2SetFileInformationResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransactNamedPipeInputStream.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransactNamedPipeOutputStream.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransCallNamedPipe.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransCallNamedPipeResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransPeekNamedPipe.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransPeekNamedPipeResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransTransactNamedPipe.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransTransactNamedPipeResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransWaitNamedPipe.cs" /> + <Compile Include="IO\SharpCifs\Smb\TransWaitNamedPipeResponse.cs" /> + <Compile Include="IO\SharpCifs\Smb\WinError.cs" /> + <Compile Include="IO\SharpCifs\UniAddress.cs" /> + <Compile Include="IO\SharpCifs\Util\Base64.cs" /> + <Compile Include="IO\SharpCifs\Util\DES.cs" /> + <Compile Include="IO\SharpCifs\Util\Encdec.cs" /> + <Compile Include="IO\SharpCifs\Util\Hexdump.cs" /> + <Compile Include="IO\SharpCifs\Util\HMACT64.cs" /> + <Compile Include="IO\SharpCifs\Util\LogStream.cs" /> + <Compile Include="IO\SharpCifs\Util\MD4.cs" /> + <Compile Include="IO\SharpCifs\Util\RC4.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\AbstractMap.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Arrays.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\BufferedReader.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\BufferedWriter.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\CharBuffer.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\CharSequence.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Collections.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\ConcurrentHashMap.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\DateFormat.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\EnumeratorWrapper.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Exceptions.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Extensions.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\FileInputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\FileOutputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\FilePath.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\FileReader.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\FileWriter.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\FilterInputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\FilterOutputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Hashtable.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\HttpURLConnection.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\ICallable.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\IConcurrentMap.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\IExecutor.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\IFilenameFilter.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\IFuture.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\InputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\InputStreamReader.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\IPrivilegedAction.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\IRunnable.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Iterator.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\LinkageError.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Matcher.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\MD5.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\MD5Managed.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\MessageDigest.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\NetworkStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\ObjectInputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\ObjectOutputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\OutputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\OutputStreamWriter.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\PipedInputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\PipedOutputStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\PrintWriter.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Properties.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\RandomAccessFile.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\ReentrantLock.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Reference.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Runtime.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\SimpleDateFormat.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\SocketEx.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\StringTokenizer.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\SynchronizedList.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\Thread.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\ThreadFactory.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\ThreadPoolExecutor.cs" /> + <Compile Include="IO\SharpCifs\Util\Sharpen\WrappedSystemStream.cs" /> + <Compile Include="IO\SharpCifs\Util\Transport\Request.cs" /> + <Compile Include="IO\SharpCifs\Util\Transport\Response.cs" /> + <Compile Include="IO\SharpCifs\Util\Transport\Transport.cs" /> + <Compile Include="IO\SharpCifs\Util\Transport\TransportException.cs" /> <Compile Include="IO\ThrottledStream.cs" /> <Compile Include="Library\CoreResolutionIgnoreRule.cs" /> <Compile Include="Library\LibraryManager.cs" /> @@ -170,9 +431,17 @@ <Compile Include="LiveTv\TunerHosts\MulticastStream.cs" /> <Compile Include="LiveTv\TunerHosts\QueueStream.cs" /> <Compile Include="Localization\LocalizationManager.cs" /> + <Compile Include="Localization\TextLocalizer.cs" /> + <Compile Include="Logging\ConsoleLogger.cs" /> + <Compile Include="Logging\SimpleLogManager.cs" /> <Compile Include="Logging\UnhandledExceptionWriter.cs" /> <Compile Include="MediaEncoder\EncodingManager.cs" /> <Compile Include="Migrations\IVersionMigration.cs" /> + <Compile Include="Networking\NetworkManager.cs" /> + <Compile Include="Net\DisposableManagedObjectBase.cs" /> + <Compile Include="Net\NetAcceptSocket.cs" /> + <Compile Include="Net\SocketFactory.cs" /> + <Compile Include="Net\UdpSocket.cs" /> <Compile Include="News\NewsEntryPoint.cs" /> <Compile Include="News\NewsService.cs" /> <Compile Include="Notifications\CoreNotificationTypes.cs" /> @@ -187,20 +456,34 @@ <Compile Include="Data\CleanDatabaseScheduledTask.cs" /> <Compile Include="Data\SqliteExtensions.cs" /> <Compile Include="Photos\PhotoAlbumImageProvider.cs" /> + <Compile Include="Playlists\ManualPlaylistsFolder.cs" /> <Compile Include="Playlists\PlaylistImageProvider.cs" /> <Compile Include="Playlists\PlaylistManager.cs" /> <Compile Include="Playlists\PlaylistsDynamicFolder.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Reflection\AssemblyInfo.cs" /> <Compile Include="ScheduledTasks\ChapterImagesTask.cs" /> + <Compile Include="ScheduledTasks\DailyTrigger.cs" /> + <Compile Include="ScheduledTasks\IntervalTrigger.cs" /> <Compile Include="ScheduledTasks\PeopleValidationTask.cs" /> <Compile Include="ScheduledTasks\PluginUpdateTask.cs" /> <Compile Include="ScheduledTasks\RefreshMediaLibraryTask.cs" /> + <Compile Include="ScheduledTasks\ScheduledTaskWorker.cs" /> + <Compile Include="ScheduledTasks\StartupTrigger.cs" /> + <Compile Include="ScheduledTasks\SystemEventTrigger.cs" /> <Compile Include="ScheduledTasks\SystemUpdateTask.cs" /> + <Compile Include="ScheduledTasks\TaskManager.cs" /> + <Compile Include="ScheduledTasks\Tasks\DeleteCacheFileTask.cs" /> + <Compile Include="ScheduledTasks\Tasks\DeleteLogFileTask.cs" /> + <Compile Include="ScheduledTasks\Tasks\ReloadLoggerFileTask.cs" /> + <Compile Include="ScheduledTasks\WeeklyTrigger.cs" /> <Compile Include="Security\AuthenticationRepository.cs" /> <Compile Include="Security\EncryptionManager.cs" /> <Compile Include="Security\MBLicenseFile.cs" /> <Compile Include="Security\PluginSecurityManager.cs" /> <Compile Include="Security\RegRecord.cs" /> + <Compile Include="Serialization\JsonSerializer.cs" /> + <Compile Include="Serialization\XmlSerializer.cs" /> <Compile Include="ServerApplicationPaths.cs" /> <Compile Include="ServerManager\ServerManager.cs" /> <Compile Include="ServerManager\WebSocketConnection.cs" /> @@ -221,7 +504,6 @@ <Compile Include="Social\SharingManager.cs" /> <Compile Include="Social\SharingRepository.cs" /> <Compile Include="Sorting\AiredEpisodeOrderComparer.cs" /> - <Compile Include="Sorting\AirTimeComparer.cs" /> <Compile Include="Sorting\AlbumArtistComparer.cs" /> <Compile Include="Sorting\AlbumComparer.cs" /> <Compile Include="Sorting\AlphanumComparator.cs" /> @@ -249,17 +531,89 @@ <Compile Include="Sorting\StartDateComparer.cs" /> <Compile Include="Sorting\StudioComparer.cs" /> <Compile Include="StartupOptions.cs" /> + <Compile Include="SystemEvents.cs" /> + <Compile Include="TextEncoding\NLangDetect\Detector.cs" /> + <Compile Include="TextEncoding\NLangDetect\DetectorFactory.cs" /> + <Compile Include="TextEncoding\NLangDetect\ErrorCode.cs" /> + <Compile Include="TextEncoding\NLangDetect\Extensions\CharExtensions.cs" /> + <Compile Include="TextEncoding\NLangDetect\Extensions\RandomExtensions.cs" /> + <Compile Include="TextEncoding\NLangDetect\Extensions\StringExtensions.cs" /> + <Compile Include="TextEncoding\NLangDetect\Extensions\UnicodeBlock.cs" /> + <Compile Include="TextEncoding\NLangDetect\GenProfile.cs" /> + <Compile Include="TextEncoding\NLangDetect\InternalException.cs" /> + <Compile Include="TextEncoding\NLangDetect\Language.cs" /> + <Compile Include="TextEncoding\NLangDetect\LanguageDetector.cs" /> + <Compile Include="TextEncoding\NLangDetect\NLangDetectException.cs" /> + <Compile Include="TextEncoding\NLangDetect\ProbVector.cs" /> + <Compile Include="TextEncoding\NLangDetect\Utils\LangProfile.cs" /> + <Compile Include="TextEncoding\NLangDetect\Utils\Messages.cs" /> + <Compile Include="TextEncoding\NLangDetect\Utils\NGram.cs" /> + <Compile Include="TextEncoding\NLangDetect\Utils\TagExtractor.cs" /> + <Compile Include="TextEncoding\TextEncoding.cs" /> + <Compile Include="TextEncoding\TextEncodingDetect.cs" /> + <Compile Include="TextEncoding\UniversalDetector\CharsetDetector.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\Big5Prober.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\BitPackage.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\CharDistributionAnalyser.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\CharsetProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\Charsets.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\CodingStateMachine.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\EscCharsetProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\EscSM.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\EUCJPProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\EUCKRProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\EUCTWProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\GB18030Prober.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\HebrewProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\JapaneseContextAnalyser.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\LangBulgarianModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\LangCyrillicModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\LangGreekModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\LangHebrewModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\LangHungarianModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\LangThaiModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\Latin1Prober.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\MBCSGroupProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\MBCSSM.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\SBCharsetProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\SBCSGroupProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\SequenceModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\SJISProber.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\SMModel.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\UniversalDetector.cs" /> + <Compile Include="TextEncoding\UniversalDetector\Core\UTF8Prober.cs" /> + <Compile Include="TextEncoding\UniversalDetector\DetectionConfidence.cs" /> + <Compile Include="TextEncoding\UniversalDetector\ICharsetDetector.cs" /> + <Compile Include="Threading\CommonTimer.cs" /> + <Compile Include="Threading\TimerFactory.cs" /> <Compile Include="TV\SeriesPostScanTask.cs" /> <Compile Include="TV\TVSeriesManager.cs" /> <Compile Include="Udp\UdpServer.cs" /> <Compile Include="Updates\InstallationManager.cs" /> <Compile Include="UserViews\CollectionFolderImageProvider.cs" /> <Compile Include="UserViews\DynamicImageProvider.cs" /> + <Compile Include="Xml\XmlReaderSettingsFactory.cs" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="Localization\iso6392.txt" /> </ItemGroup> <ItemGroup> + <ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj"> + <Project>{805844ab-e92f-45e6-9d99-4f6d48d129a5}</Project> + <Name>Emby.Dlna</Name> + </ProjectReference> + <ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj"> + <Project>{08fff49b-f175-4807-a2b5-73b0ebd9f716}</Project> + <Name>Emby.Drawing</Name> + </ProjectReference> + <ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj"> + <Project>{89ab4548-770d-41fd-a891-8daff44f452c}</Project> + <Name>Emby.Photos</Name> + </ProjectReference> + <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj"> + <Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project> + <Name>MediaBrowser.Api</Name> + </ProjectReference> <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj"> <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project> <Name>MediaBrowser.Common</Name> @@ -268,6 +622,10 @@ <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project> <Name>MediaBrowser.Controller</Name> </ProjectReference> + <ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj"> + <Project>{7ef9f3e0-697d-42f3-a08f-19deb5f84392}</Project> + <Name>MediaBrowser.LocalMetadata</Name> + </ProjectReference> <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj"> <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project> <Name>MediaBrowser.Model</Name> @@ -276,22 +634,46 @@ <Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project> <Name>MediaBrowser.Providers</Name> </ProjectReference> - <ProjectReference Include="..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj"> - <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project> - <Name>MediaBrowser.Server.Implementations</Name> + <ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj"> + <Project>{5624b7b5-b5a7-41d8-9f10-cc5611109619}</Project> + <Name>MediaBrowser.WebDashboard</Name> + </ProjectReference> + <ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj"> + <Project>{23499896-b135-4527-8574-c26e926ea99e}</Project> + <Name>MediaBrowser.XbmcMetadata</Name> + </ProjectReference> + <ProjectReference Include="..\Mono.Nat\Mono.Nat.csproj"> + <Project>{cb7f2326-6497-4a3d-ba03-48513b17a7be}</Project> + <Name>Mono.Nat</Name> + </ProjectReference> + <ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj"> + <Project>{4a4402d4-e910-443b-b8fc-2c18286a2ca0}</Project> + <Name>OpenSubtitlesHandler</Name> </ProjectReference> <ProjectReference Include="..\SocketHttpListener\SocketHttpListener.csproj"> <Project>{1d74413b-e7cf-455b-b021-f52bdf881542}</Project> <Name>SocketHttpListener</Name> </ProjectReference> + <Reference Include="Emby.Server.MediaEncoding"> + <HintPath>..\ThirdParty\emby\Emby.Server.MediaEncoding.dll</HintPath> + </Reference> <Reference Include="Emby.XmlTv, Version=1.0.6387.29335, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\Emby.XmlTv.1.0.9\lib\portable-net45+win8\Emby.XmlTv.dll</HintPath> + <HintPath>..\packages\Emby.XmlTv.1.0.10\lib\portable-net45+netstandard2.0+win8\Emby.XmlTv.dll</HintPath> + </Reference> + <Reference Include="MediaBrowser.Naming, Version=1.0.6447.2217, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\MediaBrowser.Naming.1.0.7\lib\portable-net45+netstandard2.0+win8\MediaBrowser.Naming.dll</HintPath> <Private>True</Private> </Reference> - <Reference Include="MediaBrowser.Naming, Version=1.0.6279.25941, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\MediaBrowser.Naming.1.0.5\lib\portable-net45+win8\MediaBrowser.Naming.dll</HintPath> + <Reference Include="ServiceStack.Text, Version=4.5.8.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath> <Private>True</Private> </Reference> + <Reference Include="SharpCompress, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath> + </Reference> + <Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> + <HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath> + </Reference> <Reference Include="SQLitePCL.pretty, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\packages\SQLitePCL.pretty.1.1.0\lib\portable-net45+netcore45+wpa81+wp8\SQLitePCL.pretty.dll</HintPath> <Private>True</Private> @@ -299,10 +681,10 @@ </ItemGroup> <ItemGroup> <Reference Include="SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL"> - <HintPath>..\packages\SQLitePCLRaw.core.1.1.7\lib\net45\SQLitePCLRaw.core.dll</HintPath> - <Private>True</Private> + <HintPath>..\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll</HintPath> </Reference> <Reference Include="System" /> + <Reference Include="System.Configuration" /> <Reference Include="System.Core" /> <Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Xml.Linq" /> @@ -316,7 +698,6 @@ <EmbeddedResource Include="Localization\Core\ar.json" /> <EmbeddedResource Include="Localization\Core\bg-BG.json" /> <EmbeddedResource Include="Localization\Core\ca.json" /> - <EmbeddedResource Include="Localization\Core\core.json" /> <EmbeddedResource Include="Localization\Core\cs.json" /> <EmbeddedResource Include="Localization\Core\da.json" /> <EmbeddedResource Include="Localization\Core\de.json" /> @@ -355,6 +736,60 @@ <EmbeddedResource Include="Localization\Core\zh-TW.json" /> <EmbeddedResource Include="Localization\countries.json" /> <None Include="packages.config" /> + <None Include="TextEncoding\NLangDetect\Profiles\afr" /> + <None Include="TextEncoding\NLangDetect\Profiles\ara" /> + <None Include="TextEncoding\NLangDetect\Profiles\ben" /> + <None Include="TextEncoding\NLangDetect\Profiles\bul" /> + <None Include="TextEncoding\NLangDetect\Profiles\ces" /> + <None Include="TextEncoding\NLangDetect\Profiles\dan" /> + <None Include="TextEncoding\NLangDetect\Profiles\deu" /> + <None Include="TextEncoding\NLangDetect\Profiles\ell" /> + <None Include="TextEncoding\NLangDetect\Profiles\eng" /> + <None Include="TextEncoding\NLangDetect\Profiles\est" /> + <None Include="TextEncoding\NLangDetect\Profiles\fas" /> + <None Include="TextEncoding\NLangDetect\Profiles\fin" /> + <None Include="TextEncoding\NLangDetect\Profiles\fra" /> + <None Include="TextEncoding\NLangDetect\Profiles\guj" /> + <None Include="TextEncoding\NLangDetect\Profiles\heb" /> + <None Include="TextEncoding\NLangDetect\Profiles\hin" /> + <None Include="TextEncoding\NLangDetect\Profiles\hrv" /> + <None Include="TextEncoding\NLangDetect\Profiles\hun" /> + <None Include="TextEncoding\NLangDetect\Profiles\ind" /> + <None Include="TextEncoding\NLangDetect\Profiles\ita" /> + <None Include="TextEncoding\NLangDetect\Profiles\jpn" /> + <None Include="TextEncoding\NLangDetect\Profiles\kan" /> + <None Include="TextEncoding\NLangDetect\Profiles\kor" /> + <None Include="TextEncoding\NLangDetect\Profiles\lav" /> + <None Include="TextEncoding\NLangDetect\Profiles\lit" /> + <None Include="TextEncoding\NLangDetect\Profiles\mal" /> + <None Include="TextEncoding\NLangDetect\Profiles\mar" /> + <None Include="TextEncoding\NLangDetect\Profiles\mkd" /> + <None Include="TextEncoding\NLangDetect\Profiles\nep" /> + <None Include="TextEncoding\NLangDetect\Profiles\nld" /> + <None Include="TextEncoding\NLangDetect\Profiles\nor" /> + <None Include="TextEncoding\NLangDetect\Profiles\pan" /> + <None Include="TextEncoding\NLangDetect\Profiles\pol" /> + <None Include="TextEncoding\NLangDetect\Profiles\por" /> + <None Include="TextEncoding\NLangDetect\Profiles\ron" /> + <None Include="TextEncoding\NLangDetect\Profiles\rus" /> + <None Include="TextEncoding\NLangDetect\Profiles\slk" /> + <None Include="TextEncoding\NLangDetect\Profiles\slv" /> + <None Include="TextEncoding\NLangDetect\Profiles\som" /> + <None Include="TextEncoding\NLangDetect\Profiles\spa" /> + <None Include="TextEncoding\NLangDetect\Profiles\sqi" /> + <None Include="TextEncoding\NLangDetect\Profiles\swa" /> + <None Include="TextEncoding\NLangDetect\Profiles\swe" /> + <None Include="TextEncoding\NLangDetect\Profiles\tam" /> + <None Include="TextEncoding\NLangDetect\Profiles\tel" /> + <None Include="TextEncoding\NLangDetect\Profiles\tgl" /> + <None Include="TextEncoding\NLangDetect\Profiles\tha" /> + <None Include="TextEncoding\NLangDetect\Profiles\tur" /> + <None Include="TextEncoding\NLangDetect\Profiles\ukr" /> + <None Include="TextEncoding\NLangDetect\Profiles\urd" /> + <None Include="TextEncoding\NLangDetect\Profiles\vie" /> + <EmbeddedResource Include="TextEncoding\NLangDetect\Profiles\zh-cn" /> + <EmbeddedResource Include="TextEncoding\NLangDetect\Profiles\zh-tw" /> + <EmbeddedResource Include="TextEncoding\NLangDetect\Utils\messages.properties" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="Localization\Ratings\au.txt" /> @@ -413,6 +848,9 @@ <ItemGroup> <EmbeddedResource Include="Localization\Ratings\es.txt" /> </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Localization\Ratings\ro.txt" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs index 561f5ee12..c2cee00c8 100644 --- a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs @@ -112,6 +112,7 @@ namespace Emby.Server.Implementations.EntryPoints _appHost.HasPendingRestartChanged -= _appHost_HasPendingRestartChanged; DisposeTimer(); + GC.SuppressFinalize(this); } private void DisposeTimer() diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs new file mode 100644 index 000000000..9b434d606 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -0,0 +1,336 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Net; +using System.Threading.Tasks; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Threading; +using Mono.Nat; +using MediaBrowser.Model.Extensions; + +namespace Emby.Server.Implementations.EntryPoints +{ + public class ExternalPortForwarding : IServerEntryPoint + { + private readonly IServerApplicationHost _appHost; + private readonly ILogger _logger; + private readonly IHttpClient _httpClient; + private readonly IServerConfigurationManager _config; + private readonly IDeviceDiscovery _deviceDiscovery; + + private ITimer _timer; + private bool _isStarted; + private readonly ITimerFactory _timerFactory; + + public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, ITimerFactory timerFactory) + { + _logger = logmanager.GetLogger("PortMapper"); + _appHost = appHost; + _config = config; + _deviceDiscovery = deviceDiscovery; + _httpClient = httpClient; + _timerFactory = timerFactory; + } + + private string _lastConfigIdentifier; + private string GetConfigIdentifier() + { + var values = new List<string>(); + var config = _config.Configuration; + + values.Add(config.EnableUPnP.ToString()); + values.Add(config.PublicPort.ToString(CultureInfo.InvariantCulture)); + values.Add(_appHost.HttpPort.ToString(CultureInfo.InvariantCulture)); + values.Add(_appHost.HttpsPort.ToString(CultureInfo.InvariantCulture)); + values.Add(config.EnableHttps.ToString()); + values.Add(_appHost.EnableHttps.ToString()); + + return string.Join("|", values.ToArray(values.Count)); + } + + void _config_ConfigurationUpdated(object sender, EventArgs e) + { + if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase)) + { + if (_isStarted) + { + DisposeNat(); + } + + Run(); + } + } + + public void Run() + { + NatUtility.Logger = _logger; + NatUtility.HttpClient = _httpClient; + + if (_config.Configuration.EnableUPnP) + { + Start(); + } + + _config.ConfigurationUpdated -= _config_ConfigurationUpdated; + _config.ConfigurationUpdated += _config_ConfigurationUpdated; + } + + private void Start() + { + _logger.Debug("Starting NAT discovery"); + NatUtility.EnabledProtocols = new List<NatProtocol> + { + NatProtocol.Pmp + }; + NatUtility.DeviceFound += NatUtility_DeviceFound; + + // Mono.Nat does never rise this event. The event is there however it is useless. + // You could remove it with no risk. + NatUtility.DeviceLost += NatUtility_DeviceLost; + + + NatUtility.StartDiscovery(); + + _timer = _timerFactory.Create(ClearCreatedRules, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); + + _deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered; + + _lastConfigIdentifier = GetConfigIdentifier(); + + _isStarted = true; + } + + private async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e) + { + if (_disposed) + { + return; + } + + var info = e.Argument; + + string usn; + if (!info.Headers.TryGetValue("USN", out usn)) usn = string.Empty; + + string nt; + if (!info.Headers.TryGetValue("NT", out nt)) nt = string.Empty; + + // Filter device type + if (usn.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + nt.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + usn.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + nt.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1) + { + return; + } + + var identifier = string.IsNullOrWhiteSpace(usn) ? nt : usn; + + if (info.Location == null) + { + return; + } + + lock (_usnsHandled) + { + if (_usnsHandled.Contains(identifier)) + { + return; + } + _usnsHandled.Add(identifier); + } + + _logger.Debug("Found NAT device: " + identifier); + + IPAddress address; + if (IPAddress.TryParse(info.Location.Host, out address)) + { + // The Handle method doesn't need the port + var endpoint = new IPEndPoint(address, info.Location.Port); + + IPAddress localAddress = null; + + try + { + var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false); + + Uri uri; + if (Uri.TryCreate(localAddressString, UriKind.Absolute, out uri)) + { + localAddressString = uri.Host; + + if (!IPAddress.TryParse(localAddressString, out localAddress)) + { + return; + } + } + } + catch (Exception ex) + { + return; + } + + if (_disposed) + { + return; + } + + _logger.Debug("Calling Nat.Handle on " + identifier); + NatUtility.Handle(localAddress, info, endpoint, NatProtocol.Upnp); + } + } + + private void ClearCreatedRules(object state) + { + lock (_createdRules) + { + _createdRules.Clear(); + } + lock (_usnsHandled) + { + _usnsHandled.Clear(); + } + } + + void NatUtility_DeviceFound(object sender, DeviceEventArgs e) + { + if (_disposed) + { + return; + } + + try + { + var device = e.Device; + _logger.Debug("NAT device found: {0}", device.LocalAddress.ToString()); + + CreateRules(device); + } + catch + { + // I think it could be a good idea to log the exception because + // you are using permanent portmapping here (never expire) and that means that next time + // CreatePortMap is invoked it can fails with a 718-ConflictInMappingEntry or not. That depends + // on the router's upnp implementation (specs says it should fail however some routers don't do it) + // It also can fail with others like 727-ExternalPortOnlySupportsWildcard, 728-NoPortMapsAvailable + // and those errors (upnp errors) could be useful for diagnosting. + + // Commenting out because users are reporting problems out of our control + //_logger.ErrorException("Error creating port forwarding rules", ex); + } + } + + private List<string> _createdRules = new List<string>(); + private List<string> _usnsHandled = new List<string>(); + private async void CreateRules(INatDevice device) + { + if (_disposed) + { + throw new ObjectDisposedException("PortMapper"); + } + + // On some systems the device discovered event seems to fire repeatedly + // This check will help ensure we're not trying to port map the same device over and over + + var address = device.LocalAddress.ToString(); + + lock (_createdRules) + { + if (!_createdRules.Contains(address)) + { + _createdRules.Add(address); + } + else + { + return; + } + } + + var success = await CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort).ConfigureAwait(false); + + if (success) + { + await CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort).ConfigureAwait(false); + } + } + + private async Task<bool> CreatePortMap(INatDevice device, int privatePort, int publicPort) + { + _logger.Debug("Creating port map on port {0}", privatePort); + + try + { + await device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort) + { + Description = _appHost.Name + + }).ConfigureAwait(false); + + return true; + } + catch (Exception ex) + { + _logger.Error("Error creating port map: " + ex.Message); + + return false; + } + } + + // As I said before, this method will be never invoked. You can remove it. + void NatUtility_DeviceLost(object sender, DeviceEventArgs e) + { + var device = e.Device; + _logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString()); + } + + private bool _disposed = false; + public void Dispose() + { + _disposed = true; + DisposeNat(); + GC.SuppressFinalize(this); + } + + private void DisposeNat() + { + _logger.Debug("Stopping NAT discovery"); + + if (_timer != null) + { + _timer.Dispose(); + _timer = null; + } + + _deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered; + + try + { + // This is not a significant improvement + NatUtility.StopDiscovery(); + NatUtility.DeviceFound -= NatUtility_DeviceFound; + NatUtility.DeviceLost -= NatUtility_DeviceLost; + } + // Statements in try-block will no fail because StopDiscovery is a one-line + // method that was no chances to fail. + // public static void StopDiscovery () + // { + // searching.Reset(); + // } + // IMO you could remove the catch-block + catch (Exception ex) + { + _logger.ErrorException("Error stopping NAT Discovery", ex); + } + finally + { + _isStarted = false; + } + } + } +}
\ No newline at end of file diff --git a/Emby.Server.Implementations/EntryPoints/KeepServerAwake.cs b/Emby.Server.Implementations/EntryPoints/KeepServerAwake.cs index 8ae85e390..221580681 100644 --- a/Emby.Server.Implementations/EntryPoints/KeepServerAwake.cs +++ b/Emby.Server.Implementations/EntryPoints/KeepServerAwake.cs @@ -60,6 +60,7 @@ namespace Emby.Server.Implementations.EntryPoints _timer.Dispose(); _timer = null; } + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 69a205dda..796d8cf48 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -367,15 +367,15 @@ namespace Emby.Server.Implementations.EntryPoints return new LibraryUpdateInfo { - ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), - ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), - ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), - FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), - FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList() + FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray() }; } @@ -426,6 +426,7 @@ namespace Emby.Server.Implementations.EntryPoints public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } /// <summary> diff --git a/Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs b/Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs index 0203b5192..21e075cf5 100644 --- a/Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs +++ b/Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs @@ -68,6 +68,7 @@ namespace Emby.Server.Implementations.EntryPoints _timer.Dispose(); _timer = null; } + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs index b674fc39b..f73b40b46 100644 --- a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -72,6 +72,7 @@ namespace Emby.Server.Implementations.EntryPoints _liveTvManager.SeriesTimerCancelled -= _liveTvManager_SeriesTimerCancelled; _liveTvManager.TimerCreated -= _liveTvManager_TimerCreated; _liveTvManager.SeriesTimerCreated -= _liveTvManager_SeriesTimerCreated; + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs index 77de849a1..13e14be36 100644 --- a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs +++ b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Library; +using System; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using System.Threading; @@ -36,6 +37,7 @@ namespace Emby.Server.Implementations.EntryPoints /// </summary> public void Dispose() { + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs index 4d640bc95..514321e20 100644 --- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -174,6 +174,7 @@ namespace Emby.Server.Implementations.EntryPoints public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } /// <summary> diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 424153f22..614c04fd2 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -1,4 +1,5 @@ -using Emby.Server.Implementations.Browser; +using System; +using Emby.Server.Implementations.Browser; using MediaBrowser.Controller; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; @@ -54,6 +55,7 @@ namespace Emby.Server.Implementations.EntryPoints /// </summary> public void Dispose() { + GC.SuppressFinalize(this); } } }
\ No newline at end of file diff --git a/Emby.Server.Implementations/EntryPoints/SystemEvents.cs b/Emby.Server.Implementations/EntryPoints/SystemEvents.cs index 4ab6d32f3..aa63dae27 100644 --- a/Emby.Server.Implementations/EntryPoints/SystemEvents.cs +++ b/Emby.Server.Implementations/EntryPoints/SystemEvents.cs @@ -43,6 +43,7 @@ namespace Emby.Server.Implementations.EntryPoints public void Dispose() { _systemEvents.SystemShutdown -= _systemEvents_SystemShutdown; + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index df5a7c985..d04df0d2b 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -65,6 +65,7 @@ namespace Emby.Server.Implementations.EntryPoints public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } /// <summary> diff --git a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs index 9fbe06673..fb9402986 100644 --- a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs @@ -12,6 +12,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.EntryPoints { @@ -58,7 +59,7 @@ namespace Emby.Server.Implementations.EntryPoints session.ApplicationVersion }; - var key = string.Join("_", keys.ToArray()).GetMD5(); + var key = string.Join("_", keys.ToArray(keys.Count)).GetMD5(); _apps.GetOrAdd(key, guid => GetNewClientInfo(session)); } @@ -129,6 +130,7 @@ namespace Emby.Server.Implementations.EntryPoints public void Dispose() { _sessionManager.SessionStarted -= _sessionManager_SessionStarted; + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 71e31d4d4..4a7182a43 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -126,7 +126,7 @@ namespace Emby.Server.Implementations.EntryPoints dto.ItemId = i.Id.ToString("N"); return dto; }) - .ToList(); + .ToArray(); var info = new UserDataChangeInfo { @@ -160,6 +160,7 @@ namespace Emby.Server.Implementations.EntryPoints } _userDataManager.UserDataSaved -= _userDataManager_UserDataSaved; + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/EnvironmentInfo/EnvironmentInfo.cs b/Emby.Server.Implementations/EnvironmentInfo/EnvironmentInfo.cs new file mode 100644 index 000000000..f86279f37 --- /dev/null +++ b/Emby.Server.Implementations/EnvironmentInfo/EnvironmentInfo.cs @@ -0,0 +1,100 @@ +using System; +using System.IO; +using MediaBrowser.Model.System; + +namespace Emby.Server.Implementations.EnvironmentInfo +{ + public class EnvironmentInfo : IEnvironmentInfo + { + private Architecture? _customArchitecture; + private MediaBrowser.Model.System.OperatingSystem? _customOperatingSystem; + + public virtual MediaBrowser.Model.System.OperatingSystem OperatingSystem + { + get + { + if (_customOperatingSystem.HasValue) + { + return _customOperatingSystem.Value; + } + + switch (Environment.OSVersion.Platform) + { + case PlatformID.MacOSX: + return MediaBrowser.Model.System.OperatingSystem.OSX; + case PlatformID.Win32NT: + return MediaBrowser.Model.System.OperatingSystem.Windows; + case PlatformID.Unix: + return MediaBrowser.Model.System.OperatingSystem.Linux; + } + + return MediaBrowser.Model.System.OperatingSystem.Windows; + } + set + { + _customOperatingSystem = value; + } + } + + public string OperatingSystemName + { + get + { + return Environment.OSVersion.Platform.ToString(); + } + } + + public string OperatingSystemVersion + { + get + { + return Environment.OSVersion.Version.ToString() + " " + Environment.OSVersion.ServicePack.ToString(); + } + } + + public char PathSeparator + { + get + { + return Path.PathSeparator; + } + } + + public Architecture SystemArchitecture + { + get + { + if (_customArchitecture.HasValue) + { + return _customArchitecture.Value; + } + + return Environment.Is64BitOperatingSystem ? MediaBrowser.Model.System.Architecture.X64 : MediaBrowser.Model.System.Architecture.X86; + } + set + { + _customArchitecture = value; + } + } + + public string GetEnvironmentVariable(string name) + { + return Environment.GetEnvironmentVariable(name); + } + + public virtual string GetUserId() + { + return null; + } + + public string StackTrace + { + get { return Environment.StackTrace; } + } + + public void SetProcessEnvironmentVariable(string name, string value) + { + Environment.SetEnvironmentVariable(name, value); + } + } +}
\ No newline at end of file diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientInfo.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientInfo.cs new file mode 100644 index 000000000..6d17bf94d --- /dev/null +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientInfo.cs @@ -0,0 +1,16 @@ +using System; + +namespace Emby.Server.Implementations.HttpClientManager +{ + /// <summary> + /// Class HttpClientInfo + /// </summary> + public class HttpClientInfo + { + /// <summary> + /// Gets or sets the last timeout. + /// </summary> + /// <value>The last timeout.</value> + public DateTime LastTimeout { get; set; } + } +} diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs new file mode 100644 index 000000000..fe545ecff --- /dev/null +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -0,0 +1,956 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Emby.Server.Implementations.IO; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; + +namespace Emby.Server.Implementations.HttpClientManager +{ + /// <summary> + /// Class HttpClientManager + /// </summary> + public class HttpClientManager : IHttpClient + { + /// <summary> + /// When one request to a host times out, we'll ban all other requests for this period of time, to prevent scans from stalling + /// </summary> + private const int TimeoutSeconds = 30; + + /// <summary> + /// The _logger + /// </summary> + private readonly ILogger _logger; + + /// <summary> + /// The _app paths + /// </summary> + private readonly IApplicationPaths _appPaths; + + private readonly IFileSystem _fileSystem; + private readonly IMemoryStreamFactory _memoryStreamProvider; + private readonly Func<string> _defaultUserAgentFn; + + /// <summary> + /// Initializes a new instance of the <see cref="HttpClientManager" /> class. + /// </summary> + public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamFactory memoryStreamProvider, Func<string> defaultUserAgentFn) + { + if (appPaths == null) + { + throw new ArgumentNullException("appPaths"); + } + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + _logger = logger; + _fileSystem = fileSystem; + _memoryStreamProvider = memoryStreamProvider; + _appPaths = appPaths; + _defaultUserAgentFn = defaultUserAgentFn; + + // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c + ServicePointManager.Expect100Continue = false; + +#if NET46 +// Trakt requests sometimes fail without this + ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls; +#endif + } + + /// <summary> + /// 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. + /// </summary> + /// <value>The HTTP clients.</value> + private readonly ConcurrentDictionary<string, HttpClientInfo> _httpClients = new ConcurrentDictionary<string, HttpClientInfo>(); + + /// <summary> + /// Gets + /// </summary> + /// <param name="host">The host.</param> + /// <param name="enableHttpCompression">if set to <c>true</c> [enable HTTP compression].</param> + /// <returns>HttpClient.</returns> + /// <exception cref="System.ArgumentNullException">host</exception> + 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); + + if (options.EnableHttpCompression) + { + if (options.DecompressionMethod.HasValue) + { + httpWebRequest.AutomaticDecompression = options.DecompressionMethod.Value == CompressionMethod.Gzip + ? DecompressionMethods.GZip + : DecompressionMethods.Deflate; + } + else + { + httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate; + } + } + else + { + httpWebRequest.AutomaticDecompression = DecompressionMethods.None; + } + } + + + + request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.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]); + // TODO: .net core ?? + 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) + { + var hasUserAgent = false; + + 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)) + { + SetUserAgent(request, header.Value); + hasUserAgent = true; + } + else + { + request.Headers.Set(header.Key, header.Value); + } + } + + if (!hasUserAgent && options.EnableDefaultUserAgent) + { + SetUserAgent(request, _defaultUserAgentFn()); + } + } + + private void SetUserAgent(HttpWebRequest request, string userAgent) + { + request.UserAgent = userAgent; + } + + /// <summary> + /// Gets the response internal. + /// </summary> + /// <param name="options">The options.</param> + /// <returns>Task{HttpResponseInfo}.</returns> + public Task<HttpResponseInfo> GetResponse(HttpRequestOptions options) + { + return SendAsync(options, "GET"); + } + + /// <summary> + /// Performs a GET request and returns the resulting stream + /// </summary> + /// <param name="options">The options.</param> + /// <returns>Task{Stream}.</returns> + public async Task<Stream> Get(HttpRequestOptions options) + { + var response = await GetResponse(options).ConfigureAwait(false); + + return response.Content; + } + + /// <summary> + /// Performs a GET request and returns the resulting stream + /// </summary> + /// <param name="url">The URL.</param> + /// <param name="resourcePool">The resource pool.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{Stream}.</returns> + public Task<Stream> Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken) + { + return Get(new HttpRequestOptions + { + Url = url, + ResourcePool = resourcePool, + CancellationToken = cancellationToken, + BufferContent = resourcePool != null + }); + } + + /// <summary> + /// Gets the specified URL. + /// </summary> + /// <param name="url">The URL.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{Stream}.</returns> + public Task<Stream> Get(string url, CancellationToken cancellationToken) + { + return Get(url, null, cancellationToken); + } + + /// <summary> + /// send as an asynchronous operation. + /// </summary> + /// <param name="options">The options.</param> + /// <param name="httpMethod">The HTTP method.</param> + /// <returns>Task{HttpResponseInfo}.</returns> + /// <exception cref="HttpException"> + /// </exception> + public async Task<HttpResponseInfo> 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<HttpResponseInfo> 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(_fileSystem.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<HttpResponseInfo> 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)) + { + try + { + var bytes = options.RequestContentBytes ?? + Encoding.UTF8.GetBytes(options.RequestContent ?? string.Empty); + + httpWebRequest.ContentType = options.RequestContentType ?? "application/x-www-form-urlencoded"; + + httpWebRequest.ContentLength = bytes.Length; + (await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)).Write(bytes, 0, bytes.Length); + } + catch (Exception ex) + { + throw new HttpException(ex.Message) { IsTimedOut = true }; + } + } + + 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<HttpResponseInfo> Post(HttpRequestOptions options) + { + return SendAsync(options, "POST"); + } + + /// <summary> + /// Performs a POST request + /// </summary> + /// <param name="options">The options.</param> + /// <param name="postData">Params to add to the POST data.</param> + /// <returns>stream on success, null on failure</returns> + public async Task<Stream> Post(HttpRequestOptions options, Dictionary<string, string> postData) + { + options.SetPostData(postData); + + var response = await Post(options).ConfigureAwait(false); + + return response.Content; + } + + /// <summary> + /// Performs a POST request + /// </summary> + /// <param name="url">The URL.</param> + /// <param name="postData">Params to add to the POST data.</param> + /// <param name="resourcePool">The resource pool.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>stream on success, null on failure</returns> + public Task<Stream> Post(string url, Dictionary<string, string> postData, SemaphoreSlim resourcePool, CancellationToken cancellationToken) + { + return Post(new HttpRequestOptions + { + Url = url, + ResourcePool = resourcePool, + CancellationToken = cancellationToken, + BufferContent = resourcePool != null + + }, postData); + } + + /// <summary> + /// Downloads the contents of a given url into a temporary location + /// </summary> + /// <param name="options">The options.</param> + /// <returns>Task{System.String}.</returns> + public async Task<string> GetTempFile(HttpRequestOptions options) + { + var response = await GetTempFileResponse(options).ConfigureAwait(false); + + return response.TempFilePath; + } + + public async Task<HttpResponseInfo> 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 " + webException.Status + " getting response from " + options.Url, webException); + } + + var exception = new HttpException(webException.Message, webException); + + var response = webException.Response as HttpWebResponse; + if (response != null) + { + exception.StatusCode = response.StatusCode; + + if ((int)response.StatusCode == 429) + { + client.LastTimeout = DateTime.UtcNow; + } + } + + if (!exception.StatusCode.HasValue) + { + if (webException.Status == WebExceptionStatus.NameResolutionFailure || + webException.Status == WebExceptionStatus.ConnectFailure) + { + exception.IsTimedOut = true; + } + } + + 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"); + } + } + + /// <summary> + /// Gets the host from URL. + /// </summary> + /// <param name="url">The URL.</param> + /// <returns>System.String.</returns> + 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; + } + + /// <summary> + /// Throws the cancellation exception. + /// </summary> + /// <param name="options">The options.</param> + /// <param name="client">The client.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="exception">The exception.</param> + /// <returns>Exception.</returns> + 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 + }; + } + } + + /// <summary> + /// Posts the specified URL. + /// </summary> + /// <param name="url">The URL.</param> + /// <param name="postData">The post data.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{Stream}.</returns> + public Task<Stream> Post(string url, Dictionary<string, string> postData, CancellationToken cancellationToken) + { + return Post(url, postData, null, cancellationToken); + } + + private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout) + { + var taskCompletion = new TaskCompletionSource<WebResponse>(); + + Task<WebResponse> asyncTask = Task.Factory.FromAsync<WebResponse>(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<WebResponse> taskCompletion; + + public void OnSuccess(Task<WebResponse> task) + { + taskCompletion.TrySetResult(task.Result); + } + + public void OnError(Task<WebResponse> task) + { + if (task.Exception != null) + { + taskCompletion.TrySetException(task.Exception); + } + else + { + taskCompletion.TrySetException(new List<Exception>()); + } + } + } + } +} diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs index 8cb7b5dbf..aa679e1b9 100644 --- a/Emby.Server.Implementations/HttpServer/FileWriter.cs +++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs @@ -160,6 +160,9 @@ namespace Emby.Server.Implementations.HttpServer if (string.IsNullOrWhiteSpace(RangeHeader) || (RangeStart <= 0 && RangeEnd >= TotalContentLength - 1)) { Logger.Info("Transmit file {0}", Path); + + //var count = FileShare == FileShareMode.ReadWrite ? TotalContentLength : 0; + await response.TransmitFile(Path, 0, 0, FileShare, cancellationToken).ConfigureAwait(false); return; } diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 05f78eba9..86df798d0 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -7,10 +7,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using System.Threading.Tasks; -using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.HttpServer.SocketSharp; using Emby.Server.Implementations.Services; using MediaBrowser.Common.Net; @@ -24,8 +24,6 @@ using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; using MediaBrowser.Model.System; using MediaBrowser.Model.Text; -using SocketHttpListener.Net; -using SocketHttpListener.Primitives; namespace Emby.Server.Implementations.HttpServer { @@ -34,7 +32,7 @@ namespace Emby.Server.Implementations.HttpServer private string DefaultRedirectPath { get; set; } private readonly ILogger _logger; - public IEnumerable<string> UrlPrefixes { get; private set; } + public string[] UrlPrefixes { get; private set; } private readonly List<IService> _restServices = new List<IService>(); @@ -56,14 +54,13 @@ namespace Emby.Server.Implementations.HttpServer private readonly IFileSystem _fileSystem; private readonly IJsonSerializer _jsonSerializer; private readonly IXmlSerializer _xmlSerializer; - private readonly ICertificate _certificate; + private readonly X509Certificate _certificate; private readonly IEnvironmentInfo _environment; - private readonly IStreamFactory _streamFactory; private readonly Func<Type, Func<string, object>> _funcParseFn; private readonly bool _enableDualModeSockets; - public List<Action<IRequest, IResponse, object>> RequestFilters { get; set; } - public List<Action<IRequest, IResponse, object>> ResponseFilters { get; set; } + public Action<IRequest, IResponse, object>[] RequestFilters { get; set; } + public Action<IRequest, IResponse, object>[] ResponseFilters { get; set; } private readonly Dictionary<Type, Type> ServiceOperationsMap = new Dictionary<Type, Type>(); public static HttpListenerHost Instance { get; protected set; } @@ -72,7 +69,7 @@ namespace Emby.Server.Implementations.HttpServer ILogger logger, IServerConfigurationManager config, string serviceName, - string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, IEnvironmentInfo environment, ICertificate certificate, IStreamFactory streamFactory, Func<Type, Func<string, object>> funcParseFn, bool enableDualModeSockets, IFileSystem fileSystem) + string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, IEnvironmentInfo environment, X509Certificate certificate, Func<Type, Func<string, object>> funcParseFn, bool enableDualModeSockets, IFileSystem fileSystem) { Instance = this; @@ -87,7 +84,6 @@ namespace Emby.Server.Implementations.HttpServer _xmlSerializer = xmlSerializer; _environment = environment; _certificate = certificate; - _streamFactory = streamFactory; _funcParseFn = funcParseFn; _enableDualModeSockets = enableDualModeSockets; _fileSystem = fileSystem; @@ -95,8 +91,8 @@ namespace Emby.Server.Implementations.HttpServer _logger = logger; - RequestFilters = new List<Action<IRequest, IResponse, object>>(); - ResponseFilters = new List<Action<IRequest, IResponse, object>>(); + RequestFilters = new Action<IRequest, IResponse, object>[] { }; + ResponseFilters = new Action<IRequest, IResponse, object>[] { }; } public string GlobalResponse { get; set; } @@ -125,13 +121,6 @@ namespace Emby.Server.Implementations.HttpServer return _appHost.CreateInstance(type); } - private ServiceController CreateServiceController() - { - var types = _restServices.Select(r => r.GetType()).ToArray(); - - return new ServiceController(() => types); - } - /// <summary> /// Applies the request filters. Returns whether or not the request has been handled /// and no more processing should be done. @@ -142,7 +131,9 @@ namespace Emby.Server.Implementations.HttpServer //Exec all RequestFilter attributes with Priority < 0 var attributes = GetRequestFilterAttributes(requestDto.GetType()); var i = 0; - for (; i < attributes.Length && attributes[i].Priority < 0; i++) + var count = attributes.Count; + + for (; i < count && attributes[i].Priority < 0; i++) { var attribute = attributes[i]; attribute.RequestFilter(req, res, requestDto); @@ -155,7 +146,7 @@ namespace Emby.Server.Implementations.HttpServer } //Exec remaining RequestFilter attributes with Priority >= 0 - for (; i < attributes.Length && attributes[i].Priority >= 0; i++) + for (; i < count && attributes[i].Priority >= 0; i++) { var attribute = attributes[i]; attribute.RequestFilter(req, res, requestDto); @@ -169,12 +160,12 @@ namespace Emby.Server.Implementations.HttpServer return serviceType; } - public void AddServiceInfo(Type serviceType, Type requestType, Type responseType) + public void AddServiceInfo(Type serviceType, Type requestType) { ServiceOperationsMap[requestType] = serviceType; } - private IHasRequestFilter[] GetRequestFilterAttributes(Type requestDtoType) + private List<IHasRequestFilter> GetRequestFilterAttributes(Type requestDtoType) { var attributes = requestDtoType.GetTypeInfo().GetCustomAttributes(true).OfType<IHasRequestFilter>().ToList(); @@ -186,40 +177,13 @@ namespace Emby.Server.Implementations.HttpServer attributes.Sort((x, y) => x.Priority - y.Priority); - return attributes.ToArray(); - } - - /// <summary> - /// Starts the Web Service - /// </summary> - private void StartListener() - { - WebSocketSharpRequest.HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes.First()); - - _listener = GetListener(); - - _listener.WebSocketConnected = OnWebSocketConnected; - _listener.WebSocketConnecting = OnWebSocketConnecting; - _listener.ErrorHandler = ErrorHandler; - _listener.RequestHandler = RequestHandler; - - _listener.Start(UrlPrefixes); - } - - public static string GetHandlerPathIfAny(string listenerUrl) - { - if (listenerUrl == null) return null; - var pos = listenerUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase); - if (pos == -1) return null; - var startHostUrl = listenerUrl.Substring(pos + "://".Length); - var endPos = startHostUrl.IndexOf('/'); - if (endPos == -1) return null; - var endHostUrl = startHostUrl.Substring(endPos + 1); - return string.IsNullOrEmpty(endHostUrl) ? null : endHostUrl.TrimEnd('/'); + return attributes; } private IHttpListener GetListener() { + //return new KestrelHost.KestrelListener(_logger, _environment, _fileSystem); + return new WebSocketSharpListener(_logger, _certificate, _memoryStreamProvider, @@ -227,22 +191,11 @@ namespace Emby.Server.Implementations.HttpServer _networkManager, _socketFactory, _cryptoProvider, - _streamFactory, _enableDualModeSockets, - GetRequest, _fileSystem, _environment); } - private IHttpRequest GetRequest(HttpListenerContext httpContext) - { - var operationName = httpContext.Request.GetOperationName(); - - var req = new WebSocketSharpRequest(httpContext, operationName, _logger, _memoryStreamProvider); - - return req; - } - private void OnWebSocketConnecting(WebSocketConnectingEventArgs args) { if (_disposed) @@ -355,7 +308,8 @@ namespace Emby.Server.Implementations.HttpServer if (_listener != null) { _logger.Info("Stopping HttpListener..."); - _listener.Stop(); + var task = _listener.Stop(); + Task.WaitAll(task); _logger.Info("HttpListener stopped"); } } @@ -441,7 +395,7 @@ namespace Emby.Server.Implementations.HttpServer return address.Trim('/'); } - private bool ValidateHost(Uri url) + private bool ValidateHost(string host) { var hosts = _config .Configuration @@ -454,7 +408,7 @@ namespace Emby.Server.Implementations.HttpServer return true; } - var host = url.Host ?? string.Empty; + host = host ?? string.Empty; _logger.Debug("Validating host {0}", host); @@ -472,7 +426,7 @@ namespace Emby.Server.Implementations.HttpServer /// <summary> /// Overridable method that can be used to implement a custom hnandler /// </summary> - protected async Task RequestHandler(IHttpRequest httpReq, Uri url, CancellationToken cancellationToken) + protected async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken) { var date = DateTime.Now; var httpRes = httpReq.Response; @@ -491,7 +445,7 @@ namespace Emby.Server.Implementations.HttpServer return; } - if (!ValidateHost(url)) + if (!ValidateHost(host)) { httpRes.StatusCode = 400; httpRes.ContentType = "text/plain"; @@ -511,9 +465,7 @@ namespace Emby.Server.Implementations.HttpServer } var operationName = httpReq.OperationName; - var localPath = url.LocalPath; - var urlString = url.OriginalString; enableLog = EnableLogging(urlString, localPath); urlToLog = urlString; logHeaders = enableLog && urlToLog.IndexOf("/videos/", StringComparison.OrdinalIgnoreCase) != -1; @@ -697,19 +649,26 @@ namespace Emby.Server.Implementations.HttpServer { _restServices.AddRange(services); - ServiceController = CreateServiceController(); + ServiceController = new ServiceController(); _logger.Info("Calling ServiceStack AppHost.Init"); - ServiceController.Init(this); + var types = _restServices.Select(r => r.GetType()).ToArray(); + + ServiceController.Init(this, types); - var requestFilters = _appHost.GetExports<IRequestFilter>().ToList(); - foreach (var filter in requestFilters) + var list = new List<Action<IRequest, IResponse, object>>(); + foreach (var filter in _appHost.GetExports<IRequestFilter>()) { - RequestFilters.Add(filter.Filter); + list.Add(filter.Filter); } - ResponseFilters.Add(new ResponseFilter(_logger).FilterResponse); + RequestFilters = list.ToArray(); + + ResponseFilters = new Action<IRequest, IResponse, object>[] + { + new ResponseFilter(_logger).FilterResponse + }; } public RouteAttribute[] GetRouteAttributes(Type requestType) @@ -726,22 +685,22 @@ namespace Emby.Server.Implementations.HttpServer Summary = route.Summary }); - routes.Add(new RouteAttribute(NormalizeRoutePath(route.Path), route.Verbs) + routes.Add(new RouteAttribute(NormalizeMediaBrowserRoutePath(route.Path), route.Verbs) { Notes = route.Notes, Priority = route.Priority, Summary = route.Summary }); - routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs) - { - Notes = route.Notes, - Priority = route.Priority, - Summary = route.Summary - }); + //routes.Add(new RouteAttribute(DoubleNormalizeEmbyRoutePath(route.Path), route.Verbs) + //{ + // Notes = route.Notes, + // Priority = route.Priority, + // Summary = route.Summary + //}); } - return routes.ToArray(); + return routes.ToArray(routes.Count); } public Func<string, object> GetParseFn(Type propertyType) @@ -779,24 +738,24 @@ namespace Emby.Server.Implementations.HttpServer return "emby/" + path; } - private string DoubleNormalizeEmbyRoutePath(string path) + private string NormalizeMediaBrowserRoutePath(string path) { if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase)) { - return "/emby/emby" + path; + return "/mediabrowser" + path; } - return "emby/emby/" + path; + return "mediabrowser/" + path; } - private string NormalizeRoutePath(string path) + private string DoubleNormalizeEmbyRoutePath(string path) { if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase)) { - return "/mediabrowser" + path; + return "/emby/emby" + path; } - return "mediabrowser/" + path; + return "emby/emby/" + path; } private bool _disposed; @@ -824,10 +783,18 @@ namespace Emby.Server.Implementations.HttpServer GC.SuppressFinalize(this); } - public void StartServer(IEnumerable<string> urlPrefixes) + public void StartServer(string[] urlPrefixes) { - UrlPrefixes = urlPrefixes.ToList(); - StartListener(); + UrlPrefixes = urlPrefixes; + + _listener = GetListener(); + + _listener.WebSocketConnected = OnWebSocketConnected; + _listener.WebSocketConnecting = OnWebSocketConnecting; + _listener.ErrorHandler = ErrorHandler; + _listener.RequestHandler = RequestHandler; + + _listener.Start(UrlPrefixes); } } }
\ No newline at end of file diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index 396bd8e88..f5a1fe246 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -6,19 +6,16 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; -using System.IO.Compression; using System.Net; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml; -using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.Services; using MediaBrowser.Model.IO; using MediaBrowser.Model.Services; using IRequest = MediaBrowser.Model.Services.IRequest; using MimeTypes = MediaBrowser.Model.Net.MimeTypes; -using StreamWriter = Emby.Server.Implementations.HttpServer.StreamWriter; namespace Emby.Server.Implementations.HttpServer { @@ -193,50 +190,37 @@ namespace Emby.Server.Implementations.HttpServer /// <returns></returns> public object ToOptimizedResult<T>(IRequest request, T dto) { - var compressionType = GetCompressionType(request); - if (compressionType == null) - { - var contentType = request.ResponseContentType; + var contentType = request.ResponseContentType; - switch (GetRealContentType(contentType)) - { - case "application/xml": - case "text/xml": - case "text/xml; charset=utf-8": //"text/xml; charset=utf-8" also matches xml - return SerializeToXmlString(dto); - - case "application/json": - case "text/json": - return _jsonSerializer.SerializeToString(dto); - } - } - - // Do not use the memoryStreamFactory here, they don't place nice with compression - using (var ms = new MemoryStream()) + switch (GetRealContentType(contentType)) { - var contentType = request.ResponseContentType; - var writerFn = RequestHelper.GetResponseWriter(HttpListenerHost.Instance, contentType); + case "application/xml": + case "text/xml": + case "text/xml; charset=utf-8": //"text/xml; charset=utf-8" also matches xml + return SerializeToXmlString(dto); - writerFn(dto, ms); + case "application/json": + case "text/json": + return _jsonSerializer.SerializeToString(dto); + default: + { + var ms = new MemoryStream(); + var writerFn = RequestHelper.GetResponseWriter(HttpListenerHost.Instance, contentType); - ms.Position = 0; + writerFn(dto, ms); + + ms.Position = 0; - var responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + if (string.Equals(request.Verb, "head", StringComparison.OrdinalIgnoreCase)) + { + return GetHttpResult(new byte[] { }, contentType, true); + } - return GetCompressedResult(ms, compressionType, responseHeaders, false, request.ResponseContentType).Result; + return GetHttpResult(ms, contentType, true); + } } } - private static Stream GetCompressionStream(Stream outputStream, string compressionType) - { - if (compressionType == "deflate") - return new DeflateStream(outputStream, CompressionMode.Compress, true); - if (compressionType == "gzip") - return new GZipStream(outputStream, CompressionMode.Compress, true); - - throw new NotSupportedException(compressionType); - } - public static string GetRealContentType(string contentType) { return contentType == null @@ -440,11 +424,14 @@ namespace Emby.Server.Implementations.HttpServer options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - // Quotes are valid in linux. They'll possibly cause issues here - var filename = (Path.GetFileName(path) ?? string.Empty).Replace("\"", string.Empty); - if (!string.IsNullOrWhiteSpace(filename)) + if (!options.ResponseHeaders.ContainsKey("Content-Disposition")) { - options.ResponseHeaders["Content-Disposition"] = "inline; filename=\"" + filename + "\""; + // Quotes are valid in linux. They'll possibly cause issues here + var filename = (Path.GetFileName(path) ?? string.Empty).Replace("\"", string.Empty); + if (!string.IsNullOrWhiteSpace(filename)) + { + options.ResponseHeaders["Content-Disposition"] = "inline; filename=\"" + filename + "\""; + } } return GetStaticResult(requestContext, options); @@ -503,190 +490,67 @@ namespace Emby.Server.Implementations.HttpServer return result; } - var compress = ShouldCompressResponse(requestContext, contentType); - var hasHeaders = await GetStaticResult(requestContext, options, compress).ConfigureAwait(false); - AddResponseHeaders(hasHeaders, options.ResponseHeaders); - - return hasHeaders; - } - - /// <summary> - /// Shoulds the compress response. - /// </summary> - /// <param name="requestContext">The request context.</param> - /// <param name="contentType">Type of the content.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private bool ShouldCompressResponse(IRequest requestContext, string contentType) - { - // It will take some work to support compression with byte range requests - if (!string.IsNullOrWhiteSpace(requestContext.Headers.Get("Range"))) - { - return false; - } - - // Don't compress media - if (contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - // Don't compress images - if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - if (contentType.StartsWith("application/", StringComparison.OrdinalIgnoreCase)) - { - if (string.Equals(contentType, "application/x-javascript", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - if (string.Equals(contentType, "application/xml", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - return false; - } - - return true; - } - - /// <summary> - /// The us culture - /// </summary> - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - private async Task<IHasHeaders> GetStaticResult(IRequest requestContext, StaticResultOptions options, bool compress) - { var isHeadRequest = options.IsHeadRequest; var factoryFn = options.ContentFactory; - var contentType = options.ContentType; var responseHeaders = options.ResponseHeaders; - var requestedCompressionType = GetCompressionType(requestContext); - - if (!compress || string.IsNullOrEmpty(requestedCompressionType)) - { - var rangeHeader = requestContext.Headers.Get("Range"); - - if (!isHeadRequest && !string.IsNullOrWhiteSpace(options.Path)) - { - return new FileWriter(options.Path, contentType, rangeHeader, _logger, _fileSystem) - { - OnComplete = options.OnComplete, - OnError = options.OnError, - FileShare = options.FileShare - }; - } + //var requestedCompressionType = GetCompressionType(requestContext); - if (!string.IsNullOrWhiteSpace(rangeHeader)) - { - var stream = await factoryFn().ConfigureAwait(false); + var rangeHeader = requestContext.Headers.Get("Range"); - return new RangeRequestWriter(rangeHeader, stream, contentType, isHeadRequest, _logger) - { - OnComplete = options.OnComplete - }; - } - else + if (!isHeadRequest && !string.IsNullOrWhiteSpace(options.Path)) + { + var hasHeaders = new FileWriter(options.Path, contentType, rangeHeader, _logger, _fileSystem) { - var stream = await factoryFn().ConfigureAwait(false); - - responseHeaders["Content-Length"] = stream.Length.ToString(UsCulture); - - if (isHeadRequest) - { - stream.Dispose(); - - return GetHttpResult(new byte[] { }, contentType, true); - } + OnComplete = options.OnComplete, + OnError = options.OnError, + FileShare = options.FileShare + }; - return new StreamWriter(stream, contentType, _logger) - { - OnComplete = options.OnComplete, - OnError = options.OnError - }; - } + AddResponseHeaders(hasHeaders, options.ResponseHeaders); + return hasHeaders; } - using (var stream = await factoryFn().ConfigureAwait(false)) + if (!string.IsNullOrWhiteSpace(rangeHeader)) { - return await GetCompressedResult(stream, requestedCompressionType, responseHeaders, isHeadRequest, contentType).ConfigureAwait(false); - } - } + var stream = await factoryFn().ConfigureAwait(false); - private async Task<IHasHeaders> GetCompressedResult(Stream stream, - string requestedCompressionType, - IDictionary<string, string> responseHeaders, - bool isHeadRequest, - string contentType) - { - using (var reader = new MemoryStream()) - { - await stream.CopyToAsync(reader).ConfigureAwait(false); - - reader.Position = 0; - var content = reader.ToArray(); - - if (content.Length >= 1024) + var hasHeaders = new RangeRequestWriter(rangeHeader, stream, contentType, isHeadRequest, _logger) { - content = Compress(content, requestedCompressionType); - responseHeaders["Content-Encoding"] = requestedCompressionType; - } + OnComplete = options.OnComplete + }; - responseHeaders["Vary"] = "Accept-Encoding"; - responseHeaders["Content-Length"] = content.Length.ToString(UsCulture); + AddResponseHeaders(hasHeaders, options.ResponseHeaders); + return hasHeaders; + } + else + { + var stream = await factoryFn().ConfigureAwait(false); + + responseHeaders["Content-Length"] = stream.Length.ToString(UsCulture); if (isHeadRequest) { + stream.Dispose(); + return GetHttpResult(new byte[] { }, contentType, true); } - return GetHttpResult(content, contentType, true, responseHeaders); - } - } - - private byte[] Compress(byte[] bytes, string compressionType) - { - if (compressionType == "deflate") - return Deflate(bytes); - - if (compressionType == "gzip") - return GZip(bytes); - - throw new NotSupportedException(compressionType); - } - - private byte[] Deflate(byte[] bytes) - { - // In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream - // Which means we must use MemoryStream since you have to use ToArray() on a closed Stream - using (var ms = new MemoryStream()) - using (var zipStream = new DeflateStream(ms, CompressionMode.Compress)) - { - zipStream.Write(bytes, 0, bytes.Length); - zipStream.Dispose(); + var hasHeaders = new StreamWriter(stream, contentType, _logger) + { + OnComplete = options.OnComplete, + OnError = options.OnError + }; - return ms.ToArray(); + AddResponseHeaders(hasHeaders, options.ResponseHeaders); + return hasHeaders; } } - private byte[] GZip(byte[] buffer) - { - using (var ms = new MemoryStream()) - using (var zipStream = new GZipStream(ms, CompressionMode.Compress)) - { - zipStream.Write(buffer, 0, buffer.Length); - zipStream.Dispose(); - - return ms.ToArray(); - } - } + /// <summary> + /// The us culture + /// </summary> + private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); /// <summary> /// Adds the caching responseHeaders. diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs index 82175dbed..9feb2311d 100644 --- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs +++ b/Emby.Server.Implementations/HttpServer/IHttpListener.cs @@ -19,7 +19,7 @@ namespace Emby.Server.Implementations.HttpServer /// Gets or sets the request handler. /// </summary> /// <value>The request handler.</value> - Func<IHttpRequest, Uri, CancellationToken, Task> RequestHandler { get; set; } + Func<IHttpRequest, string, string, string, CancellationToken, Task> RequestHandler { get; set; } /// <summary> /// Gets or sets the web socket handler. @@ -42,6 +42,6 @@ namespace Emby.Server.Implementations.HttpServer /// <summary> /// Stops this instance. /// </summary> - void Stop(); + Task Stop(); } } diff --git a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs index f0e75eea4..46bb4c7f9 100644 --- a/Emby.Server.Implementations/HttpServer/LoggerUtils.cs +++ b/Emby.Server.Implementations/HttpServer/LoggerUtils.cs @@ -1,7 +1,6 @@ using MediaBrowser.Model.Logging; using System; using System.Globalization; -using System.Linq; using MediaBrowser.Model.Services; using SocketHttpListener.Net; @@ -29,7 +28,20 @@ namespace Emby.Server.Implementations.HttpServer } else { - var headerText = string.Join(", ", headers.Select(i => i.Name + "=" + i.Value).ToArray()); + var headerText = string.Empty; + var index = 0; + + foreach (var i in headers) + { + if (index > 0) + { + headerText += ", "; + } + + headerText += i.Name + "=" + i.Value; + + index++; + } logger.Info("HTTP {0} {1}. {2}", method, url, headerText); } @@ -48,7 +60,8 @@ namespace Emby.Server.Implementations.HttpServer var durationMs = duration.TotalMilliseconds; var logSuffix = durationMs >= 1000 && durationMs < 60000 ? "ms (slow)" : "ms"; - var headerText = headers == null ? string.Empty : "Headers: " + string.Join(", ", headers.Where(i => i.Name.IndexOf("Access-", StringComparison.OrdinalIgnoreCase) == -1).Select(i => i.Name + "=" + i.Value).ToArray()); + //var headerText = headers == null ? string.Empty : "Headers: " + string.Join(", ", headers.Where(i => i.Name.IndexOf("Access-", StringComparison.OrdinalIgnoreCase) == -1).Select(i => i.Name + "=" + i.Value).ToArray()); + var headerText = string.Empty; logger.Info("HTTP Response {0} to {1}. Time: {2}{3}. {4} {5}", statusCode, endPoint, Convert.ToInt32(durationMs).ToString(CultureInfo.InvariantCulture), logSuffix, url, headerText); } } diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 4d00c9b19..fadab4482 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -7,8 +7,8 @@ using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using System; -using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Services; namespace Emby.Server.Implementations.HttpServer.Security { @@ -38,19 +38,19 @@ namespace Emby.Server.Implementations.HttpServer.Security /// </summary> public string HtmlRedirect { get; set; } - public void Authenticate(IServiceRequest request, + public void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues) { ValidateUser(request, authAttribtues); } - private void ValidateUser(IServiceRequest request, + private void ValidateUser(IRequest request, IAuthenticationAttributes authAttribtues) { // This code is executed before the service var auth = AuthorizationContext.GetAuthorizationInfo(request); - if (!IsExemptFromAuthenticationToken(auth, authAttribtues)) + if (!IsExemptFromAuthenticationToken(auth, authAttribtues, request)) { var valid = IsValidConnectKey(auth.Token); @@ -76,9 +76,9 @@ namespace Emby.Server.Implementations.HttpServer.Security var info = GetTokenInfo(request); - if (!IsExemptFromRoles(auth, authAttribtues, info)) + if (!IsExemptFromRoles(auth, authAttribtues, request, info)) { - var roles = authAttribtues.GetRoles().ToList(); + var roles = authAttribtues.GetRoles(); ValidateRoles(roles, user); } @@ -96,7 +96,7 @@ namespace Emby.Server.Implementations.HttpServer.Security } } - private void ValidateUserAccess(User user, IServiceRequest request, + private void ValidateUserAccess(User user, IRequest request, IAuthenticationAttributes authAttribtues, AuthorizationInfo auth) { @@ -112,7 +112,7 @@ namespace Emby.Server.Implementations.HttpServer.Security !authAttribtues.EscapeParentalControl && !user.IsParentalScheduleAllowed()) { - request.AddResponseHeader("X-Application-Error-Code", "ParentalControl"); + request.Response.AddHeader("X-Application-Error-Code", "ParentalControl"); throw new SecurityException("This user account is not allowed access at this time.") { @@ -132,23 +132,33 @@ namespace Emby.Server.Implementations.HttpServer.Security } } - private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues) + private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, IRequest request) { if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) { return true; } + if (authAttribtues.AllowLocal && request.IsLocal) + { + return true; + } + return false; } - private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo) + private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, IRequest request, AuthenticationInfo tokenInfo) { if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) { return true; } + if (authAttribtues.AllowLocal && request.IsLocal) + { + return true; + } + if (string.IsNullOrWhiteSpace(auth.Token)) { return true; @@ -162,7 +172,7 @@ namespace Emby.Server.Implementations.HttpServer.Security return false; } - private void ValidateRoles(List<string> roles, User user) + private void ValidateRoles(string[] roles, User user) { if (roles.Contains("admin", StringComparer.OrdinalIgnoreCase)) { @@ -196,7 +206,7 @@ namespace Emby.Server.Implementations.HttpServer.Security } } - private AuthenticationInfo GetTokenInfo(IServiceRequest request) + private AuthenticationInfo GetTokenInfo(IRequest request) { object info; request.Items.TryGetValue("OriginalAuthenticationInfo", out info); @@ -213,7 +223,7 @@ namespace Emby.Server.Implementations.HttpServer.Security return ConnectManager.IsAuthorizationTokenValid(token); } - private void ValidateSecurityToken(IServiceRequest request, string token) + private void ValidateSecurityToken(IRequest request, string token) { if (string.IsNullOrWhiteSpace(token)) { diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index ede85fb67..c9d5ed007 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -3,8 +3,8 @@ using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Security; using System; using System.Collections.Generic; -using System.Linq; using MediaBrowser.Model.Services; +using System.Linq; namespace Emby.Server.Implementations.HttpServer.Security { @@ -21,11 +21,10 @@ namespace Emby.Server.Implementations.HttpServer.Security public AuthorizationInfo GetAuthorizationInfo(object requestContext) { - var req = new ServiceRequest((IRequest)requestContext); - return GetAuthorizationInfo(req); + return GetAuthorizationInfo((IRequest)requestContext); } - public AuthorizationInfo GetAuthorizationInfo(IServiceRequest requestContext) + public AuthorizationInfo GetAuthorizationInfo(IRequest requestContext) { object cached; if (requestContext.Items.TryGetValue("AuthorizationInfo", out cached)) @@ -41,7 +40,7 @@ namespace Emby.Server.Implementations.HttpServer.Security /// </summary> /// <param name="httpReq">The HTTP req.</param> /// <returns>Dictionary{System.StringSystem.String}.</returns> - private AuthorizationInfo GetAuthorization(IServiceRequest httpReq) + private AuthorizationInfo GetAuthorization(IRequest httpReq) { var auth = GetAuthorizationDictionary(httpReq); @@ -90,7 +89,7 @@ namespace Emby.Server.Implementations.HttpServer.Security AccessToken = token }); - var tokenInfo = result.Items.FirstOrDefault(); + var tokenInfo = result.Items.Length > 0 ? result.Items[0] : null; if (tokenInfo != null) { @@ -135,7 +134,7 @@ namespace Emby.Server.Implementations.HttpServer.Security /// </summary> /// <param name="httpReq">The HTTP req.</param> /// <returns>Dictionary{System.StringSystem.String}.</returns> - private Dictionary<string, string> GetAuthorizationDictionary(IServiceRequest httpReq) + private Dictionary<string, string> GetAuthorizationDictionary(IRequest httpReq) { var auth = httpReq.Headers["X-Emby-Authorization"]; @@ -161,7 +160,7 @@ namespace Emby.Server.Implementations.HttpServer.Security // There should be at least to parts if (parts.Length != 2) return null; - var acceptedNames = new[] { "MediaBrowser", "Emby"}; + var acceptedNames = new[] { "MediaBrowser", "Emby" }; // It has to be a digest request if (!acceptedNames.Contains(parts[0] ?? string.Empty, StringComparer.OrdinalIgnoreCase)) diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs index 33dd4e2d7..dd5d64bf6 100644 --- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs @@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.HttpServer.Security _sessionManager = sessionManager; } - public Task<SessionInfo> GetSession(IServiceRequest requestContext) + public Task<SessionInfo> GetSession(IRequest requestContext) { var authorization = _authContext.GetAuthorizationInfo(requestContext); @@ -38,7 +38,7 @@ namespace Emby.Server.Implementations.HttpServer.Security return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.RemoteIp, user); } - private AuthenticationInfo GetTokenInfo(IServiceRequest request) + private AuthenticationInfo GetTokenInfo(IRequest request) { object info; request.Items.TryGetValue("OriginalAuthenticationInfo", out info); @@ -47,11 +47,10 @@ namespace Emby.Server.Implementations.HttpServer.Security public Task<SessionInfo> GetSession(object requestContext) { - var req = new ServiceRequest((IRequest)requestContext); - return GetSession(req); + return GetSession((IRequest)requestContext); } - public async Task<User> GetUser(IServiceRequest requestContext) + public async Task<User> GetUser(IRequest requestContext) { var session = await GetSession(requestContext).ConfigureAwait(false); @@ -60,8 +59,7 @@ namespace Emby.Server.Implementations.HttpServer.Security public Task<User> GetUser(object requestContext) { - var req = new ServiceRequest((IRequest)requestContext); - return GetUser(req); + return GetUser((IRequest)requestContext); } } } diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs index 4fbe0ed94..4e8dd7362 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/HttpUtility.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Text; using MediaBrowser.Model.Services; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.HttpServer.SocketSharp { @@ -585,7 +586,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp WriteCharBytes(bytes, ch, e); } - byte[] buf = bytes.ToArray(); + byte[] buf = bytes.ToArray(bytes.Count); bytes = null; return e.GetString(buf, 0, buf.Length); diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs index 9823a2ff5..cc7a4557e 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs @@ -123,6 +123,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } /// <summary> diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index e648838b2..10aaa4032 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -4,6 +4,7 @@ using SocketHttpListener.Net; using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Net; @@ -22,22 +23,20 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp private HttpListener _listener; private readonly ILogger _logger; - private readonly ICertificate _certificate; + private readonly X509Certificate _certificate; private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly ITextEncoding _textEncoding; private readonly INetworkManager _networkManager; private readonly ISocketFactory _socketFactory; private readonly ICryptoProvider _cryptoProvider; - private readonly IStreamFactory _streamFactory; private readonly IFileSystem _fileSystem; - private readonly Func<HttpListenerContext, IHttpRequest> _httpRequestFactory; private readonly bool _enableDualMode; private readonly IEnvironmentInfo _environment; private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); private CancellationToken _disposeCancellationToken; - public WebSocketSharpListener(ILogger logger, ICertificate certificate, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, bool enableDualMode, Func<HttpListenerContext, IHttpRequest> httpRequestFactory, IFileSystem fileSystem, IEnvironmentInfo environment) + public WebSocketSharpListener(ILogger logger, X509Certificate certificate, IMemoryStreamFactory memoryStreamProvider, ITextEncoding textEncoding, INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, bool enableDualMode, IFileSystem fileSystem, IEnvironmentInfo environment) { _logger = logger; _certificate = certificate; @@ -46,9 +45,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp _networkManager = networkManager; _socketFactory = socketFactory; _cryptoProvider = cryptoProvider; - _streamFactory = streamFactory; _enableDualMode = enableDualMode; - _httpRequestFactory = httpRequestFactory; _fileSystem = fileSystem; _environment = environment; @@ -56,7 +53,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp } public Action<Exception, IRequest, bool> ErrorHandler { get; set; } - public Func<IHttpRequest, Uri, CancellationToken, Task> RequestHandler { get; set; } + public Func<IHttpRequest, string, string, string, CancellationToken, Task> RequestHandler { get; set; } public Action<WebSocketConnectingEventArgs> WebSocketConnecting { get; set; } @@ -65,7 +62,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp public void Start(IEnumerable<string> urlPrefixes) { if (_listener == null) - _listener = new HttpListener(_logger, _cryptoProvider, _streamFactory, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider, _fileSystem, _environment); + _listener = new HttpListener(_logger, _cryptoProvider, _socketFactory, _networkManager, _textEncoding, _memoryStreamProvider, _fileSystem, _environment); _listener.EnableDualMode = _enableDualMode; @@ -117,7 +114,9 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp return Task.FromResult(true); } - return RequestHandler(httpReq, request.Url, cancellationToken); + var uri = request.Url; + + return RequestHandler(httpReq, uri.OriginalString, uri.Host, uri.LocalPath, cancellationToken); } private void ProcessWebSocketRequest(HttpListenerContext ctx) @@ -173,10 +172,14 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp private IHttpRequest GetRequest(HttpListenerContext httpContext) { - return _httpRequestFactory(httpContext); + var operationName = httpContext.Request.GetOperationName(); + + var req = new WebSocketSharpRequest(httpContext, operationName, _logger, _memoryStreamProvider); + + return req; } - public void Stop() + public Task Stop() { _disposeCancellationTokenSource.Cancel(); @@ -189,6 +192,8 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp _listener.Close(); } + + return Task.FromResult(true); } public void Dispose() diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 2dfe6a9e3..522377f0c 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -27,6 +27,20 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp _memoryStreamProvider = memoryStreamProvider; this.request = httpContext.Request; this.response = new WebSocketSharpResponse(logger, httpContext.Response, this); + + //HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes[0]); + } + + private static string GetHandlerPathIfAny(string listenerUrl) + { + if (listenerUrl == null) return null; + var pos = listenerUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase); + if (pos == -1) return null; + var startHostUrl = listenerUrl.Substring(pos + "://".Length); + var endPos = startHostUrl.IndexOf('/'); + if (endPos == -1) return null; + var endHostUrl = startHostUrl.Substring(endPos + 1); + return string.IsNullOrEmpty(endHostUrl) ? null : endHostUrl.TrimEnd('/'); } public HttpListenerRequest HttpRequest @@ -108,7 +122,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp return remoteIp ?? (remoteIp = (CheckBadChars(XForwardedFor)) ?? (NormalizeIp(CheckBadChars(XRealIp)) ?? - (request.RemoteEndPoint != null ? NormalizeIp(request.RemoteEndPoint.IpAddress.ToString()) : null))); + (request.RemoteEndPoint != null ? NormalizeIp(request.RemoteEndPoint.Address.ToString()) : null))); } } @@ -232,13 +246,12 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp set { this.responseContentType = value; - HasExplicitResponseContentType = true; } } public const string FormUrlEncoded = "application/x-www-form-urlencoded"; public const string MultiPartFormData = "multipart/form-data"; - private static string GetResponseContentType(IRequest httpReq) + public static string GetResponseContentType(IRequest httpReq) { var specifiedContentType = GetQueryStringContentType(httpReq); if (!string.IsNullOrEmpty(specifiedContentType)) return specifiedContentType; @@ -346,8 +359,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp : strVal.Substring(0, pos); } - public bool HasExplicitResponseContentType { get; private set; } - public static string HandlerFactoryPath; private string pathInfo; @@ -490,13 +501,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp get { return HttpMethod; } } - public string Param(string name) - { - return Headers[name] - ?? QueryString[name] - ?? FormData[name]; - } - public string ContentType { get { return request.ContentType; } @@ -584,18 +588,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp return stream; } - public static string GetHandlerPathIfAny(string listenerUrl) - { - if (listenerUrl == null) return null; - var pos = listenerUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase); - if (pos == -1) return null; - var startHostUrl = listenerUrl.Substring(pos + "://".Length); - var endPos = startHostUrl.IndexOf('/'); - if (endPos == -1) return null; - var endHostUrl = startHostUrl.Substring(endPos + 1); - return String.IsNullOrEmpty(endHostUrl) ? null : endHostUrl.TrimEnd('/'); - } - public static string NormalizePathInfo(string pathInfo, string handlerPath) { if (handlerPath != null && pathInfo.TrimStart('/').StartsWith( diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs index d6762d94b..5b51c0cf1 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs @@ -29,7 +29,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp } public IRequest Request { get; private set; } - public bool UseBufferedStream { get; set; } public Dictionary<string, object> Items { get; private set; } public object OriginalResponse { diff --git a/Emby.Server.Implementations/HttpServerFactory.cs b/Emby.Server.Implementations/HttpServerFactory.cs new file mode 100644 index 000000000..717c50e7b --- /dev/null +++ b/Emby.Server.Implementations/HttpServerFactory.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; +using Emby.Server.Implementations.HttpServer; +using Emby.Server.Implementations.Net; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Net; +using MediaBrowser.Model.Cryptography; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.System; +using MediaBrowser.Model.Text; +using ServiceStack.Text.Jsv; +using SocketHttpListener.Primitives; + +namespace Emby.Server.Implementations +{ + /// <summary> + /// Class ServerFactory + /// </summary> + public static class HttpServerFactory + { + /// <summary> + /// Creates the server. + /// </summary> + /// <returns>IHttpServer.</returns> + public static IHttpServer CreateServer(IServerApplicationHost applicationHost, + ILogManager logManager, + IServerConfigurationManager config, + INetworkManager networkmanager, + IMemoryStreamFactory streamProvider, + string serverName, + string defaultRedirectpath, + ITextEncoding textEncoding, + ISocketFactory socketFactory, + ICryptoProvider cryptoProvider, + IJsonSerializer json, + IXmlSerializer xml, + IEnvironmentInfo environment, + X509Certificate certificate, + IFileSystem fileSystem, + bool enableDualModeSockets) + { + var logger = logManager.GetLogger("HttpServer"); + + return new HttpListenerHost(applicationHost, + logger, + config, + serverName, + defaultRedirectpath, + networkmanager, + streamProvider, + textEncoding, + socketFactory, + cryptoProvider, + json, + xml, + environment, + certificate, + GetParseFn, + enableDualModeSockets, + fileSystem); + } + + private static Func<string, object> GetParseFn(Type propertyType) + { + return s => JsvReader.GetParseFn(propertyType)(s); + } + } +} diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs index d4914e734..20de8a518 100644 --- a/Emby.Server.Implementations/IO/FileRefresher.cs +++ b/Emby.Server.Implementations/IO/FileRefresher.cs @@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.IO RestartTimer(); } - private async void OnTimerCallback(object state) + private void OnTimerCallback(object state) { List<string> paths; @@ -130,14 +130,6 @@ namespace Emby.Server.Implementations.IO paths = _affectedPaths.ToList(); } - // Extend the timer as long as any of the paths are still being written to. - if (paths.Any(IsFileLocked)) - { - Logger.Info("Timer extended."); - RestartTimer(); - return; - } - Logger.Debug("Timer stopped."); DisposeTimer(); @@ -145,7 +137,7 @@ namespace Emby.Server.Implementations.IO try { - await ProcessPathChanges(paths.ToList()).ConfigureAwait(false); + ProcessPathChanges(paths.ToList()); } catch (Exception ex) { @@ -153,7 +145,7 @@ namespace Emby.Server.Implementations.IO } } - private async Task ProcessPathChanges(List<string> paths) + private void ProcessPathChanges(List<string> paths) { var itemsToRefresh = paths .Distinct(StringComparer.OrdinalIgnoreCase) @@ -229,90 +221,6 @@ namespace Emby.Server.Implementations.IO return item; } - private bool IsFileLocked(string path) - { - if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) - { - // Causing lockups on linux - return false; - } - - // Only try to open video files - if (!_libraryManager.IsVideoFile(path)) - { - return false; - } - - try - { - var data = _fileSystem.GetFileSystemInfo(path); - - if (!data.Exists - || data.IsDirectory - - // Opening a writable stream will fail with readonly files - || data.IsReadOnly) - { - return false; - } - } - catch (IOException) - { - return false; - } - catch (Exception ex) - { - Logger.ErrorException("Error getting file system info for: {0}", ex, path); - return false; - } - - // In order to determine if the file is being written to, we have to request write access - // But if the server only has readonly access, this is going to cause this entire algorithm to fail - // So we'll take a best guess about our access level - //var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta - // ? FileAccessMode.ReadWrite - // : FileAccessMode.Read; - - var requestedFileAccess = FileAccessMode.Read; - try - { - using (_fileSystem.GetFileStream(path, FileOpenMode.Open, requestedFileAccess, FileShareMode.ReadWrite)) - { - //file is not locked - return false; - } - } - catch (DirectoryNotFoundException) - { - // File may have been deleted - return false; - } - catch (FileNotFoundException) - { - // File may have been deleted - return false; - } - catch (UnauthorizedAccessException) - { - Logger.Debug("No write permission for: {0}.", path); - return false; - } - catch (IOException) - { - //the file is unavailable because it is: - //still being written to - //or being processed by another thread - //or does not exist (has already been processed) - Logger.Debug("{0} is locked.", path); - return true; - } - catch (Exception ex) - { - Logger.ErrorException("Error determining if file is locked: {0}", ex, path); - return false; - } - } - private void DisposeTimer() { lock (_timerLock) @@ -330,6 +238,7 @@ namespace Emby.Server.Implementations.IO { _disposed = true; DisposeTimer(); + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/IO/IsoManager.cs b/Emby.Server.Implementations/IO/IsoManager.cs new file mode 100644 index 000000000..dc0b9e122 --- /dev/null +++ b/Emby.Server.Implementations/IO/IsoManager.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.IO; + +namespace Emby.Server.Implementations.IO +{ + /// <summary> + /// Class IsoManager + /// </summary> + public class IsoManager : IIsoManager + { + /// <summary> + /// The _mounters + /// </summary> + private readonly List<IIsoMounter> _mounters = new List<IIsoMounter>(); + + /// <summary> + /// Mounts the specified iso path. + /// </summary> + /// <param name="isoPath">The iso path.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>IsoMount.</returns> + /// <exception cref="System.ArgumentNullException">isoPath</exception> + /// <exception cref="System.ArgumentException"></exception> + public Task<IIsoMount> 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); + } + + /// <summary> + /// Determines whether this instance can mount the specified path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if this instance can mount the specified path; otherwise, <c>false</c>.</returns> + public bool CanMount(string path) + { + return _mounters.Any(i => i.CanMount(path)); + } + + /// <summary> + /// Adds the parts. + /// </summary> + /// <param name="mounters">The mounters.</param> + public void AddParts(IEnumerable<IIsoMounter> mounters) + { + _mounters.AddRange(mounters); + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + foreach (var mounter in _mounters) + { + mounter.Dispose(); + } + GC.SuppressFinalize(this); + } + } +} diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs new file mode 100644 index 000000000..56b10a7e6 --- /dev/null +++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs @@ -0,0 +1,655 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.System; +using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.IO +{ + public class LibraryMonitor : ILibraryMonitor + { + /// <summary> + /// The file system watchers + /// </summary> + private readonly ConcurrentDictionary<string, FileSystemWatcher> _fileSystemWatchers = new ConcurrentDictionary<string, FileSystemWatcher>(StringComparer.OrdinalIgnoreCase); + /// <summary> + /// The affected paths + /// </summary> + private readonly List<FileRefresher> _activeRefreshers = new List<FileRefresher>(); + + /// <summary> + /// A dynamic list of paths that should be ignored. Added to during our own file sytem modifications. + /// </summary> + private readonly ConcurrentDictionary<string, string> _tempIgnoredPaths = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase); + + /// <summary> + /// Any file name ending in any of these will be ignored by the watchers + /// </summary> + private readonly string[] _alwaysIgnoreFiles = new string[] + { + "small.jpg", + "albumart.jpg", + + // WMC temp recording directories that will constantly be written to + "TempRec", + "TempSBE" + }; + + private readonly string[] _alwaysIgnoreSubstrings = new string[] + { + // Synology + "eaDir", + "#recycle", + ".wd_tv", + ".actors" + }; + + private readonly string[] _alwaysIgnoreExtensions = new string[] + { + // thumbs.db + ".db", + + // bts sync files + ".bts", + ".sync" + }; + + /// <summary> + /// Add the path to our temporary ignore list. Use when writing to a path within our listening scope. + /// </summary> + /// <param name="path">The path.</param> + private void TemporarilyIgnore(string path) + { + _tempIgnoredPaths[path] = path; + } + + public void ReportFileSystemChangeBeginning(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + TemporarilyIgnore(path); + } + + public bool IsPathLocked(string path) + { + // This method is not used by the core but it used by auto-organize + + var lockedPaths = _tempIgnoredPaths.Keys.ToList(); + return lockedPaths.Any(i => _fileSystem.AreEqual(i, path) || _fileSystem.ContainsSubPath(i, path)); + } + + public async void ReportFileSystemChangeComplete(string path, bool refreshPath) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + // This is an arbitraty amount of time, but delay it because file system writes often trigger events long after the file was actually written to. + // Seeing long delays in some situations, especially over the network, sometimes up to 45 seconds + // But if we make this delay too high, we risk missing legitimate changes, such as user adding a new file, or hand-editing metadata + await Task.Delay(45000).ConfigureAwait(false); + + string val; + _tempIgnoredPaths.TryRemove(path, out val); + + if (refreshPath) + { + try + { + ReportFileSystemChanged(path); + } + catch (Exception ex) + { + Logger.ErrorException("Error in ReportFileSystemChanged for {0}", ex, path); + } + } + } + + /// <summary> + /// Gets or sets the logger. + /// </summary> + /// <value>The logger.</value> + private ILogger Logger { get; set; } + + /// <summary> + /// Gets or sets the task manager. + /// </summary> + /// <value>The task manager.</value> + private ITaskManager TaskManager { get; set; } + + private ILibraryManager LibraryManager { get; set; } + private IServerConfigurationManager ConfigurationManager { get; set; } + + private readonly IFileSystem _fileSystem; + private readonly ITimerFactory _timerFactory; + private readonly IEnvironmentInfo _environmentInfo; + + /// <summary> + /// Initializes a new instance of the <see cref="LibraryMonitor" /> class. + /// </summary> + public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ITimerFactory timerFactory, ISystemEvents systemEvents, IEnvironmentInfo environmentInfo) + { + if (taskManager == null) + { + throw new ArgumentNullException("taskManager"); + } + + LibraryManager = libraryManager; + TaskManager = taskManager; + Logger = logManager.GetLogger(GetType().Name); + ConfigurationManager = configurationManager; + _fileSystem = fileSystem; + _timerFactory = timerFactory; + _environmentInfo = environmentInfo; + + systemEvents.Resume += _systemEvents_Resume; + } + + private void _systemEvents_Resume(object sender, EventArgs e) + { + Restart(); + } + + private void Restart() + { + Stop(); + + if (!_disposed) + { + Start(); + } + } + + private bool IsLibraryMonitorEnabaled(BaseItem item) + { + if (item is BasePluginFolder) + { + return false; + } + + var options = LibraryManager.GetLibraryOptions(item); + + if (options != null) + { + return options.EnableRealtimeMonitor; + } + + return false; + } + + public void Start() + { + LibraryManager.ItemAdded += LibraryManager_ItemAdded; + LibraryManager.ItemRemoved += LibraryManager_ItemRemoved; + + var pathsToWatch = new List<string> { }; + + var paths = LibraryManager + .RootFolder + .Children + .Where(IsLibraryMonitorEnabaled) + .OfType<Folder>() + .SelectMany(f => f.PhysicalLocations) + .Distinct(StringComparer.OrdinalIgnoreCase) + .OrderBy(i => i) + .ToList(); + + foreach (var path in paths) + { + if (!ContainsParentFolder(pathsToWatch, path)) + { + pathsToWatch.Add(path); + } + } + + foreach (var path in pathsToWatch) + { + StartWatchingPath(path); + } + } + + private void StartWatching(BaseItem item) + { + if (IsLibraryMonitorEnabaled(item)) + { + StartWatchingPath(item.Path); + } + } + + /// <summary> + /// Handles the ItemRemoved event of the LibraryManager control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="ItemChangeEventArgs"/> instance containing the event data.</param> + void LibraryManager_ItemRemoved(object sender, ItemChangeEventArgs e) + { + if (e.Item.GetParent() is AggregateFolder) + { + StopWatchingPath(e.Item.Path); + } + } + + /// <summary> + /// Handles the ItemAdded event of the LibraryManager control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="ItemChangeEventArgs"/> instance containing the event data.</param> + void LibraryManager_ItemAdded(object sender, ItemChangeEventArgs e) + { + if (e.Item.GetParent() is AggregateFolder) + { + StartWatching(e.Item); + } + } + + /// <summary> + /// Examine a list of strings assumed to be file paths to see if it contains a parent of + /// the provided path. + /// </summary> + /// <param name="lst">The LST.</param> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if [contains parent folder] [the specified LST]; otherwise, <c>false</c>.</returns> + /// <exception cref="System.ArgumentNullException">path</exception> + private static bool ContainsParentFolder(IEnumerable<string> lst, string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentNullException("path"); + } + + path = path.TrimEnd(Path.DirectorySeparatorChar); + + return lst.Any(str => + { + //this should be a little quicker than examining each actual parent folder... + var compare = str.TrimEnd(Path.DirectorySeparatorChar); + + return path.Equals(compare, StringComparison.OrdinalIgnoreCase) || (path.StartsWith(compare, StringComparison.OrdinalIgnoreCase) && path[compare.Length] == Path.DirectorySeparatorChar); + }); + } + + /// <summary> + /// Starts the watching path. + /// </summary> + /// <param name="path">The path.</param> + private void StartWatchingPath(string path) + { + if (!_fileSystem.DirectoryExists(path)) + { + // Seeing a crash in the mono runtime due to an exception being thrown on a different thread + Logger.Info("Skipping realtime monitor for {0} because the path does not exist", path); + return; + } + + if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) + { + if (path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase) || path.StartsWith("smb://", StringComparison.OrdinalIgnoreCase)) + { + // not supported + return; + } + } + + // Already being watched + if (_fileSystemWatchers.ContainsKey(path)) + { + return; + } + + // Creating a FileSystemWatcher over the LAN can take hundreds of milliseconds, so wrap it in a Task to do them all in parallel + Task.Run(() => + { + try + { + var newWatcher = new FileSystemWatcher(path, "*") + { + IncludeSubdirectories = true + }; + + if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + { + newWatcher.InternalBufferSize = 32767; + } + + newWatcher.NotifyFilter = NotifyFilters.CreationTime | + NotifyFilters.DirectoryName | + NotifyFilters.FileName | + NotifyFilters.LastWrite | + NotifyFilters.Size | + NotifyFilters.Attributes; + + newWatcher.Created += watcher_Changed; + + // Seeing mono crashes on background threads we can't catch, testing if this might help + if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + { + newWatcher.Deleted += watcher_Changed; + } + + newWatcher.Renamed += watcher_Changed; + newWatcher.Changed += watcher_Changed; + + newWatcher.Error += watcher_Error; + + if (_fileSystemWatchers.TryAdd(path, newWatcher)) + { + newWatcher.EnableRaisingEvents = true; + Logger.Info("Watching directory " + path); + } + else + { + newWatcher.Dispose(); + } + + } + catch (Exception ex) + { + Logger.ErrorException("Error watching path: {0}", ex, path); + } + }); + } + + /// <summary> + /// Stops the watching path. + /// </summary> + /// <param name="path">The path.</param> + private void StopWatchingPath(string path) + { + FileSystemWatcher watcher; + + if (_fileSystemWatchers.TryGetValue(path, out watcher)) + { + DisposeWatcher(watcher); + } + } + + /// <summary> + /// Disposes the watcher. + /// </summary> + /// <param name="watcher">The watcher.</param> + private void DisposeWatcher(FileSystemWatcher watcher) + { + try + { + using (watcher) + { + Logger.Info("Stopping directory watching for path {0}", watcher.Path); + + watcher.EnableRaisingEvents = false; + } + } + catch + { + + } + finally + { + RemoveWatcherFromList(watcher); + } + } + + /// <summary> + /// Removes the watcher from list. + /// </summary> + /// <param name="watcher">The watcher.</param> + private void RemoveWatcherFromList(FileSystemWatcher watcher) + { + FileSystemWatcher removed; + + _fileSystemWatchers.TryRemove(watcher.Path, out removed); + } + + /// <summary> + /// Handles the Error event of the watcher control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="ErrorEventArgs" /> instance containing the event data.</param> + void watcher_Error(object sender, ErrorEventArgs e) + { + var ex = e.GetException(); + var dw = (FileSystemWatcher)sender; + + Logger.ErrorException("Error in Directory watcher for: " + dw.Path, ex); + + DisposeWatcher(dw); + } + + /// <summary> + /// Handles the Changed event of the watcher control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="FileSystemEventArgs" /> instance containing the event data.</param> + void watcher_Changed(object sender, FileSystemEventArgs e) + { + try + { + //Logger.Debug("Changed detected of type " + e.ChangeType + " to " + e.FullPath); + + var path = e.FullPath; + + ReportFileSystemChanged(path); + } + catch (Exception ex) + { + Logger.ErrorException("Exception in ReportFileSystemChanged. Path: {0}", ex, e.FullPath); + } + } + + public void ReportFileSystemChanged(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var filename = Path.GetFileName(path); + + var monitorPath = !string.IsNullOrEmpty(filename) && + !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) && + !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase) && + _alwaysIgnoreSubstrings.All(i => path.IndexOf(i, StringComparison.OrdinalIgnoreCase) == -1); + + // Ignore certain files + var tempIgnorePaths = _tempIgnoredPaths.Keys.ToList(); + + // If the parent of an ignored path has a change event, ignore that too + if (tempIgnorePaths.Any(i => + { + if (_fileSystem.AreEqual(i, path)) + { + Logger.Debug("Ignoring change to {0}", path); + return true; + } + + if (_fileSystem.ContainsSubPath(i, path)) + { + Logger.Debug("Ignoring change to {0}", path); + return true; + } + + // Go up a level + var parent = _fileSystem.GetDirectoryName(i); + if (!string.IsNullOrEmpty(parent)) + { + if (_fileSystem.AreEqual(parent, path)) + { + Logger.Debug("Ignoring change to {0}", path); + return true; + } + } + + return false; + + })) + { + monitorPath = false; + } + + if (monitorPath) + { + // Avoid implicitly captured closure + CreateRefresher(path); + } + } + + private void CreateRefresher(string path) + { + var parentPath = _fileSystem.GetDirectoryName(path); + + lock (_activeRefreshers) + { + var refreshers = _activeRefreshers.ToList(); + foreach (var refresher in refreshers) + { + // Path is already being refreshed + if (_fileSystem.AreEqual(path, refresher.Path)) + { + refresher.RestartTimer(); + return; + } + + // Parent folder is already being refreshed + if (_fileSystem.ContainsSubPath(refresher.Path, path)) + { + refresher.AddPath(path); + return; + } + + // New path is a parent + if (_fileSystem.ContainsSubPath(path, refresher.Path)) + { + refresher.ResetPath(path, null); + return; + } + + // They are siblings. Rebase the refresher to the parent folder. + if (string.Equals(parentPath, _fileSystem.GetDirectoryName(refresher.Path), StringComparison.Ordinal)) + { + refresher.ResetPath(parentPath, path); + return; + } + } + + var newRefresher = new FileRefresher(path, _fileSystem, ConfigurationManager, LibraryManager, TaskManager, Logger, _timerFactory, _environmentInfo, LibraryManager); + newRefresher.Completed += NewRefresher_Completed; + _activeRefreshers.Add(newRefresher); + } + } + + private void NewRefresher_Completed(object sender, EventArgs e) + { + var refresher = (FileRefresher)sender; + DisposeRefresher(refresher); + } + + /// <summary> + /// Stops this instance. + /// </summary> + public void Stop() + { + LibraryManager.ItemAdded -= LibraryManager_ItemAdded; + LibraryManager.ItemRemoved -= LibraryManager_ItemRemoved; + + foreach (var watcher in _fileSystemWatchers.Values.ToList()) + { + watcher.Created -= watcher_Changed; + watcher.Deleted -= watcher_Changed; + watcher.Renamed -= watcher_Changed; + watcher.Changed -= watcher_Changed; + + try + { + watcher.EnableRaisingEvents = false; + } + catch (InvalidOperationException) + { + // Seeing this under mono on linux sometimes + // Collection was modified; enumeration operation may not execute. + } + + watcher.Dispose(); + } + + _fileSystemWatchers.Clear(); + DisposeRefreshers(); + } + + private void DisposeRefresher(FileRefresher refresher) + { + lock (_activeRefreshers) + { + refresher.Dispose(); + _activeRefreshers.Remove(refresher); + } + } + + private void DisposeRefreshers() + { + lock (_activeRefreshers) + { + foreach (var refresher in _activeRefreshers.ToList()) + { + refresher.Dispose(); + } + _activeRefreshers.Clear(); + } + } + + private bool _disposed; + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + _disposed = true; + Dispose(true); + GC.SuppressFinalize(this); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + Stop(); + } + } + } + + public class LibraryMonitorStartup : IServerEntryPoint + { + private readonly ILibraryMonitor _monitor; + + public LibraryMonitorStartup(ILibraryMonitor monitor) + { + _monitor = monitor; + } + + public void Run() + { + _monitor.Start(); + } + + public void Dispose() + { + GC.SuppressFinalize(this); + } + } +} diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs new file mode 100644 index 000000000..0d85a977c --- /dev/null +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -0,0 +1,1057 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.System; + +namespace Emby.Server.Implementations.IO +{ + /// <summary> + /// Class ManagedFileSystem + /// </summary> + public class ManagedFileSystem : IFileSystem + { + protected ILogger Logger; + + private readonly bool _supportsAsyncFileStreams; + private char[] _invalidFileNameChars; + private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>(); + private bool EnableFileSystemRequestConcat; + + private string _tempPath; + + private SharpCifsFileSystem _sharpCifsFileSystem; + + public ManagedFileSystem(ILogger logger, IEnvironmentInfo environmentInfo, string tempPath) + { + Logger = logger; + _supportsAsyncFileStreams = true; + _tempPath = tempPath; + + // On Linux, this needs to be true or symbolic links are ignored + EnableFileSystemRequestConcat = environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows && + environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX; + + SetInvalidFileNameChars(environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows); + + _sharpCifsFileSystem = new SharpCifsFileSystem(environmentInfo.OperatingSystem); + } + + 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); + } + + /// <summary> + /// Determines whether the specified filename is shortcut. + /// </summary> + /// <param name="filename">The filename.</param> + /// <returns><c>true</c> if the specified filename is shortcut; otherwise, <c>false</c>.</returns> + /// <exception cref="System.ArgumentNullException">filename</exception> + 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)); + } + + /// <summary> + /// Resolves the shortcut. + /// </summary> + /// <param name="filename">The filename.</param> + /// <returns>System.String.</returns> + /// <exception cref="System.ArgumentNullException">filename</exception> + 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; + } + + /// <summary> + /// Creates the shortcut. + /// </summary> + /// <param name="shortcutPath">The shortcut path.</param> + /// <param name="target">The target.</param> + /// <exception cref="System.ArgumentNullException"> + /// shortcutPath + /// or + /// target + /// </exception> + 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(); + } + } + + /// <summary> + /// Returns a <see cref="FileSystemMetadata"/> object for the specified file or directory path. + /// </summary> + /// <param name="path">A path to a file or directory.</param> + /// <returns>A <see cref="FileSystemMetadata"/> object.</returns> + /// <remarks>If the specified path points to a directory, the returned <see cref="FileSystemMetadata"/> object's + /// <see cref="FileSystemMetadata.IsDirectory"/> property will be set to true and all other properties will reflect the properties of the directory.</remarks> + public FileSystemMetadata GetFileSystemInfo(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileSystemInfo(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)); + } + } + + /// <summary> + /// Returns a <see cref="FileSystemMetadata"/> object for the specified file path. + /// </summary> + /// <param name="path">A path to a file.</param> + /// <returns>A <see cref="FileSystemMetadata"/> object.</returns> + /// <remarks><para>If the specified path points to a directory, the returned <see cref="FileSystemMetadata"/> object's + /// <see cref="FileSystemMetadata.IsDirectory"/> property and the <see cref="FileSystemMetadata.Exists"/> property will both be set to false.</para> + /// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo"/>.</para></remarks> + public FileSystemMetadata GetFileInfo(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileInfo(path); + } + + var fileInfo = new FileInfo(path); + + return GetFileSystemMetadata(fileInfo); + } + + /// <summary> + /// Returns a <see cref="FileSystemMetadata"/> object for the specified directory path. + /// </summary> + /// <param name="path">A path to a directory.</param> + /// <returns>A <see cref="FileSystemMetadata"/> object.</returns> + /// <remarks><para>If the specified path points to a file, the returned <see cref="FileSystemMetadata"/> object's + /// <see cref="FileSystemMetadata.IsDirectory"/> property will be set to true and the <see cref="FileSystemMetadata.Exists"/> property will be set to false.</para> + /// <para>For automatic handling of files <b>and</b> directories, use <see cref="GetFileSystemInfo"/>.</para></remarks> + public FileSystemMetadata GetDirectoryInfo(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectoryInfo(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; + } + + /// <summary> + /// The space char + /// </summary> + private const char SpaceChar = ' '; + + /// <summary> + /// Takes a filename and removes invalid characters + /// </summary> + /// <param name="filename">The filename.</param> + /// <returns>System.String.</returns> + /// <exception cref="System.ArgumentNullException">filename</exception> + 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(); + } + + /// <summary> + /// Gets the creation time UTC. + /// </summary> + /// <param name="info">The info.</param> + /// <returns>DateTime.</returns> + 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; + } + } + + /// <summary> + /// Gets the creation time UTC. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>DateTime.</returns> + 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; + } + + /// <summary> + /// Gets the creation time UTC. + /// </summary> + /// <param name="info">The info.</param> + /// <returns>DateTime.</returns> + 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; + } + } + + /// <summary> + /// Gets the last write time UTC. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>DateTime.</returns> + public DateTime GetLastWriteTimeUtc(string path) + { + return GetLastWriteTimeUtc(GetFileSystemInfo(path)); + } + + /// <summary> + /// Gets the file stream. + /// </summary> + /// <param name="path">The path.</param> + /// <param name="mode">The mode.</param> + /// <param name="access">The access.</param> + /// <param name="share">The share.</param> + /// <param name="isAsync">if set to <c>true</c> [is asynchronous].</param> + /// <returns>FileStream.</returns> + public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, bool isAsync = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileStream(path, mode, access, share); + } + + if (_supportsAsyncFileStreams && isAsync) + { + return GetFileStream(path, mode, access, share, FileOpenOptions.Asynchronous); + } + + return GetFileStream(path, mode, access, share, FileOpenOptions.None); + } + + public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, FileOpenOptions fileOpenOptions) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileStream(path, mode, access, share); + } + + var defaultBufferSize = 4096; + return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), defaultBufferSize, GetFileOptions(fileOpenOptions)); + } + + private FileOptions GetFileOptions(FileOpenOptions mode) + { + var val = (int)mode; + return (FileOptions)val; + } + + 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) + { + switch (mode) + { + //case FileAccessMode.ReadWrite: + // return FileAccess.ReadWrite; + case FileAccessMode.Write: + return FileAccess.Write; + case FileAccessMode.Read: + return FileAccess.Read; + default: + throw new Exception("Unrecognized FileAccessMode"); + } + } + + private FileShare GetFileShare(FileShareMode mode) + { + switch (mode) + { + case FileShareMode.ReadWrite: + return FileShare.ReadWrite; + case FileShareMode.Write: + return FileShare.Write; + case FileShareMode.Read: + return FileShare.Read; + case FileShareMode.None: + return FileShare.None; + default: + throw new Exception("Unrecognized FileShareMode"); + } + } + + public void SetHidden(string path, bool isHidden) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.SetHidden(path, isHidden); + return; + } + + var info = GetFileInfo(path); + + if (info.Exists && info.IsHidden != isHidden) + { + if (isHidden) + { + File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden); + } + else + { + FileAttributes attributes = File.GetAttributes(path); + attributes = RemoveAttribute(attributes, FileAttributes.Hidden); + File.SetAttributes(path, attributes); + } + } + } + + public void SetReadOnly(string path, bool isReadOnly) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.SetReadOnly(path, isReadOnly); + return; + } + + var info = GetFileInfo(path); + + if (info.Exists && info.IsReadOnly != isReadOnly) + { + if (isReadOnly) + { + File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.ReadOnly); + } + else + { + FileAttributes attributes = File.GetAttributes(path); + attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly); + File.SetAttributes(path, attributes); + } + } + } + + public void SetAttributes(string path, bool isHidden, bool isReadOnly) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.SetAttributes(path, isHidden, isReadOnly); + return; + } + + var info = GetFileInfo(path); + + if (!info.Exists) + { + return; + } + + if (info.IsReadOnly == isReadOnly && info.IsHidden == isHidden) + { + return; + } + + var attributes = File.GetAttributes(path); + + if (isReadOnly) + { + attributes = attributes | FileAttributes.ReadOnly; + } + else + { + attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly); + } + + if (isHidden) + { + attributes = attributes | FileAttributes.Hidden; + } + else + { + attributes = RemoveAttribute(attributes, FileAttributes.Hidden); + } + + File.SetAttributes(path, attributes); + } + + private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove) + { + return attributes & ~attributesToRemove; + } + + /// <summary> + /// Swaps the files. + /// </summary> + /// <param name="file1">The file1.</param> + /// <param name="file2">The file2.</param> + 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.Combine(_tempPath, Guid.NewGuid().ToString("N")); + + // Copying over will fail against hidden files + SetHidden(file1, false); + SetHidden(file2, false); + + Directory.CreateDirectory(_tempPath); + CopyFile(file1, temp1, true); + + CopyFile(file2, file1, true); + CopyFile(temp1, file2, true); + } + + private char GetDirectorySeparatorChar(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectorySeparatorChar(path); + } + + return Path.DirectorySeparatorChar; + } + + public bool ContainsSubPath(string parentPath, string path) + { + if (string.IsNullOrEmpty(parentPath)) + { + throw new ArgumentNullException("parentPath"); + } + + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var separatorChar = GetDirectorySeparatorChar(parentPath); + + return path.IndexOf(parentPath.TrimEnd(separatorChar) + separatorChar, StringComparison.OrdinalIgnoreCase) != -1; + } + + public bool IsRootPath(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + var parent = GetDirectoryName(path); + + if (!string.IsNullOrEmpty(parent)) + { + return false; + } + + return true; + } + + public string GetDirectoryName(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectoryName(path); + } + + return Path.GetDirectoryName(path); + } + + public string NormalizePath(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException("path"); + } + + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.NormalizePath(path); + } + + if (path.EndsWith(":\\", StringComparison.OrdinalIgnoreCase)) + { + return path; + } + + return path.TrimEnd(GetDirectorySeparatorChar(path)); + } + + public bool AreEqual(string path1, string path2) + { + if (path1 == null && path2 == null) + { + return true; + } + + if (path1 == null || path2 == null) + { + return false; + } + + return string.Equals(NormalizePath(path1), NormalizePath(path2), StringComparison.OrdinalIgnoreCase); + } + + 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 (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return true; + } + + if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 && + !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + return true; + + //return Path.IsPathRooted(path); + } + + public void DeleteFile(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.DeleteFile(path); + return; + } + + SetAttributes(path, false, false); + File.Delete(path); + } + + public void DeleteDirectory(string path, bool recursive) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.DeleteDirectory(path, recursive); + return; + } + + Directory.Delete(path, recursive); + } + + public void CreateDirectory(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.CreateDirectory(path); + return; + } + + Directory.CreateDirectory(path); + } + + public List<FileSystemMetadata> GetDrives() + { + // Only include drives in the ready state or this method could end up being very slow, waiting for drives to timeout + return DriveInfo.GetDrives().Where(d => d.IsReady).Select(d => new FileSystemMetadata + { + Name = GetName(d), + FullName = d.RootDirectory.FullName, + IsDirectory = true + + }).ToList(); + } + + private string GetName(DriveInfo drive) + { + return drive.Name; + } + + public IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectories(path, recursive); + } + + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + return ToMetadata(new DirectoryInfo(path).EnumerateDirectories("*", searchOption)); + } + + public IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false) + { + return GetFiles(path, null, false, recursive); + } + + public IEnumerable<FileSystemMetadata> GetFiles(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFiles(path, extensions, enableCaseSensitiveExtensions, recursive); + } + + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + // On linux and osx the search pattern is case sensitive + // If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method + if (enableCaseSensitiveExtensions && extensions != null && extensions.Length == 1) + { + return ToMetadata(new DirectoryInfo(path).EnumerateFiles("*" + extensions[0], searchOption)); + } + + var files = new DirectoryInfo(path).EnumerateFiles("*", searchOption); + + if (extensions != null && extensions.Length > 0) + { + files = files.Where(i => + { + var ext = i.Extension; + if (ext == null) + { + return false; + } + return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }); + } + + return ToMetadata(files); + } + + public IEnumerable<FileSystemMetadata> GetFileSystemEntries(string path, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileSystemEntries(path, recursive); + } + + var directoryInfo = new DirectoryInfo(path); + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + if (EnableFileSystemRequestConcat) + { + return ToMetadata(directoryInfo.EnumerateDirectories("*", searchOption)) + .Concat(ToMetadata(directoryInfo.EnumerateFiles("*", searchOption))); + } + + return ToMetadata(directoryInfo.EnumerateFileSystemInfos("*", searchOption)); + } + + private IEnumerable<FileSystemMetadata> ToMetadata(IEnumerable<FileSystemInfo> infos) + { + return infos.Select(GetFileSystemMetadata); + } + + public string[] ReadAllLines(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllLines(path); + } + return File.ReadAllLines(path); + } + + public void WriteAllLines(string path, IEnumerable<string> lines) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllLines(path, lines); + return; + } + File.WriteAllLines(path, lines); + } + + public Stream OpenRead(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.OpenRead(path); + } + return File.OpenRead(path); + } + + public void CopyFile(string source, string target, bool overwrite) + { + if (_sharpCifsFileSystem.IsEnabledForPath(source)) + { + _sharpCifsFileSystem.CopyFile(source, target, overwrite); + return; + } + File.Copy(source, target, overwrite); + } + + public void MoveFile(string source, string target) + { + if (_sharpCifsFileSystem.IsEnabledForPath(source)) + { + _sharpCifsFileSystem.MoveFile(source, target); + return; + } + File.Move(source, target); + } + + public void MoveDirectory(string source, string target) + { + if (_sharpCifsFileSystem.IsEnabledForPath(source)) + { + _sharpCifsFileSystem.MoveDirectory(source, target); + return; + } + Directory.Move(source, target); + } + + public bool DirectoryExists(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.DirectoryExists(path); + } + return Directory.Exists(path); + } + + public bool FileExists(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.FileExists(path); + } + return File.Exists(path); + } + + public string ReadAllText(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllText(path); + } + return File.ReadAllText(path); + } + + public byte[] ReadAllBytes(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllBytes(path); + } + return File.ReadAllBytes(path); + } + + public void WriteAllText(string path, string text, Encoding encoding) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllText(path, text, encoding); + return; + } + + File.WriteAllText(path, text, encoding); + } + + public void WriteAllText(string path, string text) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllText(path, text); + return; + } + + File.WriteAllText(path, text); + } + + public void WriteAllBytes(string path, byte[] bytes) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllBytes(path, bytes); + return; + } + + File.WriteAllBytes(path, bytes); + } + + public string ReadAllText(string path, Encoding encoding) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllText(path, encoding); + } + + return File.ReadAllText(path, encoding); + } + + public IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectoryPaths(path, recursive); + } + + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + return Directory.EnumerateDirectories(path, "*", searchOption); + } + + public IEnumerable<string> GetFilePaths(string path, bool recursive = false) + { + return GetFilePaths(path, null, false, recursive); + } + + public IEnumerable<string> GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFilePaths(path, extensions, enableCaseSensitiveExtensions, recursive); + } + + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + + // On linux and osx the search pattern is case sensitive + // If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method + if (enableCaseSensitiveExtensions && extensions != null && extensions.Length == 1) + { + return Directory.EnumerateFiles(path, "*" + extensions[0], searchOption); + } + + var files = Directory.EnumerateFiles(path, "*", searchOption); + + if (extensions != null && extensions.Length > 0) + { + files = files.Where(i => + { + var ext = Path.GetExtension(i); + if (ext == null) + { + return false; + } + return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }); + } + + return files; + } + + public IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileSystemEntryPaths(path, recursive); + } + + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + return Directory.EnumerateFileSystemEntries(path, "*", searchOption); + } + + public virtual void SetExecutable(string path) + { + + } + } +} diff --git a/Emby.Server.Implementations/IO/MemoryStreamProvider.cs b/Emby.Server.Implementations/IO/MemoryStreamProvider.cs new file mode 100644 index 000000000..e9ecb7e44 --- /dev/null +++ b/Emby.Server.Implementations/IO/MemoryStreamProvider.cs @@ -0,0 +1,29 @@ +using System.IO; +using MediaBrowser.Model.IO; + +namespace Emby.Server.Implementations.IO +{ + public class MemoryStreamProvider : IMemoryStreamFactory + { + public MemoryStream CreateNew() + { + return new MemoryStream(); + } + + public MemoryStream CreateNew(int capacity) + { + return new MemoryStream(capacity); + } + + public MemoryStream CreateNew(byte[] buffer) + { + return new MemoryStream(buffer); + } + + public bool TryGetBuffer(MemoryStream stream, out byte[] buffer) + { + buffer = stream.GetBuffer(); + return true; + } + } +} diff --git a/Emby.Server.Implementations/IO/ProgressStream.cs b/Emby.Server.Implementations/IO/ProgressStream.cs new file mode 100644 index 000000000..be1ff72f8 --- /dev/null +++ b/Emby.Server.Implementations/IO/ProgressStream.cs @@ -0,0 +1,240 @@ +using System; +using System.IO; + +namespace Emby.Server.Implementations.IO +{ + /// <summary> + /// Measures progress when reading from a stream or writing to one + /// </summary> + public class ProgressStream : Stream + { + /// <summary> + /// Gets the base stream. + /// </summary> + /// <value>The base stream.</value> + public Stream BaseStream { get; private set; } + + /// <summary> + /// Gets or sets the bytes processed. + /// </summary> + /// <value>The bytes processed.</value> + private long BytesProcessed { get; set; } + /// <summary> + /// Gets or sets the length of the write. + /// </summary> + /// <value>The length of the write.</value> + private long WriteLength { get; set; } + + /// <summary> + /// Gets or sets the length of the read. + /// </summary> + /// <value>The length of the read.</value> + private long? ReadLength { get; set; } + + /// <summary> + /// Gets or sets the progress action. + /// </summary> + /// <value>The progress action.</value> + private Action<double> ProgressAction { get; set; } + + /// <summary> + /// Creates the read progress stream. + /// </summary> + /// <param name="baseStream">The base stream.</param> + /// <param name="progressAction">The progress action.</param> + /// <param name="readLength">Length of the read.</param> + /// <returns>ProgressStream.</returns> + public static ProgressStream CreateReadProgressStream(Stream baseStream, Action<double> progressAction, long? readLength = null) + { + return new ProgressStream + { + BaseStream = baseStream, + ProgressAction = progressAction, + ReadLength = readLength + }; + } + + /// <summary> + /// Creates the write progress stream. + /// </summary> + /// <param name="baseStream">The base stream.</param> + /// <param name="progressAction">The progress action.</param> + /// <param name="writeLength">Length of the write.</param> + /// <returns>ProgressStream.</returns> + public static ProgressStream CreateWriteProgressStream(Stream baseStream, Action<double> progressAction, long writeLength) + { + return new ProgressStream + { + BaseStream = baseStream, + ProgressAction = progressAction, + WriteLength = writeLength + }; + } + + /// <summary> + /// When overridden in a derived class, gets a value indicating whether the current stream supports reading. + /// </summary> + /// <value><c>true</c> if this instance can read; otherwise, <c>false</c>.</value> + /// <returns>true if the stream supports reading; otherwise, false.</returns> + public override bool CanRead + { + get { return BaseStream.CanRead; } + } + + /// <summary> + /// When overridden in a derived class, gets a value indicating whether the current stream supports seeking. + /// </summary> + /// <value><c>true</c> if this instance can seek; otherwise, <c>false</c>.</value> + /// <returns>true if the stream supports seeking; otherwise, false.</returns> + public override bool CanSeek + { + get { return BaseStream.CanSeek; } + } + + /// <summary> + /// When overridden in a derived class, gets a value indicating whether the current stream supports writing. + /// </summary> + /// <value><c>true</c> if this instance can write; otherwise, <c>false</c>.</value> + /// <returns>true if the stream supports writing; otherwise, false.</returns> + public override bool CanWrite + { + get { return BaseStream.CanWrite; } + } + + /// <summary> + /// When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device. + /// </summary> + public override void Flush() + { + BaseStream.Flush(); + } + + /// <summary> + /// When overridden in a derived class, gets the length in bytes of the stream. + /// </summary> + /// <value>The length.</value> + /// <returns>A long value representing the length of the stream in bytes.</returns> + public override long Length + { + get { return BaseStream.Length; } + } + + /// <summary> + /// When overridden in a derived class, gets or sets the position within the current stream. + /// </summary> + /// <value>The position.</value> + /// <returns>The current position within the stream.</returns> + public override long Position + { + get { return BaseStream.Position; } + set + { + BaseStream.Position = value; + } + } + + /// <summary> + /// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. + /// </summary> + /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between <paramref name="offset" /> and (<paramref name="offset" /> + <paramref name="count" /> - 1) replaced by the bytes read from the current source.</param> + /// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin storing the data read from the current stream.</param> + /// <param name="count">The maximum number of bytes to be read from the current stream.</param> + /// <returns>The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.</returns> + public override int Read(byte[] buffer, int offset, int count) + { + var read = BaseStream.Read(buffer, offset, count); + + BytesProcessed += read; + + double percent = BytesProcessed; + percent /= ReadLength ?? BaseStream.Length; + percent *= 100; + + ProgressAction(percent); + + return read; + } + + public override int EndRead(IAsyncResult asyncResult) + { + var read = base.EndRead(asyncResult); + + BytesProcessed += read; + + double percent = BytesProcessed; + percent /= ReadLength ?? BaseStream.Length; + percent *= 100; + + ProgressAction(percent); + + return read; + } + + /// <summary> + /// When overridden in a derived class, sets the position within the current stream. + /// </summary> + /// <param name="offset">A byte offset relative to the <paramref name="origin" /> parameter.</param> + /// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin" /> indicating the reference point used to obtain the new position.</param> + /// <returns>The new position within the current stream.</returns> + public override long Seek(long offset, SeekOrigin origin) + { + return BaseStream.Seek(offset, origin); + } + + /// <summary> + /// When overridden in a derived class, sets the length of the current stream. + /// </summary> + /// <param name="value">The desired length of the current stream in bytes.</param> + public override void SetLength(long value) + { + BaseStream.SetLength(value); + } + + /// <summary> + /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. + /// </summary> + /// <param name="buffer">An array of bytes. This method copies <paramref name="count" /> bytes from <paramref name="buffer" /> to the current stream.</param> + /// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin copying bytes to the current stream.</param> + /// <param name="count">The number of bytes to be written to the current stream.</param> + public override void Write(byte[] buffer, int offset, int count) + { + BaseStream.Write(buffer, offset, count); + + BytesProcessed += count; + + double percent = BytesProcessed; + percent /= WriteLength; + percent *= 100; + + ProgressAction(percent); + } + + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + var result = base.BeginWrite(buffer, offset, count, callback, state); + + BytesProcessed += count; + + double percent = BytesProcessed; + percent /= WriteLength; + percent *= 100; + + ProgressAction(percent); + + return result; + } + + /// <summary> + /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream" /> and optionally releases the managed resources. + /// </summary> + /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> + protected override void Dispose(bool disposing) + { + if (disposing) + { + BaseStream.Dispose(); + } + base.Dispose(disposing); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Config.cs b/Emby.Server.Implementations/IO/SharpCifs/Config.cs new file mode 100644 index 000000000..3fd0e5bd6 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Config.cs @@ -0,0 +1,409 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using System.Net; +using System.Security; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs +{ + /// <summary> + /// This class uses a static + /// <see cref="Properties">Sharpen.Properties</see> + /// to act + /// as a cental repository for all jCIFS configuration properties. It cannot be + /// instantiated. Similar to <code>System</code> properties the namespace + /// is global therefore property names should be unique. Before use, + /// the <code>load</code> method should be called with the name of a + /// <code>Properties</code> file (or <code>null</code> indicating no + /// file) to initialize the <code>Config</code>. The <code>System</code> + /// properties will then populate the <code>Config</code> as well potentially + /// overwriting properties from the file. Thus properties provided on the + /// commandline with the <code>-Dproperty.name=value</code> VM parameter + /// will override properties from the configuration file. + /// + /// There are several ways to set jCIFS properties. See + /// the <a href="../overview-summary.html#scp">overview page of the API + /// documentation</a> for details. + /// </summary> + public class Config + { + + /// <summary>The static <code>Properties</code>.</summary> + /// <remarks>The static <code>Properties</code>.</remarks> + private static Properties _prp = new Properties(); + + private static LogStream _log; + + public static string DefaultOemEncoding = "UTF-8"; //"Cp850"; + + static Config() + { + int level; + FileInputStream fis = null; + _log = LogStream.GetInstance(); + + try + { + string filename = Runtime.GetProperty("jcifs.properties"); + if (filename != null && filename.Length > 1) + { + fis = new FileInputStream(filename); + } + Load(fis); + if (fis != null) + { + fis.Close(); + } + } + catch (IOException ioe) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(ioe, _log); + } + } + + if ((level = GetInt("jcifs.util.loglevel", -1)) != -1) + { + _log.SetLevel(level); + } + + try + { + Runtime.GetBytesForString(string.Empty, DefaultOemEncoding); + } + catch (Exception ex) + { + if (_log.Level >= 2) + { + _log.WriteLine("WARNING: The default OEM encoding " + DefaultOemEncoding + " does not appear to be supported by this JRE. The default encoding will be US-ASCII." + ); + } + + //DEFAULT_OEM_ENCODING = "US-ASCII"; + } + + if (_log.Level >= 4) + { + try + { + _prp.Store(_log); + } + catch (IOException) + { + } + } + } + + /// <summary> + /// This static method registers the SMB URL protocol handler which is + /// required to use SMB URLs with the <tt>java.net.URL</tt> class. + /// </summary> + /// <remarks> + /// This static method registers the SMB URL protocol handler which is + /// required to use SMB URLs with the <tt>java.net.URL</tt> class. If this + /// method is not called before attempting to create an SMB URL with the + /// URL class the following exception will occur: + /// <blockquote><pre> + /// Exception MalformedURLException: unknown protocol: smb + /// at java.net.URL.<init>(URL.java:480) + /// at java.net.URL.<init>(URL.java:376) + /// at java.net.URL.<init>(URL.java:330) + /// at jcifs.smb.SmbFile.<init>(SmbFile.java:355) + /// ... + /// </pre><blockquote> + /// </remarks> + public static void RegisterSmbURLHandler() + { + throw new NotImplementedException(); + } + + // supress javadoc constructor summary by removing 'protected' + /// <summary>Set the default properties of the static Properties used by <tt>Config</tt>. + /// </summary> + /// <remarks> + /// Set the default properties of the static Properties used by <tt>Config</tt>. This permits + /// a different Properties object/file to be used as the source of properties for + /// use by the jCIFS library. The Properties must be set <i>before jCIFS + /// classes are accessed</i> as most jCIFS classes load properties statically once. + /// Using this method will also override properties loaded + /// using the <tt>-Djcifs.properties=</tt> commandline parameter. + /// </remarks> + public static void SetProperties(Properties prp) + { + Config._prp = new Properties(prp); + try + { + Config._prp.PutAll(Runtime.GetProperties()); + } + catch (SecurityException) + { + if (_log.Level > 1) + { + _log.WriteLine("SecurityException: jcifs will ignore System properties"); + } + } + } + + /// <summary> + /// Load the <code>Config</code> with properties from the stream + /// <code>in</code> from a <code>Properties</code> file. + /// </summary> + /// <remarks> + /// Load the <code>Config</code> with properties from the stream + /// <code>in</code> from a <code>Properties</code> file. + /// </remarks> + /// <exception cref="System.IO.IOException"></exception> + public static void Load(InputStream input) + { + if (input != null) + { + _prp.Load(input); + } + try + { + _prp.PutAll(Runtime.GetProperties()); + } + catch (SecurityException) + { + if (_log.Level > 1) + { + _log.WriteLine("SecurityException: jcifs will ignore System properties"); + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public static void Store(OutputStream output, string header) + { + _prp.Store(output); + } + + /// <summary>Add a property.</summary> + /// <remarks>Add a property.</remarks> + public static void SetProperty(string key, string value) + { + _prp.SetProperty(key, value); + } + + /// <summary>Retrieve a property as an <code>Object</code>.</summary> + /// <remarks>Retrieve a property as an <code>Object</code>.</remarks> + public static object Get(string key) + { + return _prp.GetProperty(key); + } + + /// <summary>Retrieve a <code>String</code>.</summary> + /// <remarks> + /// Retrieve a <code>String</code>. If the key cannot be found, + /// the provided <code>def</code> default parameter will be returned. + /// </remarks> + public static string GetProperty(string key, string def) + { + return (string)_prp.GetProperty(key, def); + } + + /// <summary>Retrieve a <code>String</code>.</summary> + /// <remarks>Retrieve a <code>String</code>. If the property is not found, <code>null</code> is returned. + /// </remarks> + public static string GetProperty(string key) + { + return (string)_prp.GetProperty(key); + } + + /// <summary>Retrieve an <code>int</code>.</summary> + /// <remarks> + /// Retrieve an <code>int</code>. If the key does not exist or + /// cannot be converted to an <code>int</code>, the provided default + /// argument will be returned. + /// </remarks> + public static int GetInt(string key, int def) + { + string s = (string)_prp.GetProperty(key); + if (s != null) + { + try + { + def = Convert.ToInt32(s); + } + catch (FormatException nfe) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(nfe, _log); + } + } + } + return def; + } + + /// <summary>Retrieve an <code>int</code>.</summary> + /// <remarks>Retrieve an <code>int</code>. If the property is not found, <code>-1</code> is returned. + /// </remarks> + public static int GetInt(string key) + { + string s = (string)_prp.GetProperty(key); + int result = -1; + if (s != null) + { + try + { + result = Convert.ToInt32(s); + } + catch (FormatException nfe) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(nfe, _log); + } + } + } + return result; + } + + /// <summary>Retrieve a <code>long</code>.</summary> + /// <remarks> + /// Retrieve a <code>long</code>. If the key does not exist or + /// cannot be converted to a <code>long</code>, the provided default + /// argument will be returned. + /// </remarks> + public static long GetLong(string key, long def) + { + string s = (string)_prp.GetProperty(key); + if (s != null) + { + try + { + def = long.Parse(s); + } + catch (FormatException nfe) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(nfe, _log); + } + } + } + return def; + } + + /// <summary>Retrieve an <code>InetAddress</code>.</summary> + /// <remarks> + /// Retrieve an <code>InetAddress</code>. If the address is not + /// an IP address and cannot be resolved <code>null</code> will + /// be returned. + /// </remarks> + public static IPAddress GetInetAddress(string key, IPAddress def) + { + string addr = (string)_prp.GetProperty(key); + if (addr != null) + { + try + { + def = Extensions.GetAddressByName(addr); + } + catch (UnknownHostException uhe) + { + if (_log.Level > 0) + { + _log.WriteLine(addr); + Runtime.PrintStackTrace(uhe, _log); + } + } + } + return def; + } + + public static IPAddress GetLocalHost() + { + string addr = (string)_prp.GetProperty("jcifs.smb.client.laddr"); + if (addr != null) + { + try + { + return Extensions.GetAddressByName(addr); + } + catch (UnknownHostException uhe) + { + if (_log.Level > 0) + { + _log.WriteLine("Ignoring jcifs.smb.client.laddr address: " + addr); + Runtime.PrintStackTrace(uhe, _log); + } + } + } + return null; + } + + /// <summary>Retrieve a boolean value.</summary> + /// <remarks>Retrieve a boolean value. If the property is not found, the value of <code>def</code> is returned. + /// </remarks> + public static bool GetBoolean(string key, bool def) + { + string b = GetProperty(key); + if (b != null) + { + def = b.ToLower().Equals("true"); + } + return def; + } + + /// <summary> + /// Retrieve an array of <tt>InetAddress</tt> created from a property + /// value containting a <tt>delim</tt> separated list of hostnames and/or + /// ipaddresses. + /// </summary> + /// <remarks> + /// Retrieve an array of <tt>InetAddress</tt> created from a property + /// value containting a <tt>delim</tt> separated list of hostnames and/or + /// ipaddresses. + /// </remarks> + public static IPAddress[] GetInetAddressArray(string key, string delim, IPAddress + [] def) + { + string p = GetProperty(key); + if (p != null) + { + StringTokenizer tok = new StringTokenizer(p, delim); + int len = tok.CountTokens(); + IPAddress[] arr = new IPAddress[len]; + for (int i = 0; i < len; i++) + { + string addr = tok.NextToken(); + try + { + arr[i] = Extensions.GetAddressByName(addr); + } + catch (UnknownHostException uhe) + { + if (_log.Level > 0) + { + _log.WriteLine(addr); + Runtime.PrintStackTrace(uhe, _log); + } + return def; + } + } + return arr; + } + return def; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcBind.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcBind.cs new file mode 100644 index 000000000..1d8d13c08 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcBind.cs @@ -0,0 +1,102 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; +using SharpCifs.Util; + +namespace SharpCifs.Dcerpc +{ + public class DcerpcBind : DcerpcMessage + { + internal static readonly string[] ResultMessage = { "0", "DCERPC_BIND_ERR_ABSTRACT_SYNTAX_NOT_SUPPORTED" + , "DCERPC_BIND_ERR_PROPOSED_TRANSFER_SYNTAXES_NOT_SUPPORTED", "DCERPC_BIND_ERR_LOCAL_LIMIT_EXCEEDED" + }; + + internal static string GetResultMessage(int result) + { + return result < 4 ? ResultMessage[result] : "0x" + Hexdump.ToHexString(result, 4 + ); + } + + public override DcerpcException GetResult() + { + if (Result != 0) + { + return new DcerpcException(GetResultMessage(Result)); + } + return null; + } + + internal DcerpcBinding Binding; + + internal int MaxXmit; + + internal int MaxRecv; + + public DcerpcBind() + { + } + + internal DcerpcBind(DcerpcBinding binding, DcerpcHandle handle) + { + this.Binding = binding; + MaxXmit = handle.MaxXmit; + MaxRecv = handle.MaxRecv; + Ptype = 11; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + + public override int GetOpnum() + { + return 0; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_short(MaxXmit); + dst.Enc_ndr_short(MaxRecv); + dst.Enc_ndr_long(0); + dst.Enc_ndr_small(1); + dst.Enc_ndr_small(0); + dst.Enc_ndr_short(0); + dst.Enc_ndr_short(0); + dst.Enc_ndr_small(1); + dst.Enc_ndr_small(0); + Binding.Uuid.Encode(dst); + dst.Enc_ndr_short(Binding.Major); + dst.Enc_ndr_short(Binding.Minor); + DcerpcConstants.DcerpcUuidSyntaxNdr.Encode(dst); + dst.Enc_ndr_long(2); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + src.Dec_ndr_short(); + src.Dec_ndr_short(); + src.Dec_ndr_long(); + int n = src.Dec_ndr_short(); + src.Advance(n); + src.Align(4); + src.Dec_ndr_small(); + src.Align(4); + Result = src.Dec_ndr_short(); + src.Dec_ndr_short(); + src.Advance(20); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcBinding.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcBinding.cs new file mode 100644 index 000000000..234150664 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcBinding.cs @@ -0,0 +1,122 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Dcerpc.Msrpc; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Dcerpc +{ + public class DcerpcBinding + { + private static Hashtable _interfaces; + + static DcerpcBinding() + { + _interfaces = new Hashtable(); + _interfaces.Put("srvsvc", Srvsvc.GetSyntax()); + _interfaces.Put("lsarpc", Lsarpc.GetSyntax()); + _interfaces.Put("samr", Samr.GetSyntax()); + _interfaces.Put("netdfs", Netdfs.GetSyntax()); + } + + public static void AddInterface(string name, string syntax) + { + _interfaces.Put(name, syntax); + } + + internal string Proto; + + internal string Server; + + internal string Endpoint; + + internal Hashtable Options; + + internal Uuid Uuid; + + internal int Major; + + internal int Minor; + + internal DcerpcBinding(string proto, string server) + { + this.Proto = proto; + this.Server = server; + } + + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + internal virtual void SetOption(string key, object val) + { + if (key.Equals("endpoint")) + { + Endpoint = val.ToString().ToLower(); + if (Endpoint.StartsWith("\\pipe\\")) + { + string iface = (string)_interfaces.Get(Runtime.Substring(Endpoint, 6)); + if (iface != null) + { + int c; + int p; + c = iface.IndexOf(':'); + p = iface.IndexOf('.', c + 1); + Uuid = new Uuid(Runtime.Substring(iface, 0, c)); + Major = Convert.ToInt32(Runtime.Substring(iface, c + 1, p)); + Minor = Convert.ToInt32(Runtime.Substring(iface, p + 1)); + return; + } + } + throw new DcerpcException("Bad endpoint: " + Endpoint); + } + if (Options == null) + { + Options = new Hashtable(); + } + Options.Put(key, val); + } + + internal virtual object GetOption(string key) + { + if (key.Equals("endpoint")) + { + return Endpoint; + } + if (Options != null) + { + return Options.Get(key); + } + return null; + } + + public override string ToString() + { + /* string ret = proto + ":" + server + "[" + endpoint; + if (options != null) + { + Iterator iter = (Iterator) options.Keys.GetEnumerator(); + while (iter.HasNext()) + { + object key = iter.Next(); + object val = options.Get(key); + ret += "," + key + "=" + val; + } + } + ret += "]"; + return ret; */ + return null; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcConstants.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcConstants.cs new file mode 100644 index 000000000..5b69c5c2e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcConstants.cs @@ -0,0 +1,40 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc +{ + public static class DcerpcConstants + { + public static Uuid DcerpcUuidSyntaxNdr = new Uuid("8a885d04-1ceb-11c9-9fe8-08002b104860" + ); + + public static int DcerpcFirstFrag = unchecked(0x01); + + public static int DcerpcLastFrag = unchecked(0x02); + + public static int DcerpcPendingCancel = unchecked(0x04); + + public static int DcerpcReserved1 = unchecked(0x08); + + public static int DcerpcConcMpx = unchecked(0x10); + + public static int DcerpcDidNotExecute = unchecked(0x20); + + public static int DcerpcMaybe = unchecked(0x40); + + public static int DcerpcObjectUuid = unchecked(0x80); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcError.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcError.cs new file mode 100644 index 000000000..55c061065 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcError.cs @@ -0,0 +1,48 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc +{ + public static class DcerpcError + { + public static int DcerpcFaultOther = unchecked(0x00000001); + + public static int DcerpcFaultAccessDenied = unchecked(0x00000005); + + public static int DcerpcFaultCantPerform = unchecked(0x000006D8); + + public static int DcerpcFaultNdr = unchecked(0x000006F7); + + public static int DcerpcFaultInvalidTag = unchecked(0x1C000006); + + public static int DcerpcFaultContextMismatch = unchecked(0x1C00001A); + + public static int DcerpcFaultOpRngError = unchecked(0x1C010002); + + public static int DcerpcFaultUnkIf = unchecked(0x1C010003); + + public static int DcerpcFaultProtoError = unchecked(0x1c01000b); + + public static int[] DcerpcFaultCodes = { DcerpcFaultOther, DcerpcFaultAccessDenied + , DcerpcFaultCantPerform, DcerpcFaultNdr, DcerpcFaultInvalidTag, DcerpcFaultContextMismatch + , DcerpcFaultOpRngError, DcerpcFaultUnkIf, DcerpcFaultProtoError }; + + public static string[] DcerpcFaultMessages = { "DCERPC_FAULT_OTHER" + , "DCERPC_FAULT_ACCESS_DENIED", "DCERPC_FAULT_CANT_PERFORM", "DCERPC_FAULT_NDR", + "DCERPC_FAULT_INVALID_TAG", "DCERPC_FAULT_CONTEXT_MISMATCH", "DCERPC_FAULT_OP_RNG_ERROR" + , "DCERPC_FAULT_UNK_IF", "DCERPC_FAULT_PROTO_ERROR" }; + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcException.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcException.cs new file mode 100644 index 000000000..13c4f0d0c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcException.cs @@ -0,0 +1,93 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Dcerpc +{ + + public class DcerpcException : IOException + { + internal static string GetMessageByDcerpcError(int errcode) + { + int min = 0; + int max = DcerpcError.DcerpcFaultCodes.Length; + while (max >= min) + { + int mid = (min + max) / 2; + if (errcode > DcerpcError.DcerpcFaultCodes[mid]) + { + min = mid + 1; + } + else + { + if (errcode < DcerpcError.DcerpcFaultCodes[mid]) + { + max = mid - 1; + } + else + { + return DcerpcError.DcerpcFaultMessages[mid]; + } + } + } + return "0x" + Hexdump.ToHexString(errcode, 8); + } + + private int _error; + + private Exception _rootCause; + + internal DcerpcException(int error) : base(GetMessageByDcerpcError(error)) + { + this._error = error; + } + + public DcerpcException(string msg) : base(msg) + { + } + + public DcerpcException(string msg, Exception rootCause) : base(msg) + { + this._rootCause = rootCause; + } + + public virtual int GetErrorCode() + { + return _error; + } + + public virtual Exception GetRootCause() + { + return _rootCause; + } + + public override string ToString() + { + if (_rootCause != null) + { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Runtime.PrintStackTrace(_rootCause, pw); + return base.ToString() + "\n" + sw; + } + return base.ToString(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcHandle.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcHandle.cs new file mode 100644 index 000000000..786b0ac12 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcHandle.cs @@ -0,0 +1,332 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Dcerpc.Ndr; +using SharpCifs.Smb; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Dcerpc +{ + public abstract class DcerpcHandle + { + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + protected internal static DcerpcBinding ParseBinding(string str) + { + int state; + int mark; + int si; + char[] arr = str.ToCharArray(); + string proto = null; + string key = null; + DcerpcBinding binding = null; + state = mark = si = 0; + do + { + char ch = arr[si]; + switch (state) + { + case 0: + { + if (ch == ':') + { + proto = Runtime.Substring(str, mark, si); + mark = si + 1; + state = 1; + } + break; + } + + case 1: + { + if (ch == '\\') + { + mark = si + 1; + break; + } + state = 2; + goto case 2; + } + + case 2: + { + if (ch == '[') + { + string server = Runtime.Substring(str, mark, si).Trim(); + if (server.Length == 0) + { + server = "127.0.0.1"; + } + binding = new DcerpcBinding(proto, Runtime.Substring(str, mark, si)); + mark = si + 1; + state = 5; + } + break; + } + + case 5: + { + if (ch == '=') + { + key = Runtime.Substring(str, mark, si).Trim(); + mark = si + 1; + } + else + { + if (ch == ',' || ch == ']') + { + string val = Runtime.Substring(str, mark, si).Trim(); + if (key == null) + { + key = "endpoint"; + } + binding.SetOption(key, val); + key = null; + } + } + break; + } + + default: + { + si = arr.Length; + break; + } + } + si++; + } + while (si < arr.Length); + if (binding == null || binding.Endpoint == null) + { + throw new DcerpcException("Invalid binding URL: " + str); + } + return binding; + } + + protected internal DcerpcBinding Binding; + + protected internal int MaxXmit = 4280; + + protected internal int MaxRecv; + + protected internal int State; + + protected internal IDcerpcSecurityProvider SecurityProvider; + + private static int _callId = 1; + + /// <exception cref="UnknownHostException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + public static DcerpcHandle GetHandle(string url, NtlmPasswordAuthentication auth) + { + if (url.StartsWith("ncacn_np:")) + { + return new DcerpcPipeHandle(url, auth); + } + throw new DcerpcException("DCERPC transport not supported: " + url); + } + + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + /// <exception cref="System.IO.IOException"></exception> + public virtual void Bind() + { + lock (this) + { + try + { + State = 1; + DcerpcMessage bind = new DcerpcBind(Binding, this); + Sendrecv(bind); + } + catch (IOException ioe) + { + State = 0; + throw; + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + /// <exception cref="System.IO.IOException"></exception> + public virtual void Sendrecv(DcerpcMessage msg) + { + byte[] stub; + byte[] frag; + NdrBuffer buf; + NdrBuffer fbuf; + bool isLast; + bool isDirect; + DcerpcException de; + if (State == 0) + { + Bind(); + } + isDirect = true; + stub = BufferCache.GetBuffer(); + try + { + int off; + int tot; + int n; + buf = new NdrBuffer(stub, 0); + msg.Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + msg.CallId = _callId++; + msg.Encode(buf); + if (SecurityProvider != null) + { + buf.SetIndex(0); + SecurityProvider.Wrap(buf); + } + tot = buf.GetLength() - 24; + off = 0; + while (off < tot) + { + n = tot - off; + if ((24 + n) > MaxXmit) + { + msg.Flags &= ~DcerpcConstants.DcerpcLastFrag; + n = MaxXmit - 24; + } + else + { + msg.Flags |= DcerpcConstants.DcerpcLastFrag; + isDirect = false; + msg.AllocHint = n; + } + msg.Length = 24 + n; + if (off > 0) + { + msg.Flags &= ~DcerpcConstants.DcerpcFirstFrag; + } + if ((msg.Flags & (DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag)) != (DcerpcConstants.DcerpcFirstFrag | + DcerpcConstants.DcerpcLastFrag)) + { + buf.Start = off; + buf.Reset(); + msg.Encode_header(buf); + buf.Enc_ndr_long(msg.AllocHint); + buf.Enc_ndr_short(0); + buf.Enc_ndr_short(msg.GetOpnum()); + } + DoSendFragment(stub, off, msg.Length, isDirect); + off += n; + } + DoReceiveFragment(stub, isDirect); + buf.Reset(); + buf.SetIndex(8); + buf.SetLength(buf.Dec_ndr_short()); + if (SecurityProvider != null) + { + SecurityProvider.Unwrap(buf); + } + buf.SetIndex(0); + msg.Decode_header(buf); + off = 24; + if (msg.Ptype == 2 && msg.IsFlagSet(DcerpcConstants.DcerpcLastFrag) == false) + { + off = msg.Length; + } + frag = null; + fbuf = null; + while (msg.IsFlagSet(DcerpcConstants.DcerpcLastFrag) == false) + { + int stubFragLen; + if (frag == null) + { + frag = new byte[MaxRecv]; + fbuf = new NdrBuffer(frag, 0); + } + DoReceiveFragment(frag, isDirect); + fbuf.Reset(); + fbuf.SetIndex(8); + fbuf.SetLength(fbuf.Dec_ndr_short()); + if (SecurityProvider != null) + { + SecurityProvider.Unwrap(fbuf); + } + fbuf.Reset(); + msg.Decode_header(fbuf); + stubFragLen = msg.Length - 24; + if ((off + stubFragLen) > stub.Length) + { + // shouldn't happen if alloc_hint is correct or greater + byte[] tmp = new byte[off + stubFragLen]; + Array.Copy(stub, 0, tmp, 0, off); + stub = tmp; + } + Array.Copy(frag, 24, stub, off, stubFragLen); + off += stubFragLen; + } + buf = new NdrBuffer(stub, 0); + msg.Decode(buf); + } + finally + { + BufferCache.ReleaseBuffer(stub); + } + if ((de = msg.GetResult()) != null) + { + throw de; + } + } + + public virtual void SetDcerpcSecurityProvider(IDcerpcSecurityProvider securityProvider + ) + { + this.SecurityProvider = securityProvider; + } + + public virtual string GetServer() + { + if (this is DcerpcPipeHandle) + { + return ((DcerpcPipeHandle)this).Pipe.GetServer(); + } + return null; + } + + public virtual Principal GetPrincipal() + { + if (this is DcerpcPipeHandle) + { + return ((DcerpcPipeHandle)this).Pipe.GetPrincipal(); + } + return null; + } + + public override string ToString() + { + return Binding.ToString(); + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract void DoSendFragment(byte[] buf, int off, int length, + bool isDirect); + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract void DoReceiveFragment(byte[] buf, bool isDirect); + + /// <exception cref="System.IO.IOException"></exception> + public abstract void Close(); + + public DcerpcHandle() + { + MaxRecv = MaxXmit; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcMessage.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcMessage.cs new file mode 100644 index 000000000..543dd72dd --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcMessage.cs @@ -0,0 +1,150 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc +{ + public abstract class DcerpcMessage : NdrObject + { + protected internal int Ptype = -1; + + protected internal int Flags; + + protected internal int Length; + + protected internal int CallId; + + protected internal int AllocHint; + + protected internal int Result; + + public virtual bool IsFlagSet(int flag) + { + return (Flags & flag) == flag; + } + + public virtual void UnsetFlag(int flag) + { + Flags &= ~flag; + } + + public virtual void SetFlag(int flag) + { + Flags |= flag; + } + + public virtual DcerpcException GetResult() + { + if (Result != 0) + { + return new DcerpcException(Result); + } + return null; + } + + internal virtual void Encode_header(NdrBuffer buf) + { + buf.Enc_ndr_small(5); + buf.Enc_ndr_small(0); + buf.Enc_ndr_small(Ptype); + buf.Enc_ndr_small(Flags); + buf.Enc_ndr_long(unchecked(0x00000010)); + buf.Enc_ndr_short(Length); + buf.Enc_ndr_short(0); + buf.Enc_ndr_long(CallId); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + internal virtual void Decode_header(NdrBuffer buf) + { + if (buf.Dec_ndr_small() != 5 || buf.Dec_ndr_small() != 0) + { + throw new NdrException("DCERPC version not supported"); + } + Ptype = buf.Dec_ndr_small(); + Flags = buf.Dec_ndr_small(); + if (buf.Dec_ndr_long() != unchecked(0x00000010)) + { + throw new NdrException("Data representation not supported"); + } + Length = buf.Dec_ndr_short(); + if (buf.Dec_ndr_short() != 0) + { + throw new NdrException("DCERPC authentication not supported"); + } + CallId = buf.Dec_ndr_long(); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer buf) + { + int start = buf.GetIndex(); + int allocHintIndex = 0; + buf.Advance(16); + if (Ptype == 0) + { + allocHintIndex = buf.GetIndex(); + buf.Enc_ndr_long(0); + buf.Enc_ndr_short(0); + buf.Enc_ndr_short(GetOpnum()); + } + Encode_in(buf); + Length = buf.GetIndex() - start; + if (Ptype == 0) + { + buf.SetIndex(allocHintIndex); + AllocHint = Length - allocHintIndex; + buf.Enc_ndr_long(AllocHint); + } + buf.SetIndex(start); + Encode_header(buf); + buf.SetIndex(start + Length); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer buf) + { + Decode_header(buf); + if (Ptype != 12 && Ptype != 2 && Ptype != 3 && Ptype != 13) + { + throw new NdrException("Unexpected ptype: " + Ptype); + } + if (Ptype == 2 || Ptype == 3) + { + AllocHint = buf.Dec_ndr_long(); + buf.Dec_ndr_short(); + buf.Dec_ndr_short(); + } + if (Ptype == 3 || Ptype == 13) + { + Result = buf.Dec_ndr_long(); + } + else + { + Decode_out(buf); + } + } + + public abstract int GetOpnum(); + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public abstract void Encode_in(NdrBuffer dst); + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public abstract void Decode_out(NdrBuffer src); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcPipeHandle.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcPipeHandle.cs new file mode 100644 index 000000000..0399578cd --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcPipeHandle.cs @@ -0,0 +1,135 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Smb; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Dcerpc +{ + public class DcerpcPipeHandle : DcerpcHandle + { + internal SmbNamedPipe Pipe; + + internal SmbFileInputStream In; + + internal SmbFileOutputStream Out; + + internal bool IsStart = true; + + /// <exception cref="UnknownHostException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + public DcerpcPipeHandle(string url, NtlmPasswordAuthentication auth) + { + Binding = ParseBinding(url); + url = "smb://" + Binding.Server + "/IPC$/" + Runtime.Substring(Binding.Endpoint + , 6); + string @params = string.Empty; + string server; + string address; + server = (string)Binding.GetOption("server"); + if (server != null) + { + @params += "&server=" + server; + } + address = (string)Binding.GetOption("address"); + if (server != null) + { + @params += "&address=" + address; + } + if (@params.Length > 0) + { + url += "?" + Runtime.Substring(@params, 1); + } + Pipe = new SmbNamedPipe(url, (unchecked(0x2019F) << 16) | SmbNamedPipe.PipeTypeRdwr + | SmbNamedPipe.PipeTypeDceTransact, auth); + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void DoSendFragment(byte[] buf, int off, int length, + bool isDirect) + { + if (Out != null && Out.IsOpen() == false) + { + throw new IOException("DCERPC pipe is no longer open"); + } + if (In == null) + { + In = (SmbFileInputStream)Pipe.GetNamedPipeInputStream(); + } + if (Out == null) + { + Out = (SmbFileOutputStream)Pipe.GetNamedPipeOutputStream(); + } + if (isDirect) + { + Out.WriteDirect(buf, off, length, 1); + return; + } + Out.Write(buf, off, length); + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void DoReceiveFragment(byte[] buf, bool isDirect) + { + int off; + int flags; + int length; + if (buf.Length < MaxRecv) + { + throw new ArgumentException("buffer too small"); + } + if (IsStart && !isDirect) + { + // start of new frag, do trans + off = In.Read(buf, 0, 1024); + } + else + { + off = In.ReadDirect(buf, 0, buf.Length); + } + if (buf[0] != 5 && buf[1] != 0) + { + throw new IOException("Unexpected DCERPC PDU header"); + } + flags = buf[3] & unchecked(0xFF); + // next read is start of new frag + IsStart = (flags & DcerpcConstants.DcerpcLastFrag) == DcerpcConstants.DcerpcLastFrag; + length = Encdec.Dec_uint16le(buf, 8); + if (length > MaxRecv) + { + throw new IOException("Unexpected fragment length: " + length); + } + while (off < length) + { + off += In.ReadDirect(buf, off, length - off); + } + } + + /// <exception cref="System.IO.IOException"></exception> + public override void Close() + { + State = 0; + if (Out != null) + { + Out.Close(); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcSecurityProvider.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcSecurityProvider.cs new file mode 100644 index 000000000..cc46902f1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/DcerpcSecurityProvider.cs @@ -0,0 +1,29 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc +{ + public interface IDcerpcSecurityProvider + { + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + void Wrap(NdrBuffer outgoing); + + /// <exception cref="SharpCifs.Dcerpc.DcerpcException"></exception> + void Unwrap(NdrBuffer incoming); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/LsaPolicyHandle.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/LsaPolicyHandle.cs new file mode 100644 index 000000000..03964fcc7 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/LsaPolicyHandle.cs @@ -0,0 +1,43 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class LsaPolicyHandle : Rpc.PolicyHandle + { + /// <exception cref="System.IO.IOException"></exception> + public LsaPolicyHandle(DcerpcHandle handle, string server, int access) + { + if (server == null) + { + server = "\\\\"; + } + MsrpcLsarOpenPolicy2 rpc = new MsrpcLsarOpenPolicy2(server, access, this); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual void Close() + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/LsarSidArrayX.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/LsarSidArrayX.cs new file mode 100644 index 000000000..ef09bb16e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/LsarSidArrayX.cs @@ -0,0 +1,34 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + internal class LsarSidArrayX : Lsarpc.LsarSidArray + { + internal LsarSidArrayX(Sid[] sids) + { + NumSids = sids.Length; + this.Sids = new Lsarpc.LsarSidPtr[sids.Length]; + for (int si = 0; si < sids.Length; si++) + { + this.Sids[si] = new Lsarpc.LsarSidPtr(); + this.Sids[si].Sid = sids[si]; + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Lsarpc.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Lsarpc.cs new file mode 100644 index 000000000..1ae85c473 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Lsarpc.cs @@ -0,0 +1,1161 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class Lsarpc + { + public static string GetSyntax() + { + return "12345778-1234-abcd-ef00-0123456789ab:0.0"; + } + + public class LsarQosInfo : NdrObject + { + public int Length; + + public short ImpersonationLevel; + + public byte ContextMode; + + public byte EffectiveOnly; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Length); + dst.Enc_ndr_short(ImpersonationLevel); + dst.Enc_ndr_small(ContextMode); + dst.Enc_ndr_small(EffectiveOnly); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Length = src.Dec_ndr_long(); + ImpersonationLevel = (short)src.Dec_ndr_short(); + ContextMode = unchecked((byte)src.Dec_ndr_small()); + EffectiveOnly = unchecked((byte)src.Dec_ndr_small()); + } + } + + public class LsarObjectAttributes : NdrObject + { + public int Length; + + public NdrSmall RootDirectory; + + public Rpc.Unicode_string ObjectName; + + public int Attributes; + + public int SecurityDescriptor; + + public LsarQosInfo SecurityQualityOfService; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Length); + dst.Enc_ndr_referent(RootDirectory, 1); + dst.Enc_ndr_referent(ObjectName, 1); + dst.Enc_ndr_long(Attributes); + dst.Enc_ndr_long(SecurityDescriptor); + dst.Enc_ndr_referent(SecurityQualityOfService, 1); + if (RootDirectory != null) + { + dst = dst.Deferred; + RootDirectory.Encode(dst); + } + if (ObjectName != null) + { + dst = dst.Deferred; + ObjectName.Encode(dst); + } + if (SecurityQualityOfService != null) + { + dst = dst.Deferred; + SecurityQualityOfService.Encode(dst); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Length = src.Dec_ndr_long(); + int rootDirectoryp = src.Dec_ndr_long(); + int objectNamep = src.Dec_ndr_long(); + Attributes = src.Dec_ndr_long(); + SecurityDescriptor = src.Dec_ndr_long(); + int securityQualityOfServicep = src.Dec_ndr_long(); + if (rootDirectoryp != 0) + { + src = src.Deferred; + RootDirectory.Decode(src); + } + if (objectNamep != 0) + { + if (ObjectName == null) + { + ObjectName = new Rpc.Unicode_string(); + } + src = src.Deferred; + ObjectName.Decode(src); + } + if (securityQualityOfServicep != 0) + { + if (SecurityQualityOfService == null) + { + SecurityQualityOfService = new LsarQosInfo(); + } + src = src.Deferred; + SecurityQualityOfService.Decode(src); + } + } + } + + public class LsarDomainInfo : NdrObject + { + public Rpc.Unicode_string Name; + + public Rpc.SidT Sid; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_short(Name.Length); + dst.Enc_ndr_short(Name.MaximumLength); + dst.Enc_ndr_referent(Name.Buffer, 1); + dst.Enc_ndr_referent(Sid, 1); + if (Name.Buffer != null) + { + dst = dst.Deferred; + int nameBufferl = Name.Length / 2; + int nameBuffers = Name.MaximumLength / 2; + dst.Enc_ndr_long(nameBuffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(nameBufferl); + int nameBufferi = dst.Index; + dst.Advance(2 * nameBufferl); + dst = dst.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + dst.Enc_ndr_short(Name.Buffer[i]); + } + } + if (Sid != null) + { + dst = dst.Deferred; + Sid.Encode(dst); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + src.Align(4); + if (Name == null) + { + Name = new Rpc.Unicode_string(); + } + Name.Length = (short)src.Dec_ndr_short(); + Name.MaximumLength = (short)src.Dec_ndr_short(); + int nameBufferp = src.Dec_ndr_long(); + int sidp = src.Dec_ndr_long(); + if (nameBufferp != 0) + { + src = src.Deferred; + int nameBuffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int nameBufferl = src.Dec_ndr_long(); + int nameBufferi = src.Index; + src.Advance(2 * nameBufferl); + if (Name.Buffer == null) + { + if (nameBuffers < 0 || nameBuffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Name.Buffer = new short[nameBuffers]; + } + src = src.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + Name.Buffer[i] = (short)src.Dec_ndr_short(); + } + } + if (sidp != 0) + { + if (Sid == null) + { + Sid = new Rpc.SidT(); + } + src = src.Deferred; + Sid.Decode(src); + } + } + } + + public class LsarDnsDomainInfo : NdrObject + { + public Rpc.Unicode_string Name; + + public Rpc.Unicode_string DnsDomain; + + public Rpc.Unicode_string DnsForest; + + public Rpc.UuidT DomainGuid; + + public Rpc.SidT Sid; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_short(Name.Length); + dst.Enc_ndr_short(Name.MaximumLength); + dst.Enc_ndr_referent(Name.Buffer, 1); + dst.Enc_ndr_short(DnsDomain.Length); + dst.Enc_ndr_short(DnsDomain.MaximumLength); + dst.Enc_ndr_referent(DnsDomain.Buffer, 1); + dst.Enc_ndr_short(DnsForest.Length); + dst.Enc_ndr_short(DnsForest.MaximumLength); + dst.Enc_ndr_referent(DnsForest.Buffer, 1); + dst.Enc_ndr_long(DomainGuid.TimeLow); + dst.Enc_ndr_short(DomainGuid.TimeMid); + dst.Enc_ndr_short(DomainGuid.TimeHiAndVersion); + dst.Enc_ndr_small(DomainGuid.ClockSeqHiAndReserved); + dst.Enc_ndr_small(DomainGuid.ClockSeqLow); + int domainGuidNodes = 6; + int domainGuidNodei = dst.Index; + dst.Advance(1 * domainGuidNodes); + dst.Enc_ndr_referent(Sid, 1); + if (Name.Buffer != null) + { + dst = dst.Deferred; + int nameBufferl = Name.Length / 2; + int nameBuffers = Name.MaximumLength / 2; + dst.Enc_ndr_long(nameBuffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(nameBufferl); + int nameBufferi = dst.Index; + dst.Advance(2 * nameBufferl); + dst = dst.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + dst.Enc_ndr_short(Name.Buffer[i]); + } + } + if (DnsDomain.Buffer != null) + { + dst = dst.Deferred; + int dnsDomainBufferl = DnsDomain.Length / 2; + int dnsDomainBuffers = DnsDomain.MaximumLength / 2; + dst.Enc_ndr_long(dnsDomainBuffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(dnsDomainBufferl); + int dnsDomainBufferi = dst.Index; + dst.Advance(2 * dnsDomainBufferl); + dst = dst.Derive(dnsDomainBufferi); + for (int i = 0; i < dnsDomainBufferl; i++) + { + dst.Enc_ndr_short(DnsDomain.Buffer[i]); + } + } + if (DnsForest.Buffer != null) + { + dst = dst.Deferred; + int dnsForestBufferl = DnsForest.Length / 2; + int dnsForestBuffers = DnsForest.MaximumLength / 2; + dst.Enc_ndr_long(dnsForestBuffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(dnsForestBufferl); + int dnsForestBufferi = dst.Index; + dst.Advance(2 * dnsForestBufferl); + dst = dst.Derive(dnsForestBufferi); + for (int i = 0; i < dnsForestBufferl; i++) + { + dst.Enc_ndr_short(DnsForest.Buffer[i]); + } + } + dst = dst.Derive(domainGuidNodei); + for (int i1 = 0; i1 < domainGuidNodes; i1++) + { + dst.Enc_ndr_small(DomainGuid.Node[i1]); + } + if (Sid != null) + { + dst = dst.Deferred; + Sid.Encode(dst); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + src.Align(4); + if (Name == null) + { + Name = new Rpc.Unicode_string(); + } + Name.Length = (short)src.Dec_ndr_short(); + Name.MaximumLength = (short)src.Dec_ndr_short(); + int nameBufferp = src.Dec_ndr_long(); + src.Align(4); + if (DnsDomain == null) + { + DnsDomain = new Rpc.Unicode_string(); + } + DnsDomain.Length = (short)src.Dec_ndr_short(); + DnsDomain.MaximumLength = (short)src.Dec_ndr_short(); + int dnsDomainBufferp = src.Dec_ndr_long(); + src.Align(4); + if (DnsForest == null) + { + DnsForest = new Rpc.Unicode_string(); + } + DnsForest.Length = (short)src.Dec_ndr_short(); + DnsForest.MaximumLength = (short)src.Dec_ndr_short(); + int dnsForestBufferp = src.Dec_ndr_long(); + src.Align(4); + if (DomainGuid == null) + { + DomainGuid = new Rpc.UuidT(); + } + DomainGuid.TimeLow = src.Dec_ndr_long(); + DomainGuid.TimeMid = (short)src.Dec_ndr_short(); + DomainGuid.TimeHiAndVersion = (short)src.Dec_ndr_short(); + DomainGuid.ClockSeqHiAndReserved = unchecked((byte)src.Dec_ndr_small()); + DomainGuid.ClockSeqLow = unchecked((byte)src.Dec_ndr_small()); + int domainGuidNodes = 6; + int domainGuidNodei = src.Index; + src.Advance(1 * domainGuidNodes); + int sidp = src.Dec_ndr_long(); + if (nameBufferp != 0) + { + src = src.Deferred; + int nameBuffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int nameBufferl = src.Dec_ndr_long(); + int nameBufferi = src.Index; + src.Advance(2 * nameBufferl); + if (Name.Buffer == null) + { + if (nameBuffers < 0 || nameBuffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Name.Buffer = new short[nameBuffers]; + } + src = src.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + Name.Buffer[i] = (short)src.Dec_ndr_short(); + } + } + if (dnsDomainBufferp != 0) + { + src = src.Deferred; + int dnsDomainBuffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int dnsDomainBufferl = src.Dec_ndr_long(); + int dnsDomainBufferi = src.Index; + src.Advance(2 * dnsDomainBufferl); + if (DnsDomain.Buffer == null) + { + if (dnsDomainBuffers < 0 || dnsDomainBuffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + DnsDomain.Buffer = new short[dnsDomainBuffers]; + } + src = src.Derive(dnsDomainBufferi); + for (int i = 0; i < dnsDomainBufferl; i++) + { + DnsDomain.Buffer[i] = (short)src.Dec_ndr_short(); + } + } + if (dnsForestBufferp != 0) + { + src = src.Deferred; + int dnsForestBuffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int dnsForestBufferl = src.Dec_ndr_long(); + int dnsForestBufferi = src.Index; + src.Advance(2 * dnsForestBufferl); + if (DnsForest.Buffer == null) + { + if (dnsForestBuffers < 0 || dnsForestBuffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + DnsForest.Buffer = new short[dnsForestBuffers]; + } + src = src.Derive(dnsForestBufferi); + for (int i = 0; i < dnsForestBufferl; i++) + { + DnsForest.Buffer[i] = (short)src.Dec_ndr_short(); + } + } + if (DomainGuid.Node == null) + { + if (domainGuidNodes < 0 || domainGuidNodes > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + DomainGuid.Node = new byte[domainGuidNodes]; + } + src = src.Derive(domainGuidNodei); + for (int i1 = 0; i1 < domainGuidNodes; i1++) + { + DomainGuid.Node[i1] = unchecked((byte)src.Dec_ndr_small()); + } + if (sidp != 0) + { + if (Sid == null) + { + Sid = new Rpc.SidT(); + } + src = src.Deferred; + Sid.Decode(src); + } + } + } + + public const int PolicyInfoAuditEvents = 2; + + public const int PolicyInfoPrimaryDomain = 3; + + public const int PolicyInfoAccountDomain = 5; + + public const int PolicyInfoServerRole = 6; + + public const int PolicyInfoModification = 9; + + public const int PolicyInfoDnsDomain = 12; + + public class LsarSidPtr : NdrObject + { + public Rpc.SidT Sid; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_referent(Sid, 1); + if (Sid != null) + { + dst = dst.Deferred; + Sid.Encode(dst); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int sidp = src.Dec_ndr_long(); + if (sidp != 0) + { + if (Sid == null) + { + Sid = new Rpc.SidT(); + } + src = src.Deferred; + Sid.Decode(src); + } + } + } + + public class LsarSidArray : NdrObject + { + public int NumSids; + + public LsarSidPtr[] Sids; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(NumSids); + dst.Enc_ndr_referent(Sids, 1); + if (Sids != null) + { + dst = dst.Deferred; + int sidss = NumSids; + dst.Enc_ndr_long(sidss); + int sidsi = dst.Index; + dst.Advance(4 * sidss); + dst = dst.Derive(sidsi); + for (int i = 0; i < sidss; i++) + { + Sids[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + NumSids = src.Dec_ndr_long(); + int sidsp = src.Dec_ndr_long(); + if (sidsp != 0) + { + src = src.Deferred; + int sidss = src.Dec_ndr_long(); + int sidsi = src.Index; + src.Advance(4 * sidss); + if (Sids == null) + { + if (sidss < 0 || sidss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Sids = new LsarSidPtr[sidss]; + } + src = src.Derive(sidsi); + for (int i = 0; i < sidss; i++) + { + if (Sids[i] == null) + { + Sids[i] = new LsarSidPtr(); + } + Sids[i].Decode(src); + } + } + } + } + + public const int SidNameUseNone = 0; + + public const int SidNameUser = 1; + + public const int SidNameDomGrp = 2; + + public const int SidNameDomain = 3; + + public const int SidNameAlias = 4; + + public const int SidNameWknGrp = 5; + + public const int SidNameDeleted = 6; + + public const int SidNameInvalid = 7; + + public const int SidNameUnknown = 8; + + public class LsarTranslatedSid : NdrObject + { + public int SidType; + + public int Rid; + + public int SidIndex; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_short(SidType); + dst.Enc_ndr_long(Rid); + dst.Enc_ndr_long(SidIndex); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + SidType = src.Dec_ndr_short(); + Rid = src.Dec_ndr_long(); + SidIndex = src.Dec_ndr_long(); + } + } + + public class LsarTransSidArray : NdrObject + { + public int Count; + + public LsarTranslatedSid[] Sids; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Sids, 1); + if (Sids != null) + { + dst = dst.Deferred; + int sidss = Count; + dst.Enc_ndr_long(sidss); + int sidsi = dst.Index; + dst.Advance(12 * sidss); + dst = dst.Derive(sidsi); + for (int i = 0; i < sidss; i++) + { + Sids[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int sidsp = src.Dec_ndr_long(); + if (sidsp != 0) + { + src = src.Deferred; + int sidss = src.Dec_ndr_long(); + int sidsi = src.Index; + src.Advance(12 * sidss); + if (Sids == null) + { + if (sidss < 0 || sidss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Sids = new LsarTranslatedSid[sidss]; + } + src = src.Derive(sidsi); + for (int i = 0; i < sidss; i++) + { + if (Sids[i] == null) + { + Sids[i] = new LsarTranslatedSid(); + } + Sids[i].Decode(src); + } + } + } + } + + public class LsarTrustInformation : NdrObject + { + public Rpc.Unicode_string Name; + + public Rpc.SidT Sid; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_short(Name.Length); + dst.Enc_ndr_short(Name.MaximumLength); + dst.Enc_ndr_referent(Name.Buffer, 1); + dst.Enc_ndr_referent(Sid, 1); + if (Name.Buffer != null) + { + dst = dst.Deferred; + int nameBufferl = Name.Length / 2; + int nameBuffers = Name.MaximumLength / 2; + dst.Enc_ndr_long(nameBuffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(nameBufferl); + int nameBufferi = dst.Index; + dst.Advance(2 * nameBufferl); + dst = dst.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + dst.Enc_ndr_short(Name.Buffer[i]); + } + } + if (Sid != null) + { + dst = dst.Deferred; + Sid.Encode(dst); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + src.Align(4); + if (Name == null) + { + Name = new Rpc.Unicode_string(); + } + Name.Length = (short)src.Dec_ndr_short(); + Name.MaximumLength = (short)src.Dec_ndr_short(); + int nameBufferp = src.Dec_ndr_long(); + int sidp = src.Dec_ndr_long(); + if (nameBufferp != 0) + { + src = src.Deferred; + int nameBuffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int nameBufferl = src.Dec_ndr_long(); + int nameBufferi = src.Index; + src.Advance(2 * nameBufferl); + if (Name.Buffer == null) + { + if (nameBuffers < 0 || nameBuffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Name.Buffer = new short[nameBuffers]; + } + src = src.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + Name.Buffer[i] = (short)src.Dec_ndr_short(); + } + } + if (sidp != 0) + { + if (Sid == null) + { + Sid = new Rpc.SidT(); + } + src = src.Deferred; + Sid.Decode(src); + } + } + } + + public class LsarRefDomainList : NdrObject + { + public int Count; + + public LsarTrustInformation[] Domains; + + public int MaxCount; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Domains, 1); + dst.Enc_ndr_long(MaxCount); + if (Domains != null) + { + dst = dst.Deferred; + int domainss = Count; + dst.Enc_ndr_long(domainss); + int domainsi = dst.Index; + dst.Advance(12 * domainss); + dst = dst.Derive(domainsi); + for (int i = 0; i < domainss; i++) + { + Domains[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int domainsp = src.Dec_ndr_long(); + MaxCount = src.Dec_ndr_long(); + if (domainsp != 0) + { + src = src.Deferred; + int domainss = src.Dec_ndr_long(); + int domainsi = src.Index; + src.Advance(12 * domainss); + if (Domains == null) + { + if (domainss < 0 || domainss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Domains = new LsarTrustInformation[domainss]; + } + src = src.Derive(domainsi); + for (int i = 0; i < domainss; i++) + { + if (Domains[i] == null) + { + Domains[i] = new LsarTrustInformation(); + } + Domains[i].Decode(src); + } + } + } + } + + public class LsarTranslatedName : NdrObject + { + public short SidType; + + public Rpc.Unicode_string Name; + + public int SidIndex; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_short(SidType); + dst.Enc_ndr_short(Name.Length); + dst.Enc_ndr_short(Name.MaximumLength); + dst.Enc_ndr_referent(Name.Buffer, 1); + dst.Enc_ndr_long(SidIndex); + if (Name.Buffer != null) + { + dst = dst.Deferred; + int nameBufferl = Name.Length / 2; + int nameBuffers = Name.MaximumLength / 2; + dst.Enc_ndr_long(nameBuffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(nameBufferl); + int nameBufferi = dst.Index; + dst.Advance(2 * nameBufferl); + dst = dst.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + dst.Enc_ndr_short(Name.Buffer[i]); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + SidType = (short)src.Dec_ndr_short(); + src.Align(4); + if (Name == null) + { + Name = new Rpc.Unicode_string(); + } + Name.Length = (short)src.Dec_ndr_short(); + Name.MaximumLength = (short)src.Dec_ndr_short(); + int nameBufferp = src.Dec_ndr_long(); + SidIndex = src.Dec_ndr_long(); + if (nameBufferp != 0) + { + src = src.Deferred; + int nameBuffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int nameBufferl = src.Dec_ndr_long(); + int nameBufferi = src.Index; + src.Advance(2 * nameBufferl); + if (Name.Buffer == null) + { + if (nameBuffers < 0 || nameBuffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Name.Buffer = new short[nameBuffers]; + } + src = src.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + Name.Buffer[i] = (short)src.Dec_ndr_short(); + } + } + } + } + + public class LsarTransNameArray : NdrObject + { + public int Count; + + public LsarTranslatedName[] Names; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Names, 1); + if (Names != null) + { + dst = dst.Deferred; + int namess = Count; + dst.Enc_ndr_long(namess); + int namesi = dst.Index; + dst.Advance(16 * namess); + dst = dst.Derive(namesi); + for (int i = 0; i < namess; i++) + { + Names[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int namesp = src.Dec_ndr_long(); + if (namesp != 0) + { + src = src.Deferred; + int namess = src.Dec_ndr_long(); + int namesi = src.Index; + src.Advance(16 * namess); + if (Names == null) + { + if (namess < 0 || namess > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Names = new LsarTranslatedName[namess]; + } + src = src.Derive(namesi); + for (int i = 0; i < namess; i++) + { + if (Names[i] == null) + { + Names[i] = new LsarTranslatedName(); + } + Names[i].Decode(src); + } + } + } + } + + public class LsarClose : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x00); + } + + public int Retval; + + public Rpc.PolicyHandle Handle; + + public LsarClose(Rpc.PolicyHandle handle) + { + this.Handle = handle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + Handle.Encode(dst); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + Handle.Decode(src); + Retval = src.Dec_ndr_long(); + } + } + + public class LsarQueryInformationPolicy : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x07); + } + + public int Retval; + + public Rpc.PolicyHandle Handle; + + public short Level; + + public NdrObject Info; + + public LsarQueryInformationPolicy(Rpc.PolicyHandle handle, short level, NdrObject + info) + { + this.Handle = handle; + this.Level = level; + this.Info = info; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + Handle.Encode(dst); + dst.Enc_ndr_short(Level); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + int infop = src.Dec_ndr_long(); + if (infop != 0) + { + src.Dec_ndr_short(); + Info.Decode(src); + } + Retval = src.Dec_ndr_long(); + } + } + + public class LsarLookupSids : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x0f); + } + + public int Retval; + + public Rpc.PolicyHandle Handle; + + public LsarSidArray Sids; + + public LsarRefDomainList Domains; + + public LsarTransNameArray Names; + + public short Level; + + public int Count; + + public LsarLookupSids(Rpc.PolicyHandle handle, LsarSidArray sids, LsarRefDomainList + domains, LsarTransNameArray names, short level, int count) + { + this.Handle = handle; + this.Sids = sids; + this.Domains = domains; + this.Names = names; + this.Level = level; + this.Count = count; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + Handle.Encode(dst); + Sids.Encode(dst); + Names.Encode(dst); + dst.Enc_ndr_short(Level); + dst.Enc_ndr_long(Count); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + int domainsp = src.Dec_ndr_long(); + if (domainsp != 0) + { + if (Domains == null) + { + Domains = new LsarRefDomainList(); + } + Domains.Decode(src); + } + Names.Decode(src); + Count = src.Dec_ndr_long(); + Retval = src.Dec_ndr_long(); + } + } + + public class LsarOpenPolicy2 : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x2c); + } + + public int Retval; + + public string SystemName; + + public LsarObjectAttributes ObjectAttributes; + + public int DesiredAccess; + + public Rpc.PolicyHandle PolicyHandle; + + public LsarOpenPolicy2(string systemName, LsarObjectAttributes objectAttributes + , int desiredAccess, Rpc.PolicyHandle policyHandle) + { + this.SystemName = systemName; + this.ObjectAttributes = objectAttributes; + this.DesiredAccess = desiredAccess; + this.PolicyHandle = policyHandle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_referent(SystemName, 1); + if (SystemName != null) + { + dst.Enc_ndr_string(SystemName); + } + ObjectAttributes.Encode(dst); + dst.Enc_ndr_long(DesiredAccess); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + PolicyHandle.Decode(src); + Retval = src.Dec_ndr_long(); + } + } + + public class LsarQueryInformationPolicy2 : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x2e); + } + + public int Retval; + + public Rpc.PolicyHandle Handle; + + public short Level; + + public NdrObject Info; + + public LsarQueryInformationPolicy2(Rpc.PolicyHandle handle, short level, NdrObject + info) + { + this.Handle = handle; + this.Level = level; + this.Info = info; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + Handle.Encode(dst); + dst.Enc_ndr_short(Level); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + int infop = src.Dec_ndr_long(); + if (infop != 0) + { + src.Dec_ndr_short(); + Info.Decode(src); + } + Retval = src.Dec_ndr_long(); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcDfsRootEnum.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcDfsRootEnum.cs new file mode 100644 index 000000000..6a9d4302a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcDfsRootEnum.cs @@ -0,0 +1,43 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcDfsRootEnum : Netdfs.NetrDfsEnumEx + { + public MsrpcDfsRootEnum(string server) : base(server, 200, unchecked(0xFFFF), new Netdfs.DfsEnumStruct(), new NdrLong(0)) + { + Info.Level = Level; + Info.E = new Netdfs.DfsEnumArray200(); + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + + public virtual IFileEntry[] GetEntries() + { + Netdfs.DfsEnumArray200 a200 = (Netdfs.DfsEnumArray200)Info.E; + SmbShareInfo[] entries = new SmbShareInfo[a200.Count]; + for (int i = 0; i < a200.Count; i++) + { + entries[i] = new SmbShareInfo(a200.S[i].DfsName, 0, null); + } + return entries; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcEnumerateAliasesInDomain.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcEnumerateAliasesInDomain.cs new file mode 100644 index 000000000..d9c0afb34 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcEnumerateAliasesInDomain.cs @@ -0,0 +1,29 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcEnumerateAliasesInDomain : Samr.SamrEnumerateAliasesInDomain + { + public MsrpcEnumerateAliasesInDomain(SamrDomainHandle domainHandle, int acctFlags + , Samr.SamrSamArray sam) : base(domainHandle, 0, acctFlags, null, 0) + { + this.Sam = sam; + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcGetMembersInAlias.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcGetMembersInAlias.cs new file mode 100644 index 000000000..77b2ee375 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcGetMembersInAlias.cs @@ -0,0 +1,29 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcGetMembersInAlias : Samr.SamrGetMembersInAlias + { + public MsrpcGetMembersInAlias(SamrAliasHandle aliasHandle, Lsarpc.LsarSidArray sids + ) : base(aliasHandle, sids) + { + this.Sids = sids; + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcLookupSids.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcLookupSids.cs new file mode 100644 index 000000000..0aaf31026 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcLookupSids.cs @@ -0,0 +1,34 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcLookupSids : Lsarpc.LsarLookupSids + { + internal Sid[] sids; + + public MsrpcLookupSids(LsaPolicyHandle policyHandle, Sid[] sids) : base(policyHandle + , new LsarSidArrayX(sids), new Lsarpc.LsarRefDomainList(), new Lsarpc.LsarTransNameArray + (), 1, sids.Length) + { + this.sids = sids; + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcLsarOpenPolicy2.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcLsarOpenPolicy2.cs new file mode 100644 index 000000000..9d2c2a0f4 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcLsarOpenPolicy2.cs @@ -0,0 +1,35 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcLsarOpenPolicy2 : Lsarpc.LsarOpenPolicy2 + { + public MsrpcLsarOpenPolicy2(string server, int access, LsaPolicyHandle policyHandle + ) : base(server, new Lsarpc.LsarObjectAttributes(), access, policyHandle) + { + ObjectAttributes.Length = 24; + Lsarpc.LsarQosInfo qos = new Lsarpc.LsarQosInfo(); + qos.Length = 12; + qos.ImpersonationLevel = 2; + qos.ContextMode = 1; + qos.EffectiveOnly = 0; + ObjectAttributes.SecurityQualityOfService = qos; + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcQueryInformationPolicy.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcQueryInformationPolicy.cs new file mode 100644 index 000000000..820d81ab2 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcQueryInformationPolicy.cs @@ -0,0 +1,30 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcQueryInformationPolicy : Lsarpc.LsarQueryInformationPolicy + { + public MsrpcQueryInformationPolicy(LsaPolicyHandle policyHandle, short level, NdrObject + info) : base(policyHandle, level, info) + { + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrConnect2.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrConnect2.cs new file mode 100644 index 000000000..80c45257c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrConnect2.cs @@ -0,0 +1,28 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcSamrConnect2 : Samr.SamrConnect2 + { + public MsrpcSamrConnect2(string server, int access, SamrPolicyHandle policyHandle + ) : base(server, access, policyHandle) + { + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrConnect4.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrConnect4.cs new file mode 100644 index 000000000..0f2603e9c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrConnect4.cs @@ -0,0 +1,28 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcSamrConnect4 : Samr.SamrConnect4 + { + public MsrpcSamrConnect4(string server, int access, SamrPolicyHandle policyHandle + ) : base(server, 2, access, policyHandle) + { + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrOpenAlias.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrOpenAlias.cs new file mode 100644 index 000000000..e0b9b68d3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrOpenAlias.cs @@ -0,0 +1,28 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcSamrOpenAlias : Samr.SamrOpenAlias + { + public MsrpcSamrOpenAlias(SamrDomainHandle handle, int access, int rid, SamrAliasHandle + aliasHandle) : base(handle, access, rid, aliasHandle) + { + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrOpenDomain.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrOpenDomain.cs new file mode 100644 index 000000000..2ac6bceed --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcSamrOpenDomain.cs @@ -0,0 +1,28 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcSamrOpenDomain : Samr.SamrOpenDomain + { + public MsrpcSamrOpenDomain(SamrPolicyHandle handle, int access, Rpc.SidT sid, SamrDomainHandle + domainHandle) : base(handle, access, sid, domainHandle) + { + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcShareEnum.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcShareEnum.cs new file mode 100644 index 000000000..7c7b64abf --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcShareEnum.cs @@ -0,0 +1,55 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcShareEnum : Srvsvc.ShareEnumAll + { + internal class MsrpcShareInfo1 : SmbShareInfo + { + internal MsrpcShareInfo1(MsrpcShareEnum enclosing, Srvsvc.ShareInfo1 info1) + { + this._enclosing = enclosing; + NetName = info1.Netname; + Type = info1.Type; + Remark = info1.Remark; + } + + private readonly MsrpcShareEnum _enclosing; + } + + public MsrpcShareEnum(string server) : base("\\\\" + server, 1, new Srvsvc.ShareInfoCtr1 + (), -1, 0, 0) + { + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + + public virtual IFileEntry[] GetEntries() + { + Srvsvc.ShareInfoCtr1 ctr = (Srvsvc.ShareInfoCtr1)Info; + MsrpcShareInfo1[] entries = new MsrpcShareInfo1[ctr + .Count]; + for (int i = 0; i < ctr.Count; i++) + { + entries[i] = new MsrpcShareInfo1(this, ctr.Array[i]); + } + return entries; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcShareGetInfo.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcShareGetInfo.cs new file mode 100644 index 000000000..802ed61a3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/MsrpcShareGetInfo.cs @@ -0,0 +1,43 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class MsrpcShareGetInfo : Srvsvc.ShareGetInfo + { + public MsrpcShareGetInfo(string server, string sharename) : base(server, sharename + , 502, new Srvsvc.ShareInfo502()) + { + Ptype = 0; + Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual Ace[] GetSecurity() + { + Srvsvc.ShareInfo502 info502 = (Srvsvc.ShareInfo502)Info; + if (info502.SecurityDescriptor != null) + { + SecurityDescriptor sd; + sd = new SecurityDescriptor(info502.SecurityDescriptor, 0, info502.SdSize); + return sd.Aces; + } + return null; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Netdfs.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Netdfs.cs new file mode 100644 index 000000000..a338b2885 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Netdfs.cs @@ -0,0 +1,616 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class Netdfs + { + public static string GetSyntax() + { + return "4fc742e0-4a10-11cf-8273-00aa004ae673:3.0"; + } + + public const int DfsVolumeFlavorStandalone = unchecked(0x100); + + public const int DfsVolumeFlavorAdBlob = unchecked(0x200); + + public const int DfsStorageStateOffline = unchecked(0x0001); + + public const int DfsStorageStateOnline = unchecked(0x0002); + + public const int DfsStorageStateActive = unchecked(0x0004); + + public class DfsInfo1 : NdrObject + { + public string EntryPath; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_referent(EntryPath, 1); + if (EntryPath != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(EntryPath); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int entryPathp = src.Dec_ndr_long(); + if (entryPathp != 0) + { + src = src.Deferred; + EntryPath = src.Dec_ndr_string(); + } + } + } + + public class DfsEnumArray1 : NdrObject + { + public int Count; + + public DfsInfo1[] S; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(S, 1); + if (S != null) + { + dst = dst.Deferred; + int ss = Count; + dst.Enc_ndr_long(ss); + int si = dst.Index; + dst.Advance(4 * ss); + dst = dst.Derive(si); + for (int i = 0; i < ss; i++) + { + S[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int sp = src.Dec_ndr_long(); + if (sp != 0) + { + src = src.Deferred; + int ss = src.Dec_ndr_long(); + int si = src.Index; + src.Advance(4 * ss); + if (S == null) + { + if (ss < 0 || ss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + S = new DfsInfo1[ss]; + } + src = src.Derive(si); + for (int i = 0; i < ss; i++) + { + if (S[i] == null) + { + S[i] = new DfsInfo1(); + } + S[i].Decode(src); + } + } + } + } + + public class DfsStorageInfo : NdrObject + { + public int State; + + public string ServerName; + + public string ShareName; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(State); + dst.Enc_ndr_referent(ServerName, 1); + dst.Enc_ndr_referent(ShareName, 1); + if (ServerName != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(ServerName); + } + if (ShareName != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(ShareName); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + State = src.Dec_ndr_long(); + int serverNamep = src.Dec_ndr_long(); + int shareNamep = src.Dec_ndr_long(); + if (serverNamep != 0) + { + src = src.Deferred; + ServerName = src.Dec_ndr_string(); + } + if (shareNamep != 0) + { + src = src.Deferred; + ShareName = src.Dec_ndr_string(); + } + } + } + + public class DfsInfo3 : NdrObject + { + public string Path; + + public string Comment; + + public int State; + + public int NumStores; + + public DfsStorageInfo[] Stores; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_referent(Path, 1); + dst.Enc_ndr_referent(Comment, 1); + dst.Enc_ndr_long(State); + dst.Enc_ndr_long(NumStores); + dst.Enc_ndr_referent(Stores, 1); + if (Path != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Path); + } + if (Comment != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Comment); + } + if (Stores != null) + { + dst = dst.Deferred; + int storess = NumStores; + dst.Enc_ndr_long(storess); + int storesi = dst.Index; + dst.Advance(12 * storess); + dst = dst.Derive(storesi); + for (int i = 0; i < storess; i++) + { + Stores[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int pathp = src.Dec_ndr_long(); + int commentp = src.Dec_ndr_long(); + State = src.Dec_ndr_long(); + NumStores = src.Dec_ndr_long(); + int storesp = src.Dec_ndr_long(); + if (pathp != 0) + { + src = src.Deferred; + Path = src.Dec_ndr_string(); + } + if (commentp != 0) + { + src = src.Deferred; + Comment = src.Dec_ndr_string(); + } + if (storesp != 0) + { + src = src.Deferred; + int storess = src.Dec_ndr_long(); + int storesi = src.Index; + src.Advance(12 * storess); + if (Stores == null) + { + if (storess < 0 || storess > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Stores = new DfsStorageInfo[storess]; + } + src = src.Derive(storesi); + for (int i = 0; i < storess; i++) + { + if (Stores[i] == null) + { + Stores[i] = new DfsStorageInfo(); + } + Stores[i].Decode(src); + } + } + } + } + + public class DfsEnumArray3 : NdrObject + { + public int Count; + + public DfsInfo3[] S; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(S, 1); + if (S != null) + { + dst = dst.Deferred; + int ss = Count; + dst.Enc_ndr_long(ss); + int si = dst.Index; + dst.Advance(20 * ss); + dst = dst.Derive(si); + for (int i = 0; i < ss; i++) + { + S[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int sp = src.Dec_ndr_long(); + if (sp != 0) + { + src = src.Deferred; + int ss = src.Dec_ndr_long(); + int si = src.Index; + src.Advance(20 * ss); + if (S == null) + { + if (ss < 0 || ss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + S = new DfsInfo3[ss]; + } + src = src.Derive(si); + for (int i = 0; i < ss; i++) + { + if (S[i] == null) + { + S[i] = new DfsInfo3(); + } + S[i].Decode(src); + } + } + } + } + + public class DfsInfo200 : NdrObject + { + public string DfsName; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_referent(DfsName, 1); + if (DfsName != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(DfsName); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int dfsNamep = src.Dec_ndr_long(); + if (dfsNamep != 0) + { + src = src.Deferred; + DfsName = src.Dec_ndr_string(); + } + } + } + + public class DfsEnumArray200 : NdrObject + { + public int Count; + + public DfsInfo200[] S; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(S, 1); + if (S != null) + { + dst = dst.Deferred; + int ss = Count; + dst.Enc_ndr_long(ss); + int si = dst.Index; + dst.Advance(4 * ss); + dst = dst.Derive(si); + for (int i = 0; i < ss; i++) + { + S[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int sp = src.Dec_ndr_long(); + if (sp != 0) + { + src = src.Deferred; + int ss = src.Dec_ndr_long(); + int si = src.Index; + src.Advance(4 * ss); + if (S == null) + { + if (ss < 0 || ss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + S = new DfsInfo200[ss]; + } + src = src.Derive(si); + for (int i = 0; i < ss; i++) + { + if (S[i] == null) + { + S[i] = new DfsInfo200(); + } + S[i].Decode(src); + } + } + } + } + + public class DfsInfo300 : NdrObject + { + public int Flags; + + public string DfsName; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Flags); + dst.Enc_ndr_referent(DfsName, 1); + if (DfsName != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(DfsName); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Flags = src.Dec_ndr_long(); + int dfsNamep = src.Dec_ndr_long(); + if (dfsNamep != 0) + { + src = src.Deferred; + DfsName = src.Dec_ndr_string(); + } + } + } + + public class DfsEnumArray300 : NdrObject + { + public int Count; + + public DfsInfo300[] S; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(S, 1); + if (S != null) + { + dst = dst.Deferred; + int ss = Count; + dst.Enc_ndr_long(ss); + int si = dst.Index; + dst.Advance(8 * ss); + dst = dst.Derive(si); + for (int i = 0; i < ss; i++) + { + S[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int sp = src.Dec_ndr_long(); + if (sp != 0) + { + src = src.Deferred; + int ss = src.Dec_ndr_long(); + int si = src.Index; + src.Advance(8 * ss); + if (S == null) + { + if (ss < 0 || ss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + S = new DfsInfo300[ss]; + } + src = src.Derive(si); + for (int i = 0; i < ss; i++) + { + if (S[i] == null) + { + S[i] = new DfsInfo300(); + } + S[i].Decode(src); + } + } + } + } + + public class DfsEnumStruct : NdrObject + { + public int Level; + + public NdrObject E; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Level); + int descr = Level; + dst.Enc_ndr_long(descr); + dst.Enc_ndr_referent(E, 1); + if (E != null) + { + dst = dst.Deferred; + E.Encode(dst); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Level = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int ep = src.Dec_ndr_long(); + if (ep != 0) + { + if (E == null) + { + E = new DfsEnumArray1(); + } + src = src.Deferred; + E.Decode(src); + } + } + } + + public class NetrDfsEnumEx : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x15); + } + + public int Retval; + + public string DfsName; + + public int Level; + + public int Prefmaxlen; + + public DfsEnumStruct Info; + + public NdrLong Totalentries; + + public NetrDfsEnumEx(string dfsName, int level, int prefmaxlen, DfsEnumStruct + info, NdrLong totalentries) + { + this.DfsName = dfsName; + this.Level = level; + this.Prefmaxlen = prefmaxlen; + this.Info = info; + this.Totalentries = totalentries; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_string(DfsName); + dst.Enc_ndr_long(Level); + dst.Enc_ndr_long(Prefmaxlen); + dst.Enc_ndr_referent(Info, 1); + if (Info != null) + { + Info.Encode(dst); + } + dst.Enc_ndr_referent(Totalentries, 1); + if (Totalentries != null) + { + Totalentries.Encode(dst); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + int infop = src.Dec_ndr_long(); + if (infop != 0) + { + if (Info == null) + { + Info = new DfsEnumStruct(); + } + Info.Decode(src); + } + int totalentriesp = src.Dec_ndr_long(); + if (totalentriesp != 0) + { + Totalentries.Decode(src); + } + Retval = src.Dec_ndr_long(); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Samr.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Samr.cs new file mode 100644 index 000000000..bdc71695e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Samr.cs @@ -0,0 +1,579 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class Samr + { + public static string GetSyntax() + { + return "12345778-1234-abcd-ef00-0123456789ac:1.0"; + } + + public const int AcbDisabled = 1; + + public const int AcbHomdirreq = 2; + + public const int AcbPwnotreq = 4; + + public const int AcbTempdup = 8; + + public const int AcbNormal = 16; + + public const int AcbMns = 32; + + public const int AcbDomtrust = 64; + + public const int AcbWstrust = 128; + + public const int AcbSvrtrust = 256; + + public const int AcbPwnoexp = 512; + + public const int AcbAutolock = 1024; + + public const int AcbEncTxtPwdAllowed = 2048; + + public const int AcbSmartcardRequired = 4096; + + public const int AcbTrustedForDelegation = 8192; + + public const int AcbNotDelegated = 16384; + + public const int AcbUseDesKeyOnly = 32768; + + public const int AcbDontRequirePreauth = 65536; + + public class SamrCloseHandle : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x01); + } + + public int Retval; + + public Rpc.PolicyHandle Handle; + + public SamrCloseHandle(Rpc.PolicyHandle handle) + { + this.Handle = handle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + Handle.Encode(dst); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + Retval = src.Dec_ndr_long(); + } + } + + public class SamrConnect2 : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x39); + } + + public int Retval; + + public string SystemName; + + public int AccessMask; + + public Rpc.PolicyHandle Handle; + + public SamrConnect2(string systemName, int accessMask, Rpc.PolicyHandle handle + ) + { + this.SystemName = systemName; + this.AccessMask = accessMask; + this.Handle = handle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_referent(SystemName, 1); + if (SystemName != null) + { + dst.Enc_ndr_string(SystemName); + } + dst.Enc_ndr_long(AccessMask); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + Handle.Decode(src); + Retval = src.Dec_ndr_long(); + } + } + + public class SamrConnect4 : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x3e); + } + + public int Retval; + + public string SystemName; + + public int Unknown; + + public int AccessMask; + + public Rpc.PolicyHandle Handle; + + public SamrConnect4(string systemName, int unknown, int accessMask, Rpc.PolicyHandle + handle) + { + this.SystemName = systemName; + this.Unknown = unknown; + this.AccessMask = accessMask; + this.Handle = handle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_referent(SystemName, 1); + if (SystemName != null) + { + dst.Enc_ndr_string(SystemName); + } + dst.Enc_ndr_long(Unknown); + dst.Enc_ndr_long(AccessMask); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + Handle.Decode(src); + Retval = src.Dec_ndr_long(); + } + } + + public class SamrOpenDomain : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x07); + } + + public int Retval; + + public Rpc.PolicyHandle Handle; + + public int AccessMask; + + public Rpc.SidT Sid; + + public Rpc.PolicyHandle DomainHandle; + + public SamrOpenDomain(Rpc.PolicyHandle handle, int accessMask, Rpc.SidT sid, Rpc.PolicyHandle + domainHandle) + { + this.Handle = handle; + this.AccessMask = accessMask; + this.Sid = sid; + this.DomainHandle = domainHandle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + Handle.Encode(dst); + dst.Enc_ndr_long(AccessMask); + Sid.Encode(dst); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + DomainHandle.Decode(src); + Retval = src.Dec_ndr_long(); + } + } + + public class SamrSamEntry : NdrObject + { + public int Idx; + + public Rpc.Unicode_string Name; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Idx); + dst.Enc_ndr_short(Name.Length); + dst.Enc_ndr_short(Name.MaximumLength); + dst.Enc_ndr_referent(Name.Buffer, 1); + if (Name.Buffer != null) + { + dst = dst.Deferred; + int nameBufferl = Name.Length / 2; + int nameBuffers = Name.MaximumLength / 2; + dst.Enc_ndr_long(nameBuffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(nameBufferl); + int nameBufferi = dst.Index; + dst.Advance(2 * nameBufferl); + dst = dst.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + dst.Enc_ndr_short(Name.Buffer[i]); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Idx = src.Dec_ndr_long(); + src.Align(4); + if (Name == null) + { + Name = new Rpc.Unicode_string(); + } + Name.Length = (short)src.Dec_ndr_short(); + Name.MaximumLength = (short)src.Dec_ndr_short(); + int nameBufferp = src.Dec_ndr_long(); + if (nameBufferp != 0) + { + src = src.Deferred; + int nameBuffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int nameBufferl = src.Dec_ndr_long(); + int nameBufferi = src.Index; + src.Advance(2 * nameBufferl); + if (Name.Buffer == null) + { + if (nameBuffers < 0 || nameBuffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Name.Buffer = new short[nameBuffers]; + } + src = src.Derive(nameBufferi); + for (int i = 0; i < nameBufferl; i++) + { + Name.Buffer[i] = (short)src.Dec_ndr_short(); + } + } + } + } + + public class SamrSamArray : NdrObject + { + public int Count; + + public SamrSamEntry[] Entries; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Entries, 1); + if (Entries != null) + { + dst = dst.Deferred; + int entriess = Count; + dst.Enc_ndr_long(entriess); + int entriesi = dst.Index; + dst.Advance(12 * entriess); + dst = dst.Derive(entriesi); + for (int i = 0; i < entriess; i++) + { + Entries[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int entriesp = src.Dec_ndr_long(); + if (entriesp != 0) + { + src = src.Deferred; + int entriess = src.Dec_ndr_long(); + int entriesi = src.Index; + src.Advance(12 * entriess); + if (Entries == null) + { + if (entriess < 0 || entriess > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Entries = new SamrSamEntry[entriess]; + } + src = src.Derive(entriesi); + for (int i = 0; i < entriess; i++) + { + if (Entries[i] == null) + { + Entries[i] = new SamrSamEntry(); + } + Entries[i].Decode(src); + } + } + } + } + + public class SamrEnumerateAliasesInDomain : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x0f); + } + + public int Retval; + + public Rpc.PolicyHandle DomainHandle; + + public int ResumeHandle; + + public int AcctFlags; + + public SamrSamArray Sam; + + public int NumEntries; + + public SamrEnumerateAliasesInDomain(Rpc.PolicyHandle domainHandle, int resumeHandle + , int acctFlags, SamrSamArray sam, int numEntries) + { + this.DomainHandle = domainHandle; + this.ResumeHandle = resumeHandle; + this.AcctFlags = acctFlags; + this.Sam = sam; + this.NumEntries = numEntries; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + DomainHandle.Encode(dst); + dst.Enc_ndr_long(ResumeHandle); + dst.Enc_ndr_long(AcctFlags); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + ResumeHandle = src.Dec_ndr_long(); + int samp = src.Dec_ndr_long(); + if (samp != 0) + { + if (Sam == null) + { + Sam = new SamrSamArray(); + } + Sam.Decode(src); + } + NumEntries = src.Dec_ndr_long(); + Retval = src.Dec_ndr_long(); + } + } + + public class SamrOpenAlias : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x1b); + } + + public int Retval; + + public Rpc.PolicyHandle DomainHandle; + + public int AccessMask; + + public int Rid; + + public Rpc.PolicyHandle AliasHandle; + + public SamrOpenAlias(Rpc.PolicyHandle domainHandle, int accessMask, int rid, Rpc.PolicyHandle + aliasHandle) + { + this.DomainHandle = domainHandle; + this.AccessMask = accessMask; + this.Rid = rid; + this.AliasHandle = aliasHandle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + DomainHandle.Encode(dst); + dst.Enc_ndr_long(AccessMask); + dst.Enc_ndr_long(Rid); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + AliasHandle.Decode(src); + Retval = src.Dec_ndr_long(); + } + } + + public class SamrGetMembersInAlias : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x21); + } + + public int Retval; + + public Rpc.PolicyHandle AliasHandle; + + public Lsarpc.LsarSidArray Sids; + + public SamrGetMembersInAlias(Rpc.PolicyHandle aliasHandle, Lsarpc.LsarSidArray + sids) + { + this.AliasHandle = aliasHandle; + this.Sids = sids; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + AliasHandle.Encode(dst); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + Sids.Decode(src); + Retval = src.Dec_ndr_long(); + } + } + + public const int SeGroupMandatory = 1; + + public const int SeGroupEnabledByDefault = 2; + + public const int SeGroupEnabled = 4; + + public const int SeGroupOwner = 8; + + public const int SeGroupUseForDenyOnly = 16; + + public const int SeGroupResource = 536870912; + + public const int SeGroupLogonId = -1073741824; + + public class SamrRidWithAttribute : NdrObject + { + public int Rid; + + public int Attributes; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Rid); + dst.Enc_ndr_long(Attributes); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Rid = src.Dec_ndr_long(); + Attributes = src.Dec_ndr_long(); + } + } + + public class SamrRidWithAttributeArray : NdrObject + { + public int Count; + + public SamrRidWithAttribute[] Rids; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Rids, 1); + if (Rids != null) + { + dst = dst.Deferred; + int ridss = Count; + dst.Enc_ndr_long(ridss); + int ridsi = dst.Index; + dst.Advance(8 * ridss); + dst = dst.Derive(ridsi); + for (int i = 0; i < ridss; i++) + { + Rids[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int ridsp = src.Dec_ndr_long(); + if (ridsp != 0) + { + src = src.Deferred; + int ridss = src.Dec_ndr_long(); + int ridsi = src.Index; + src.Advance(8 * ridss); + if (Rids == null) + { + if (ridss < 0 || ridss > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Rids = new SamrRidWithAttribute[ridss]; + } + src = src.Derive(ridsi); + for (int i = 0; i < ridss; i++) + { + if (Rids[i] == null) + { + Rids[i] = new SamrRidWithAttribute(); + } + Rids[i].Decode(src); + } + } + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrAliasHandle.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrAliasHandle.cs new file mode 100644 index 000000000..d4ebdacc4 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrAliasHandle.cs @@ -0,0 +1,40 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class SamrAliasHandle : Rpc.PolicyHandle + { + /// <exception cref="System.IO.IOException"></exception> + public SamrAliasHandle(DcerpcHandle handle, SamrDomainHandle domainHandle, int access + , int rid) + { + MsrpcSamrOpenAlias rpc = new MsrpcSamrOpenAlias(domainHandle, access, rid, this); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual void Close() + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrDomainHandle.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrDomainHandle.cs new file mode 100644 index 000000000..d44c79886 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrDomainHandle.cs @@ -0,0 +1,41 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Smb; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class SamrDomainHandle : Rpc.PolicyHandle + { + /// <exception cref="System.IO.IOException"></exception> + public SamrDomainHandle(DcerpcHandle handle, SamrPolicyHandle policyHandle, int access + , Rpc.SidT sid) + { + MsrpcSamrOpenDomain rpc = new MsrpcSamrOpenDomain(policyHandle, access, sid, this + ); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual void Close() + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrPolicyHandle.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrPolicyHandle.cs new file mode 100644 index 000000000..0cd3f9369 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/SamrPolicyHandle.cs @@ -0,0 +1,49 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Msrpc +{ + public class SamrPolicyHandle : Rpc.PolicyHandle + { + /// <exception cref="System.IO.IOException"></exception> + public SamrPolicyHandle(DcerpcHandle handle, string server, int access) + { + if (server == null) + { + server = "\\\\"; + } + MsrpcSamrConnect4 rpc = new MsrpcSamrConnect4(server, access, this); + try + { + handle.Sendrecv(rpc); + } + catch (DcerpcException de) + { + if (de.GetErrorCode() != DcerpcError.DcerpcFaultOpRngError) + { + throw; + } + MsrpcSamrConnect2 rpc2 = new MsrpcSamrConnect2(server, access, this); + handle.Sendrecv(rpc2); + } + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual void Close() + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Srvsvc.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Srvsvc.cs new file mode 100644 index 000000000..f33f48327 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Msrpc/Srvsvc.cs @@ -0,0 +1,734 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc.Msrpc +{ + public class Srvsvc + { + public static string GetSyntax() + { + return "4b324fc8-1670-01d3-1278-5a47bf6ee188:3.0"; + } + + public class ShareInfo0 : NdrObject + { + public string Netname; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_referent(Netname, 1); + if (Netname != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Netname); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int netnamep = src.Dec_ndr_long(); + if (netnamep != 0) + { + src = src.Deferred; + Netname = src.Dec_ndr_string(); + } + } + } + + public class ShareInfoCtr0 : NdrObject + { + public int Count; + + public ShareInfo0[] Array; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Array, 1); + if (Array != null) + { + dst = dst.Deferred; + int arrays = Count; + dst.Enc_ndr_long(arrays); + int arrayi = dst.Index; + dst.Advance(4 * arrays); + dst = dst.Derive(arrayi); + for (int i = 0; i < arrays; i++) + { + Array[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int arrayp = src.Dec_ndr_long(); + if (arrayp != 0) + { + src = src.Deferred; + int arrays = src.Dec_ndr_long(); + int arrayi = src.Index; + src.Advance(4 * arrays); + if (Array == null) + { + if (arrays < 0 || arrays > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Array = new ShareInfo0[arrays]; + } + src = src.Derive(arrayi); + for (int i = 0; i < arrays; i++) + { + if (Array[i] == null) + { + Array[i] = new ShareInfo0(); + } + Array[i].Decode(src); + } + } + } + } + + public class ShareInfo1 : NdrObject + { + public string Netname; + + public int Type; + + public string Remark; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_referent(Netname, 1); + dst.Enc_ndr_long(Type); + dst.Enc_ndr_referent(Remark, 1); + if (Netname != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Netname); + } + if (Remark != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Remark); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int netnamep = src.Dec_ndr_long(); + Type = src.Dec_ndr_long(); + int remarkp = src.Dec_ndr_long(); + if (netnamep != 0) + { + src = src.Deferred; + Netname = src.Dec_ndr_string(); + } + if (remarkp != 0) + { + src = src.Deferred; + Remark = src.Dec_ndr_string(); + } + } + } + + public class ShareInfoCtr1 : NdrObject + { + public int Count; + + public ShareInfo1[] Array; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Array, 1); + if (Array != null) + { + dst = dst.Deferred; + int arrays = Count; + dst.Enc_ndr_long(arrays); + int arrayi = dst.Index; + dst.Advance(12 * arrays); + dst = dst.Derive(arrayi); + for (int i = 0; i < arrays; i++) + { + Array[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int arrayp = src.Dec_ndr_long(); + if (arrayp != 0) + { + src = src.Deferred; + int arrays = src.Dec_ndr_long(); + int arrayi = src.Index; + src.Advance(12 * arrays); + if (Array == null) + { + if (arrays < 0 || arrays > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Array = new ShareInfo1[arrays]; + } + src = src.Derive(arrayi); + for (int i = 0; i < arrays; i++) + { + if (Array[i] == null) + { + Array[i] = new ShareInfo1(); + } + Array[i].Decode(src); + } + } + } + } + + public class ShareInfo502 : NdrObject + { + public string Netname; + + public int Type; + + public string Remark; + + public int Permissions; + + public int MaxUses; + + public int CurrentUses; + + public string Path; + + public string Password; + + public int SdSize; + + public byte[] SecurityDescriptor; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_referent(Netname, 1); + dst.Enc_ndr_long(Type); + dst.Enc_ndr_referent(Remark, 1); + dst.Enc_ndr_long(Permissions); + dst.Enc_ndr_long(MaxUses); + dst.Enc_ndr_long(CurrentUses); + dst.Enc_ndr_referent(Path, 1); + dst.Enc_ndr_referent(Password, 1); + dst.Enc_ndr_long(SdSize); + dst.Enc_ndr_referent(SecurityDescriptor, 1); + if (Netname != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Netname); + } + if (Remark != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Remark); + } + if (Path != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Path); + } + if (Password != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Password); + } + if (SecurityDescriptor != null) + { + dst = dst.Deferred; + int securityDescriptors = SdSize; + dst.Enc_ndr_long(securityDescriptors); + int securityDescriptori = dst.Index; + dst.Advance(1 * securityDescriptors); + dst = dst.Derive(securityDescriptori); + for (int i = 0; i < securityDescriptors; i++) + { + dst.Enc_ndr_small(SecurityDescriptor[i]); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int netnamep = src.Dec_ndr_long(); + Type = src.Dec_ndr_long(); + int remarkp = src.Dec_ndr_long(); + Permissions = src.Dec_ndr_long(); + MaxUses = src.Dec_ndr_long(); + CurrentUses = src.Dec_ndr_long(); + int pathp = src.Dec_ndr_long(); + int passwordp = src.Dec_ndr_long(); + SdSize = src.Dec_ndr_long(); + int securityDescriptorp = src.Dec_ndr_long(); + if (netnamep != 0) + { + src = src.Deferred; + Netname = src.Dec_ndr_string(); + } + if (remarkp != 0) + { + src = src.Deferred; + Remark = src.Dec_ndr_string(); + } + if (pathp != 0) + { + src = src.Deferred; + Path = src.Dec_ndr_string(); + } + if (passwordp != 0) + { + src = src.Deferred; + Password = src.Dec_ndr_string(); + } + if (securityDescriptorp != 0) + { + src = src.Deferred; + int securityDescriptors = src.Dec_ndr_long(); + int securityDescriptori = src.Index; + src.Advance(1 * securityDescriptors); + if (SecurityDescriptor == null) + { + if (securityDescriptors < 0 || securityDescriptors > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + SecurityDescriptor = new byte[securityDescriptors]; + } + src = src.Derive(securityDescriptori); + for (int i = 0; i < securityDescriptors; i++) + { + SecurityDescriptor[i] = unchecked((byte)src.Dec_ndr_small()); + } + } + } + } + + public class ShareInfoCtr502 : NdrObject + { + public int Count; + + public ShareInfo502[] Array; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Count); + dst.Enc_ndr_referent(Array, 1); + if (Array != null) + { + dst = dst.Deferred; + int arrays = Count; + dst.Enc_ndr_long(arrays); + int arrayi = dst.Index; + dst.Advance(40 * arrays); + dst = dst.Derive(arrayi); + for (int i = 0; i < arrays; i++) + { + Array[i].Encode(dst); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Count = src.Dec_ndr_long(); + int arrayp = src.Dec_ndr_long(); + if (arrayp != 0) + { + src = src.Deferred; + int arrays = src.Dec_ndr_long(); + int arrayi = src.Index; + src.Advance(40 * arrays); + if (Array == null) + { + if (arrays < 0 || arrays > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Array = new ShareInfo502[arrays]; + } + src = src.Derive(arrayi); + for (int i = 0; i < arrays; i++) + { + if (Array[i] == null) + { + Array[i] = new ShareInfo502(); + } + Array[i].Decode(src); + } + } + } + } + + public class ShareEnumAll : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x0f); + } + + public int Retval; + + public string Servername; + + public int Level; + + public NdrObject Info; + + public int Prefmaxlen; + + public int Totalentries; + + public int ResumeHandle; + + public ShareEnumAll(string servername, int level, NdrObject info, int prefmaxlen, + int totalentries, int resumeHandle) + { + this.Servername = servername; + this.Level = level; + this.Info = info; + this.Prefmaxlen = prefmaxlen; + this.Totalentries = totalentries; + this.ResumeHandle = resumeHandle; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_referent(Servername, 1); + if (Servername != null) + { + dst.Enc_ndr_string(Servername); + } + dst.Enc_ndr_long(Level); + int descr = Level; + dst.Enc_ndr_long(descr); + dst.Enc_ndr_referent(Info, 1); + if (Info != null) + { + dst = dst.Deferred; + Info.Encode(dst); + } + dst.Enc_ndr_long(Prefmaxlen); + dst.Enc_ndr_long(ResumeHandle); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + Level = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int infop = src.Dec_ndr_long(); + if (infop != 0) + { + if (Info == null) + { + Info = new ShareInfoCtr0(); + } + src = src.Deferred; + Info.Decode(src); + } + Totalentries = src.Dec_ndr_long(); + ResumeHandle = src.Dec_ndr_long(); + Retval = src.Dec_ndr_long(); + } + } + + public class ShareGetInfo : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x10); + } + + public int Retval; + + public string Servername; + + public string Sharename; + + public int Level; + + public NdrObject Info; + + public ShareGetInfo(string servername, string sharename, int level, NdrObject info + ) + { + this.Servername = servername; + this.Sharename = sharename; + this.Level = level; + this.Info = info; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_referent(Servername, 1); + if (Servername != null) + { + dst.Enc_ndr_string(Servername); + } + dst.Enc_ndr_string(Sharename); + dst.Enc_ndr_long(Level); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + src.Dec_ndr_long(); + int infop = src.Dec_ndr_long(); + if (infop != 0) + { + if (Info == null) + { + Info = new ShareInfo0(); + } + src = src.Deferred; + Info.Decode(src); + } + Retval = src.Dec_ndr_long(); + } + } + + public class ServerInfo100 : NdrObject + { + public int PlatformId; + + public string Name; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(PlatformId); + dst.Enc_ndr_referent(Name, 1); + if (Name != null) + { + dst = dst.Deferred; + dst.Enc_ndr_string(Name); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + PlatformId = src.Dec_ndr_long(); + int namep = src.Dec_ndr_long(); + if (namep != 0) + { + src = src.Deferred; + Name = src.Dec_ndr_string(); + } + } + } + + public class ServerGetInfo : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x15); + } + + public int Retval; + + public string Servername; + + public int Level; + + public NdrObject Info; + + public ServerGetInfo(string servername, int level, NdrObject info) + { + this.Servername = servername; + this.Level = level; + this.Info = info; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_referent(Servername, 1); + if (Servername != null) + { + dst.Enc_ndr_string(Servername); + } + dst.Enc_ndr_long(Level); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + src.Dec_ndr_long(); + int infop = src.Dec_ndr_long(); + if (infop != 0) + { + if (Info == null) + { + Info = new ServerInfo100(); + } + src = src.Deferred; + Info.Decode(src); + } + Retval = src.Dec_ndr_long(); + } + } + + public class TimeOfDayInfo : NdrObject + { + public int Elapsedt; + + public int Msecs; + + public int Hours; + + public int Mins; + + public int Secs; + + public int Hunds; + + public int Timezone; + + public int Tinterval; + + public int Day; + + public int Month; + + public int Year; + + public int Weekday; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Elapsedt); + dst.Enc_ndr_long(Msecs); + dst.Enc_ndr_long(Hours); + dst.Enc_ndr_long(Mins); + dst.Enc_ndr_long(Secs); + dst.Enc_ndr_long(Hunds); + dst.Enc_ndr_long(Timezone); + dst.Enc_ndr_long(Tinterval); + dst.Enc_ndr_long(Day); + dst.Enc_ndr_long(Month); + dst.Enc_ndr_long(Year); + dst.Enc_ndr_long(Weekday); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Elapsedt = src.Dec_ndr_long(); + Msecs = src.Dec_ndr_long(); + Hours = src.Dec_ndr_long(); + Mins = src.Dec_ndr_long(); + Secs = src.Dec_ndr_long(); + Hunds = src.Dec_ndr_long(); + Timezone = src.Dec_ndr_long(); + Tinterval = src.Dec_ndr_long(); + Day = src.Dec_ndr_long(); + Month = src.Dec_ndr_long(); + Year = src.Dec_ndr_long(); + Weekday = src.Dec_ndr_long(); + } + } + + public class RemoteTod : DcerpcMessage + { + public override int GetOpnum() + { + return unchecked(0x1c); + } + + public int Retval; + + public string Servername; + + public TimeOfDayInfo Info; + + public RemoteTod(string servername, TimeOfDayInfo info) + { + this.Servername = servername; + this.Info = info; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode_in(NdrBuffer dst) + { + dst.Enc_ndr_referent(Servername, 1); + if (Servername != null) + { + dst.Enc_ndr_string(Servername); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode_out(NdrBuffer src) + { + int infop = src.Dec_ndr_long(); + if (infop != 0) + { + if (Info == null) + { + Info = new TimeOfDayInfo(); + } + Info.Decode(src); + } + Retval = src.Dec_ndr_long(); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrBuffer.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrBuffer.cs new file mode 100644 index 000000000..0a47de799 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrBuffer.cs @@ -0,0 +1,305 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Dcerpc.Ndr +{ + public class NdrBuffer + { + internal int Referent; + + internal Hashtable Referents; + + internal class Entry + { + internal int Referent; + + internal object Obj; + } + + public byte[] Buf; + + public int Start; + + public int Index; + + public int Length; + + public NdrBuffer Deferred; + + public NdrBuffer(byte[] buf, int start) + { + this.Buf = buf; + this.Start = Index = start; + Length = 0; + Deferred = this; + } + + public virtual NdrBuffer Derive(int idx) + { + NdrBuffer nb = new NdrBuffer(Buf, Start); + nb.Index = idx; + nb.Deferred = Deferred; + return nb; + } + + public virtual void Reset() + { + Index = Start; + Length = 0; + Deferred = this; + } + + public virtual int GetIndex() + { + return Index; + } + + public virtual void SetIndex(int index) + { + this.Index = index; + } + + public virtual int GetCapacity() + { + return Buf.Length - Start; + } + + public virtual int GetTailSpace() + { + return Buf.Length - Index; + } + + public virtual byte[] GetBuffer() + { + return Buf; + } + + public virtual int Align(int boundary, byte value) + { + int n = Align(boundary); + int i = n; + while (i > 0) + { + Buf[Index - i] = value; + i--; + } + return n; + } + + public virtual void WriteOctetArray(byte[] b, int i, int l) + { + Array.Copy(b, i, Buf, Index, l); + Advance(l); + } + + public virtual void ReadOctetArray(byte[] b, int i, int l) + { + Array.Copy(Buf, Index, b, i, l); + Advance(l); + } + + public virtual int GetLength() + { + return Deferred.Length; + } + + public virtual void SetLength(int length) + { + Deferred.Length = length; + } + + public virtual void Advance(int n) + { + Index += n; + if ((Index - Start) > Deferred.Length) + { + Deferred.Length = Index - Start; + } + } + + public virtual int Align(int boundary) + { + int m = boundary - 1; + int i = Index - Start; + int n = ((i + m) & ~m) - i; + Advance(n); + return n; + } + + public virtual void Enc_ndr_small(int s) + { + Buf[Index] = unchecked((byte)(s & unchecked(0xFF))); + Advance(1); + } + + public virtual int Dec_ndr_small() + { + int val = Buf[Index] & unchecked(0xFF); + Advance(1); + return val; + } + + public virtual void Enc_ndr_short(int s) + { + Align(2); + Encdec.Enc_uint16le((short)s, Buf, Index); + Advance(2); + } + + public virtual int Dec_ndr_short() + { + Align(2); + int val = Encdec.Dec_uint16le(Buf, Index); + Advance(2); + return val; + } + + public virtual void Enc_ndr_long(int l) + { + Align(4); + Encdec.Enc_uint32le(l, Buf, Index); + Advance(4); + } + + public virtual int Dec_ndr_long() + { + Align(4); + int val = Encdec.Dec_uint32le(Buf, Index); + Advance(4); + return val; + } + + public virtual void Enc_ndr_hyper(long h) + { + Align(8); + Encdec.Enc_uint64le(h, Buf, Index); + Advance(8); + } + + public virtual long Dec_ndr_hyper() + { + Align(8); + long val = Encdec.Dec_uint64le(Buf, Index); + Advance(8); + return val; + } + + public virtual void Enc_ndr_string(string s) + { + Align(4); + int i = Index; + int len = s.Length; + Encdec.Enc_uint32le(len + 1, Buf, i); + i += 4; + Encdec.Enc_uint32le(0, Buf, i); + i += 4; + Encdec.Enc_uint32le(len + 1, Buf, i); + i += 4; + try + { + Array.Copy(Runtime.GetBytesForString(s, "UTF-16LE"), 0, Buf, i, len + * 2); + } + catch (UnsupportedEncodingException) + { + } + i += len * 2; + Buf[i++] = unchecked((byte)('\0')); + Buf[i++] = unchecked((byte)('\0')); + Advance(i - Index); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public virtual string Dec_ndr_string() + { + Align(4); + int i = Index; + string val = null; + int len = Encdec.Dec_uint32le(Buf, i); + i += 12; + if (len != 0) + { + len--; + int size = len * 2; + try + { + if (size < 0 || size > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + val = Runtime.GetStringForBytes(Buf, i, size, "UTF-16LE"); + i += size + 2; + } + catch (UnsupportedEncodingException) + { + } + } + Advance(i - Index); + return val; + } + + private int GetDceReferent(object obj) + { + Entry e; + if (Referents == null) + { + Referents = new Hashtable(); + Referent = 1; + } + if ((e = (Entry)Referents.Get(obj)) == null) + { + e = new Entry(); + e.Referent = Referent++; + e.Obj = obj; + Referents.Put(obj, e); + } + return e.Referent; + } + + public virtual void Enc_ndr_referent(object obj, int type) + { + if (obj == null) + { + Enc_ndr_long(0); + return; + } + switch (type) + { + case 1: + case 3: + { + Enc_ndr_long(Runtime.IdentityHashCode(obj)); + return; + } + + case 2: + { + Enc_ndr_long(GetDceReferent(obj)); + return; + } + } + } + + public override string ToString() + { + return "start=" + Start + ",index=" + Index + ",length=" + GetLength(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrException.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrException.cs new file mode 100644 index 000000000..7757735f8 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrException.cs @@ -0,0 +1,32 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; + +namespace SharpCifs.Dcerpc.Ndr +{ + + public class NdrException : IOException + { + public static readonly string NoNullRef = "ref pointer cannot be null"; + + public static readonly string InvalidConformance = "invalid array conformance"; + + public NdrException(string msg) : base(msg) + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrHyper.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrHyper.cs new file mode 100644 index 000000000..9e2932337 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrHyper.cs @@ -0,0 +1,40 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Ndr +{ + public class NdrHyper : NdrObject + { + public long Value; + + public NdrHyper(long value) + { + this.Value = value; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Enc_ndr_hyper(Value); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + Value = src.Dec_ndr_hyper(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrLong.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrLong.cs new file mode 100644 index 000000000..74d90465e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrLong.cs @@ -0,0 +1,40 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Ndr +{ + public class NdrLong : NdrObject + { + public int Value; + + public NdrLong(int value) + { + this.Value = value; + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Enc_ndr_long(Value); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + Value = src.Dec_ndr_long(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrObject.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrObject.cs new file mode 100644 index 000000000..8951fa202 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrObject.cs @@ -0,0 +1,27 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Ndr +{ + public abstract class NdrObject + { + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public abstract void Encode(NdrBuffer dst); + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public abstract void Decode(NdrBuffer src); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrShort.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrShort.cs new file mode 100644 index 000000000..e2ea8c65b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrShort.cs @@ -0,0 +1,40 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Ndr +{ + public class NdrShort : NdrObject + { + public int Value; + + public NdrShort(int value) + { + this.Value = value & unchecked(0xFF); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Enc_ndr_short(Value); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + Value = src.Dec_ndr_short(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrSmall.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrSmall.cs new file mode 100644 index 000000000..8309dea66 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrSmall.cs @@ -0,0 +1,40 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc.Ndr +{ + public class NdrSmall : NdrObject + { + public int Value; + + public NdrSmall(int value) + { + this.Value = value & unchecked(0xFF); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Enc_ndr_small(Value); + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + Value = src.Dec_ndr_small(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Rpc.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Rpc.cs new file mode 100644 index 000000000..aa33d3522 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/Rpc.cs @@ -0,0 +1,285 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Dcerpc.Ndr; + +namespace SharpCifs.Dcerpc +{ + public class Rpc + { + public class UuidT : NdrObject + { + public int TimeLow; + + public short TimeMid; + + public short TimeHiAndVersion; + + public byte ClockSeqHiAndReserved; + + public byte ClockSeqLow; + + public byte[] Node; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(TimeLow); + dst.Enc_ndr_short(TimeMid); + dst.Enc_ndr_short(TimeHiAndVersion); + dst.Enc_ndr_small(ClockSeqHiAndReserved); + dst.Enc_ndr_small(ClockSeqLow); + int nodes = 6; + int nodei = dst.Index; + dst.Advance(1 * nodes); + dst = dst.Derive(nodei); + for (int i = 0; i < nodes; i++) + { + dst.Enc_ndr_small(Node[i]); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + TimeLow = src.Dec_ndr_long(); + TimeMid = (short)src.Dec_ndr_short(); + TimeHiAndVersion = (short)src.Dec_ndr_short(); + ClockSeqHiAndReserved = unchecked((byte)src.Dec_ndr_small()); + ClockSeqLow = unchecked((byte)src.Dec_ndr_small()); + int nodes = 6; + int nodei = src.Index; + src.Advance(1 * nodes); + if (Node == null) + { + if (nodes < 0 || nodes > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Node = new byte[nodes]; + } + src = src.Derive(nodei); + for (int i = 0; i < nodes; i++) + { + Node[i] = unchecked((byte)src.Dec_ndr_small()); + } + } + } + + public class PolicyHandle : NdrObject + { + public int Type; + + public UuidT Uuid; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_long(Type); + dst.Enc_ndr_long(Uuid.TimeLow); + dst.Enc_ndr_short(Uuid.TimeMid); + dst.Enc_ndr_short(Uuid.TimeHiAndVersion); + dst.Enc_ndr_small(Uuid.ClockSeqHiAndReserved); + dst.Enc_ndr_small(Uuid.ClockSeqLow); + int uuidNodes = 6; + int uuidNodei = dst.Index; + dst.Advance(1 * uuidNodes); + dst = dst.Derive(uuidNodei); + for (int i = 0; i < uuidNodes; i++) + { + dst.Enc_ndr_small(Uuid.Node[i]); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Type = src.Dec_ndr_long(); + src.Align(4); + if (Uuid == null) + { + Uuid = new UuidT(); + } + Uuid.TimeLow = src.Dec_ndr_long(); + Uuid.TimeMid = (short)src.Dec_ndr_short(); + Uuid.TimeHiAndVersion = (short)src.Dec_ndr_short(); + Uuid.ClockSeqHiAndReserved = unchecked((byte)src.Dec_ndr_small()); + Uuid.ClockSeqLow = unchecked((byte)src.Dec_ndr_small()); + int uuidNodes = 6; + int uuidNodei = src.Index; + src.Advance(1 * uuidNodes); + if (Uuid.Node == null) + { + if (uuidNodes < 0 || uuidNodes > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Uuid.Node = new byte[uuidNodes]; + } + src = src.Derive(uuidNodei); + for (int i = 0; i < uuidNodes; i++) + { + Uuid.Node[i] = unchecked((byte)src.Dec_ndr_small()); + } + } + } + + public class Unicode_string : NdrObject + { + public short Length; + + public short MaximumLength; + + public short[] Buffer; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + dst.Enc_ndr_short(Length); + dst.Enc_ndr_short(MaximumLength); + dst.Enc_ndr_referent(Buffer, 1); + if (Buffer != null) + { + dst = dst.Deferred; + int bufferl = Length / 2; + int buffers = MaximumLength / 2; + dst.Enc_ndr_long(buffers); + dst.Enc_ndr_long(0); + dst.Enc_ndr_long(bufferl); + int bufferi = dst.Index; + dst.Advance(2 * bufferl); + dst = dst.Derive(bufferi); + for (int i = 0; i < bufferl; i++) + { + dst.Enc_ndr_short(Buffer[i]); + } + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + Length = (short)src.Dec_ndr_short(); + MaximumLength = (short)src.Dec_ndr_short(); + int bufferp = src.Dec_ndr_long(); + if (bufferp != 0) + { + src = src.Deferred; + int buffers = src.Dec_ndr_long(); + src.Dec_ndr_long(); + int bufferl = src.Dec_ndr_long(); + int bufferi = src.Index; + src.Advance(2 * bufferl); + if (Buffer == null) + { + if (buffers < 0 || buffers > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + Buffer = new short[buffers]; + } + src = src.Derive(bufferi); + for (int i = 0; i < bufferl; i++) + { + Buffer[i] = (short)src.Dec_ndr_short(); + } + } + } + } + + public class SidT : NdrObject + { + public byte Revision; + + public byte SubAuthorityCount; + + public byte[] IdentifierAuthority; + + public int[] SubAuthority; + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Encode(NdrBuffer dst) + { + dst.Align(4); + int subAuthoritys = SubAuthorityCount; + dst.Enc_ndr_long(subAuthoritys); + dst.Enc_ndr_small(Revision); + dst.Enc_ndr_small(SubAuthorityCount); + int identifierAuthoritys = 6; + int identifierAuthorityi = dst.Index; + dst.Advance(1 * identifierAuthoritys); + int subAuthorityi = dst.Index; + dst.Advance(4 * subAuthoritys); + dst = dst.Derive(identifierAuthorityi); + for (int i = 0; i < identifierAuthoritys; i++) + { + dst.Enc_ndr_small(IdentifierAuthority[i]); + } + dst = dst.Derive(subAuthorityi); + for (int i1 = 0; i1 < subAuthoritys; i1++) + { + dst.Enc_ndr_long(SubAuthority[i1]); + } + } + + /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception> + public override void Decode(NdrBuffer src) + { + src.Align(4); + int subAuthoritys = src.Dec_ndr_long(); + Revision = unchecked((byte)src.Dec_ndr_small()); + SubAuthorityCount = unchecked((byte)src.Dec_ndr_small()); + int identifierAuthoritys = 6; + int identifierAuthorityi = src.Index; + src.Advance(1 * identifierAuthoritys); + int subAuthorityi = src.Index; + src.Advance(4 * subAuthoritys); + if (IdentifierAuthority == null) + { + if (identifierAuthoritys < 0 || identifierAuthoritys > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + IdentifierAuthority = new byte[identifierAuthoritys]; + } + src = src.Derive(identifierAuthorityi); + for (int i = 0; i < identifierAuthoritys; i++) + { + IdentifierAuthority[i] = unchecked((byte)src.Dec_ndr_small()); + } + if (SubAuthority == null) + { + if (subAuthoritys < 0 || subAuthoritys > unchecked(0xFFFF)) + { + throw new NdrException(NdrException.InvalidConformance); + } + SubAuthority = new int[subAuthoritys]; + } + src = src.Derive(subAuthorityi); + for (int i1 = 0; i1 < subAuthoritys; i1++) + { + SubAuthority[i1] = src.Dec_ndr_long(); + } + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/UUID.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/UUID.cs new file mode 100644 index 000000000..bef4be214 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/UUID.cs @@ -0,0 +1,148 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Dcerpc +{ + public class Uuid : Rpc.UuidT + { + public static int Hex_to_bin(char[] arr, int offset, int length) + { + int value = 0; + int ai; + int count; + count = 0; + for (ai = offset; ai < arr.Length && count < length; ai++) + { + value <<= 4; + switch (arr[ai]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + value += arr[ai] - '0'; + break; + } + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + { + value += 10 + (arr[ai] - 'A'); + break; + } + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + { + value += 10 + (arr[ai] - 'a'); + break; + } + + default: + { + throw new ArgumentException(new string(arr, offset, length)); + } + } + count++; + } + return value; + } + + internal static readonly char[] Hexchars = { '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + public static string Bin_to_hex(int value, int length) + { + char[] arr = new char[length]; + int ai = arr.Length; + while (ai-- > 0) + { + arr[ai] = Hexchars[value & unchecked(0xF)]; + value = (int)(((uint)value) >> 4); + } + return new string(arr); + } + + private static byte B(int i) + { + return unchecked((byte)(i & unchecked(0xFF))); + } + + private static short S(int i) + { + return (short)(i & unchecked(0xFFFF)); + } + + public Uuid(Rpc.UuidT uuid) + { + TimeLow = uuid.TimeLow; + TimeMid = uuid.TimeMid; + TimeHiAndVersion = uuid.TimeHiAndVersion; + ClockSeqHiAndReserved = uuid.ClockSeqHiAndReserved; + ClockSeqLow = uuid.ClockSeqLow; + Node = new byte[6]; + Node[0] = uuid.Node[0]; + Node[1] = uuid.Node[1]; + Node[2] = uuid.Node[2]; + Node[3] = uuid.Node[3]; + Node[4] = uuid.Node[4]; + Node[5] = uuid.Node[5]; + } + + public Uuid(string str) + { + char[] arr = str.ToCharArray(); + TimeLow = Hex_to_bin(arr, 0, 8); + TimeMid = S(Hex_to_bin(arr, 9, 4)); + TimeHiAndVersion = S(Hex_to_bin(arr, 14, 4)); + ClockSeqHiAndReserved = B(Hex_to_bin(arr, 19, 2)); + ClockSeqLow = B(Hex_to_bin(arr, 21, 2)); + Node = new byte[6]; + Node[0] = B(Hex_to_bin(arr, 24, 2)); + Node[1] = B(Hex_to_bin(arr, 26, 2)); + Node[2] = B(Hex_to_bin(arr, 28, 2)); + Node[3] = B(Hex_to_bin(arr, 30, 2)); + Node[4] = B(Hex_to_bin(arr, 32, 2)); + Node[5] = B(Hex_to_bin(arr, 34, 2)); + } + + public override string ToString() + { + return Bin_to_hex(TimeLow, 8) + '-' + Bin_to_hex(TimeMid, 4) + '-' + Bin_to_hex + (TimeHiAndVersion, 4) + '-' + Bin_to_hex(ClockSeqHiAndReserved, 2) + Bin_to_hex + (ClockSeqLow, 2) + '-' + Bin_to_hex(Node[0], 2) + Bin_to_hex(Node[1], 2) + Bin_to_hex + (Node[2], 2) + Bin_to_hex(Node[3], 2) + Bin_to_hex(Node[4], 2) + Bin_to_hex(Node + [5], 2); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/UnicodeString.cs b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/UnicodeString.cs new file mode 100644 index 000000000..b0c36898c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Dcerpc/UnicodeString.cs @@ -0,0 +1,65 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Dcerpc +{ + public class UnicodeString : Rpc.Unicode_string + { + internal bool Zterm; + + public UnicodeString(bool zterm) + { + this.Zterm = zterm; + } + + public UnicodeString(Rpc.Unicode_string rus, bool zterm) + { + Length = rus.Length; + MaximumLength = rus.MaximumLength; + Buffer = rus.Buffer; + this.Zterm = zterm; + } + + public UnicodeString(string str, bool zterm) + { + this.Zterm = zterm; + int len = str.Length; + int zt = zterm ? 1 : 0; + Length = MaximumLength = (short)((len + zt) * 2); + Buffer = new short[len + zt]; + int i; + for (i = 0; i < len; i++) + { + Buffer[i] = (short)str[i]; + } + if (zterm) + { + Buffer[i] = 0; + } + } + + public override string ToString() + { + int len = Length / 2 - (Zterm ? 1 : 0); + char[] ca = new char[len]; + for (int i = 0; i < len; i++) + { + ca[i] = (char)Buffer[i]; + } + return new string(ca, 0, len); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs new file mode 100644 index 000000000..c94d0a260 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/Lmhosts.cs @@ -0,0 +1,202 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; +using SharpCifs.Smb; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Netbios +{ + public class Lmhosts + { + private static readonly string Filename = Config.GetProperty("jcifs.netbios.lmhosts" + ); + + private static readonly Hashtable Tab = new Hashtable(); + + private static long _lastModified = 1L; + + private static int _alt; + + private static LogStream _log = LogStream.GetInstance(); + + /// <summary> + /// This is really just for + /// <see cref="SharpCifs.UniAddress">Jcifs.UniAddress</see> + /// . It does + /// not throw an + /// <see cref="UnknownHostException">Sharpen.UnknownHostException</see> + /// because this + /// is queried frequently and exceptions would be rather costly to + /// throw on a regular basis here. + /// </summary> + public static NbtAddress GetByName(string host) + { + lock (typeof(Lmhosts)) + { + return GetByName(new Name(host, 0x20, null)); + } + } + + internal static NbtAddress GetByName(Name name) + { + lock (typeof(Lmhosts)) + { + NbtAddress result = null; + try + { + if (Filename != null) + { + FilePath f = new FilePath(Filename); + long lm; + if ((lm = f.LastModified()) > _lastModified) + { + _lastModified = lm; + Tab.Clear(); + _alt = 0; + + //path -> fileStream + //Populate(new FileReader(f)); + Populate(new FileReader(new FileStream(f, FileMode.Open))); + } + result = (NbtAddress)Tab[name]; + } + } + catch (FileNotFoundException fnfe) + { + if (_log.Level > 1) + { + _log.WriteLine("lmhosts file: " + Filename); + Runtime.PrintStackTrace(fnfe, _log); + } + } + catch (IOException ioe) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(ioe, _log); + } + } + return result; + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal static void Populate(StreamReader r) + { + string line; + BufferedReader br = new BufferedReader((InputStreamReader)r); + while ((line = br.ReadLine()) != null) + { + line = line.ToUpper().Trim(); + if (line.Length == 0) + { + } + else + { + if (line[0] == '#') + { + if (line.StartsWith("#INCLUDE ")) + { + line = Runtime.Substring(line, line.IndexOf('\\')); + string url = "smb:" + line.Replace('\\', '/'); + if (_alt > 0) + { + try + { + Populate(new InputStreamReader(new SmbFileInputStream(url))); + } + catch (IOException ioe) + { + _log.WriteLine("lmhosts URL: " + url); + Runtime.PrintStackTrace(ioe, _log); + continue; + } + _alt--; + while ((line = br.ReadLine()) != null) + { + line = line.ToUpper().Trim(); + if (line.StartsWith("#END_ALTERNATE")) + { + break; + } + } + } + else + { + Populate(new InputStreamReader(new SmbFileInputStream(url))); + } + } + else + { + if (line.StartsWith("#BEGIN_ALTERNATE")) + { + _alt++; + } + else + { + if (line.StartsWith("#END_ALTERNATE") && _alt > 0) + { + _alt--; + throw new IOException("no lmhosts alternate includes loaded"); + } + } + } + } + else + { + if (char.IsDigit(line[0])) + { + char[] data = line.ToCharArray(); + int ip; + int i; + int j; + Name name; + NbtAddress addr; + char c; + c = '.'; + ip = i = 0; + for (; i < data.Length && c == '.'; i++) + { + int b = unchecked(0x00); + for (; i < data.Length && (c = data[i]) >= 48 && c <= 57; i++) + { + b = b * 10 + c - '0'; + } + ip = (ip << 8) + b; + } + while (i < data.Length && char.IsWhiteSpace(data[i])) + { + i++; + } + j = i; + while (j < data.Length && char.IsWhiteSpace(data[j]) == false) + { + j++; + } + name = new Name(Runtime.Substring(line, i, j), unchecked(0x20), null + ); + addr = new NbtAddress(name, ip, false, NbtAddress.BNode, false, false, true, true + , NbtAddress.UnknownMacAddress); + Tab.Put(name, addr); + } + } + } + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/Name.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/Name.cs new file mode 100644 index 000000000..6c37d57a4 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/Name.cs @@ -0,0 +1,269 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Text; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Netbios +{ + public class Name + { + private const int TypeOffset = 31; + + private const int ScopeOffset = 33; + + private static readonly string DefaultScope = Config.GetProperty("jcifs.netbios.scope" + ); + + internal static readonly string OemEncoding = Config.GetProperty("jcifs.encoding" + , Runtime.GetProperty("file.encoding")); + + public string name; + + public string Scope; + + public int HexCode; + + internal int SrcHashCode; + + public Name() + { + } + + public Name(string name, int hexCode, string scope) + { + if (name.Length > 15) + { + name = Runtime.Substring(name, 0, 15); + } + this.name = name.ToUpper(); + this.HexCode = hexCode; + this.Scope = !string.IsNullOrEmpty(scope) ? scope : DefaultScope; + SrcHashCode = 0; + } + + internal virtual int WriteWireFormat(byte[] dst, int dstIndex) + { + // write 0x20 in first byte + dst[dstIndex] = unchecked(0x20); + // write name + try + { + byte[] tmp = Runtime.GetBytesForString(name, OemEncoding + ); + int i; + for (i = 0; i < tmp.Length; i++) + { + dst[dstIndex + (2 * i + 1)] = unchecked((byte)(((tmp[i] & unchecked(0xF0)) + >> 4) + unchecked(0x41))); + dst[dstIndex + (2 * i + 2)] = unchecked((byte)((tmp[i] & unchecked(0x0F)) + + unchecked(0x41))); + } + for (; i < 15; i++) + { + dst[dstIndex + (2 * i + 1)] = unchecked(unchecked(0x43)); + dst[dstIndex + (2 * i + 2)] = unchecked(unchecked(0x41)); + } + dst[dstIndex + TypeOffset] = unchecked((byte)(((HexCode & unchecked(0xF0) + ) >> 4) + unchecked(0x41))); + dst[dstIndex + TypeOffset + 1] = unchecked((byte)((HexCode & unchecked(0x0F)) + unchecked(0x41))); + } + catch (UnsupportedEncodingException) + { + } + return ScopeOffset + WriteScopeWireFormat(dst, dstIndex + ScopeOffset); + } + + internal virtual int ReadWireFormat(byte[] src, int srcIndex) + { + byte[] tmp = new byte[ScopeOffset]; + int length = 15; + for (int i = 0; i < 15; i++) + { + tmp[i] = unchecked((byte)(((src[srcIndex + (2 * i + 1)] & unchecked(0xFF)) + - unchecked(0x41)) << 4)); + tmp[i] |= unchecked((byte)(((src[srcIndex + (2 * i + 2)] & unchecked(0xFF) + ) - unchecked(0x41)) & unchecked(0x0F))); + if (tmp[i] != unchecked((byte)' ')) + { + length = i + 1; + } + } + try + { + name = Runtime.GetStringForBytes(tmp, 0, length, OemEncoding + ); + } + catch (UnsupportedEncodingException) + { + } + HexCode = ((src[srcIndex + TypeOffset] & unchecked(0xFF)) - unchecked(0x41)) << 4; + HexCode |= ((src[srcIndex + TypeOffset + 1] & unchecked(0xFF)) - unchecked( + 0x41)) & unchecked(0x0F); + return ScopeOffset + ReadScopeWireFormat(src, srcIndex + ScopeOffset); + } + + internal int ReadWireFormatDos(byte[] src, int srcIndex) + { + + int length = 15; + byte[] tmp = new byte[length]; + + Array.Copy(src, srcIndex, tmp, 0, length); + + try + { + name = Runtime.GetStringForBytes(tmp, 0, length).Trim(); + } + catch (Exception ex) + { + + } + + HexCode = src[srcIndex + length]; + + return length + 1; + } + + + internal virtual int WriteScopeWireFormat(byte[] dst, int dstIndex) + { + if (Scope == null) + { + dst[dstIndex] = unchecked(unchecked(0x00)); + return 1; + } + // copy new scope in + dst[dstIndex++] = unchecked((byte)('.')); + try + { + Array.Copy(Runtime.GetBytesForString(Scope, OemEncoding + ), 0, dst, dstIndex, Scope.Length); + } + catch (UnsupportedEncodingException) + { + } + dstIndex += Scope.Length; + dst[dstIndex++] = unchecked(unchecked(0x00)); + // now go over scope backwards converting '.' to label length + int i = dstIndex - 2; + int e = i - Scope.Length; + int c = 0; + do + { + if (dst[i] == '.') + { + dst[i] = unchecked((byte)c); + c = 0; + } + else + { + c++; + } + } + while (i-- > e); + return Scope.Length + 2; + } + + internal virtual int ReadScopeWireFormat(byte[] src, int srcIndex) + { + int start = srcIndex; + int n; + StringBuilder sb; + if ((n = src[srcIndex++] & unchecked(0xFF)) == 0) + { + Scope = null; + return 1; + } + try + { + sb = new StringBuilder(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding)); + srcIndex += n; + while ((n = src[srcIndex++] & unchecked(0xFF)) != 0) + { + sb.Append('.').Append(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding)); + srcIndex += n; + } + Scope = sb.ToString(); + } + catch (UnsupportedEncodingException) + { + } + return srcIndex - start; + } + + public override int GetHashCode() + { + int result; + result = name.GetHashCode(); + result += 65599 * HexCode; + result += 65599 * SrcHashCode; + if (Scope != null && Scope.Length != 0) + { + result += Scope.GetHashCode(); + } + return result; + } + + public override bool Equals(object obj) + { + Name n; + if (!(obj is Name)) + { + return false; + } + n = (Name)obj; + if (Scope == null && n.Scope == null) + { + return name.Equals(n.name) && HexCode == n.HexCode; + } + return name.Equals(n.name) && HexCode == n.HexCode && Scope.Equals(n.Scope); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + //return ""; + + string n = name; + // fix MSBROWSE name + if (n == null) + { + n = "null"; + } + else + { + if (n[0] == unchecked(0x01)) + { + char[] c = n.ToCharArray(); + c[0] = '.'; + c[1] = '.'; + c[14] = '.'; + n = new string(c); + } + } + sb.Append(n).Append("<").Append(Hexdump.ToHexString(HexCode, 2)).Append(">"); + if (Scope != null) + { + sb.Append(".").Append(Scope); + } + return sb.ToString(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs new file mode 100644 index 000000000..646e65bf8 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameQueryRequest.cs @@ -0,0 +1,52 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Netbios +{ + internal class NameQueryRequest : NameServicePacket + { + internal NameQueryRequest(Name name) + { + QuestionName = name; + QuestionType = Nb; + } + + internal override int WriteBodyWireFormat(byte[] dst, int dstIndex) + { + return WriteQuestionSectionWireFormat(dst, dstIndex); + } + + internal override int ReadBodyWireFormat(byte[] src, int srcIndex) + { + return ReadQuestionSectionWireFormat(src, srcIndex); + } + + internal override int WriteRDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadRDataWireFormat(byte[] src, int srcIndex) + { + return 0; + } + + public override string ToString() + { + return "NameQueryRequest[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs new file mode 100644 index 000000000..c7fac8e93 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameQueryResponse.cs @@ -0,0 +1,68 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Netbios +{ + internal class NameQueryResponse : NameServicePacket + { + public NameQueryResponse() + { + RecordName = new Name(); + } + + internal override int WriteBodyWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadBodyWireFormat(byte[] src, int srcIndex) + { + return ReadResourceRecordWireFormat(src, srcIndex); + } + + internal override int WriteRDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadRDataWireFormat(byte[] src, int srcIndex) + { + if (ResultCode != 0 || OpCode != Query) + { + return 0; + } + bool groupName = ((src[srcIndex] & unchecked(0x80)) == unchecked(0x80)) ? true : false; + int nodeType = (src[srcIndex] & unchecked(0x60)) >> 5; + srcIndex += 2; + int address = ReadInt4(src, srcIndex); + if (address != 0) + { + AddrEntry[AddrIndex] = new NbtAddress(RecordName, address, groupName, nodeType); + } + else + { + AddrEntry[AddrIndex] = null; + } + return 6; + } + + public override string ToString() + { + return "NameQueryResponse[" + base.ToString() + ",addrEntry=" + AddrEntry + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs new file mode 100644 index 000000000..01700e64a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameServiceClient.cs @@ -0,0 +1,660 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Linq; +using System.Threading; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +using Thread = SharpCifs.Util.Sharpen.Thread; + +namespace SharpCifs.Netbios +{ + internal class NameServiceClient : IRunnable + { + internal const int DefaultSoTimeout = 5000; + + internal const int DefaultRcvBufSize = 576; + + internal const int DefaultSndBufSize = 576; + + internal const int NameServiceUdpPort = 137; + + internal const int DefaultRetryCount = 2; + + internal const int DefaultRetryTimeout = 3000; + + internal const int ResolverLmhosts = 1; + + internal const int ResolverBcast = 2; + + internal const int ResolverWins = 3; + + private static readonly int SndBufSize = Config.GetInt("jcifs.netbios.snd_buf_size" + , DefaultSndBufSize); + + private static readonly int RcvBufSize = Config.GetInt("jcifs.netbios.rcv_buf_size" + , DefaultRcvBufSize); + + private static readonly int SoTimeout = Config.GetInt("jcifs.netbios.soTimeout", + DefaultSoTimeout); + + private static readonly int RetryCount = Config.GetInt("jcifs.netbios.retryCount" + , DefaultRetryCount); + + private static readonly int RetryTimeout = Config.GetInt("jcifs.netbios.retryTimeout" + , DefaultRetryTimeout); + + private static readonly int Lport = Config.GetInt("jcifs.netbios.lport", 137); + + private static readonly IPAddress Laddr = Config.GetInetAddress("jcifs.netbios.laddr" + , null); + + private static readonly string Ro = Config.GetProperty("jcifs.resolveOrder"); + + private static LogStream _log = LogStream.GetInstance(); + + private readonly object _lock = new object(); + + private int _lport; + + private int _closeTimeout; + + private byte[] _sndBuf; + + private byte[] _rcvBuf; + + private SocketEx _socket; + + private Hashtable _responseTable = new Hashtable(); + + private Thread _thread; + + private int _nextNameTrnId; + + private int[] _resolveOrder; + + private bool _waitResponse = true; + + private AutoResetEvent _autoResetWaitReceive; + + internal IPAddress laddr; + + internal IPAddress Baddr; + + public NameServiceClient() + : this(Lport, Laddr) + { + } + + internal NameServiceClient(int lport, IPAddress laddr) + { + this._lport = lport; + + this.laddr = laddr + ?? Config.GetLocalHost() + ?? Extensions.GetAddressesByName(Dns.GetHostName()).FirstOrDefault(); + + try + { + Baddr = Config.GetInetAddress("jcifs.netbios.baddr", Extensions.GetAddressByName("255.255.255.255")); + } + catch (Exception ex) + { + } + + _sndBuf = new byte[SndBufSize]; + _rcvBuf = new byte[RcvBufSize]; + + + if (string.IsNullOrEmpty(Ro)) + { + if (NbtAddress.GetWinsAddress() == null) + { + _resolveOrder = new int[2]; + _resolveOrder[0] = ResolverLmhosts; + _resolveOrder[1] = ResolverBcast; + } + else + { + _resolveOrder = new int[3]; + _resolveOrder[0] = ResolverLmhosts; + _resolveOrder[1] = ResolverWins; + _resolveOrder[2] = ResolverBcast; + } + } + else + { + int[] tmp = new int[3]; + StringTokenizer st = new StringTokenizer(Ro, ","); + int i = 0; + while (st.HasMoreTokens()) + { + string s = st.NextToken().Trim(); + if (Runtime.EqualsIgnoreCase(s, "LMHOSTS")) + { + tmp[i++] = ResolverLmhosts; + } + else + { + if (Runtime.EqualsIgnoreCase(s, "WINS")) + { + if (NbtAddress.GetWinsAddress() == null) + { + if (_log.Level > 1) + { + _log.WriteLine("NetBIOS resolveOrder specifies WINS however the " + "jcifs.netbios.wins property has not been set" + ); + } + continue; + } + tmp[i++] = ResolverWins; + } + else + { + if (Runtime.EqualsIgnoreCase(s, "BCAST")) + { + tmp[i++] = ResolverBcast; + } + else + { + if (Runtime.EqualsIgnoreCase(s, "DNS")) + { + } + else + { + // skip + if (_log.Level > 1) + { + _log.WriteLine("unknown resolver method: " + s); + } + } + } + } + } + } + _resolveOrder = new int[i]; + Array.Copy(tmp, 0, _resolveOrder, 0, i); + } + } + + internal virtual int GetNextNameTrnId() + { + if ((++_nextNameTrnId & unchecked(0xFFFF)) == 0) + { + _nextNameTrnId = 1; + } + return _nextNameTrnId; + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual void EnsureOpen(int timeout) + { + _closeTimeout = 0; + if (SoTimeout != 0) + { + _closeTimeout = Math.Max(SoTimeout, timeout); + } + // If socket is still good, the new closeTimeout will + // be ignored; see tryClose comment. + if (_socket == null) + { + _socket = new SocketEx(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + + //IPAddress.`Address` property deleted + //_socket.Bind(new IPEndPoint(laddr.Address, _lport)); + _socket.Bind(new IPEndPoint(laddr, _lport)); + + if (_waitResponse) + { + _thread = new Thread(this); //new Sharpen.Thread(this, "JCIFS-NameServiceClient"); + _thread.SetDaemon(true); + _thread.Start(); + } + } + } + + internal virtual void TryClose() + { + lock (_lock) + { + if (_socket != null) + { + //Socket.`Close` method deleted + //_socket.Close(); + _socket.Dispose(); + _socket = null; + } + _thread = null; + + if (_waitResponse) + { + _responseTable.Clear(); + } else + { + _autoResetWaitReceive.Set(); + } + } + } + + public virtual void Run() + { + int nameTrnId; + NameServicePacket response; + + try + { + + while (_thread == Thread.CurrentThread()) + { + _socket.SoTimeOut = _closeTimeout; + + int len = _socket.Receive(_rcvBuf, 0, RcvBufSize); + + if (_log.Level > 3) + { + _log.WriteLine("NetBIOS: new data read from socket"); + } + nameTrnId = NameServicePacket.ReadNameTrnId(_rcvBuf, 0); + response = (NameServicePacket)_responseTable.Get(nameTrnId); + + + if (response == null || response.Received) + { + continue; + } + + lock (response) + { + response.ReadWireFormat(_rcvBuf, 0); + + if (_log.Level > 3) + { + _log.WriteLine(response); + Hexdump.ToHexdump(_log, _rcvBuf, 0, len); + } + + if (response.IsResponse) + { + response.Received = true; + + Runtime.Notify(response); + } + } + } + + } + catch (TimeoutException) { } + catch (Exception ex) + { + if (_log.Level > 2) + { + Runtime.PrintStackTrace(ex, _log); + } + } + finally + { + TryClose(); + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual void Send(NameServicePacket request, NameServicePacket response, + int timeout) + { + int nid = 0; + int max = NbtAddress.Nbns.Length; + if (max == 0) + { + max = 1; + } + + lock (response) + { + + while (max-- > 0) + { + try + { + lock (_lock) + { + request.NameTrnId = GetNextNameTrnId(); + nid = request.NameTrnId; + response.Received = false; + _responseTable.Put(nid, response); + EnsureOpen(timeout + 1000); + int requestLenght = request.WriteWireFormat(_sndBuf, 0); + _socket.Send(_sndBuf, 0, requestLenght, new IPEndPoint(request.Addr, _lport)); + if (_log.Level > 3) + { + _log.WriteLine(request); + Hexdump.ToHexdump(_log, _sndBuf, 0, requestLenght); + } + + } + if (_waitResponse) + { + long start = Runtime.CurrentTimeMillis(); + while (timeout > 0) + { + Runtime.Wait(response, timeout); + if (response.Received && request.QuestionType == response.RecordType) + { + return; + } + response.Received = false; + timeout -= (int)(Runtime.CurrentTimeMillis() - start); + } + } + } + catch (Exception ie) + { + throw new IOException(ie.Message); + } + finally + { + //Sharpen.Collections.Remove(responseTable, nid); + if (_waitResponse) + { + _responseTable.Remove(nid); + } + } + if (_waitResponse) + { + lock (_lock) + { + if (NbtAddress.IsWins(request.Addr) == false) + { + break; + } + if (request.Addr == NbtAddress.GetWinsAddress()) + { + NbtAddress.SwitchWins(); + } + request.Addr = NbtAddress.GetWinsAddress(); + } + } + } + } + } + + /// <exception cref="UnknownHostException"></exception> + internal virtual NbtAddress[] GetAllByName(Name name, IPAddress addr) + { + int n; + NameQueryRequest request = new NameQueryRequest(name); + NameQueryResponse response = new NameQueryResponse(); + request.Addr = addr ?? NbtAddress.GetWinsAddress(); + request.IsBroadcast = request.Addr == null; + if (request.IsBroadcast) + { + request.Addr = Baddr; + n = RetryCount; + } + else + { + request.IsBroadcast = false; + n = 1; + } + do + { + try + { + Send(request, response, RetryTimeout); + } + catch (IOException ioe) + { + if (_log.Level > 1) + { + Runtime.PrintStackTrace(ioe, _log); + } + throw new UnknownHostException(ioe); + } + if (response.Received && response.ResultCode == 0) + { + return response.AddrEntry; + } + } + while (--n > 0 && request.IsBroadcast); + throw new UnknownHostException(); + } + + /// <exception cref="UnknownHostException"></exception> + internal virtual NbtAddress GetByName(Name name, IPAddress addr) + { + int n; + + NameQueryRequest request = new NameQueryRequest(name); + NameQueryResponse response = new NameQueryResponse(); + if (addr != null) + { + request.Addr = addr; + request.IsBroadcast = (addr.GetAddressBytes()[3] == unchecked(unchecked(0xFF))); + n = RetryCount; + do + { + try + { + Send(request, response, RetryTimeout); + } + catch (IOException ioe) + { + if (_log.Level > 1) + { + Runtime.PrintStackTrace(ioe, _log); + } + throw new UnknownHostException(ioe); + } + if (response.Received && response.ResultCode == 0 + && response.IsResponse) + { + int last = response.AddrEntry.Length - 1; + response.AddrEntry[last].HostName.SrcHashCode = addr.GetHashCode(); + return response.AddrEntry[last]; + } + } + while (--n > 0 && request.IsBroadcast); + throw new UnknownHostException(); + } + for (int i = 0; i < _resolveOrder.Length; i++) + { + try + { + switch (_resolveOrder[i]) + { + case ResolverLmhosts: + { + NbtAddress ans = Lmhosts.GetByName(name); + if (ans != null) + { + ans.HostName.SrcHashCode = 0; + // just has to be different + // from other methods + return ans; + } + break; + } + + case ResolverWins: + case ResolverBcast: + { + if (_resolveOrder[i] == ResolverWins && name.name != NbtAddress.MasterBrowserName + && name.HexCode != unchecked(0x1d)) + { + request.Addr = NbtAddress.GetWinsAddress(); + request.IsBroadcast = false; + } + else + { + request.Addr = Baddr; + request.IsBroadcast = true; + } + n = RetryCount; + while (n-- > 0) + { + try + { + Send(request, response, RetryTimeout); + } + catch (IOException ioe) + { + if (_log.Level > 1) + { + Runtime.PrintStackTrace(ioe, _log); + } + throw new UnknownHostException(ioe); + } + if (response.Received && response.ResultCode == 0 + && response.IsResponse) + { + + response.AddrEntry[0].HostName.SrcHashCode = request.Addr.GetHashCode(); + return response.AddrEntry[0]; + } + if (_resolveOrder[i] == ResolverWins) + { + break; + } + } + break; + } + } + } + catch (IOException) + { + } + } + throw new UnknownHostException(); + } + + /// <exception cref="UnknownHostException"></exception> + internal virtual NbtAddress[] GetNodeStatus(NbtAddress addr) + { + int n; + int srcHashCode; + NodeStatusRequest request; + NodeStatusResponse response; + response = new NodeStatusResponse(addr); + request = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName, unchecked(0x00), null)); + request.Addr = addr.GetInetAddress(); + n = RetryCount; + while (n-- > 0) + { + try + { + Send(request, response, RetryTimeout); + } + catch (IOException ioe) + { + if (_log.Level > 1) + { + Runtime.PrintStackTrace(ioe, _log); + } + throw new UnknownHostException(ioe); + } + if (response.Received && response.ResultCode == 0) + { + srcHashCode = request.Addr.GetHashCode(); + for (int i = 0; i < response.AddressArray.Length; i++) + { + response.AddressArray[i].HostName.SrcHashCode = srcHashCode; + } + return response.AddressArray; + } + } + throw new UnknownHostException(); + } + + internal virtual NbtAddress[] GetHosts() + { + try + { + _waitResponse = false; + + byte[] bAddrBytes = laddr.GetAddressBytes(); + + for (int i = 1; i <= 254; i++) + { + NodeStatusRequest request; + NodeStatusResponse response; + + byte[] addrBytes = { + bAddrBytes[0], + bAddrBytes[1], + bAddrBytes[2], + (byte)i + }; + + IPAddress addr = new IPAddress(addrBytes); + + //response = new NodeStatusResponse(new NbtAddress(NbtAddress.UnknownName, + // (int)addr.Address, false, 0x20)); + response = new NodeStatusResponse(new NbtAddress(NbtAddress.UnknownName, + BitConverter.ToInt32(addr.GetAddressBytes(), 0) , false, 0x20)); + + request = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName, unchecked(0x20), null)); + request.Addr = addr; + Send(request, response, 0); + } + + } + catch (IOException ioe) + { + if (_log.Level > 1) + { + Runtime.PrintStackTrace(ioe, _log); + } + throw new UnknownHostException(ioe); + } + + _autoResetWaitReceive = new AutoResetEvent(false); + _thread = new Thread(this); + _thread.SetDaemon(true); + _thread.Start(); + + _autoResetWaitReceive.WaitOne(); + + List<NbtAddress> result = new List<NbtAddress>(); + + foreach (var key in _responseTable.Keys) + { + NodeStatusResponse resp = (NodeStatusResponse)_responseTable[key]; + + if (resp.Received && resp.ResultCode == 0) + { + foreach (var entry in resp.AddressArray) + { + if (entry.HostName.HexCode == 0x20) + { + result.Add(entry); + } + } + } + } + + _responseTable.Clear(); + + _waitResponse = true; + + return result.Count > 0 ? result.ToArray() : null; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs new file mode 100644 index 000000000..28e98406e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NameServicePacket.cs @@ -0,0 +1,448 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.Net; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Netbios +{ + internal abstract class NameServicePacket + { + internal const int Query = 0; + + internal const int Wack = 7; + + internal const int FmtErr = 0x1; + + internal const int SrvErr = 0x2; + + internal const int ImpErr = 0x4; + + internal const int RfsErr = 0x5; + + internal const int ActErr = 0x6; + + internal const int CftErr = 0x7; + + internal const int NbIn = 0x00200001; + + internal const int NbstatIn = 0x00210001; + + internal const int Nb = 0x0020; + + internal const int Nbstat = 0x0021; + + internal const int In = 0x0001; + + internal const int A = 0x0001; + + internal const int Ns = 0x0002; + + internal const int Null = 0x000a; + + internal const int HeaderLength = 12; + + internal const int OpcodeOffset = 2; + + internal const int QuestionOffset = 4; + + internal const int AnswerOffset = 6; + + internal const int AuthorityOffset = 8; + + internal const int AdditionalOffset = 10; + + // opcode + // rcode + // type/class + // header field offsets + internal static void WriteInt2(int val, byte[] dst, int dstIndex) + { + dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF))); + dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF))); + } + + internal static void WriteInt4(int val, byte[] dst, int dstIndex) + { + dst[dstIndex++] = unchecked((byte)((val >> 24) & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((val >> 16) & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF))); + dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF))); + } + + internal static int ReadInt2(byte[] src, int srcIndex) + { + return ((src[srcIndex] & unchecked(0xFF)) << 8) + (src[srcIndex + 1] & unchecked( + 0xFF)); + } + + internal static int ReadInt4(byte[] src, int srcIndex) + { + return ((src[srcIndex] & unchecked(0xFF)) << 24) + ((src[srcIndex + 1] & unchecked( + 0xFF)) << 16) + ((src[srcIndex + 2] & unchecked(0xFF)) << 8) + (src + [srcIndex + 3] & unchecked(0xFF)); + } + + internal static int ReadNameTrnId(byte[] src, int srcIndex) + { + return ReadInt2(src, srcIndex); + } + + internal int AddrIndex; + + internal NbtAddress[] AddrEntry; + + internal int NameTrnId; + + internal int OpCode; + + internal int ResultCode; + + internal int QuestionCount; + + internal int AnswerCount; + + internal int AuthorityCount; + + internal int AdditionalCount; + + internal bool Received; + + internal bool IsResponse; + + internal bool IsAuthAnswer; + + internal bool IsTruncated; + + internal bool IsRecurDesired; + + internal bool IsRecurAvailable; + + internal bool IsBroadcast; + + internal Name QuestionName; + + internal Name RecordName; + + internal int QuestionType; + + internal int QuestionClass; + + internal int RecordType; + + internal int RecordClass; + + internal int Ttl; + + internal int RDataLength; + + internal IPAddress Addr; + + public NameServicePacket() + { + IsRecurDesired = true; + IsBroadcast = true; + QuestionCount = 1; + QuestionClass = In; + } + + internal virtual int WriteWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dstIndex += WriteHeaderWireFormat(dst, dstIndex); + dstIndex += WriteBodyWireFormat(dst, dstIndex); + return dstIndex - start; + } + + internal virtual int ReadWireFormat(byte[] src, int srcIndex) + { + int start = srcIndex; + srcIndex += ReadHeaderWireFormat(src, srcIndex); + srcIndex += ReadBodyWireFormat(src, srcIndex); + return srcIndex - start; + } + + internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(NameTrnId, dst, dstIndex); + dst[dstIndex + OpcodeOffset] = unchecked((byte)((IsResponse ? unchecked(0x80) : unchecked(0x00)) + ((OpCode << 3) & unchecked(0x78)) + (IsAuthAnswer + ? unchecked(0x04) : unchecked(0x00)) + (IsTruncated ? unchecked(0x02) : unchecked(0x00)) + (IsRecurDesired ? unchecked(0x01) + : unchecked(0x00)))); + dst[dstIndex + OpcodeOffset + 1] = unchecked((byte)((IsRecurAvailable ? unchecked( + 0x80) : unchecked(0x00)) + (IsBroadcast ? unchecked(0x10) : + unchecked(0x00)) + (ResultCode & unchecked(0x0F)))); + WriteInt2(QuestionCount, dst, start + QuestionOffset); + WriteInt2(AnswerCount, dst, start + AnswerOffset); + WriteInt2(AuthorityCount, dst, start + AuthorityOffset); + WriteInt2(AdditionalCount, dst, start + AdditionalOffset); + return HeaderLength; + } + + internal virtual int ReadHeaderWireFormat(byte[] src, int srcIndex) + { + NameTrnId = ReadInt2(src, srcIndex); + IsResponse = ((src[srcIndex + OpcodeOffset] & unchecked(0x80)) == 0) ? false + : true; + OpCode = (src[srcIndex + OpcodeOffset] & unchecked(0x78)) >> 3; + IsAuthAnswer = ((src[srcIndex + OpcodeOffset] & unchecked(0x04)) == 0) ? + false : true; + IsTruncated = ((src[srcIndex + OpcodeOffset] & unchecked(0x02)) == 0) ? false + : true; + IsRecurDesired = ((src[srcIndex + OpcodeOffset] & unchecked(0x01)) == 0) ? + false : true; + IsRecurAvailable = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x80)) + == 0) ? false : true; + IsBroadcast = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x10)) == 0) + ? false : true; + ResultCode = src[srcIndex + OpcodeOffset + 1] & unchecked(0x0F); + QuestionCount = ReadInt2(src, srcIndex + QuestionOffset); + AnswerCount = ReadInt2(src, srcIndex + AnswerOffset); + AuthorityCount = ReadInt2(src, srcIndex + AuthorityOffset); + AdditionalCount = ReadInt2(src, srcIndex + AdditionalOffset); + return HeaderLength; + } + + internal virtual int WriteQuestionSectionWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dstIndex += QuestionName.WriteWireFormat(dst, dstIndex); + WriteInt2(QuestionType, dst, dstIndex); + dstIndex += 2; + WriteInt2(QuestionClass, dst, dstIndex); + dstIndex += 2; + return dstIndex - start; + } + + internal virtual int ReadQuestionSectionWireFormat(byte[] src, int srcIndex) + { + int start = srcIndex; + srcIndex += QuestionName.ReadWireFormat(src, srcIndex); + QuestionType = ReadInt2(src, srcIndex); + srcIndex += 2; + QuestionClass = ReadInt2(src, srcIndex); + srcIndex += 2; + return srcIndex - start; + } + + internal virtual int WriteResourceRecordWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + if (RecordName == QuestionName) + { + dst[dstIndex++] = unchecked(unchecked(0xC0)); + // label string pointer to + dst[dstIndex++] = unchecked(unchecked(0x0C)); + } + else + { + // questionName (offset 12) + dstIndex += RecordName.WriteWireFormat(dst, dstIndex); + } + WriteInt2(RecordType, dst, dstIndex); + dstIndex += 2; + WriteInt2(RecordClass, dst, dstIndex); + dstIndex += 2; + WriteInt4(Ttl, dst, dstIndex); + dstIndex += 4; + RDataLength = WriteRDataWireFormat(dst, dstIndex + 2); + WriteInt2(RDataLength, dst, dstIndex); + dstIndex += 2 + RDataLength; + return dstIndex - start; + } + + internal virtual int ReadResourceRecordWireFormat(byte[] src, int srcIndex) + { + int start = srcIndex; + int end; + if ((src[srcIndex] & unchecked(0xC0)) == unchecked(0xC0)) + { + RecordName = QuestionName; + // label string pointer to questionName + srcIndex += 2; + } + else + { + srcIndex += RecordName.ReadWireFormat(src, srcIndex); + } + RecordType = ReadInt2(src, srcIndex); + srcIndex += 2; + RecordClass = ReadInt2(src, srcIndex); + srcIndex += 2; + Ttl = ReadInt4(src, srcIndex); + srcIndex += 4; + RDataLength = ReadInt2(src, srcIndex); + srcIndex += 2; + AddrEntry = new NbtAddress[RDataLength / 6]; + end = srcIndex + RDataLength; + for (AddrIndex = 0; srcIndex < end; AddrIndex++) + { + srcIndex += ReadRDataWireFormat(src, srcIndex); + } + return srcIndex - start; + } + + internal abstract int WriteBodyWireFormat(byte[] dst, int dstIndex); + + internal abstract int ReadBodyWireFormat(byte[] src, int srcIndex); + + internal abstract int WriteRDataWireFormat(byte[] dst, int dstIndex); + + internal abstract int ReadRDataWireFormat(byte[] src, int srcIndex); + + public override string ToString() + { + string opCodeString; + string resultCodeString; + string questionTypeString; + string recordTypeString; + + switch (OpCode) + { + case Query: + { + opCodeString = "QUERY"; + break; + } + + case Wack: + { + opCodeString = "WACK"; + break; + } + + default: + { + opCodeString = Extensions.ToString(OpCode); + break; + } + } + switch (ResultCode) + { + case FmtErr: + { + resultCodeString = "FMT_ERR"; + break; + } + + case SrvErr: + { + resultCodeString = "SRV_ERR"; + break; + } + + case ImpErr: + { + resultCodeString = "IMP_ERR"; + break; + } + + case RfsErr: + { + resultCodeString = "RFS_ERR"; + break; + } + + case ActErr: + { + resultCodeString = "ACT_ERR"; + break; + } + + case CftErr: + { + resultCodeString = "CFT_ERR"; + break; + } + + default: + { + resultCodeString = "0x" + Hexdump.ToHexString(ResultCode, 1); + break; + } + } + switch (QuestionType) + { + case Nb: + { + questionTypeString = "NB"; + break; + } + + case Nbstat: + { + questionTypeString = "NBSTAT"; + break; + } + + default: + { + questionTypeString = "0x" + Hexdump.ToHexString(QuestionType, 4); + break; + } + } + switch (RecordType) + { + case A: + { + recordTypeString = "A"; + break; + } + + case Ns: + { + recordTypeString = "NS"; + break; + } + + case Null: + { + recordTypeString = "NULL"; + break; + } + + case Nb: + { + recordTypeString = "NB"; + break; + } + + case Nbstat: + { + recordTypeString = "NBSTAT"; + break; + } + + default: + { + recordTypeString = "0x" + Hexdump.ToHexString(RecordType, 4); + break; + } + } + return "nameTrnId=" + NameTrnId + ",isResponse=" + IsResponse + ",opCode=" + + opCodeString + ",isAuthAnswer=" + IsAuthAnswer + ",isTruncated=" + IsTruncated + + ",isRecurAvailable=" + IsRecurAvailable + ",isRecurDesired=" + IsRecurDesired + + ",isBroadcast=" + IsBroadcast + ",resultCode=" + ResultCode + ",questionCount=" + + QuestionCount + ",answerCount=" + AnswerCount + ",authorityCount=" + AuthorityCount + + ",additionalCount=" + AdditionalCount + ",questionName=" + QuestionName + ",questionType=" + + questionTypeString + ",questionClass=" + (QuestionClass == In ? "IN" : "0x" + + Hexdump.ToHexString(QuestionClass, 4)) + ",recordName=" + RecordName + ",recordType=" + + recordTypeString + ",recordClass=" + (RecordClass == In ? "IN" : "0x" + Hexdump + .ToHexString(RecordClass, 4)) + ",ttl=" + Ttl + ",rDataLength=" + RDataLength; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs new file mode 100644 index 000000000..c64d385f1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtAddress.cs @@ -0,0 +1,920 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Linq; +using System.Net; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; +using Extensions = SharpCifs.Util.Sharpen.Extensions; + +namespace SharpCifs.Netbios +{ + /// <summary>This class represents a NetBIOS over TCP/IP address.</summary> + /// <remarks> + /// This class represents a NetBIOS over TCP/IP address. Under normal + /// conditions, users of jCIFS need not be concerned with this class as + /// name resolution and session services are handled internally by the smb package. + /// <p> Applications can use the methods <code>getLocalHost</code>, + /// <code>getByName</code>, and + /// <code>getAllByAddress</code> to create a new NbtAddress instance. This + /// class is symmetric with + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// . + /// <p><b>About NetBIOS:</b> The NetBIOS name + /// service is a dynamic distributed service that allows hosts to resolve + /// names by broadcasting a query, directing queries to a server such as + /// Samba or WINS. NetBIOS is currently the primary networking layer for + /// providing name service, datagram service, and session service to the + /// Microsoft Windows platform. A NetBIOS name can be 15 characters long + /// and hosts usually registers several names on the network. From a + /// Windows command prompt you can see + /// what names a host registers with the nbtstat command. + /// <p><blockquote><pre> + /// C:\>nbtstat -a 192.168.1.15 + /// NetBIOS Remote Machine Name Table + /// Name Type Status + /// --------------------------------------------- + /// JMORRIS2 <00> UNIQUE Registered + /// BILLING-NY <00> GROUP Registered + /// JMORRIS2 <03> UNIQUE Registered + /// JMORRIS2 <20> UNIQUE Registered + /// BILLING-NY <1E> GROUP Registered + /// JMORRIS <03> UNIQUE Registered + /// MAC Address = 00-B0-34-21-FA-3B + /// </blockquote></pre> + /// <p> The hostname of this machine is <code>JMORRIS2</code>. It is + /// a member of the group(a.k.a workgroup and domain) <code>BILLING-NY</code>. To + /// obtain an + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// for a host one might do: + /// <pre> + /// InetAddress addr = NbtAddress.getByName( "jmorris2" ).getInetAddress(); + /// </pre> + /// <p>From a UNIX platform with Samba installed you can perform similar + /// diagnostics using the <code>nmblookup</code> utility. + /// </remarks> + /// <author>Michael B. Allen</author> + /// <seealso cref="System.Net.IPAddress">System.Net.IPAddress</seealso> + /// <since>jcifs-0.1</since> + public sealed class NbtAddress + { + internal static readonly string AnyHostsName = "*\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"; + + /// <summary> + /// This is a special name for querying the master browser that serves the + /// list of hosts found in "Network Neighborhood". + /// </summary> + /// <remarks> + /// This is a special name for querying the master browser that serves the + /// list of hosts found in "Network Neighborhood". + /// </remarks> + public static readonly string MasterBrowserName = "\u0001\u0002__MSBROWSE__\u0002"; + + /// <summary> + /// A special generic name specified when connecting to a host for which + /// a name is not known. + /// </summary> + /// <remarks> + /// A special generic name specified when connecting to a host for which + /// a name is not known. Not all servers respond to this name. + /// </remarks> + public static readonly string SmbserverName = "*SMBSERVER "; + + /// <summary>A B node only broadcasts name queries.</summary> + /// <remarks> + /// A B node only broadcasts name queries. This is the default if a + /// nameserver such as WINS or Samba is not specified. + /// </remarks> + public const int BNode = 0; + + /// <summary> + /// A Point-to-Point node, or P node, unicasts queries to a nameserver + /// only. + /// </summary> + /// <remarks> + /// A Point-to-Point node, or P node, unicasts queries to a nameserver + /// only. Natrually the <code>jcifs.netbios.nameserver</code> property must + /// be set. + /// </remarks> + public const int PNode = 1; + + /// <summary> + /// Try Broadcast queries first, then try to resolve the name using the + /// nameserver. + /// </summary> + /// <remarks> + /// Try Broadcast queries first, then try to resolve the name using the + /// nameserver. + /// </remarks> + public const int MNode = 2; + + /// <summary>A Hybrid node tries to resolve a name using the nameserver first.</summary> + /// <remarks> + /// A Hybrid node tries to resolve a name using the nameserver first. If + /// that fails use the broadcast address. This is the default if a nameserver + /// is provided. This is the behavior of Microsoft Windows machines. + /// </remarks> + public const int HNode = 3; + + internal static readonly IPAddress[] Nbns = Config.GetInetAddressArray("jcifs.netbios.wins" + , ",", new IPAddress[0]); + + private static readonly NameServiceClient Client = new NameServiceClient(); + + private const int DefaultCachePolicy = 30; + + private static readonly int CachePolicy = Config.GetInt("jcifs.netbios.cachePolicy" + , DefaultCachePolicy); + + private const int Forever = -1; + + private static int _nbnsIndex; + + private static readonly Hashtable AddressCache = new Hashtable(); + + private static readonly Hashtable LookupTable = new Hashtable(); + + internal static readonly Name UnknownName = new Name("0.0.0.0", unchecked(0x00), null); + + internal static readonly NbtAddress UnknownAddress = new NbtAddress + (UnknownName, 0, false, BNode); + + internal static readonly byte[] UnknownMacAddress = { unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)), unchecked(unchecked(0x00)) }; + + internal sealed class CacheEntry + { + internal Name HostName; + + internal NbtAddress Address; + + internal long Expiration; + + internal CacheEntry(Name hostName, NbtAddress address, long expiration) + { + this.HostName = hostName; + this.Address = address; + this.Expiration = expiration; + } + } + + internal static NbtAddress Localhost; + + static NbtAddress() + { + IPAddress localInetAddress; + string localHostname; + Name localName; + AddressCache.Put(UnknownName, new CacheEntry(UnknownName, UnknownAddress + , Forever)); + localInetAddress = Client.laddr; + if (localInetAddress == null) + { + try + { + localInetAddress = Extensions.GetAddressByName("127.0.0.1"); + } + catch (UnknownHostException) + { + + } + } + localHostname = Config.GetProperty("jcifs.netbios.hostname", null); + if (string.IsNullOrEmpty(localHostname)) + { + byte[] addr = localInetAddress.GetAddressBytes(); + + /*localHostname = "JCIFS" + (addr[2] & unchecked((int)(0xFF))) + "_" + (addr[3] & unchecked( + (int)(0xFF))) + "_" + Hexdump.ToHexString((int)(new Random().NextDouble() * (double)unchecked( + (int)(0xFF))), 2);*/ + localHostname = "JCIFS_127_0_0_1"; + } + localName = new Name(localHostname, unchecked(0x00), Config.GetProperty("jcifs.netbios.scope" + , null)); + Localhost = new NbtAddress(localName, localInetAddress.GetHashCode(), false, BNode + , false, false, true, false, UnknownMacAddress); + CacheAddress(localName, Localhost, Forever); + } + + internal static void CacheAddress(Name hostName, NbtAddress addr) + { + if (CachePolicy == 0) + { + return; + } + long expiration = -1; + if (CachePolicy != Forever) + { + expiration = Runtime.CurrentTimeMillis() + CachePolicy * 1000; + } + CacheAddress(hostName, addr, expiration); + } + + internal static void CacheAddress(Name hostName, NbtAddress addr, long expiration + ) + { + if (CachePolicy == 0) + { + return; + } + lock (AddressCache) + { + CacheEntry entry = (CacheEntry)AddressCache.Get(hostName); + if (entry == null) + { + entry = new CacheEntry(hostName, addr, expiration); + AddressCache.Put(hostName, entry); + } + else + { + entry.Address = addr; + entry.Expiration = expiration; + } + } + } + + internal static void CacheAddressArray(NbtAddress[] addrs) + { + if (CachePolicy == 0) + { + return; + } + long expiration = -1; + if (CachePolicy != Forever) + { + expiration = Runtime.CurrentTimeMillis() + CachePolicy * 1000; + } + lock (AddressCache) + { + for (int i = 0; i < addrs.Length; i++) + { + CacheEntry entry = (CacheEntry)AddressCache.Get(addrs[i].HostName + ); + if (entry == null) + { + entry = new CacheEntry(addrs[i].HostName, addrs[i], expiration); + AddressCache.Put(addrs[i].HostName, entry); + } + else + { + entry.Address = addrs[i]; + entry.Expiration = expiration; + } + } + } + } + + internal static NbtAddress GetCachedAddress(Name hostName) + { + if (CachePolicy == 0) + { + return null; + } + lock (AddressCache) + { + CacheEntry entry = (CacheEntry)AddressCache.Get(hostName); + if (entry != null && entry.Expiration < Runtime.CurrentTimeMillis() && entry.Expiration + >= 0) + { + entry = null; + } + return entry != null ? entry.Address : null; + } + } + + /// <exception cref="UnknownHostException"></exception> + internal static NbtAddress DoNameQuery(Name name, IPAddress svr) + { + NbtAddress addr; + if (name.HexCode == unchecked(0x1d) && svr == null) + { + svr = Client.Baddr; + } + // bit of a hack but saves a lookup + name.SrcHashCode = svr != null ? svr.GetHashCode() : 0; + addr = GetCachedAddress(name); + if (addr == null) + { + if ((addr = (NbtAddress)CheckLookupTable(name)) == null) + { + try + { + addr = Client.GetByName(name, svr); + } + catch (UnknownHostException) + { + addr = UnknownAddress; + } + finally + { + CacheAddress(name, addr); + UpdateLookupTable(name); + } + } + } + if (addr == UnknownAddress) + { + throw new UnknownHostException(name.ToString()); + } + return addr; + } + + private static object CheckLookupTable(Name name) + { + object obj; + lock (LookupTable) + { + if (LookupTable.ContainsKey(name) == false) + { + LookupTable.Put(name, name); + return null; + } + while (LookupTable.ContainsKey(name)) + { + try + { + Runtime.Wait(LookupTable); + } + catch (Exception) + { + } + } + } + obj = GetCachedAddress(name); + if (obj == null) + { + lock (LookupTable) + { + LookupTable.Put(name, name); + } + } + return obj; + } + + private static void UpdateLookupTable(Name name) + { + lock (LookupTable) + { + //Sharpen.Collections.Remove(LOOKUP_TABLE, name); + LookupTable.Remove(name); + Runtime.NotifyAll(LookupTable); + } + } + + /// <summary>Retrieves the local host address.</summary> + /// <remarks>Retrieves the local host address.</remarks> + /// <exception cref="UnknownHostException"> + /// This is not likely as the IP returned + /// by <code>InetAddress</code> should be available + /// </exception> + public static NbtAddress GetLocalHost() + { + return Localhost; + } + + public static NbtAddress[] GetHosts() + { + return new NameServiceClient().GetHosts(); + } + + public static Name GetLocalName() + { + return Localhost.HostName; + } + + /// <summary>Determines the address of a host given it's host name.</summary> + /// <remarks> + /// Determines the address of a host given it's host name. The name can be a NetBIOS name like + /// "freto" or an IP address like "192.168.1.15". It cannot be a DNS name; + /// the analygous + /// <see cref="SharpCifs.UniAddress">Jcifs.UniAddress</see> + /// or + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// <code>getByName</code> methods can be used for that. + /// </remarks> + /// <param name="host">hostname to resolve</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress GetByName(string host) + { + return GetByName(host, unchecked(0x00), null); + } + + /// <summary>Determines the address of a host given it's host name.</summary> + /// <remarks> + /// Determines the address of a host given it's host name. NetBIOS + /// names also have a <code>type</code>. Types(aka Hex Codes) + /// are used to distiquish the various services on a host. <a + /// href="../../../nbtcodes.html">Here</a> is + /// a fairly complete list of NetBIOS hex codes. Scope is not used but is + /// still functional in other NetBIOS products and so for completeness it has been + /// implemented. A <code>scope</code> of <code>null</code> or <code>""</code> + /// signifies no scope. + /// </remarks> + /// <param name="host">the name to resolve</param> + /// <param name="type">the hex code of the name</param> + /// <param name="scope">the scope of the name</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress GetByName(string host, int type, string scope) + { + return GetByName(host, type, scope, null); + } + + /// <exception cref="UnknownHostException"></exception> + public static NbtAddress GetByName(string host, int type, string scope, IPAddress + svr) + { + if (string.IsNullOrEmpty(host)) + { + return GetLocalHost(); + } + if (!char.IsDigit(host[0])) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + int ip = unchecked(0x00); + int hitDots = 0; + char[] data = host.ToCharArray(); + for (int i = 0; i < data.Length; i++) + { + char c = data[i]; + if (c < 48 || c > 57) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + int b = unchecked(0x00); + while (c != '.') + { + if (c < 48 || c > 57) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + b = b * 10 + c - '0'; + if (++i >= data.Length) + { + break; + } + c = data[i]; + } + if (b > unchecked(0xFF)) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + ip = (ip << 8) + b; + hitDots++; + } + if (hitDots != 4 || host.EndsWith(".")) + { + return DoNameQuery(new Name(host, type, scope), svr); + } + return new NbtAddress(UnknownName, ip, false, BNode); + } + + /// <exception cref="UnknownHostException"></exception> + public static NbtAddress[] GetAllByName(string host, int type, string scope, IPAddress + svr) + { + return Client.GetAllByName(new Name(host, type, scope), svr); + } + + /// <summary>Retrieve all addresses of a host by it's address.</summary> + /// <remarks> + /// Retrieve all addresses of a host by it's address. NetBIOS hosts can + /// have many names for a given IP address. The name and IP address make the + /// NetBIOS address. This provides a way to retrieve the other names for a + /// host with the same IP address. + /// </remarks> + /// <param name="host">hostname to lookup all addresses for</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress[] GetAllByAddress(string host) + { + return GetAllByAddress(GetByName(host, unchecked(0x00), null)); + } + + /// <summary>Retrieve all addresses of a host by it's address.</summary> + /// <remarks> + /// Retrieve all addresses of a host by it's address. NetBIOS hosts can + /// have many names for a given IP address. The name and IP address make + /// the NetBIOS address. This provides a way to retrieve the other names + /// for a host with the same IP address. See + /// <see cref="GetByName(string)">GetByName(string)</see> + /// for a description of <code>type</code> + /// and <code>scope</code>. + /// </remarks> + /// <param name="host">hostname to lookup all addresses for</param> + /// <param name="type">the hexcode of the name</param> + /// <param name="scope">the scope of the name</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static NbtAddress[] GetAllByAddress(string host, int type, string scope) + { + return GetAllByAddress(GetByName(host, type, scope)); + } + + /// <summary>Retrieve all addresses of a host by it's address.</summary> + /// <remarks> + /// Retrieve all addresses of a host by it's address. NetBIOS hosts can + /// have many names for a given IP address. The name and IP address make the + /// NetBIOS address. This provides a way to retrieve the other names for a + /// host with the same IP address. + /// </remarks> + /// <param name="addr">the address to query</param> + /// <exception cref="UnknownHostException">if address cannot be resolved</exception> + public static NbtAddress[] GetAllByAddress(NbtAddress addr) + { + try + { + NbtAddress[] addrs = Client.GetNodeStatus(addr); + CacheAddressArray(addrs); + return addrs; + } + catch (UnknownHostException) + { + throw new UnknownHostException("no name with type 0x" + Hexdump.ToHexString(addr. + HostName.HexCode, 2) + (((addr.HostName.Scope == null) || (addr.HostName.Scope.Length + == 0)) ? " with no scope" : " with scope " + addr.HostName.Scope) + " for host " + + addr.GetHostAddress()); + } + } + + public static IPAddress GetWinsAddress() + { + return Nbns.Length == 0 ? null : Nbns[_nbnsIndex]; + } + + public static bool IsWins(IPAddress svr) + { + for (int i = 0; svr != null && i < Nbns.Length; i++) + { + if (svr.GetHashCode() == Nbns[i].GetHashCode()) + { + return true; + } + } + return false; + } + + internal static IPAddress SwitchWins() + { + _nbnsIndex = (_nbnsIndex + 1) < Nbns.Length ? _nbnsIndex + 1 : 0; + return Nbns.Length == 0 ? null : Nbns[_nbnsIndex]; + } + + internal Name HostName; + + internal int Address; + + internal int NodeType; + + internal bool GroupName; + + internal bool isBeingDeleted; + + internal bool isInConflict; + + internal bool isActive; + + internal bool isPermanent; + + internal bool IsDataFromNodeStatus; + + internal byte[] MacAddress; + + internal string CalledName; + + internal NbtAddress(Name hostName, int address, bool groupName, int nodeType) + { + this.HostName = hostName; + this.Address = address; + this.GroupName = groupName; + this.NodeType = nodeType; + } + + internal NbtAddress(Name hostName, int address, bool groupName, int nodeType, bool + isBeingDeleted, bool isInConflict, bool isActive, bool isPermanent, byte[] macAddress + ) + { + this.HostName = hostName; + this.Address = address; + this.GroupName = groupName; + this.NodeType = nodeType; + this.isBeingDeleted = isBeingDeleted; + this.isInConflict = isInConflict; + this.isActive = isActive; + this.isPermanent = isPermanent; + this.MacAddress = macAddress; + IsDataFromNodeStatus = true; + } + + public string FirstCalledName() + { + CalledName = HostName.name; + if (char.IsDigit(CalledName[0])) + { + int i; + int len; + int dots; + char[] data; + i = dots = 0; + len = CalledName.Length; + data = CalledName.ToCharArray(); + while (i < len && char.IsDigit(data[i++])) + { + if (i == len && dots == 3) + { + // probably an IP address + CalledName = SmbserverName; + break; + } + if (i < len && data[i] == '.') + { + dots++; + i++; + } + } + } + else + { + switch (HostName.HexCode) + { + case unchecked(0x1B): + case unchecked(0x1C): + case unchecked(0x1D): + { + CalledName = SmbserverName; + break; + } + } + } + return CalledName; + } + + public string NextCalledName() + { + if (CalledName == HostName.name) + { + CalledName = SmbserverName; + } + else + { + if (CalledName == SmbserverName) + { + NbtAddress[] addrs; + try + { + addrs = Client.GetNodeStatus(this); + if (HostName.HexCode == unchecked(0x1D)) + { + for (int i = 0; i < addrs.Length; i++) + { + if (addrs[i].HostName.HexCode == unchecked(0x20)) + { + return addrs[i].HostName.name; + } + } + return null; + } + if (IsDataFromNodeStatus) + { + CalledName = null; + return HostName.name; + } + } + catch (UnknownHostException) + { + CalledName = null; + } + } + else + { + CalledName = null; + } + } + return CalledName; + } + + /// <exception cref="UnknownHostException"></exception> + internal void CheckData() + { + if (HostName == UnknownName) + { + GetAllByAddress(this); + } + } + + /// <exception cref="UnknownHostException"></exception> + internal void CheckNodeStatusData() + { + if (IsDataFromNodeStatus == false) + { + GetAllByAddress(this); + } + } + + /// <summary>Determines if the address is a group address.</summary> + /// <remarks> + /// Determines if the address is a group address. This is also + /// known as a workgroup name or group name. + /// </remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsGroupAddress() + { + CheckData(); + return GroupName; + } + + /// <summary>Checks the node type of this address.</summary> + /// <remarks>Checks the node type of this address.</remarks> + /// <returns> + /// + /// <see cref="BNode">B_NODE</see> + /// , + /// <see cref="PNode">P_NODE</see> + /// , + /// <see cref="MNode">M_NODE</see> + /// , + /// <see cref="HNode">H_NODE</see> + /// </returns> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public int GetNodeType() + { + CheckData(); + return NodeType; + } + + /// <summary>Determines if this address in the process of being deleted.</summary> + /// <remarks>Determines if this address in the process of being deleted.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsBeingDeleted() + { + CheckNodeStatusData(); + return isBeingDeleted; + } + + /// <summary>Determines if this address in conflict with another address.</summary> + /// <remarks>Determines if this address in conflict with another address.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsInConflict() + { + CheckNodeStatusData(); + return isInConflict; + } + + /// <summary>Determines if this address is active.</summary> + /// <remarks>Determines if this address is active.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsActive() + { + CheckNodeStatusData(); + return isActive; + } + + /// <summary>Determines if this address is set to be permanent.</summary> + /// <remarks>Determines if this address is set to be permanent.</remarks> + /// <exception cref="UnknownHostException">if the host cannot be resolved to find out. + /// </exception> + public bool IsPermanent() + { + CheckNodeStatusData(); + return isPermanent; + } + + /// <summary>Retrieves the MAC address of the remote network interface.</summary> + /// <remarks>Retrieves the MAC address of the remote network interface. Samba returns all zeros. + /// </remarks> + /// <returns>the MAC address as an array of six bytes</returns> + /// <exception cref="UnknownHostException"> + /// if the host cannot be resolved to + /// determine the MAC address. + /// </exception> + public byte[] GetMacAddress() + { + CheckNodeStatusData(); + return MacAddress; + } + + /// <summary>The hostname of this address.</summary> + /// <remarks> + /// The hostname of this address. If the hostname is null the local machines + /// IP address is returned. + /// </remarks> + /// <returns>the text representation of the hostname associated with this address</returns> + public string GetHostName() + { + if (HostName == UnknownName) + { + return GetHostAddress(); + } + return HostName.name; + } + + /// <summary>Returns the raw IP address of this NbtAddress.</summary> + /// <remarks> + /// Returns the raw IP address of this NbtAddress. The result is in network + /// byte order: the highest order byte of the address is in getAddress()[0]. + /// </remarks> + /// <returns>a four byte array</returns> + public byte[] GetAddress() + { + byte[] addr = new byte[4]; + addr[0] = unchecked((byte)(((int)(((uint)Address) >> 24)) & unchecked(0xFF + ))); + addr[1] = unchecked((byte)(((int)(((uint)Address) >> 16)) & unchecked(0xFF + ))); + addr[2] = unchecked((byte)(((int)(((uint)Address) >> 8)) & unchecked(0xFF) + )); + addr[3] = unchecked((byte)(Address & unchecked(0xFF))); + return addr; + } + + /// <summary>To convert this address to an <code>InetAddress</code>.</summary> + /// <remarks>To convert this address to an <code>InetAddress</code>.</remarks> + /// <returns> + /// the + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// representation of this address. + /// </returns> + /// <exception cref="UnknownHostException"></exception> + public IPAddress GetInetAddress() + { + return Extensions.GetAddressByName(GetHostAddress()); + } + + /// <summary> + /// Returns this IP adress as a + /// <see cref="string">string</see> + /// in the form "%d.%d.%d.%d". + /// </summary> + public string GetHostAddress() + { + return (((int)(((uint)Address) >> 24)) & unchecked(0xFF)) + "." + (((int)( + ((uint)Address) >> 16)) & unchecked(0xFF)) + "." + (((int)(((uint)Address + ) >> 8)) & unchecked(0xFF)) + "." + (((int)(((uint)Address) >> 0)) & unchecked( + 0xFF)); + } + + /// <summary>Returned the hex code associated with this name(e.g.</summary> + /// <remarks>Returned the hex code associated with this name(e.g. 0x20 is for the file service) + /// </remarks> + public int GetNameType() + { + return HostName.HexCode; + } + + /// <summary>Returns a hashcode for this IP address.</summary> + /// <remarks> + /// Returns a hashcode for this IP address. The hashcode comes from the IP address + /// and is not generated from the string representation. So because NetBIOS nodes + /// can have many names, all names associated with an IP will have the same + /// hashcode. + /// </remarks> + public override int GetHashCode() + { + return Address; + } + + /// <summary>Determines if this address is equal two another.</summary> + /// <remarks> + /// Determines if this address is equal two another. Only the IP Addresses + /// are compared. Similar to the + /// <see cref="GetHashCode()">GetHashCode()</see> + /// method, the comparison + /// is based on the integer IP address and not the string representation. + /// </remarks> + public override bool Equals(object obj) + { + return (obj != null) && (obj is NbtAddress) && (((NbtAddress)obj).Address == Address + ); + } + + /// <summary> + /// Returns the + /// <see cref="string">string</see> + /// representaion of this address. + /// </summary> + public override string ToString() + { + return HostName + "/" + GetHostAddress(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtException.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtException.cs new file mode 100644 index 000000000..e785c9943 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NbtException.cs @@ -0,0 +1,164 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; + +namespace SharpCifs.Netbios +{ + + public class NbtException : IOException + { + public const int Success = 0; + + public const int ErrNamSrvc = unchecked(0x01); + + public const int ErrSsnSrvc = unchecked(0x02); + + public const int FmtErr = unchecked(0x1); + + public const int SrvErr = unchecked(0x2); + + public const int ImpErr = unchecked(0x4); + + public const int RfsErr = unchecked(0x5); + + public const int ActErr = unchecked(0x6); + + public const int CftErr = unchecked(0x7); + + public const int ConnectionRefused = -1; + + public const int NotListeningCalled = unchecked(0x80); + + public const int NotListeningCalling = unchecked(0x81); + + public const int CalledNotPresent = unchecked(0x82); + + public const int NoResources = unchecked(0x83); + + public const int Unspecified = unchecked(0x8F); + + public int ErrorClass; + + public int ErrorCode; + + // error classes + // name service error codes + // session service error codes + public static string GetErrorString(int errorClass, int errorCode) + { + string result = string.Empty; + switch (errorClass) + { + case Success: + { + result += "SUCCESS"; + break; + } + + case ErrNamSrvc: + { + result += "ERR_NAM_SRVC/"; + switch (errorCode) + { + case FmtErr: + { + result += "FMT_ERR: Format Error"; + goto default; + } + + default: + { + result += "Unknown error code: " + errorCode; + break; + } + } + break; + } + + case ErrSsnSrvc: + { + result += "ERR_SSN_SRVC/"; + switch (errorCode) + { + case ConnectionRefused: + { + result += "Connection refused"; + break; + } + + case NotListeningCalled: + { + result += "Not listening on called name"; + break; + } + + case NotListeningCalling: + { + result += "Not listening for calling name"; + break; + } + + case CalledNotPresent: + { + result += "Called name not present"; + break; + } + + case NoResources: + { + result += "Called name present, but insufficient resources"; + break; + } + + case Unspecified: + { + result += "Unspecified error"; + break; + } + + default: + { + result += "Unknown error code: " + errorCode; + break; + } + } + break; + } + + default: + { + result += "unknown error class: " + errorClass; + break; + } + } + return result; + } + + public NbtException(int errorClass, int errorCode) : base(GetErrorString(errorClass + , errorCode)) + { + this.ErrorClass = errorClass; + this.ErrorCode = errorCode; + } + + public override string ToString() + { + return "errorClass=" + ErrorClass + ",errorCode=" + ErrorCode + ",errorString=" + + GetErrorString(ErrorClass, ErrorCode); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs new file mode 100644 index 000000000..66d3bb3e5 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NodeStatusRequest.cs @@ -0,0 +1,59 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Netbios +{ + internal class NodeStatusRequest : NameServicePacket + { + internal NodeStatusRequest(Name name) + { + QuestionName = name; + QuestionType = Nbstat; + IsRecurDesired = false; + IsBroadcast = false; + } + + internal override int WriteBodyWireFormat(byte[] dst, int dstIndex) + { + int tmp = QuestionName.HexCode; + QuestionName.HexCode = unchecked(0x00); + // type has to be 0x00 for node status + int result = WriteQuestionSectionWireFormat(dst, dstIndex); + QuestionName.HexCode = tmp; + return result; + } + + internal override int ReadBodyWireFormat(byte[] src, int srcIndex) + { + return 0; + } + + internal override int WriteRDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadRDataWireFormat(byte[] src, int srcIndex) + { + return 0; + } + + public override string ToString() + { + return "NodeStatusRequest[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs new file mode 100644 index 000000000..aa3214419 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/NodeStatusResponse.cs @@ -0,0 +1,140 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Netbios +{ + internal class NodeStatusResponse : NameServicePacket + { + private NbtAddress _queryAddress; + + private int _numberOfNames; + + private byte[] _macAddress; + + private byte[] _stats; + + internal NbtAddress[] AddressArray; + + internal NodeStatusResponse(NbtAddress queryAddress) + { + this._queryAddress = queryAddress; + RecordName = new Name(); + _macAddress = new byte[6]; + } + + internal override int WriteBodyWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadBodyWireFormat(byte[] src, int srcIndex) + { + return ReadResourceRecordWireFormat(src, srcIndex); + } + + internal override int WriteRDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadRDataWireFormat(byte[] src, int srcIndex) + { + int start = srcIndex; + _numberOfNames = src[srcIndex] & unchecked(0xFF); + int namesLength = _numberOfNames * 18; + int statsLength = RDataLength - namesLength - 1; + _numberOfNames = src[srcIndex++] & unchecked(0xFF); + // gotta read the mac first so we can populate addressArray with it + Array.Copy(src, srcIndex + namesLength, _macAddress, 0, 6); + srcIndex += ReadNodeNameArray(src, srcIndex); + _stats = new byte[statsLength]; + Array.Copy(src, srcIndex, _stats, 0, statsLength); + srcIndex += statsLength; + return srcIndex - start; + } + + private int ReadNodeNameArray(byte[] src, int srcIndex) + { + int start = srcIndex; + AddressArray = new NbtAddress[_numberOfNames]; + string n; + int hexCode; + string scope = _queryAddress.HostName.Scope; + bool groupName; + int ownerNodeType; + bool isBeingDeleted; + bool isInConflict; + bool isActive; + bool isPermanent; + int j; + bool addrFound = false; + try + { + for (int i = 0; i < _numberOfNames; srcIndex += 18, i++) + { + for (j = srcIndex + 14; src[j] == unchecked(0x20); j--) + { + } + n = Runtime.GetStringForBytes(src, srcIndex, j - srcIndex + 1, Name.OemEncoding + ); + hexCode = src[srcIndex + 15] & unchecked(0xFF); + groupName = ((src[srcIndex + 16] & unchecked(0x80)) == unchecked(0x80)) ? true : false; + ownerNodeType = (src[srcIndex + 16] & unchecked(0x60)) >> 5; + isBeingDeleted = ((src[srcIndex + 16] & unchecked(0x10)) == unchecked(0x10)) ? true : false; + isInConflict = ((src[srcIndex + 16] & unchecked(0x08)) == unchecked(0x08)) ? true : false; + isActive = ((src[srcIndex + 16] & unchecked(0x04)) == unchecked(0x04)) ? true : false; + isPermanent = ((src[srcIndex + 16] & unchecked(0x02)) == unchecked(0x02)) ? true : false; + if (!addrFound && _queryAddress.HostName.HexCode == hexCode && (_queryAddress.HostName + == NbtAddress.UnknownName || _queryAddress.HostName.name.Equals(n))) + { + if (_queryAddress.HostName == NbtAddress.UnknownName) + { + _queryAddress.HostName = new Name(n, hexCode, scope); + } + _queryAddress.GroupName = groupName; + _queryAddress.NodeType = ownerNodeType; + _queryAddress.isBeingDeleted = isBeingDeleted; + _queryAddress.isInConflict = isInConflict; + _queryAddress.isActive = isActive; + _queryAddress.isPermanent = isPermanent; + _queryAddress.MacAddress = _macAddress; + _queryAddress.IsDataFromNodeStatus = true; + addrFound = true; + AddressArray[i] = _queryAddress; + } + else + { + AddressArray[i] = new NbtAddress(new Name(n, hexCode, scope), _queryAddress.Address + , groupName, ownerNodeType, isBeingDeleted, isInConflict, isActive, isPermanent, + _macAddress); + } + } + } + catch (UnsupportedEncodingException) + { + } + return srcIndex - start; + } + + public override string ToString() + { + return "NodeStatusResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs new file mode 100644 index 000000000..a5243f7aa --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionRequestPacket.cs @@ -0,0 +1,63 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Netbios +{ + public class SessionRequestPacket : SessionServicePacket + { + private Name _calledName; + + private Name _callingName; + + public SessionRequestPacket() + { + _calledName = new Name(); + _callingName = new Name(); + } + + public SessionRequestPacket(Name calledName, Name callingName) + { + Type = SessionRequest; + this._calledName = calledName; + this._callingName = callingName; + } + + internal override int WriteTrailerWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dstIndex += _calledName.WriteWireFormat(dst, dstIndex); + dstIndex += _callingName.WriteWireFormat(dst, dstIndex); + return dstIndex - start; + } + + /// <exception cref="System.IO.IOException"></exception> + internal override int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + if (@in.Read(buffer, bufferIndex, Length) != Length) + { + throw new IOException("invalid session request wire format"); + } + bufferIndex += _calledName.ReadWireFormat(buffer, bufferIndex); + bufferIndex += _callingName.ReadWireFormat(buffer, bufferIndex); + return bufferIndex - start; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs new file mode 100644 index 000000000..c901c6e26 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionRetargetResponsePacket.cs @@ -0,0 +1,54 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Netbios +{ + internal class SessionRetargetResponsePacket : SessionServicePacket + { + private NbtAddress _retargetAddress; + + private int _retargetPort; + + public SessionRetargetResponsePacket() + { + Type = SessionRetargetResponse; + Length = 6; + } + + internal override int WriteTrailerWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + /// <exception cref="System.IO.IOException"></exception> + internal override int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex + ) + { + if (@in.Read(buffer, bufferIndex, Length) != Length) + { + throw new IOException("unexpected EOF reading netbios retarget session response"); + } + int addr = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + _retargetAddress = new NbtAddress(null, addr, false, NbtAddress.BNode); + _retargetPort = ReadInt2(buffer, bufferIndex); + return Length; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs b/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs new file mode 100644 index 000000000..c8d194222 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Netbios/SessionServicePacket.cs @@ -0,0 +1,156 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Netbios +{ + public abstract class SessionServicePacket + { + internal const int SessionMessage = unchecked(0x00); + + internal const int SessionRequest = unchecked(0x81); + + public const int PositiveSessionResponse = unchecked(0x82); + + public const int NegativeSessionResponse = unchecked(0x83); + + internal const int SessionRetargetResponse = unchecked(0x84); + + internal const int SessionKeepAlive = unchecked(0x85); + + internal const int MaxMessageSize = unchecked(0x0001FFFF); + + internal const int HeaderLength = 4; + + // session service packet types + internal static void WriteInt2(int val, byte[] dst, int dstIndex) + { + dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF))); + dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF))); + } + + internal static void WriteInt4(int val, byte[] dst, int dstIndex) + { + dst[dstIndex++] = unchecked((byte)((val >> 24) & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((val >> 16) & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF))); + dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF))); + } + + internal static int ReadInt2(byte[] src, int srcIndex) + { + return ((src[srcIndex] & unchecked(0xFF)) << 8) + (src[srcIndex + 1] & unchecked( + 0xFF)); + } + + internal static int ReadInt4(byte[] src, int srcIndex) + { + return ((src[srcIndex] & unchecked(0xFF)) << 24) + ((src[srcIndex + 1] & unchecked( + 0xFF)) << 16) + ((src[srcIndex + 2] & unchecked(0xFF)) << 8) + (src + [srcIndex + 3] & unchecked(0xFF)); + } + + internal static int ReadLength(byte[] src, int srcIndex) + { + srcIndex++; + return ((src[srcIndex++] & unchecked(0x01)) << 16) + ((src[srcIndex++] & unchecked( + 0xFF)) << 8) + (src[srcIndex++] & unchecked(0xFF)); + } + + /// <exception cref="System.IO.IOException"></exception> + internal static int Readn(InputStream @in, byte[] b, int off, int len) + { + int i = 0; + int n; + while (i < len) + { + n = @in.Read(b, off + i, len - i); + if (n <= 0) + { + break; + } + i += n; + } + return i; + } + + /// <exception cref="System.IO.IOException"></exception> + internal static int ReadPacketType(InputStream @in, byte[] buffer, int bufferIndex + ) + { + int n; + if ((n = Readn(@in, buffer, bufferIndex, HeaderLength)) != HeaderLength) + { + if (n == -1) + { + return -1; + } + throw new IOException("unexpected EOF reading netbios session header"); + } + int t = buffer[bufferIndex] & unchecked(0xFF); + return t; + } + + internal int Type; + + internal int Length; + + public virtual int WriteWireFormat(byte[] dst, int dstIndex) + { + Length = WriteTrailerWireFormat(dst, dstIndex + HeaderLength); + WriteHeaderWireFormat(dst, dstIndex); + return HeaderLength + Length; + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual int ReadWireFormat(InputStream @in, byte[] buffer, int bufferIndex + ) + { + ReadHeaderWireFormat(@in, buffer, bufferIndex); + return HeaderLength + ReadTrailerWireFormat(@in, buffer, bufferIndex); + } + + internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = unchecked((byte)Type); + if (Length > unchecked(0x0000FFFF)) + { + dst[dstIndex] = unchecked(unchecked(0x01)); + } + dstIndex++; + WriteInt2(Length, dst, dstIndex); + return HeaderLength; + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual int ReadHeaderWireFormat(InputStream @in, byte[] buffer, int bufferIndex + ) + { + Type = buffer[bufferIndex++] & unchecked(0xFF); + Length = ((buffer[bufferIndex] & unchecked(0x01)) << 16) + ReadInt2(buffer + , bufferIndex + 1); + return HeaderLength; + } + + internal abstract int WriteTrailerWireFormat(byte[] dst, int dstIndex); + + /// <exception cref="System.IO.IOException"></exception> + internal abstract int ReadTrailerWireFormat(InputStream @in, byte[] buffer, int bufferIndex + ); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmFlags.cs b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmFlags.cs new file mode 100644 index 000000000..116f71b75 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmFlags.cs @@ -0,0 +1,197 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Ntlmssp +{ + /// <summary>Flags used during negotiation of NTLMSSP authentication.</summary> + /// <remarks>Flags used during negotiation of NTLMSSP authentication.</remarks> + public abstract class NtlmFlags + { + /// <summary>Indicates whether Unicode strings are supported or used.</summary> + /// <remarks>Indicates whether Unicode strings are supported or used.</remarks> + public const int NtlmsspNegotiateUnicode = unchecked(0x00000001); + + /// <summary>Indicates whether OEM strings are supported or used.</summary> + /// <remarks>Indicates whether OEM strings are supported or used.</remarks> + public const int NtlmsspNegotiateOem = unchecked(0x00000002); + + /// <summary> + /// Indicates whether the authentication target is requested from + /// the server. + /// </summary> + /// <remarks> + /// Indicates whether the authentication target is requested from + /// the server. + /// </remarks> + public const int NtlmsspRequestTarget = unchecked(0x00000004); + + /// <summary> + /// Specifies that communication across the authenticated channel + /// should carry a digital signature (message integrity). + /// </summary> + /// <remarks> + /// Specifies that communication across the authenticated channel + /// should carry a digital signature (message integrity). + /// </remarks> + public const int NtlmsspNegotiateSign = unchecked(0x00000010); + + /// <summary> + /// Specifies that communication across the authenticated channel + /// should be encrypted (message confidentiality). + /// </summary> + /// <remarks> + /// Specifies that communication across the authenticated channel + /// should be encrypted (message confidentiality). + /// </remarks> + public const int NtlmsspNegotiateSeal = unchecked(0x00000020); + + /// <summary>Indicates datagram authentication.</summary> + /// <remarks>Indicates datagram authentication.</remarks> + public const int NtlmsspNegotiateDatagramStyle = unchecked(0x00000040); + + /// <summary> + /// Indicates that the LAN Manager session key should be used for + /// signing and sealing authenticated communication. + /// </summary> + /// <remarks> + /// Indicates that the LAN Manager session key should be used for + /// signing and sealing authenticated communication. + /// </remarks> + public const int NtlmsspNegotiateLmKey = unchecked(0x00000080); + + public const int NtlmsspNegotiateNetware = unchecked(0x00000100); + + /// <summary>Indicates support for NTLM authentication.</summary> + /// <remarks>Indicates support for NTLM authentication.</remarks> + public const int NtlmsspNegotiateNtlm = unchecked(0x00000200); + + /// <summary> + /// Indicates whether the OEM-formatted domain name in which the + /// client workstation has membership is supplied in the Type-1 message. + /// </summary> + /// <remarks> + /// Indicates whether the OEM-formatted domain name in which the + /// client workstation has membership is supplied in the Type-1 message. + /// This is used in the negotation of local authentication. + /// </remarks> + public const int NtlmsspNegotiateOemDomainSupplied = unchecked(0x00001000); + + /// <summary> + /// Indicates whether the OEM-formatted workstation name is supplied + /// in the Type-1 message. + /// </summary> + /// <remarks> + /// Indicates whether the OEM-formatted workstation name is supplied + /// in the Type-1 message. This is used in the negotiation of local + /// authentication. + /// </remarks> + public const int NtlmsspNegotiateOemWorkstationSupplied = unchecked(0x00002000); + + /// <summary> + /// Sent by the server to indicate that the server and client are + /// on the same machine. + /// </summary> + /// <remarks> + /// Sent by the server to indicate that the server and client are + /// on the same machine. This implies that the server will include + /// a local security context handle in the Type 2 message, for + /// use in local authentication. + /// </remarks> + public const int NtlmsspNegotiateLocalCall = unchecked(0x00004000); + + /// <summary> + /// Indicates that authenticated communication between the client + /// and server should carry a "dummy" digital signature. + /// </summary> + /// <remarks> + /// Indicates that authenticated communication between the client + /// and server should carry a "dummy" digital signature. + /// </remarks> + public const int NtlmsspNegotiateAlwaysSign = unchecked(0x00008000); + + /// <summary> + /// Sent by the server in the Type 2 message to indicate that the + /// target authentication realm is a domain. + /// </summary> + /// <remarks> + /// Sent by the server in the Type 2 message to indicate that the + /// target authentication realm is a domain. + /// </remarks> + public const int NtlmsspTargetTypeDomain = unchecked(0x00010000); + + /// <summary> + /// Sent by the server in the Type 2 message to indicate that the + /// target authentication realm is a server. + /// </summary> + /// <remarks> + /// Sent by the server in the Type 2 message to indicate that the + /// target authentication realm is a server. + /// </remarks> + public const int NtlmsspTargetTypeServer = unchecked(0x00020000); + + /// <summary> + /// Sent by the server in the Type 2 message to indicate that the + /// target authentication realm is a share (presumably for share-level + /// authentication). + /// </summary> + /// <remarks> + /// Sent by the server in the Type 2 message to indicate that the + /// target authentication realm is a share (presumably for share-level + /// authentication). + /// </remarks> + public const int NtlmsspTargetTypeShare = unchecked(0x00040000); + + /// <summary> + /// Indicates that the NTLM2 signing and sealing scheme should be used + /// for protecting authenticated communications. + /// </summary> + /// <remarks> + /// Indicates that the NTLM2 signing and sealing scheme should be used + /// for protecting authenticated communications. This refers to a + /// particular session security scheme, and is not related to the use + /// of NTLMv2 authentication. + /// </remarks> + public const int NtlmsspNegotiateNtlm2 = unchecked(0x00080000); + + public const int NtlmsspRequestInitResponse = unchecked(0x00100000); + + public const int NtlmsspRequestAcceptResponse = unchecked(0x00200000); + + public const int NtlmsspRequestNonNtSessionKey = unchecked(0x00400000 + ); + + /// <summary> + /// Sent by the server in the Type 2 message to indicate that it is + /// including a Target Information block in the message. + /// </summary> + /// <remarks> + /// Sent by the server in the Type 2 message to indicate that it is + /// including a Target Information block in the message. The Target + /// Information block is used in the calculation of the NTLMv2 response. + /// </remarks> + public const int NtlmsspNegotiateTargetInfo = unchecked(0x00800000); + + /// <summary>Indicates that 128-bit encryption is supported.</summary> + /// <remarks>Indicates that 128-bit encryption is supported.</remarks> + public const int NtlmsspNegotiate128 = unchecked(0x20000000); + + public const int NtlmsspNegotiateKeyExch = unchecked(0x40000000); + + /// <summary>Indicates that 56-bit encryption is supported.</summary> + /// <remarks>Indicates that 56-bit encryption is supported.</remarks> + public const int NtlmsspNegotiate56 = unchecked((int)(0x80000000)); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmMessage.cs b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmMessage.cs new file mode 100644 index 000000000..02827d2d0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmMessage.cs @@ -0,0 +1,140 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Ntlmssp +{ + /// <summary>Abstract superclass for all NTLMSSP messages.</summary> + /// <remarks>Abstract superclass for all NTLMSSP messages.</remarks> + public abstract class NtlmMessage : NtlmFlags + { + /// <summary>The NTLMSSP "preamble".</summary> + /// <remarks>The NTLMSSP "preamble".</remarks> + protected internal static readonly byte[] NtlmsspSignature = { unchecked( + (byte)('N')), unchecked((byte)('T')), unchecked((byte)('L')), + unchecked((byte)('M')), unchecked((byte)('S')), unchecked((byte + )('S')), unchecked((byte)('P')), unchecked(0) }; + + private static readonly string OemEncoding = Config.DefaultOemEncoding; + + protected internal static readonly string UniEncoding = "UTF-16LE"; + + private int _flags; + + /// <summary>Returns the flags currently in use for this message.</summary> + /// <remarks>Returns the flags currently in use for this message.</remarks> + /// <returns> + /// An <code>int</code> containing the flags in use for this + /// message. + /// </returns> + public virtual int GetFlags() + { + return _flags; + } + + /// <summary>Sets the flags for this message.</summary> + /// <remarks>Sets the flags for this message.</remarks> + /// <param name="flags">The flags for this message.</param> + public virtual void SetFlags(int flags) + { + this._flags = flags; + } + + /// <summary>Returns the status of the specified flag.</summary> + /// <remarks>Returns the status of the specified flag.</remarks> + /// <param name="flag">The flag to test (i.e., <code>NTLMSSP_NEGOTIATE_OEM</code>).</param> + /// <returns>A <code>boolean</code> indicating whether the flag is set.</returns> + public virtual bool GetFlag(int flag) + { + return (GetFlags() & flag) != 0; + } + + /// <summary>Sets or clears the specified flag.</summary> + /// <remarks>Sets or clears the specified flag.</remarks> + /// <param name="flag"> + /// The flag to set/clear (i.e., + /// <code>NTLMSSP_NEGOTIATE_OEM</code>). + /// </param> + /// <param name="value"> + /// Indicates whether to set (<code>true</code>) or + /// clear (<code>false</code>) the specified flag. + /// </param> + public virtual void SetFlag(int flag, bool value) + { + SetFlags(value ? (GetFlags() | flag) : (GetFlags() & (unchecked((int)(0xffffffff) + ) ^ flag))); + } + + internal static int ReadULong(byte[] src, int index) + { + return (src[index] & unchecked(0xff)) | ((src[index + 1] & unchecked(0xff)) << 8) | ((src[index + 2] & unchecked(0xff)) << 16) | ((src[index + + 3] & unchecked(0xff)) << 24); + } + + internal static int ReadUShort(byte[] src, int index) + { + return (src[index] & unchecked(0xff)) | ((src[index + 1] & unchecked(0xff)) << 8); + } + + internal static byte[] ReadSecurityBuffer(byte[] src, int index) + { + int length = ReadUShort(src, index); + int offset = ReadULong(src, index + 4); + byte[] buffer = new byte[length]; + Array.Copy(src, offset, buffer, 0, length); + return buffer; + } + + internal static void WriteULong(byte[] dest, int offset, int value) + { + dest[offset] = unchecked((byte)(value & unchecked(0xff))); + dest[offset + 1] = unchecked((byte)(value >> 8 & unchecked(0xff))); + dest[offset + 2] = unchecked((byte)(value >> 16 & unchecked(0xff))); + dest[offset + 3] = unchecked((byte)(value >> 24 & unchecked(0xff))); + } + + internal static void WriteUShort(byte[] dest, int offset, int value) + { + dest[offset] = unchecked((byte)(value & unchecked(0xff))); + dest[offset + 1] = unchecked((byte)(value >> 8 & unchecked(0xff))); + } + + internal static void WriteSecurityBuffer(byte[] dest, int offset, int bodyOffset, + byte[] src) + { + int length = (src != null) ? src.Length : 0; + if (length == 0) + { + return; + } + WriteUShort(dest, offset, length); + WriteUShort(dest, offset + 2, length); + WriteULong(dest, offset + 4, bodyOffset); + Array.Copy(src, 0, dest, bodyOffset, length); + } + + internal static string GetOemEncoding() + { + return OemEncoding; + } + + /// <summary>Returns the raw byte representation of this message.</summary> + /// <remarks>Returns the raw byte representation of this message.</remarks> + /// <returns>A <code>byte[]</code> containing the raw message material.</returns> + public abstract byte[] ToByteArray(); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type1Message.cs b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type1Message.cs new file mode 100644 index 000000000..afcf5ec7e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type1Message.cs @@ -0,0 +1,249 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Netbios; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Ntlmssp +{ + /// <summary>Represents an NTLMSSP Type-1 message.</summary> + /// <remarks>Represents an NTLMSSP Type-1 message.</remarks> + public class Type1Message : NtlmMessage + { + private static readonly int DefaultFlags; + + private static readonly string DefaultDomain; + + private static readonly string DefaultWorkstation; + + private string _suppliedDomain; + + private string _suppliedWorkstation; + + static Type1Message() + { + DefaultFlags = NtlmsspNegotiateNtlm | (Config.GetBoolean("jcifs.smb.client.useUnicode" + , true) ? NtlmsspNegotiateUnicode : NtlmsspNegotiateOem); + DefaultDomain = Config.GetProperty("jcifs.smb.client.domain", null); + string defaultWorkstation = null; + try + { + defaultWorkstation = NbtAddress.GetLocalHost().GetHostName(); + } + catch (UnknownHostException) + { + } + DefaultWorkstation = defaultWorkstation; + } + + /// <summary> + /// Creates a Type-1 message using default values from the current + /// environment. + /// </summary> + /// <remarks> + /// Creates a Type-1 message using default values from the current + /// environment. + /// </remarks> + public Type1Message() : this(GetDefaultFlags(), GetDefaultDomain(), GetDefaultWorkstation + ()) + { + } + + /// <summary>Creates a Type-1 message with the specified parameters.</summary> + /// <remarks>Creates a Type-1 message with the specified parameters.</remarks> + /// <param name="flags">The flags to apply to this message.</param> + /// <param name="suppliedDomain">The supplied authentication domain.</param> + /// <param name="suppliedWorkstation">The supplied workstation name.</param> + public Type1Message(int flags, string suppliedDomain, string suppliedWorkstation) + { + SetFlags(GetDefaultFlags() | flags); + SetSuppliedDomain(suppliedDomain); + if (suppliedWorkstation == null) + { + suppliedWorkstation = GetDefaultWorkstation(); + } + SetSuppliedWorkstation(suppliedWorkstation); + } + + /// <summary>Creates a Type-1 message using the given raw Type-1 material.</summary> + /// <remarks>Creates a Type-1 message using the given raw Type-1 material.</remarks> + /// <param name="material">The raw Type-1 material used to construct this message.</param> + /// <exception cref="System.IO.IOException">If an error occurs while parsing the material. + /// </exception> + public Type1Message(byte[] material) + { + Parse(material); + } + + /// <summary>Returns the supplied authentication domain.</summary> + /// <remarks>Returns the supplied authentication domain.</remarks> + /// <returns>A <code>String</code> containing the supplied domain.</returns> + public virtual string GetSuppliedDomain() + { + return _suppliedDomain; + } + + /// <summary>Sets the supplied authentication domain for this message.</summary> + /// <remarks>Sets the supplied authentication domain for this message.</remarks> + /// <param name="suppliedDomain">The supplied domain for this message.</param> + public virtual void SetSuppliedDomain(string suppliedDomain) + { + this._suppliedDomain = suppliedDomain; + } + + /// <summary>Returns the supplied workstation name.</summary> + /// <remarks>Returns the supplied workstation name.</remarks> + /// <returns>A <code>String</code> containing the supplied workstation name.</returns> + public virtual string GetSuppliedWorkstation() + { + return _suppliedWorkstation; + } + + /// <summary>Sets the supplied workstation name for this message.</summary> + /// <remarks>Sets the supplied workstation name for this message.</remarks> + /// <param name="suppliedWorkstation">The supplied workstation for this message.</param> + public virtual void SetSuppliedWorkstation(string suppliedWorkstation) + { + this._suppliedWorkstation = suppliedWorkstation; + } + + public override byte[] ToByteArray() + { + try + { + string suppliedDomain = GetSuppliedDomain(); + string suppliedWorkstation = GetSuppliedWorkstation(); + int flags = GetFlags(); + bool hostInfo = false; + byte[] domain = new byte[0]; + if (!string.IsNullOrEmpty(suppliedDomain)) + { + hostInfo = true; + flags |= NtlmsspNegotiateOemDomainSupplied; + domain = Runtime.GetBytesForString(suppliedDomain.ToUpper(), GetOemEncoding + ()); + } + else + { + flags &= (NtlmsspNegotiateOemDomainSupplied ^ unchecked((int)(0xffffffff))); + } + byte[] workstation = new byte[0]; + if (!string.IsNullOrEmpty(suppliedWorkstation)) + { + hostInfo = true; + flags |= NtlmsspNegotiateOemWorkstationSupplied; + workstation = Runtime.GetBytesForString(suppliedWorkstation.ToUpper(), GetOemEncoding + ()); + } + else + { + flags &= (NtlmsspNegotiateOemWorkstationSupplied ^ unchecked((int)(0xffffffff + ))); + } + byte[] type1 = new byte[hostInfo ? (32 + domain.Length + workstation.Length) : 16 + ]; + Array.Copy(NtlmsspSignature, 0, type1, 0, 8); + WriteULong(type1, 8, 1); + WriteULong(type1, 12, flags); + if (hostInfo) + { + WriteSecurityBuffer(type1, 16, 32, domain); + WriteSecurityBuffer(type1, 24, 32 + domain.Length, workstation); + } + return type1; + } + catch (IOException ex) + { + throw new InvalidOperationException(ex.Message); + } + } + + public override string ToString() + { + string suppliedDomain = GetSuppliedDomain(); + string suppliedWorkstation = GetSuppliedWorkstation(); + return "Type1Message[suppliedDomain=" + (suppliedDomain ?? "null" + ) + ",suppliedWorkstation=" + (suppliedWorkstation ?? "null" + ) + ",flags=0x" + Hexdump.ToHexString(GetFlags(), 8) + "]"; + } + + /// <summary> + /// Returns the default flags for a generic Type-1 message in the + /// current environment. + /// </summary> + /// <remarks> + /// Returns the default flags for a generic Type-1 message in the + /// current environment. + /// </remarks> + /// <returns>An <code>int</code> containing the default flags.</returns> + public static int GetDefaultFlags() + { + return DefaultFlags; + } + + /// <summary>Returns the default domain from the current environment.</summary> + /// <remarks>Returns the default domain from the current environment.</remarks> + /// <returns>A <code>String</code> containing the default domain.</returns> + public static string GetDefaultDomain() + { + return DefaultDomain; + } + + /// <summary>Returns the default workstation from the current environment.</summary> + /// <remarks>Returns the default workstation from the current environment.</remarks> + /// <returns>A <code>String</code> containing the default workstation.</returns> + public static string GetDefaultWorkstation() + { + return DefaultWorkstation; + } + + /// <exception cref="System.IO.IOException"></exception> + private void Parse(byte[] material) + { + for (int i = 0; i < 8; i++) + { + if (material[i] != NtlmsspSignature[i]) + { + throw new IOException("Not an NTLMSSP message."); + } + } + if (ReadULong(material, 8) != 1) + { + throw new IOException("Not a Type 1 message."); + } + int flags = ReadULong(material, 12); + string suppliedDomain = null; + if ((flags & NtlmsspNegotiateOemDomainSupplied) != 0) + { + byte[] domain = ReadSecurityBuffer(material, 16); + suppliedDomain = Runtime.GetStringForBytes(domain, GetOemEncoding()); + } + string suppliedWorkstation = null; + if ((flags & NtlmsspNegotiateOemWorkstationSupplied) != 0) + { + byte[] workstation = ReadSecurityBuffer(material, 24); + suppliedWorkstation = Runtime.GetStringForBytes(workstation, GetOemEncoding + ()); + } + SetFlags(flags); + SetSuppliedDomain(suppliedDomain); + SetSuppliedWorkstation(suppliedWorkstation); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type2Message.cs b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type2Message.cs new file mode 100644 index 000000000..104e5b0fd --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type2Message.cs @@ -0,0 +1,438 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Netbios; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Ntlmssp +{ + /// <summary>Represents an NTLMSSP Type-2 message.</summary> + /// <remarks>Represents an NTLMSSP Type-2 message.</remarks> + public class Type2Message : NtlmMessage + { + private static readonly int DefaultFlags; + + private static readonly string DefaultDomain; + + private static readonly byte[] DefaultTargetInformation; + + private byte[] _challenge; + + private string _target; + + private byte[] _context; + + private byte[] _targetInformation; + + static Type2Message() + { + DefaultFlags = NtlmsspNegotiateNtlm | (Config.GetBoolean("jcifs.smb.client.useUnicode" + , true) ? NtlmsspNegotiateUnicode : NtlmsspNegotiateOem); + DefaultDomain = Config.GetProperty("jcifs.smb.client.domain", null); + byte[] domain = new byte[0]; + if (DefaultDomain != null) + { + try + { + domain = Runtime.GetBytesForString(DefaultDomain, UniEncoding); + } + catch (IOException) + { + } + } + int domainLength = domain.Length; + byte[] server = new byte[0]; + try + { + string host = NbtAddress.GetLocalHost().GetHostName(); + if (host != null) + { + try + { + server = Runtime.GetBytesForString(host, UniEncoding); + } + catch (IOException) + { + } + } + } + catch (UnknownHostException) + { + } + int serverLength = server.Length; + byte[] targetInfo = new byte[(domainLength > 0 ? domainLength + 4 : 0) + (serverLength + > 0 ? serverLength + 4 : 0) + 4]; + int offset = 0; + if (domainLength > 0) + { + WriteUShort(targetInfo, offset, 2); + offset += 2; + WriteUShort(targetInfo, offset, domainLength); + offset += 2; + Array.Copy(domain, 0, targetInfo, offset, domainLength); + offset += domainLength; + } + if (serverLength > 0) + { + WriteUShort(targetInfo, offset, 1); + offset += 2; + WriteUShort(targetInfo, offset, serverLength); + offset += 2; + Array.Copy(server, 0, targetInfo, offset, serverLength); + } + DefaultTargetInformation = targetInfo; + } + + /// <summary> + /// Creates a Type-2 message using default values from the current + /// environment. + /// </summary> + /// <remarks> + /// Creates a Type-2 message using default values from the current + /// environment. + /// </remarks> + public Type2Message() : this(GetDefaultFlags(), null, null) + { + } + + /// <summary> + /// Creates a Type-2 message in response to the given Type-1 message + /// using default values from the current environment. + /// </summary> + /// <remarks> + /// Creates a Type-2 message in response to the given Type-1 message + /// using default values from the current environment. + /// </remarks> + /// <param name="type1">The Type-1 message which this represents a response to.</param> + public Type2Message(Type1Message type1) : this(type1, null, null) + { + } + + /// <summary>Creates a Type-2 message in response to the given Type-1 message.</summary> + /// <remarks>Creates a Type-2 message in response to the given Type-1 message.</remarks> + /// <param name="type1">The Type-1 message which this represents a response to.</param> + /// <param name="challenge">The challenge from the domain controller/server.</param> + /// <param name="target">The authentication target.</param> + public Type2Message(Type1Message type1, byte[] challenge, string target) : this(GetDefaultFlags + (type1), challenge, (type1 != null && target == null && type1.GetFlag(NtlmsspRequestTarget + )) ? GetDefaultDomain() : target) + { + } + + /// <summary>Creates a Type-2 message with the specified parameters.</summary> + /// <remarks>Creates a Type-2 message with the specified parameters.</remarks> + /// <param name="flags">The flags to apply to this message.</param> + /// <param name="challenge">The challenge from the domain controller/server.</param> + /// <param name="target">The authentication target.</param> + public Type2Message(int flags, byte[] challenge, string target) + { + SetFlags(flags); + SetChallenge(challenge); + SetTarget(target); + if (target != null) + { + SetTargetInformation(GetDefaultTargetInformation()); + } + } + + /// <summary>Creates a Type-2 message using the given raw Type-2 material.</summary> + /// <remarks>Creates a Type-2 message using the given raw Type-2 material.</remarks> + /// <param name="material">The raw Type-2 material used to construct this message.</param> + /// <exception cref="System.IO.IOException">If an error occurs while parsing the material. + /// </exception> + public Type2Message(byte[] material) + { + Parse(material); + } + + /// <summary>Returns the challenge for this message.</summary> + /// <remarks>Returns the challenge for this message.</remarks> + /// <returns>A <code>byte[]</code> containing the challenge.</returns> + public virtual byte[] GetChallenge() + { + return _challenge; + } + + /// <summary>Sets the challenge for this message.</summary> + /// <remarks>Sets the challenge for this message.</remarks> + /// <param name="challenge">The challenge from the domain controller/server.</param> + public virtual void SetChallenge(byte[] challenge) + { + this._challenge = challenge; + } + + /// <summary>Returns the authentication target.</summary> + /// <remarks>Returns the authentication target.</remarks> + /// <returns>A <code>String</code> containing the authentication target.</returns> + public virtual string GetTarget() + { + return _target; + } + + /// <summary>Sets the authentication target.</summary> + /// <remarks>Sets the authentication target.</remarks> + /// <param name="target">The authentication target.</param> + public virtual void SetTarget(string target) + { + this._target = target; + } + + /// <summary>Returns the target information block.</summary> + /// <remarks>Returns the target information block.</remarks> + /// <returns> + /// A <code>byte[]</code> containing the target information block. + /// The target information block is used by the client to create an + /// NTLMv2 response. + /// </returns> + public virtual byte[] GetTargetInformation() + { + return _targetInformation; + } + + /// <summary>Sets the target information block.</summary> + /// <remarks> + /// Sets the target information block. + /// The target information block is used by the client to create + /// an NTLMv2 response. + /// </remarks> + /// <param name="targetInformation">The target information block.</param> + public virtual void SetTargetInformation(byte[] targetInformation) + { + this._targetInformation = targetInformation; + } + + /// <summary>Returns the local security context.</summary> + /// <remarks>Returns the local security context.</remarks> + /// <returns> + /// A <code>byte[]</code> containing the local security + /// context. This is used by the client to negotiate local + /// authentication. + /// </returns> + public virtual byte[] GetContext() + { + return _context; + } + + /// <summary>Sets the local security context.</summary> + /// <remarks> + /// Sets the local security context. This is used by the client + /// to negotiate local authentication. + /// </remarks> + /// <param name="context">The local security context.</param> + public virtual void SetContext(byte[] context) + { + this._context = context; + } + + public override byte[] ToByteArray() + { + try + { + string targetName = GetTarget(); + byte[] challenge = GetChallenge(); + byte[] context = GetContext(); + byte[] targetInformation = GetTargetInformation(); + int flags = GetFlags(); + byte[] target = new byte[0]; + if ((flags & NtlmsspRequestTarget) != 0) + { + if (!string.IsNullOrEmpty(targetName)) + { + target = (flags & NtlmsspNegotiateUnicode) != 0 ? Runtime.GetBytesForString + (targetName, UniEncoding) : Runtime.GetBytesForString(targetName.ToUpper + (), GetOemEncoding()); + } + else + { + flags &= (unchecked((int)(0xffffffff)) ^ NtlmsspRequestTarget); + } + } + if (targetInformation != null) + { + flags |= NtlmsspNegotiateTargetInfo; + // empty context is needed for padding when t.i. is supplied. + if (context == null) + { + context = new byte[8]; + } + } + int data = 32; + if (context != null) + { + data += 8; + } + if (targetInformation != null) + { + data += 8; + } + byte[] type2 = new byte[data + target.Length + (targetInformation != null ? targetInformation + .Length : 0)]; + Array.Copy(NtlmsspSignature, 0, type2, 0, 8); + WriteULong(type2, 8, 2); + WriteSecurityBuffer(type2, 12, data, target); + WriteULong(type2, 20, flags); + Array.Copy(challenge ?? new byte[8], 0, type2, 24, 8); + if (context != null) + { + Array.Copy(context, 0, type2, 32, 8); + } + if (targetInformation != null) + { + WriteSecurityBuffer(type2, 40, data + target.Length, targetInformation); + } + return type2; + } + catch (IOException ex) + { + throw new InvalidOperationException(ex.Message); + } + } + + public override string ToString() + { + string target = GetTarget(); + byte[] challenge = GetChallenge(); + byte[] context = GetContext(); + byte[] targetInformation = GetTargetInformation(); + return "Type2Message[target=" + target + ",challenge=" + (challenge == null ? "null" + : "<" + challenge.Length + " bytes>") + ",context=" + (context == null ? "null" + : "<" + context.Length + " bytes>") + ",targetInformation=" + (targetInformation + == null ? "null" : "<" + targetInformation.Length + " bytes>") + ",flags=0x" + + Hexdump.ToHexString(GetFlags(), 8) + "]"; + } + + /// <summary> + /// Returns the default flags for a generic Type-2 message in the + /// current environment. + /// </summary> + /// <remarks> + /// Returns the default flags for a generic Type-2 message in the + /// current environment. + /// </remarks> + /// <returns>An <code>int</code> containing the default flags.</returns> + public static int GetDefaultFlags() + { + return DefaultFlags; + } + + /// <summary> + /// Returns the default flags for a Type-2 message created in response + /// to the given Type-1 message in the current environment. + /// </summary> + /// <remarks> + /// Returns the default flags for a Type-2 message created in response + /// to the given Type-1 message in the current environment. + /// </remarks> + /// <returns>An <code>int</code> containing the default flags.</returns> + public static int GetDefaultFlags(Type1Message type1) + { + if (type1 == null) + { + return DefaultFlags; + } + int flags = NtlmsspNegotiateNtlm; + int type1Flags = type1.GetFlags(); + flags |= ((type1Flags & NtlmsspNegotiateUnicode) != 0) ? NtlmsspNegotiateUnicode + : NtlmsspNegotiateOem; + if ((type1Flags & NtlmsspRequestTarget) != 0) + { + string domain = GetDefaultDomain(); + if (domain != null) + { + flags |= NtlmsspRequestTarget | NtlmsspTargetTypeDomain; + } + } + return flags; + } + + /// <summary>Returns the default domain from the current environment.</summary> + /// <remarks>Returns the default domain from the current environment.</remarks> + /// <returns>A <code>String</code> containing the domain.</returns> + public static string GetDefaultDomain() + { + return DefaultDomain; + } + + public static byte[] GetDefaultTargetInformation() + { + return DefaultTargetInformation; + } + + /// <exception cref="System.IO.IOException"></exception> + private void Parse(byte[] material) + { + for (int i = 0; i < 8; i++) + { + if (material[i] != NtlmsspSignature[i]) + { + throw new IOException("Not an NTLMSSP message."); + } + } + if (ReadULong(material, 8) != 2) + { + throw new IOException("Not a Type 2 message."); + } + int flags = ReadULong(material, 20); + SetFlags(flags); + string target = null; + byte[] bytes = ReadSecurityBuffer(material, 12); + if (bytes.Length != 0) + { + target = Runtime.GetStringForBytes(bytes, ((flags & NtlmsspNegotiateUnicode + ) != 0) ? UniEncoding : GetOemEncoding()); + } + SetTarget(target); + for (int i1 = 24; i1 < 32; i1++) + { + if (material[i1] != 0) + { + byte[] challenge = new byte[8]; + Array.Copy(material, 24, challenge, 0, 8); + SetChallenge(challenge); + break; + } + } + int offset = ReadULong(material, 16); + // offset of targetname start + if (offset == 32 || material.Length == 32) + { + return; + } + for (int i2 = 32; i2 < 40; i2++) + { + if (material[i2] != 0) + { + byte[] context = new byte[8]; + Array.Copy(material, 32, context, 0, 8); + SetContext(context); + break; + } + } + if (offset == 40 || material.Length == 40) + { + return; + } + bytes = ReadSecurityBuffer(material, 40); + if (bytes.Length != 0) + { + SetTargetInformation(bytes); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type3Message.cs b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type3Message.cs new file mode 100644 index 000000000..9a2a37f3c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type3Message.cs @@ -0,0 +1,677 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Netbios; +using SharpCifs.Smb; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Ntlmssp +{ + /// <summary>Represents an NTLMSSP Type-3 message.</summary> + /// <remarks>Represents an NTLMSSP Type-3 message.</remarks> + public class Type3Message : NtlmMessage + { + internal const long MillisecondsBetween1970And1601 = 11644473600000L; + + private static readonly int DefaultFlags; + + private static readonly string DefaultDomain; + + private static readonly string DefaultUser; + + private static readonly string DefaultPassword; + + private static readonly string DefaultWorkstation; + + private static readonly int LmCompatibility; + + //private static readonly SecureRandom RANDOM = new SecureRandom(); + + private byte[] _lmResponse; + + private byte[] _ntResponse; + + private string _domain; + + private string _user; + + private string _workstation; + + private byte[] _masterKey; + + private byte[] _sessionKey; + + static Type3Message() + { + DefaultFlags = NtlmsspNegotiateNtlm | (Config.GetBoolean("jcifs.smb.client.useUnicode" + , true) ? NtlmsspNegotiateUnicode : NtlmsspNegotiateOem); + DefaultDomain = Config.GetProperty("jcifs.smb.client.domain", null); + DefaultUser = Config.GetProperty("jcifs.smb.client.username", null); + DefaultPassword = Config.GetProperty("jcifs.smb.client.password", null); + string defaultWorkstation = null; + try + { + defaultWorkstation = NbtAddress.GetLocalHost().GetHostName(); + } + catch (UnknownHostException) + { + } + DefaultWorkstation = defaultWorkstation; + LmCompatibility = Config.GetInt("jcifs.smb.lmCompatibility", 3); + } + + /// <summary> + /// Creates a Type-3 message using default values from the current + /// environment. + /// </summary> + /// <remarks> + /// Creates a Type-3 message using default values from the current + /// environment. + /// </remarks> + public Type3Message() + { + SetFlags(GetDefaultFlags()); + SetDomain(GetDefaultDomain()); + SetUser(GetDefaultUser()); + SetWorkstation(GetDefaultWorkstation()); + } + + /// <summary> + /// Creates a Type-3 message in response to the given Type-2 message + /// using default values from the current environment. + /// </summary> + /// <remarks> + /// Creates a Type-3 message in response to the given Type-2 message + /// using default values from the current environment. + /// </remarks> + /// <param name="type2">The Type-2 message which this represents a response to.</param> + public Type3Message(Type2Message type2) + { + SetFlags(GetDefaultFlags(type2)); + SetWorkstation(GetDefaultWorkstation()); + string domain = GetDefaultDomain(); + SetDomain(domain); + string user = GetDefaultUser(); + SetUser(user); + string password = GetDefaultPassword(); + switch (LmCompatibility) + { + case 0: + case 1: + { + SetLmResponse(GetLMResponse(type2, password)); + SetNtResponse(GetNTResponse(type2, password)); + break; + } + + case 2: + { + byte[] nt = GetNTResponse(type2, password); + SetLmResponse(nt); + SetNtResponse(nt); + break; + } + + case 3: + case 4: + case 5: + { + byte[] clientChallenge = new byte[8]; + //RANDOM.NextBytes(clientChallenge); + SetLmResponse(GetLMv2Response(type2, domain, user, password, clientChallenge)); + break; + } + + default: + { + SetLmResponse(GetLMResponse(type2, password)); + SetNtResponse(GetNTResponse(type2, password)); + break; + } + } + } + + /// <summary>Creates a Type-3 message in response to the given Type-2 message.</summary> + /// <remarks>Creates a Type-3 message in response to the given Type-2 message.</remarks> + /// <param name="type2">The Type-2 message which this represents a response to.</param> + /// <param name="password">The password to use when constructing the response.</param> + /// <param name="domain">The domain in which the user has an account.</param> + /// <param name="user">The username for the authenticating user.</param> + /// <param name="workstation"> + /// The workstation from which authentication is + /// taking place. + /// </param> + public Type3Message(Type2Message type2, string password, string domain, string user + , string workstation, int flags) + { + SetFlags(flags | GetDefaultFlags(type2)); + if (workstation == null) + { + workstation = GetDefaultWorkstation(); + } + SetWorkstation(workstation); + SetDomain(domain); + SetUser(user); + switch (LmCompatibility) + { + case 0: + case 1: + { + if ((GetFlags() & NtlmsspNegotiateNtlm2) == 0) + { + SetLmResponse(GetLMResponse(type2, password)); + SetNtResponse(GetNTResponse(type2, password)); + } + else + { + // NTLM2 Session Response + byte[] clientChallenge = new byte[24]; + //RANDOM.NextBytes(clientChallenge); + Arrays.Fill(clientChallenge, 8, 24, unchecked((byte)unchecked(0x00))); + // NTLMv1 w/ NTLM2 session sec and key exch all been verified with a debug build of smbclient + byte[] responseKeyNt = NtlmPasswordAuthentication.NtowFv1(password); + byte[] ntlm2Response = NtlmPasswordAuthentication.GetNtlm2Response(responseKeyNt, + type2.GetChallenge(), clientChallenge); + SetLmResponse(clientChallenge); + SetNtResponse(ntlm2Response); + if ((GetFlags() & NtlmsspNegotiateSign) == NtlmsspNegotiateSign) + { + byte[] sessionNonce = new byte[16]; + Array.Copy(type2.GetChallenge(), 0, sessionNonce, 0, 8); + Array.Copy(clientChallenge, 0, sessionNonce, 8, 8); + Md4 md4 = new Md4(); + md4.Update(responseKeyNt); + byte[] userSessionKey = md4.Digest(); + Hmact64 hmac = new Hmact64(userSessionKey); + hmac.Update(sessionNonce); + byte[] ntlm2SessionKey = hmac.Digest(); + if ((GetFlags() & NtlmsspNegotiateKeyExch) != 0) + { + _masterKey = new byte[16]; + //RANDOM.NextBytes(masterKey); + byte[] exchangedKey = new byte[16]; + Rc4 rc4 = new Rc4(ntlm2SessionKey); + rc4.Update(_masterKey, 0, 16, exchangedKey, 0); + SetSessionKey(exchangedKey); + } + else + { + _masterKey = ntlm2SessionKey; + SetSessionKey(_masterKey); + } + } + } + break; + } + + case 2: + { + byte[] nt = GetNTResponse(type2, password); + SetLmResponse(nt); + SetNtResponse(nt); + break; + } + + case 3: + case 4: + case 5: + { + byte[] responseKeyNt1 = NtlmPasswordAuthentication.NtowFv2(domain, user, password + ); + byte[] clientChallenge1 = new byte[8]; + //RANDOM.NextBytes(clientChallenge_1); + SetLmResponse(GetLMv2Response(type2, domain, user, password, clientChallenge1)); + byte[] clientChallenge2 = new byte[8]; + //RANDOM.NextBytes(clientChallenge2); + SetNtResponse(GetNtlMv2Response(type2, responseKeyNt1, clientChallenge2)); + if ((GetFlags() & NtlmsspNegotiateSign) == NtlmsspNegotiateSign) + { + Hmact64 hmac = new Hmact64(responseKeyNt1); + hmac.Update(_ntResponse, 0, 16); + // only first 16 bytes of ntResponse + byte[] userSessionKey = hmac.Digest(); + if ((GetFlags() & NtlmsspNegotiateKeyExch) != 0) + { + _masterKey = new byte[16]; + //RANDOM.NextBytes(masterKey); + byte[] exchangedKey = new byte[16]; + Rc4 rc4 = new Rc4(userSessionKey); + rc4.Update(_masterKey, 0, 16, exchangedKey, 0); + SetSessionKey(exchangedKey); + } + else + { + _masterKey = userSessionKey; + SetSessionKey(_masterKey); + } + } + break; + } + + default: + { + SetLmResponse(GetLMResponse(type2, password)); + SetNtResponse(GetNTResponse(type2, password)); + break; + } + } + } + + /// <summary>Creates a Type-3 message with the specified parameters.</summary> + /// <remarks>Creates a Type-3 message with the specified parameters.</remarks> + /// <param name="flags">The flags to apply to this message.</param> + /// <param name="lmResponse">The LanManager/LMv2 response.</param> + /// <param name="ntResponse">The NT/NTLMv2 response.</param> + /// <param name="domain">The domain in which the user has an account.</param> + /// <param name="user">The username for the authenticating user.</param> + /// <param name="workstation"> + /// The workstation from which authentication is + /// taking place. + /// </param> + public Type3Message(int flags, byte[] lmResponse, byte[] ntResponse, string domain + , string user, string workstation) + { + SetFlags(flags); + SetLmResponse(lmResponse); + SetNtResponse(ntResponse); + SetDomain(domain); + SetUser(user); + SetWorkstation(workstation); + } + + /// <summary>Creates a Type-3 message using the given raw Type-3 material.</summary> + /// <remarks>Creates a Type-3 message using the given raw Type-3 material.</remarks> + /// <param name="material">The raw Type-3 material used to construct this message.</param> + /// <exception cref="System.IO.IOException">If an error occurs while parsing the material. + /// </exception> + public Type3Message(byte[] material) + { + Parse(material); + } + + /// <summary>Returns the LanManager/LMv2 response.</summary> + /// <remarks>Returns the LanManager/LMv2 response.</remarks> + /// <returns>A <code>byte[]</code> containing the LanManager response.</returns> + public virtual byte[] GetLMResponse() + { + return _lmResponse; + } + + /// <summary>Sets the LanManager/LMv2 response for this message.</summary> + /// <remarks>Sets the LanManager/LMv2 response for this message.</remarks> + /// <param name="lmResponse">The LanManager response.</param> + public virtual void SetLmResponse(byte[] lmResponse) + { + this._lmResponse = lmResponse; + } + + /// <summary>Returns the NT/NTLMv2 response.</summary> + /// <remarks>Returns the NT/NTLMv2 response.</remarks> + /// <returns>A <code>byte[]</code> containing the NT/NTLMv2 response.</returns> + public virtual byte[] GetNTResponse() + { + return _ntResponse; + } + + /// <summary>Sets the NT/NTLMv2 response for this message.</summary> + /// <remarks>Sets the NT/NTLMv2 response for this message.</remarks> + /// <param name="ntResponse">The NT/NTLMv2 response.</param> + public virtual void SetNtResponse(byte[] ntResponse) + { + this._ntResponse = ntResponse; + } + + /// <summary>Returns the domain in which the user has an account.</summary> + /// <remarks>Returns the domain in which the user has an account.</remarks> + /// <returns>A <code>String</code> containing the domain for the user.</returns> + public virtual string GetDomain() + { + return _domain; + } + + /// <summary>Sets the domain for this message.</summary> + /// <remarks>Sets the domain for this message.</remarks> + /// <param name="domain">The domain.</param> + public virtual void SetDomain(string domain) + { + this._domain = domain; + } + + /// <summary>Returns the username for the authenticating user.</summary> + /// <remarks>Returns the username for the authenticating user.</remarks> + /// <returns>A <code>String</code> containing the user for this message.</returns> + public virtual string GetUser() + { + return _user; + } + + /// <summary>Sets the user for this message.</summary> + /// <remarks>Sets the user for this message.</remarks> + /// <param name="user">The user.</param> + public virtual void SetUser(string user) + { + this._user = user; + } + + /// <summary>Returns the workstation from which authentication is being performed.</summary> + /// <remarks>Returns the workstation from which authentication is being performed.</remarks> + /// <returns>A <code>String</code> containing the workstation.</returns> + public virtual string GetWorkstation() + { + return _workstation; + } + + /// <summary>Sets the workstation for this message.</summary> + /// <remarks>Sets the workstation for this message.</remarks> + /// <param name="workstation">The workstation.</param> + public virtual void SetWorkstation(string workstation) + { + this._workstation = workstation; + } + + /// <summary> + /// The real session key if the regular session key is actually + /// the encrypted version used for key exchange. + /// </summary> + /// <remarks> + /// The real session key if the regular session key is actually + /// the encrypted version used for key exchange. + /// </remarks> + /// <returns>A <code>byte[]</code> containing the session key.</returns> + public virtual byte[] GetMasterKey() + { + return _masterKey; + } + + /// <summary>Returns the session key.</summary> + /// <remarks>Returns the session key.</remarks> + /// <returns>A <code>byte[]</code> containing the session key.</returns> + public virtual byte[] GetSessionKey() + { + return _sessionKey; + } + + /// <summary>Sets the session key.</summary> + /// <remarks>Sets the session key.</remarks> + /// <param name="sessionKey">The session key.</param> + public virtual void SetSessionKey(byte[] sessionKey) + { + this._sessionKey = sessionKey; + } + + public override byte[] ToByteArray() + { + try + { + int flags = GetFlags(); + bool unicode = (flags & NtlmsspNegotiateUnicode) != 0; + string oem = unicode ? null : GetOemEncoding(); + string domainName = GetDomain(); + byte[] domain = null; + if (!string.IsNullOrEmpty(domainName)) + { + domain = unicode ? Runtime.GetBytesForString(domainName, UniEncoding) : + Runtime.GetBytesForString(domainName, oem); + } + int domainLength = (domain != null) ? domain.Length : 0; + string userName = GetUser(); + byte[] user = null; + if (!string.IsNullOrEmpty(userName)) + { + user = unicode ? Runtime.GetBytesForString(userName, UniEncoding) : Runtime.GetBytesForString + (userName.ToUpper(), oem); + } + int userLength = (user != null) ? user.Length : 0; + string workstationName = GetWorkstation(); + byte[] workstation = null; + if (!string.IsNullOrEmpty(workstationName)) + { + workstation = unicode ? Runtime.GetBytesForString(workstationName, UniEncoding + ) : Runtime.GetBytesForString(workstationName.ToUpper(), oem); + } + int workstationLength = (workstation != null) ? workstation.Length : 0; + byte[] lmResponse = GetLMResponse(); + int lmLength = (lmResponse != null) ? lmResponse.Length : 0; + byte[] ntResponse = GetNTResponse(); + int ntLength = (ntResponse != null) ? ntResponse.Length : 0; + byte[] sessionKey = GetSessionKey(); + int keyLength = (sessionKey != null) ? sessionKey.Length : 0; + byte[] type3 = new byte[64 + domainLength + userLength + workstationLength + lmLength + + ntLength + keyLength]; + Array.Copy(NtlmsspSignature, 0, type3, 0, 8); + WriteULong(type3, 8, 3); + int offset = 64; + WriteSecurityBuffer(type3, 12, offset, lmResponse); + offset += lmLength; + WriteSecurityBuffer(type3, 20, offset, ntResponse); + offset += ntLength; + WriteSecurityBuffer(type3, 28, offset, domain); + offset += domainLength; + WriteSecurityBuffer(type3, 36, offset, user); + offset += userLength; + WriteSecurityBuffer(type3, 44, offset, workstation); + offset += workstationLength; + WriteSecurityBuffer(type3, 52, offset, sessionKey); + WriteULong(type3, 60, flags); + return type3; + } + catch (IOException ex) + { + throw new InvalidOperationException(ex.Message); + } + } + + public override string ToString() + { + string user = GetUser(); + string domain = GetDomain(); + string workstation = GetWorkstation(); + byte[] lmResponse = GetLMResponse(); + byte[] ntResponse = GetNTResponse(); + byte[] sessionKey = GetSessionKey(); + return "Type3Message[domain=" + domain + ",user=" + user + ",workstation=" + workstation + + ",lmResponse=" + (lmResponse == null ? "null" : "<" + lmResponse.Length + " bytes>" + ) + ",ntResponse=" + (ntResponse == null ? "null" : "<" + ntResponse.Length + " bytes>" + ) + ",sessionKey=" + (sessionKey == null ? "null" : "<" + sessionKey.Length + " bytes>" + ) + ",flags=0x" + Hexdump.ToHexString(GetFlags(), 8) + "]"; + } + + /// <summary> + /// Returns the default flags for a generic Type-3 message in the + /// current environment. + /// </summary> + /// <remarks> + /// Returns the default flags for a generic Type-3 message in the + /// current environment. + /// </remarks> + /// <returns>An <code>int</code> containing the default flags.</returns> + public static int GetDefaultFlags() + { + return DefaultFlags; + } + + /// <summary> + /// Returns the default flags for a Type-3 message created in response + /// to the given Type-2 message in the current environment. + /// </summary> + /// <remarks> + /// Returns the default flags for a Type-3 message created in response + /// to the given Type-2 message in the current environment. + /// </remarks> + /// <returns>An <code>int</code> containing the default flags.</returns> + public static int GetDefaultFlags(Type2Message type2) + { + if (type2 == null) + { + return DefaultFlags; + } + int flags = NtlmsspNegotiateNtlm; + flags |= ((type2.GetFlags() & NtlmsspNegotiateUnicode) != 0) ? NtlmsspNegotiateUnicode + : NtlmsspNegotiateOem; + return flags; + } + + /// <summary> + /// Constructs the LanManager response to the given Type-2 message using + /// the supplied password. + /// </summary> + /// <remarks> + /// Constructs the LanManager response to the given Type-2 message using + /// the supplied password. + /// </remarks> + /// <param name="type2">The Type-2 message.</param> + /// <param name="password">The password.</param> + /// <returns>A <code>byte[]</code> containing the LanManager response.</returns> + public static byte[] GetLMResponse(Type2Message type2, string password) + { + if (type2 == null || password == null) + { + return null; + } + return NtlmPasswordAuthentication.GetPreNtlmResponse(password, type2.GetChallenge + ()); + } + + public static byte[] GetLMv2Response(Type2Message type2, string domain, string user + , string password, byte[] clientChallenge) + { + if (type2 == null || domain == null || user == null || password == null || clientChallenge + == null) + { + return null; + } + return NtlmPasswordAuthentication.GetLMv2Response(domain, user, password, type2.GetChallenge + (), clientChallenge); + } + + public static byte[] GetNtlMv2Response(Type2Message type2, byte[] responseKeyNt, + byte[] clientChallenge) + { + if (type2 == null || responseKeyNt == null || clientChallenge == null) + { + return null; + } + long nanos1601 = (Runtime.CurrentTimeMillis() + MillisecondsBetween1970And1601 + ) * 10000L; + return NtlmPasswordAuthentication.GetNtlMv2Response(responseKeyNt, type2.GetChallenge + (), clientChallenge, nanos1601, type2.GetTargetInformation()); + } + + /// <summary> + /// Constructs the NT response to the given Type-2 message using + /// the supplied password. + /// </summary> + /// <remarks> + /// Constructs the NT response to the given Type-2 message using + /// the supplied password. + /// </remarks> + /// <param name="type2">The Type-2 message.</param> + /// <param name="password">The password.</param> + /// <returns>A <code>byte[]</code> containing the NT response.</returns> + public static byte[] GetNTResponse(Type2Message type2, string password) + { + if (type2 == null || password == null) + { + return null; + } + return NtlmPasswordAuthentication.GetNtlmResponse(password, type2.GetChallenge()); + } + + /// <summary>Returns the default domain from the current environment.</summary> + /// <remarks>Returns the default domain from the current environment.</remarks> + /// <returns>The default domain.</returns> + public static string GetDefaultDomain() + { + return DefaultDomain; + } + + /// <summary>Returns the default user from the current environment.</summary> + /// <remarks>Returns the default user from the current environment.</remarks> + /// <returns>The default user.</returns> + public static string GetDefaultUser() + { + return DefaultUser; + } + + /// <summary>Returns the default password from the current environment.</summary> + /// <remarks>Returns the default password from the current environment.</remarks> + /// <returns>The default password.</returns> + public static string GetDefaultPassword() + { + return DefaultPassword; + } + + /// <summary>Returns the default workstation from the current environment.</summary> + /// <remarks>Returns the default workstation from the current environment.</remarks> + /// <returns>The default workstation.</returns> + public static string GetDefaultWorkstation() + { + return DefaultWorkstation; + } + + /// <exception cref="System.IO.IOException"></exception> + private void Parse(byte[] material) + { + for (int i = 0; i < 8; i++) + { + if (material[i] != NtlmsspSignature[i]) + { + throw new IOException("Not an NTLMSSP message."); + } + } + if (ReadULong(material, 8) != 3) + { + throw new IOException("Not a Type 3 message."); + } + byte[] lmResponse = ReadSecurityBuffer(material, 12); + int lmResponseOffset = ReadULong(material, 16); + byte[] ntResponse = ReadSecurityBuffer(material, 20); + int ntResponseOffset = ReadULong(material, 24); + byte[] domain = ReadSecurityBuffer(material, 28); + int domainOffset = ReadULong(material, 32); + byte[] user = ReadSecurityBuffer(material, 36); + int userOffset = ReadULong(material, 40); + byte[] workstation = ReadSecurityBuffer(material, 44); + int workstationOffset = ReadULong(material, 48); + int flags; + string charset; + byte[] _sessionKey = null; + if (lmResponseOffset == 52 || ntResponseOffset == 52 || domainOffset == 52 || userOffset + == 52 || workstationOffset == 52) + { + flags = NtlmsspNegotiateNtlm | NtlmsspNegotiateOem; + charset = GetOemEncoding(); + } + else + { + _sessionKey = ReadSecurityBuffer(material, 52); + flags = ReadULong(material, 60); + charset = ((flags & NtlmsspNegotiateUnicode) != 0) ? UniEncoding : GetOemEncoding + (); + } + SetSessionKey(_sessionKey); + SetFlags(flags); + SetLmResponse(lmResponse); + SetNtResponse(ntResponse); + SetDomain(Runtime.GetStringForBytes(domain, charset)); + SetUser(Runtime.GetStringForBytes(user, charset)); + SetWorkstation(Runtime.GetStringForBytes(workstation, charset)); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs new file mode 100644 index 000000000..73b742cfb --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs @@ -0,0 +1,287 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.Text; +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + /// <summary> + /// An Access Control Entry (ACE) is an element in a security descriptor + /// such as those associated with files and directories. + /// </summary> + /// <remarks> + /// An Access Control Entry (ACE) is an element in a security descriptor + /// such as those associated with files and directories. The Windows OS + /// determines which users have the necessary permissions to access objects + /// based on these entries. + /// <p> + /// To fully understand the information exposed by this class a description + /// of the access check algorithm used by Windows is required. The following + /// is a basic description of the algorithm. For a more complete description + /// we recommend reading the section on Access Control in Keith Brown's + /// "The .NET Developer's Guide to Windows Security" (which is also + /// available online). + /// <p> + /// Direct ACEs are evaluated first in order. The SID of the user performing + /// the operation and the desired access bits are compared to the SID + /// and access mask of each ACE. If the SID matches, the allow/deny flags + /// and access mask are considered. If the ACE is a "deny" + /// ACE and <i>any</i> of the desired access bits match bits in the access + /// mask of the ACE, the whole access check fails. If the ACE is an "allow" + /// ACE and <i>all</i> of the bits in the desired access bits match bits in + /// the access mask of the ACE, the access check is successful. Otherwise, + /// more ACEs are evaluated until all desired access bits (combined) + /// are "allowed". If all of the desired access bits are not "allowed" + /// the then same process is repeated for inherited ACEs. + /// <p> + /// For example, if user <tt>WNET\alice</tt> tries to open a file + /// with desired access bits <tt>0x00000003</tt> (<tt>FILE_READ_DATA | + /// FILE_WRITE_DATA</tt>) and the target file has the following security + /// descriptor ACEs: + /// <pre> + /// Allow WNET\alice 0x001200A9 Direct + /// Allow Administrators 0x001F01FF Inherited + /// Allow SYSTEM 0x001F01FF Inherited + /// </pre> + /// the access check would fail because the direct ACE has an access mask + /// of <tt>0x001200A9</tt> which doesn't have the + /// <tt>FILE_WRITE_DATA</tt> bit on (bit <tt>0x00000002</tt>). Actually, this isn't quite correct. If + /// <tt>WNET\alice</tt> is in the local <tt>Administrators</tt> group the access check + /// will succeed because the inherited ACE allows local <tt>Administrators</tt> + /// both <tt>FILE_READ_DATA</tt> and <tt>FILE_WRITE_DATA</tt> access. + /// </remarks> + public class Ace + { + public const int FileReadData = unchecked(0x00000001); + + public const int FileWriteData = unchecked(0x00000002); + + public const int FileAppendData = unchecked(0x00000004); + + public const int FileReadEa = unchecked(0x00000008); + + public const int FileWriteEa = unchecked(0x00000010); + + public const int FileExecute = unchecked(0x00000020); + + public const int FileDelete = unchecked(0x00000040); + + public const int FileReadAttributes = unchecked(0x00000080); + + public const int FileWriteAttributes = unchecked(0x00000100); + + public const int Delete = unchecked(0x00010000); + + public const int ReadControl = unchecked(0x00020000); + + public const int WriteDac = unchecked(0x00040000); + + public const int WriteOwner = unchecked(0x00080000); + + public const int Synchronize = unchecked(0x00100000); + + public const int GenericAll = unchecked(0x10000000); + + public const int GenericExecute = unchecked(0x20000000); + + public const int GenericWrite = unchecked(0x40000000); + + public const int GenericRead = unchecked((int)(0x80000000)); + + public const int FlagsObjectInherit = unchecked(0x01); + + public const int FlagsContainerInherit = unchecked(0x02); + + public const int FlagsNoPropagate = unchecked(0x04); + + public const int FlagsInheritOnly = unchecked(0x08); + + public const int FlagsInherited = unchecked(0x10); + + internal bool Allow; + + internal int Flags; + + internal int Access; + + internal Sid Sid; + + // 1 + // 2 + // 3 + // 4 + // 5 + // 6 + // 7 + // 8 + // 9 + // 16 + // 17 + // 18 + // 19 + // 20 + // 28 + // 29 + // 30 + // 31 + /// <summary>Returns true if this ACE is an allow ACE and false if it is a deny ACE.</summary> + /// <remarks>Returns true if this ACE is an allow ACE and false if it is a deny ACE.</remarks> + public virtual bool IsAllow() + { + return Allow; + } + + /// <summary>Returns true if this ACE is an inherited ACE and false if it is a direct ACE. + /// </summary> + /// <remarks> + /// Returns true if this ACE is an inherited ACE and false if it is a direct ACE. + /// <p> + /// Note: For reasons not fully understood, <tt>FLAGS_INHERITED</tt> may + /// not be set within all security descriptors even though the ACE was in + /// face inherited. If an inherited ACE is added to a parent the Windows + /// ACL editor will rebuild all children ACEs and set this flag accordingly. + /// </remarks> + public virtual bool IsInherited() + { + return (Flags & FlagsInherited) != 0; + } + + /// <summary>Returns the flags for this ACE.</summary> + /// <remarks> + /// Returns the flags for this ACE. The </tt>isInherited()</tt> + /// method checks the <tt>FLAGS_INHERITED</tt> bit in these flags. + /// </remarks> + public virtual int GetFlags() + { + return Flags; + } + + /// <summary> + /// Returns the 'Apply To' text for inheritance of ACEs on + /// directories such as 'This folder, subfolder and files'. + /// </summary> + /// <remarks> + /// Returns the 'Apply To' text for inheritance of ACEs on + /// directories such as 'This folder, subfolder and files'. For + /// files the text is always 'This object only'. + /// </remarks> + public virtual string GetApplyToText() + { + switch (Flags & (FlagsObjectInherit | FlagsContainerInherit | FlagsInheritOnly + )) + { + case unchecked(0x00): + { + return "This folder only"; + } + + case unchecked(0x03): + { + return "This folder, subfolders and files"; + } + + case unchecked(0x0B): + { + return "Subfolders and files only"; + } + + case unchecked(0x02): + { + return "This folder and subfolders"; + } + + case unchecked(0x0A): + { + return "Subfolders only"; + } + + case unchecked(0x01): + { + return "This folder and files"; + } + + case unchecked(0x09): + { + return "Files only"; + } + } + return "Invalid"; + } + + /// <summary>Returns the access mask accociated with this ACE.</summary> + /// <remarks> + /// Returns the access mask accociated with this ACE. Use the + /// constants for <tt>FILE_READ_DATA</tt>, <tt>FILE_WRITE_DATA</tt>, + /// <tt>READ_CONTROL</tt>, <tt>GENERIC_ALL</tt>, etc with bitwise + /// operators to determine which bits of the mask are on or off. + /// </remarks> + public virtual int GetAccessMask() + { + return Access; + } + + /// <summary>Return the SID associated with this ACE.</summary> + /// <remarks>Return the SID associated with this ACE.</remarks> + public virtual Sid GetSid() + { + return Sid; + } + + internal virtual int Decode(byte[] buf, int bi) + { + Allow = buf[bi++] == unchecked(unchecked(0x00)); + Flags = buf[bi++] & unchecked(0xFF); + int size = ServerMessageBlock.ReadInt2(buf, bi); + bi += 2; + Access = ServerMessageBlock.ReadInt4(buf, bi); + bi += 4; + Sid = new Sid(buf, bi); + return size; + } + + internal virtual void AppendCol(StringBuilder sb, string str, int width) + { + sb.Append(str); + int count = width - str.Length; + for (int i = 0; i < count; i++) + { + sb.Append(' '); + } + } + + /// <summary>Return a string represeting this ACE.</summary> + /// <remarks> + /// Return a string represeting this ACE. + /// <p> + /// Note: This function should probably be changed to return SDDL + /// fragments but currently it does not. + /// </remarks> + public override string ToString() + { + int count; + int i; + string str; + StringBuilder sb = new StringBuilder(); + sb.Append(IsAllow() ? "Allow " : "Deny "); + AppendCol(sb, Sid.ToDisplayString(), 25); + sb.Append(" 0x").Append(Hexdump.ToHexString(Access, 8)).Append(' '); + sb.Append(IsInherited() ? "Inherited " : "Direct "); + AppendCol(sb, GetApplyToText(), 34); + return sb.ToString(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/AllocInfo.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/AllocInfo.cs new file mode 100644 index 000000000..6ebe88293 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/AllocInfo.cs @@ -0,0 +1,25 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal interface IAllocInfo + { + long GetCapacity(); + + long GetFree(); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs new file mode 100644 index 000000000..e78bff9d0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs @@ -0,0 +1,221 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal abstract class AndXServerMessageBlock : ServerMessageBlock + { + private const int AndxCommandOffset = 1; + + private const int AndxReservedOffset = 2; + + private const int AndxOffsetOffset = 3; + + private byte _andxCommand = unchecked(unchecked(0xFF)); + + private int _andxOffset; + + internal ServerMessageBlock Andx; + + public AndXServerMessageBlock() + { + } + + internal AndXServerMessageBlock(ServerMessageBlock andx) + { + if (andx != null) + { + this.Andx = andx; + _andxCommand = andx.Command; + } + } + + internal virtual int GetBatchLimit(byte command) + { + return 0; + } + + internal override int Encode(byte[] dst, int dstIndex) + { + int start = HeaderStart = dstIndex; + dstIndex += WriteHeaderWireFormat(dst, dstIndex); + dstIndex += WriteAndXWireFormat(dst, dstIndex); + Length = dstIndex - start; + if (Digest != null) + { + Digest.Sign(dst, HeaderStart, Length, this, Response); + } + return Length; + } + + internal override int Decode(byte[] buffer, int bufferIndex) + { + int start = HeaderStart = bufferIndex; + bufferIndex += ReadHeaderWireFormat(buffer, bufferIndex); + bufferIndex += ReadAndXWireFormat(buffer, bufferIndex); + Length = bufferIndex - start; + return Length; + } + + internal virtual int WriteAndXWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WordCount = WriteParameterWordsWireFormat(dst, start + AndxOffsetOffset + 2); + WordCount += 4; + // for command, reserved, and offset + dstIndex += WordCount + 1; + WordCount /= 2; + dst[start] = unchecked((byte)(WordCount & unchecked(0xFF))); + ByteCount = WriteBytesWireFormat(dst, dstIndex + 2); + dst[dstIndex++] = unchecked((byte)(ByteCount & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((ByteCount >> 8) & unchecked(0xFF))); + dstIndex += ByteCount; + if (Andx == null || SmbConstants.UseBatching == false || BatchLevel >= GetBatchLimit(Andx.Command + )) + { + _andxCommand = unchecked(unchecked(0xFF)); + Andx = null; + dst[start + AndxCommandOffset] = unchecked(unchecked(0xFF)); + dst[start + AndxReservedOffset] = unchecked(unchecked(0x00)); + // dst[start + ANDX_OFFSET_OFFSET] = (byte)0x00; + // dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0x00; + dst[start + AndxOffsetOffset] = unchecked(unchecked(0xde)); + dst[start + AndxOffsetOffset + 1] = unchecked(unchecked(0xde)); + // andx not used; return + return dstIndex - start; + } + Andx.BatchLevel = BatchLevel + 1; + dst[start + AndxCommandOffset] = _andxCommand; + dst[start + AndxReservedOffset] = unchecked(unchecked(0x00)); + _andxOffset = dstIndex - HeaderStart; + WriteInt2(_andxOffset, dst, start + AndxOffsetOffset); + Andx.UseUnicode = UseUnicode; + if (Andx is AndXServerMessageBlock) + { + Andx.Uid = Uid; + dstIndex += ((AndXServerMessageBlock)Andx).WriteAndXWireFormat(dst, dstIndex + ); + } + else + { + // the andx smb is not of type andx so lets just write it here and + // were done. + int andxStart = dstIndex; + Andx.WordCount = Andx.WriteParameterWordsWireFormat(dst, dstIndex); + dstIndex += Andx.WordCount + 1; + Andx.WordCount /= 2; + dst[andxStart] = unchecked((byte)(Andx.WordCount & unchecked(0xFF))); + Andx.ByteCount = Andx.WriteBytesWireFormat(dst, dstIndex + 2); + dst[dstIndex++] = unchecked((byte)(Andx.ByteCount & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((Andx.ByteCount >> 8) & unchecked(0xFF) + )); + dstIndex += Andx.ByteCount; + } + return dstIndex - start; + } + + internal virtual int ReadAndXWireFormat(byte[] buffer, int bufferIndex) + { + int start = bufferIndex; + WordCount = buffer[bufferIndex++]; + if (WordCount != 0) + { + _andxCommand = buffer[bufferIndex]; + _andxOffset = ReadInt2(buffer, bufferIndex + 2); + if (_andxOffset == 0) + { + _andxCommand = unchecked(unchecked(0xFF)); + } + if (WordCount > 2) + { + ReadParameterWordsWireFormat(buffer, bufferIndex + 4); + if (Command == SmbComNtCreateAndx && ((SmbComNtCreateAndXResponse)this).IsExtended) + { + WordCount += 8; + } + } + bufferIndex = start + 1 + (WordCount * 2); + } + ByteCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if (ByteCount != 0) + { + int n; + n = ReadBytesWireFormat(buffer, bufferIndex); + bufferIndex += ByteCount; + } + if (ErrorCode != 0 || _andxCommand == unchecked(unchecked(0xFF))) + { + _andxCommand = unchecked(unchecked(0xFF)); + Andx = null; + } + else + { + if (Andx == null) + { + _andxCommand = unchecked(unchecked(0xFF)); + throw new RuntimeException("no andx command supplied with response"); + } + bufferIndex = HeaderStart + _andxOffset; + Andx.HeaderStart = HeaderStart; + Andx.Command = _andxCommand; + Andx.ErrorCode = ErrorCode; + Andx.Flags = Flags; + Andx.Flags2 = Flags2; + Andx.Tid = Tid; + Andx.Pid = Pid; + Andx.Uid = Uid; + Andx.Mid = Mid; + Andx.UseUnicode = UseUnicode; + if (Andx is AndXServerMessageBlock) + { + bufferIndex += ((AndXServerMessageBlock)Andx).ReadAndXWireFormat(buffer + , bufferIndex); + } + else + { + buffer[bufferIndex++] = unchecked((byte)(Andx.WordCount & unchecked(0xFF)) + ); + if (Andx.WordCount != 0) + { + if (Andx.WordCount > 2) + { + bufferIndex += Andx.ReadParameterWordsWireFormat(buffer, bufferIndex); + } + } + Andx.ByteCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if (Andx.ByteCount != 0) + { + Andx.ReadBytesWireFormat(buffer, bufferIndex); + bufferIndex += Andx.ByteCount; + } + } + Andx.Received = true; + } + return bufferIndex - start; + } + + public override string ToString() + { + return base.ToString() + ",andxCommand=0x" + Hexdump.ToHexString(_andxCommand + , 2) + ",andxOffset=" + _andxOffset; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/BufferCache.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/BufferCache.cs new file mode 100644 index 000000000..b36816e26 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/BufferCache.cs @@ -0,0 +1,80 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public class BufferCache + { + private static readonly int MaxBuffers = Config.GetInt("jcifs.smb.maxBuffers", 16 + ); + + internal static object[] Cache = new object[MaxBuffers]; + + private static int _freeBuffers; + + public static byte[] GetBuffer() + { + lock (Cache) + { + byte[] buf; + if (_freeBuffers > 0) + { + for (int i = 0; i < MaxBuffers; i++) + { + if (Cache[i] != null) + { + buf = (byte[])Cache[i]; + Cache[i] = null; + _freeBuffers--; + return buf; + } + } + } + buf = new byte[SmbComTransaction.TransactionBufSize]; + return buf; + } + } + + internal static void GetBuffers(SmbComTransaction req, SmbComTransactionResponse + rsp) + { + lock (Cache) + { + req.TxnBuf = GetBuffer(); + rsp.TxnBuf = GetBuffer(); + } + } + + public static void ReleaseBuffer(byte[] buf) + { + lock (Cache) + { + if (_freeBuffers < MaxBuffers) + { + for (int i = 0; i < MaxBuffers; i++) + { + if (Cache[i] == null) + { + Cache[i] = buf; + _freeBuffers++; + return; + } + } + } + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Dfs.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Dfs.cs new file mode 100644 index 000000000..2f62e5b8d --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Dfs.cs @@ -0,0 +1,389 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + public class Dfs + { + internal class CacheEntry + { + internal long Expiration; + + internal Hashtable Map; + + internal CacheEntry(long ttl) + { + if (ttl == 0) + { + ttl = Ttl; + } + Expiration = Runtime.CurrentTimeMillis() + ttl * 1000L; + Map = new Hashtable(); + } + } + + internal static LogStream Log = LogStream.GetInstance(); + + internal static readonly bool StrictView = Config.GetBoolean("jcifs.smb.client.dfs.strictView" + , false); + + internal static readonly long Ttl = Config.GetLong("jcifs.smb.client.dfs.ttl", 300 + ); + + internal static readonly bool Disabled = Config.GetBoolean("jcifs.smb.client.dfs.disabled" + , false); + + internal static CacheEntry FalseEntry = new CacheEntry(0L); + + internal CacheEntry Domains; + + internal CacheEntry Referrals; + + /// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> + public virtual Hashtable GetTrustedDomains(NtlmPasswordAuthentication auth) + { + if (Disabled || auth.Domain == "?") + { + return null; + } + if (Domains != null && Runtime.CurrentTimeMillis() > Domains.Expiration) + { + Domains = null; + } + if (Domains != null) + { + return Domains.Map; + } + try + { + UniAddress addr = UniAddress.GetByName(auth.Domain, true); + SmbTransport trans = SmbTransport.GetSmbTransport(addr, 0); + CacheEntry entry = new CacheEntry(Ttl * 10L); + DfsReferral dr = trans.GetDfsReferrals(auth, string.Empty, 0); + if (dr != null) + { + DfsReferral start = dr; + do + { + string domain = dr.Server.ToLower(); + entry.Map.Put(domain, new Hashtable()); + dr = dr.Next; + } + while (dr != start); + Domains = entry; + return Domains.Map; + } + } + catch (IOException ioe) + { + if (Log.Level >= 3) + { + Runtime.PrintStackTrace(ioe, Log); + } + if (StrictView && ioe is SmbAuthException) + { + throw (SmbAuthException)ioe; + } + } + return null; + } + + /// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> + public virtual bool IsTrustedDomain(string domain, NtlmPasswordAuthentication auth + ) + { + Hashtable domains = GetTrustedDomains(auth); + if (domains == null) + { + return false; + } + domain = domain.ToLower(); + return domains.Get(domain) != null; + } + + /// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> + public virtual SmbTransport GetDc(string domain, NtlmPasswordAuthentication auth) + { + if (Disabled) + { + return null; + } + try + { + UniAddress addr = UniAddress.GetByName(domain, true); + SmbTransport trans = SmbTransport.GetSmbTransport(addr, 0); + DfsReferral dr = trans.GetDfsReferrals(auth, "\\" + domain, 1); + if (dr != null) + { + DfsReferral start = dr; + IOException e = null; + do + { + try + { + addr = UniAddress.GetByName(dr.Server); + return SmbTransport.GetSmbTransport(addr, 0); + } + catch (IOException ioe) + { + e = ioe; + } + dr = dr.Next; + } + while (dr != start); + throw e; + } + } + catch (IOException ioe) + { + if (Log.Level >= 3) + { + Runtime.PrintStackTrace(ioe, Log); + } + if (StrictView && ioe is SmbAuthException) + { + throw (SmbAuthException)ioe; + } + } + return null; + } + + /// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> + public virtual DfsReferral GetReferral(SmbTransport trans, string domain, string + root, string path, NtlmPasswordAuthentication auth) + { + if (Disabled) + { + return null; + } + try + { + string p = "\\" + domain + "\\" + root; + if (path != null) + { + p += path; + } + DfsReferral dr = trans.GetDfsReferrals(auth, p, 0); + if (dr != null) + { + return dr; + } + } + catch (IOException ioe) + { + if (Log.Level >= 4) + { + Runtime.PrintStackTrace(ioe, Log); + } + if (StrictView && ioe is SmbAuthException) + { + throw (SmbAuthException)ioe; + } + } + return null; + } + + /// <exception cref="SharpCifs.Smb.SmbAuthException"></exception> + public virtual DfsReferral Resolve(string domain, string root, string path, NtlmPasswordAuthentication + auth) + { + lock (this) + { + DfsReferral dr = null; + long now = Runtime.CurrentTimeMillis(); + if (Disabled || root.Equals("IPC$")) + { + return null; + } + Hashtable domains = GetTrustedDomains(auth); + if (domains != null) + { + domain = domain.ToLower(); + Hashtable roots = (Hashtable)domains.Get(domain); + if (roots != null) + { + SmbTransport trans = null; + root = root.ToLower(); + CacheEntry links = (CacheEntry)roots.Get(root); + if (links != null && now > links.Expiration) + { + //Sharpen.Collections.Remove(roots, root); + roots.Remove(root); + links = null; + } + if (links == null) + { + if ((trans = GetDc(domain, auth)) == null) + { + return null; + } + dr = GetReferral(trans, domain, root, path, auth); + if (dr != null) + { + int len = 1 + domain.Length + 1 + root.Length; + links = new CacheEntry(0L); + DfsReferral tmp = dr; + do + { + if (path == null) + { + // TODO: fix this + //tmp.map = links.map; + tmp.Key = "\\"; + } + tmp.PathConsumed -= len; + tmp = tmp.Next; + } + while (tmp != dr); + if (dr.Key != null) + { + links.Map.Put(dr.Key, dr); + } + roots.Put(root, links); + } + else + { + if (path == null) + { + roots.Put(root, FalseEntry); + } + } + } + else + { + if (links == FalseEntry) + { + links = null; + } + } + if (links != null) + { + string link = "\\"; + dr = (DfsReferral)links.Map.Get(link); + if (dr != null && now > dr.Expiration) + { + //Sharpen.Collections.Remove(links.map, link); + links.Map.Remove(link); + dr = null; + } + if (dr == null) + { + if (trans == null) + { + if ((trans = GetDc(domain, auth)) == null) + { + return null; + } + } + dr = GetReferral(trans, domain, root, path, auth); + if (dr != null) + { + dr.PathConsumed -= 1 + domain.Length + 1 + root.Length; + dr.Link = link; + links.Map.Put(link, dr); + } + } + } + } + } + if (dr == null && path != null) + { + if (Referrals != null && now > Referrals.Expiration) + { + Referrals = null; + } + if (Referrals == null) + { + Referrals = new CacheEntry(0); + } + string key = "\\" + domain + "\\" + root; + if (path.Equals("\\") == false) + { + key += path; + } + key = key.ToLower(); + //ListIterator<object> iter = new ListIterator<object>(referrals.map.Keys.GetEnumerator(), 0); + foreach (var current in Referrals.Map.Keys) + { + string _key = (string)current; + int klen = _key.Length; + bool match = false; + if (klen == key.Length) + { + match = _key.Equals(key); + } + else + { + if (klen < key.Length) + { + match = _key.RegionMatches(false, 0, key, 0, klen) && key[klen] == '\\'; + } + } + if (match) + { + dr = (DfsReferral)Referrals.Map.Get(_key); + } + } + } + return dr; + } + } + + internal virtual void Insert(string path, DfsReferral dr) + { + lock (this) + { + int s1; + int s2; + string server; + string share; + string key; + if (Disabled) + { + return; + } + s1 = path.IndexOf('\\', 1); + s2 = path.IndexOf('\\', s1 + 1); + server = Runtime.Substring(path, 1, s1); + share = Runtime.Substring(path, s1 + 1, s2); + key = Runtime.Substring(path, 0, dr.PathConsumed).ToLower(); + int ki = key.Length; + while (ki > 1 && key[ki - 1] == '\\') + { + ki--; + } + if (ki < key.Length) + { + key = Runtime.Substring(key, 0, ki); + } + dr.PathConsumed -= 1 + server.Length + 1 + share.Length; + if (Referrals != null && (Runtime.CurrentTimeMillis() + 10000) > Referrals.Expiration) + { + Referrals = null; + } + if (Referrals == null) + { + Referrals = new CacheEntry(0); + } + Referrals.Map.Put(key, dr); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/DfsReferral.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/DfsReferral.cs new file mode 100644 index 000000000..3b6091f73 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/DfsReferral.cs @@ -0,0 +1,67 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.Collections.Generic; + +namespace SharpCifs.Smb +{ + + public class DfsReferral : SmbException + { + public int PathConsumed; + + public long Ttl; + + public string Server; + + public string Share; + + public string Link; + + public string Path; + + public bool ResolveHashes; + + public long Expiration; + + internal DfsReferral Next; + + internal IDictionary<string, DfsReferral> Map; + + internal string Key = null; + + public DfsReferral() + { + // Server + // Share + // Path relative to tree from which this referral was thrown + Next = this; + } + + internal virtual void Append(DfsReferral dr) + { + dr.Next = Next; + Next = dr; + } + + public override string ToString() + { + return "DfsReferral[pathConsumed=" + PathConsumed + ",server=" + Server + ",share=" + + Share + ",link=" + Link + ",path=" + Path + ",ttl=" + Ttl + ",expiration=" + + Expiration + ",resolveHashes=" + ResolveHashes + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/DosError.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/DosError.cs new file mode 100644 index 000000000..d89e5bafa --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/DosError.cs @@ -0,0 +1,64 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public static class DosError + { + public static int[][] DosErrorCodes = { new[] { unchecked(0x00000000), unchecked(0x00000000) }, new[] { unchecked(0x00010001), unchecked((int)(0xc0000002)) }, new[] { unchecked(0x00010002), unchecked( + (int)(0xc0000002)) }, new[] { unchecked(0x00020001), unchecked((int)( + 0xc000000f)) }, new[] { unchecked(0x00020002), unchecked((int)(0xc000006a + )) }, new[] { unchecked(0x00030001), unchecked((int)(0xc000003a)) }, + new[] { unchecked(0x00030002), unchecked((int)(0xc00000cb)) }, new[] { unchecked(0x00040002), unchecked((int)(0xc00000ca)) }, new[] { unchecked( + 0x00050001), unchecked((int)(0xc0000022)) }, new[] { unchecked(0x00050002), unchecked((int)(0xc000000d)) }, new[] { unchecked(0x00060001), unchecked((int)(0xc0000008)) }, new[] { unchecked(0x00060002), unchecked( + (int)(0xc00000cc)) }, new[] { unchecked(0x00080001), unchecked((int)( + 0xc000009a)) }, new[] { unchecked(0x00130003), unchecked((int)(0xc00000a2 + )) }, new[] { unchecked(0x00150003), unchecked((int)(0xc0000013)) }, + new[] { unchecked(0x001f0001), unchecked((int)(0xc0000001)) }, new[] { unchecked(0x001f0003), unchecked((int)(0xc0000001)) }, new[] { unchecked( + 0x00200001), unchecked((int)(0xc0000043)) }, new[] { unchecked(0x00200003), unchecked((int)(0xc0000043)) }, new[] { unchecked(0x00210003), unchecked((int)(0xc0000054)) }, new[] { unchecked(0x00270003), unchecked( + (int)(0xc000007f)) }, new[] { unchecked(0x00340001), unchecked((int)( + 0xC00000bd)) }, new[] { unchecked(0x00430001), unchecked((int)(0xc00000cc + )) }, new[] { unchecked(0x00470001), unchecked((int)(0xC00000d0)) }, + new[] { unchecked(0x00500001), unchecked((int)(0xc0000035)) }, new[] { unchecked(0x00570001), unchecked((int)(0xc0000003)) }, new[] { unchecked( + 0x005a0002), unchecked((int)(0xc00000ce)) }, new[] { unchecked(0x005b0002), unchecked((int)(0xc000000d)) }, new[] { unchecked(0x006d0001), unchecked((int)(0xC000014b)) }, new[] { unchecked(0x007b0001), unchecked( + (int)(0xc0000033)) }, new[] { unchecked(0x00910001), unchecked((int)( + 0xC0000101)) }, new[] { unchecked(0x00b70001), unchecked((int)(0xc0000035 + )) }, new[] { unchecked(0x00e70001), unchecked((int)(0xc00000ab)) }, + new[] { unchecked(0x00e80001), unchecked((int)(0xc00000b1)) }, new[] { unchecked(0x00e90001), unchecked((int)(0xc00000b0)) }, new[] { unchecked( + 0x00ea0001), unchecked((int)(0xc0000016)) }, new[] { unchecked(0x08bf0002), unchecked((int)(0xC0000193)) }, new[] { unchecked(0x08c00002), unchecked((int)(0xC0000070)) }, new[] { unchecked(0x08c10002), unchecked( + (int)(0xC000006f)) }, new[] { unchecked(0x08c20002), unchecked((int)( + 0xC0000071)) } }; + + public static string[] DosErrorMessages = { "The operation completed successfully." + , "Incorrect function.", "Incorrect function.", "The system cannot find the file specified." + , "Bad password.", "The system cannot find the path specified.", "reserved", "The client does not have the necessary access rights to perform the requested function." + , "Access is denied.", "The TID specified was invalid.", "The handle is invalid." + , "The network name cannot be found.", "Not enough storage is available to process this command." + , "The media is write protected.", "The device is not ready.", "A device attached to the system is not functioning." + , "A device attached to the system is not functioning.", "The process cannot access the file because it is being used by another process." + , "The process cannot access the file because it is being used by another process." + , "The process cannot access the file because another process has locked a portion of the file." + , "The disk is full.", "A duplicate name exists on the network.", "The network name cannot be found." + , "ERRnomoreconn.", "The file exists.", "The parameter is incorrect.", "Too many Uids active on this session." + , "The Uid is not known as a valid user identifier on this session.", "The pipe has been ended." + , "The filename, directory name, or volume label syntax is incorrect.", "The directory is not empty." + , "Cannot create a file when that file already exists.", "All pipe instances are busy." + , "The pipe is being closed.", "No process is on the other end of the pipe.", "More data is available." + , "This user account has expired.", "The user is not allowed to log on from this workstation." + , "The user is not allowed to log on at this time.", "The password of this user has expired." + }; + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/DosFileFilter.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/DosFileFilter.cs new file mode 100644 index 000000000..bbf7882c8 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/DosFileFilter.cs @@ -0,0 +1,37 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public class DosFileFilter : ISmbFileFilter + { + protected internal string Wildcard; + + protected internal int Attributes; + + public DosFileFilter(string wildcard, int attributes) + { + this.Wildcard = wildcard; + this.Attributes = attributes; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual bool Accept(SmbFile file) + { + return (file.GetAttributes() & Attributes) != 0; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/FileEntry.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/FileEntry.cs new file mode 100644 index 000000000..bbf3e7cc4 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/FileEntry.cs @@ -0,0 +1,33 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public interface IFileEntry + { + string GetName(); + + int GetType(); + + int GetAttributes(); + + long CreateTime(); + + long LastModified(); + + long Length(); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/IInfo.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/IInfo.cs new file mode 100644 index 000000000..b0e40c5cd --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/IInfo.cs @@ -0,0 +1,29 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal interface IInfo + { + int GetAttributes(); + + long GetCreateTime(); + + long GetLastWriteTime(); + + long GetSize(); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NetServerEnum2.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetServerEnum2.cs new file mode 100644 index 000000000..b4a02d8c3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetServerEnum2.cs @@ -0,0 +1,122 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class NetServerEnum2 : SmbComTransaction + { + internal const int SvTypeAll = unchecked((int)(0xFFFFFFFF)); + + internal const int SvTypeDomainEnum = unchecked((int)(0x80000000)); + + internal static readonly string[] Descr = { "WrLehDO\u0000B16BBDz\u0000" + , "WrLehDz\u0000B16BBDz\u0000" }; + + internal string Domain; + + internal string LastName; + + internal int ServerTypes; + + internal NetServerEnum2(string domain, int serverTypes) + { + this.Domain = domain; + this.ServerTypes = serverTypes; + Command = SmbComTransaction; + SubCommand = NetServerEnum2; + // not really true be used by upper logic + Name = "\\PIPE\\LANMAN"; + MaxParameterCount = 8; + MaxDataCount = 16384; + MaxSetupCount = unchecked(unchecked(0x00)); + SetupCount = 0; + Timeout = 5000; + } + + internal override void Reset(int key, string lastName) + { + base.Reset(); + this.LastName = lastName; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + byte[] descr; + int which = SubCommand == NetServerEnum2 ? 0 : 1; + try + { + descr = Runtime.GetBytesForString(Descr[which], "UTF-8"); //"ASCII"); + } + catch (UnsupportedEncodingException) + { + return 0; + } + WriteInt2(SubCommand & unchecked(0xFF), dst, dstIndex); + dstIndex += 2; + Array.Copy(descr, 0, dst, dstIndex, descr.Length); + dstIndex += descr.Length; + WriteInt2(unchecked(0x0001), dst, dstIndex); + dstIndex += 2; + WriteInt2(MaxDataCount, dst, dstIndex); + dstIndex += 2; + WriteInt4(ServerTypes, dst, dstIndex); + dstIndex += 4; + dstIndex += WriteString(Domain.ToUpper(), dst, dstIndex, false); + if (which == 1) + { + dstIndex += WriteString(LastName.ToUpper(), dst, dstIndex, false); + } + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "NetServerEnum2[" + base.ToString() + ",name=" + Name + ",serverTypes=" + + (ServerTypes == SvTypeAll ? "SV_TYPE_ALL" : "SV_TYPE_DOMAIN_ENUM") + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NetServerEnum2Response.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetServerEnum2Response.cs new file mode 100644 index 000000000..9a0e5e3d5 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetServerEnum2Response.cs @@ -0,0 +1,157 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class NetServerEnum2Response : SmbComTransactionResponse + { + internal class ServerInfo1 : IFileEntry + { + internal string Name; + + internal int VersionMajor; + + internal int VersionMinor; + + internal int Type; + + internal string CommentOrMasterBrowser; + + public virtual string GetName() + { + return Name; + } + + public new virtual int GetType() + { + return (Type & unchecked((int)(0x80000000))) != 0 ? SmbFile.TypeWorkgroup : + SmbFile.TypeServer; + } + + public virtual int GetAttributes() + { + return SmbFile.AttrReadonly | SmbFile.AttrDirectory; + } + + public virtual long CreateTime() + { + return 0L; + } + + public virtual long LastModified() + { + return 0L; + } + + public virtual long Length() + { + return 0L; + } + + public override string ToString() + { + return "ServerInfo1[" + "name=" + Name + ",versionMajor=" + VersionMajor + ",versionMinor=" + VersionMinor + ",type=0x" + Hexdump.ToHexString + (Type, 8) + ",commentOrMasterBrowser=" + CommentOrMasterBrowser + "]"; + } + + internal ServerInfo1(NetServerEnum2Response enclosing) + { + this._enclosing = enclosing; + } + + private readonly NetServerEnum2Response _enclosing; + } + + private int _converter; + + private int _totalAvailableEntries; + + internal string LastName; + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + int start = bufferIndex; + Status = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _converter = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + NumEntries = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _totalAvailableEntries = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + return bufferIndex - start; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + int start = bufferIndex; + ServerInfo1 e = null; + Results = new ServerInfo1[NumEntries]; + for (int i = 0; i < NumEntries; i++) + { + Results[i] = e = new ServerInfo1(this); + e.Name = ReadString(buffer, bufferIndex, 16, false); + bufferIndex += 16; + e.VersionMajor = buffer[bufferIndex++] & unchecked(0xFF); + e.VersionMinor = buffer[bufferIndex++] & unchecked(0xFF); + e.Type = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + int off = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + off = (off & unchecked(0xFFFF)) - _converter; + off = start + off; + e.CommentOrMasterBrowser = ReadString(buffer, off, 48, false); + if (Log.Level >= 4) + { + Log.WriteLine(e); + } + } + LastName = NumEntries == 0 ? null : e.Name; + return bufferIndex - start; + } + + public override string ToString() + { + return "NetServerEnum2Response[" + base.ToString() + ",status=" + Status + + ",converter=" + _converter + ",entriesReturned=" + NumEntries + ",totalAvailableEntries=" + + _totalAvailableEntries + ",lastName=" + LastName + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NetShareEnum.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetShareEnum.cs new file mode 100644 index 000000000..1b0c6f931 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetShareEnum.cs @@ -0,0 +1,95 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class NetShareEnum : SmbComTransaction + { + private static readonly string Descr = "WrLeh\u0000B13BWz\u0000"; + + public NetShareEnum() + { + Command = SmbComTransaction; + SubCommand = NetShareEnum; + // not really true be used by upper logic + Name ="\\PIPE\\LANMAN"; + MaxParameterCount = 8; + // maxDataCount = 4096; why was this set? + MaxSetupCount = 0x00; + SetupCount = 0; + Timeout = 5000; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + byte[] descr; + try + { + //descr = Runtime.GetBytesForString(Descr, "ASCII"); + descr = Runtime.GetBytesForString(Descr, "UTF-8"); + } + catch (UnsupportedEncodingException) + { + return 0; + } + WriteInt2(NetShareEnum, dst, dstIndex); + dstIndex += 2; + Array.Copy(descr, 0, dst, dstIndex, descr.Length); + dstIndex += descr.Length; + WriteInt2(unchecked(0x0001), dst, dstIndex); + dstIndex += 2; + WriteInt2(MaxDataCount, dst, dstIndex); + dstIndex += 2; + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "NetShareEnum[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NetShareEnumResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetShareEnumResponse.cs new file mode 100644 index 000000000..408f8e4d1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NetShareEnumResponse.cs @@ -0,0 +1,94 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class NetShareEnumResponse : SmbComTransactionResponse + { + private int _converter; + + private int _totalAvailableEntries; + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + int start = bufferIndex; + Status = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _converter = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + NumEntries = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _totalAvailableEntries = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + return bufferIndex - start; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + int start = bufferIndex; + SmbShareInfo e; + UseUnicode = false; + Results = new SmbShareInfo[NumEntries]; + for (int i = 0; i < NumEntries; i++) + { + Results[i] = e = new SmbShareInfo(); + e.NetName = ReadString(buffer, bufferIndex, 13, false); + bufferIndex += 14; + e.Type = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + int off = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + off = (off & unchecked(0xFFFF)) - _converter; + off = start + off; + e.Remark = ReadString(buffer, off, 128, false); + if (Log.Level >= 4) + { + Log.WriteLine(e); + } + } + return bufferIndex - start; + } + + public override string ToString() + { + return "NetShareEnumResponse[" + base.ToString() + ",status=" + Status + + ",converter=" + _converter + ",entriesReturned=" + NumEntries + ",totalAvailableEntries=" + + _totalAvailableEntries + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NtStatus.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtStatus.cs new file mode 100644 index 000000000..511e7ae84 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtStatus.cs @@ -0,0 +1,202 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public static class NtStatus + { + public const int NtStatusOk = unchecked(0x00000000); + + public const int NtStatusUnsuccessful = unchecked((int)(0xC0000001)); + + public const int NtStatusNotImplemented = unchecked((int)(0xC0000002)); + + public const int NtStatusInvalidInfoClass = unchecked((int)(0xC0000003)); + + public const int NtStatusAccessViolation = unchecked((int)(0xC0000005)); + + public const int NtStatusInvalidHandle = unchecked((int)(0xC0000008)); + + public const int NtStatusInvalidParameter = unchecked((int)(0xC000000d)); + + public const int NtStatusNoSuchDevice = unchecked((int)(0xC000000e)); + + public const int NtStatusNoSuchFile = unchecked((int)(0xC000000f)); + + public const int NtStatusMoreProcessingRequired = unchecked((int)(0xC0000016) + ); + + public const int NtStatusAccessDenied = unchecked((int)(0xC0000022)); + + public const int NtStatusBufferTooSmall = unchecked((int)(0xC0000023)); + + public const int NtStatusObjectNameInvalid = unchecked((int)(0xC0000033)); + + public const int NtStatusObjectNameNotFound = unchecked((int)(0xC0000034)); + + public const int NtStatusObjectNameCollision = unchecked((int)(0xC0000035)); + + public const int NtStatusPortDisconnected = unchecked((int)(0xC0000037)); + + public const int NtStatusObjectPathInvalid = unchecked((int)(0xC0000039)); + + public const int NtStatusObjectPathNotFound = unchecked((int)(0xC000003a)); + + public const int NtStatusObjectPathSyntaxBad = unchecked((int)(0xC000003b)); + + public const int NtStatusSharingViolation = unchecked((int)(0xC0000043)); + + public const int NtStatusDeletePending = unchecked((int)(0xC0000056)); + + public const int NtStatusNoLogonServers = unchecked((int)(0xC000005e)); + + public const int NtStatusUserExists = unchecked((int)(0xC0000063)); + + public const int NtStatusNoSuchUser = unchecked((int)(0xC0000064)); + + public const int NtStatusWrongPassword = unchecked((int)(0xC000006a)); + + public const int NtStatusLogonFailure = unchecked((int)(0xC000006d)); + + public const int NtStatusAccountRestriction = unchecked((int)(0xC000006e)); + + public const int NtStatusInvalidLogonHours = unchecked((int)(0xC000006f)); + + public const int NtStatusInvalidWorkstation = unchecked((int)(0xC0000070)); + + public const int NtStatusPasswordExpired = unchecked((int)(0xC0000071)); + + public const int NtStatusAccountDisabled = unchecked((int)(0xC0000072)); + + public const int NtStatusNoneMapped = unchecked((int)(0xC0000073)); + + public const int NtStatusInvalidSid = unchecked((int)(0xC0000078)); + + public const int NtStatusInstanceNotAvailable = unchecked((int)(0xC00000ab)); + + public const int NtStatusPipeNotAvailable = unchecked((int)(0xC00000ac)); + + public const int NtStatusInvalidPipeState = unchecked((int)(0xC00000ad)); + + public const int NtStatusPipeBusy = unchecked((int)(0xC00000ae)); + + public const int NtStatusPipeDisconnected = unchecked((int)(0xC00000b0)); + + public const int NtStatusPipeClosing = unchecked((int)(0xC00000b1)); + + public const int NtStatusPipeListening = unchecked((int)(0xC00000b3)); + + public const int NtStatusFileIsADirectory = unchecked((int)(0xC00000ba)); + + public const int NtStatusDuplicateName = unchecked((int)(0xC00000bd)); + + public const int NtStatusNetworkNameDeleted = unchecked((int)(0xC00000c9)); + + public const int NtStatusNetworkAccessDenied = unchecked((int)(0xC00000ca)); + + public const int NtStatusBadNetworkName = unchecked((int)(0xC00000cc)); + + public const int NtStatusRequestNotAccepted = unchecked((int)(0xC00000d0)); + + public const int NtStatusCantAccessDomainInfo = unchecked((int)(0xC00000da)); + + public const int NtStatusNoSuchDomain = unchecked((int)(0xC00000df)); + + public const int NtStatusNotADirectory = unchecked((int)(0xC0000103)); + + public const int NtStatusCannotDelete = unchecked((int)(0xC0000121)); + + public const int NtStatusInvalidComputerName = unchecked((int)(0xC0000122)); + + public const int NtStatusPipeBroken = unchecked((int)(0xC000014b)); + + public const int NtStatusNoSuchAlias = unchecked((int)(0xC0000151)); + + public const int NtStatusLogonTypeNotGranted = unchecked((int)(0xC000015b)); + + public const int NtStatusNoTrustSamAccount = unchecked((int)(0xC000018b)); + + public const int NtStatusTrustedDomainFailure = unchecked((int)(0xC000018c)); + + public const int NtStatusNologonWorkstationTrustAccount = unchecked((int)(0xC0000199 + )); + + public const int NtStatusPasswordMustChange = unchecked((int)(0xC0000224)); + + public const int NtStatusNotFound = unchecked((int)(0xC0000225)); + + public const int NtStatusAccountLockedOut = unchecked((int)(0xC0000234)); + + public const int NtStatusPathNotCovered = unchecked((int)(0xC0000257)); + + public const int NtStatusIoReparseTagNotHandled = unchecked((int)(0xC0000279 + )); + + public static int[] NtStatusCodes = { NtStatusOk, NtStatusUnsuccessful + , NtStatusNotImplemented, NtStatusInvalidInfoClass, NtStatusAccessViolation + , NtStatusInvalidHandle, NtStatusInvalidParameter, NtStatusNoSuchDevice + , NtStatusNoSuchFile, NtStatusMoreProcessingRequired, NtStatusAccessDenied + , NtStatusBufferTooSmall, NtStatusObjectNameInvalid, NtStatusObjectNameNotFound + , NtStatusObjectNameCollision, NtStatusPortDisconnected, NtStatusObjectPathInvalid + , NtStatusObjectPathNotFound, NtStatusObjectPathSyntaxBad, NtStatusSharingViolation + , NtStatusDeletePending, NtStatusNoLogonServers, NtStatusUserExists, NtStatusNoSuchUser + , NtStatusWrongPassword, NtStatusLogonFailure, NtStatusAccountRestriction + , NtStatusInvalidLogonHours, NtStatusInvalidWorkstation, NtStatusPasswordExpired + , NtStatusAccountDisabled, NtStatusNoneMapped, NtStatusInvalidSid, NtStatusInstanceNotAvailable + , NtStatusPipeNotAvailable, NtStatusInvalidPipeState, NtStatusPipeBusy + , NtStatusPipeDisconnected, NtStatusPipeClosing, NtStatusPipeListening, + NtStatusFileIsADirectory, NtStatusDuplicateName, NtStatusNetworkNameDeleted + , NtStatusNetworkAccessDenied, NtStatusBadNetworkName, NtStatusRequestNotAccepted + , NtStatusCantAccessDomainInfo, NtStatusNoSuchDomain, NtStatusNotADirectory + , NtStatusCannotDelete, NtStatusInvalidComputerName, NtStatusPipeBroken + , NtStatusNoSuchAlias, NtStatusLogonTypeNotGranted, NtStatusNoTrustSamAccount + , NtStatusTrustedDomainFailure, NtStatusNologonWorkstationTrustAccount, + NtStatusPasswordMustChange, NtStatusNotFound, NtStatusAccountLockedOut + , NtStatusPathNotCovered, NtStatusIoReparseTagNotHandled }; + + public static string[] NtStatusMessages = { "The operation completed successfully." + , "A device attached to the system is not functioning.", "Incorrect function.", + "The parameter is incorrect.", "Invalid access to memory location.", "The handle is invalid." + , "The parameter is incorrect.", "The system cannot find the file specified.", "The system cannot find the file specified." + , "More data is available.", "Access is denied.", "The data area passed to a system call is too small." + , "The filename, directory name, or volume label syntax is incorrect.", "The system cannot find the file specified." + , "Cannot create a file when that file already exists.", "The handle is invalid." + , "The specified path is invalid.", "The system cannot find the path specified." + , "The specified path is invalid.", "The process cannot access the file because it is being used by another process." + , "Access is denied.", "There are currently no logon servers available to service the logon request." + , "The specified user already exists.", "The specified user does not exist.", "The specified network password is not correct." + , "Logon failure: unknown user name or bad password.", "Logon failure: user account restriction." + , "Logon failure: account logon time restriction violation.", "Logon failure: user not allowed to log on to this computer." + , "Logon failure: the specified account password has expired.", "Logon failure: account currently disabled." + , "No mapping between account names and security IDs was done.", "The security ID structure is invalid." + , "All pipe instances are busy.", "All pipe instances are busy.", "The pipe state is invalid." + , "All pipe instances are busy.", "No process is on the other end of the pipe.", + "The pipe is being closed.", "Waiting for a process to open the other end of the pipe." + , "Access is denied.", "A duplicate name exists on the network.", "The specified network name is no longer available." + , "Network access is denied.", "The network name cannot be found.", "No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept." + , "Indicates a Windows NT Server could not be contacted or that objects within the domain are protected such that necessary information could not be retrieved." + , "The specified domain did not exist.", "The directory name is invalid.", "Access is denied." + , "The format of the specified computer name is invalid.", "The pipe has been ended." + , "The specified local group does not exist.", "Logon failure: the user has not been granted the requested logon type at this computer." + , "The SAM database on the Windows NT Server does not have a computer account for this workstation trust relationship." + , "The trust relationship between the primary domain and the trusted domain failed." + , "The account used is a Computer Account. Use your global user account or local user account to access this server." + , "The user must change his password before he logs on the first time.", "NT_STATUS_NOT_FOUND" + , "The referenced account is currently locked out and may not be logged on to.", + "The remote system is not reachable by the transport.", "NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED" + }; + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NtTransQuerySecurityDesc.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtTransQuerySecurityDesc.cs new file mode 100644 index 000000000..6a83543b1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtTransQuerySecurityDesc.cs @@ -0,0 +1,88 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class NtTransQuerySecurityDesc : SmbComNtTransaction + { + internal int Fid; + + internal int SecurityInformation; + + internal NtTransQuerySecurityDesc(int fid, int securityInformation) + { + this.Fid = fid; + this.SecurityInformation = securityInformation; + Command = SmbComNtTransact; + Function = NtTransactQuerySecurityDesc; + SetupCount = 0; + TotalDataCount = 0; + MaxParameterCount = 4; + MaxDataCount = 32768; + MaxSetupCount = unchecked(unchecked(0x00)); + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(Fid, dst, dstIndex); + dstIndex += 2; + dst[dstIndex++] = unchecked(unchecked(0x00)); + // Reserved + dst[dstIndex++] = unchecked(unchecked(0x00)); + // Reserved + WriteInt4(SecurityInformation, dst, dstIndex); + dstIndex += 4; + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "NtTransQuerySecurityDesc[" + base.ToString() + ",fid=0x" + Hexdump + .ToHexString(Fid, 4) + ",securityInformation=0x" + Hexdump.ToHexString(SecurityInformation + , 8) + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NtTransQuerySecurityDescResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtTransQuerySecurityDescResponse.cs new file mode 100644 index 000000000..9365d5154 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtTransQuerySecurityDescResponse.cs @@ -0,0 +1,78 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class NtTransQuerySecurityDescResponse : SmbComNtTransactionResponse + { + internal SecurityDescriptor SecurityDescriptor; + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + Length = ReadInt4(buffer, bufferIndex); + return 4; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + int start = bufferIndex; + if (ErrorCode != 0) + { + return 4; + } + try + { + SecurityDescriptor = new SecurityDescriptor(); + bufferIndex += SecurityDescriptor.Decode(buffer, bufferIndex, len); + } + catch (IOException ioe) + { + throw new RuntimeException(ioe.Message); + } + return bufferIndex - start; + } + + public override string ToString() + { + return "NtTransQuerySecurityResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmAuthenticator.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmAuthenticator.cs new file mode 100644 index 000000000..853364f8e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmAuthenticator.cs @@ -0,0 +1,93 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + /// <summary>This class can be extended by applications that wish to trap authentication related exceptions and automatically retry the exceptional operation with different credentials. + /// </summary> + /// <remarks>This class can be extended by applications that wish to trap authentication related exceptions and automatically retry the exceptional operation with different credentials. Read <a href="../../../authhandler.html">jCIFS Exceptions and NtlmAuthenticator</a> for complete details. + /// </remarks> + public abstract class NtlmAuthenticator + { + private static NtlmAuthenticator _auth; + + private string _url; + + private SmbAuthException _sae; + + private void Reset() + { + _url = null; + _sae = null; + } + + /// <summary>Set the default <tt>NtlmAuthenticator</tt>.</summary> + /// <remarks>Set the default <tt>NtlmAuthenticator</tt>. Once the default authenticator is set it cannot be changed. Calling this metho again will have no effect. + /// </remarks> + public static void SetDefault(NtlmAuthenticator a) + { + lock (typeof(NtlmAuthenticator)) + { + if (_auth != null) + { + return; + } + _auth = a; + } + } + + protected internal string GetRequestingUrl() + { + return _url; + } + + protected internal SmbAuthException GetRequestingException() + { + return _sae; + } + + /// <summary>Used internally by jCIFS when an <tt>SmbAuthException</tt> is trapped to retrieve new user credentials. + /// </summary> + /// <remarks>Used internally by jCIFS when an <tt>SmbAuthException</tt> is trapped to retrieve new user credentials. + /// </remarks> + public static NtlmPasswordAuthentication RequestNtlmPasswordAuthentication(string + url, SmbAuthException sae) + { + if (_auth == null) + { + return null; + } + lock (_auth) + { + _auth._url = url; + _auth._sae = sae; + return _auth.GetNtlmPasswordAuthentication(); + } + } + + /// <summary>An application extending this class must provide an implementation for this method that returns new user credentials try try when accessing SMB resources described by the <tt>getRequestingURL</tt> and <tt>getRequestingException</tt> methods. + /// </summary> + /// <remarks> + /// An application extending this class must provide an implementation for this method that returns new user credentials try try when accessing SMB resources described by the <tt>getRequestingURL</tt> and <tt>getRequestingException</tt> methods. + /// If this method returns <tt>null</tt> the <tt>SmbAuthException</tt> that triggered the authenticator check will simply be rethrown. The default implementation returns <tt>null</tt>. + /// </remarks> + protected internal virtual NtlmPasswordAuthentication GetNtlmPasswordAuthentication + () + { + return null; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmChallenge.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmChallenge.cs new file mode 100644 index 000000000..745b1f663 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmChallenge.cs @@ -0,0 +1,40 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + + public sealed class NtlmChallenge + { + public byte[] Challenge; + + public UniAddress Dc; + + internal NtlmChallenge(byte[] challenge, UniAddress dc) + { + this.Challenge = challenge; + this.Dc = dc; + } + + public override string ToString() + { + return "NtlmChallenge[challenge=0x" + Hexdump.ToHexString(Challenge, 0, Challenge + .Length * 2) + ",dc=" + Dc + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmContext.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmContext.cs new file mode 100644 index 000000000..44266f974 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmContext.cs @@ -0,0 +1,206 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Ntlmssp; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + /// <summary>For initiating NTLM authentication (including NTLMv2).</summary> + /// <remarks>For initiating NTLM authentication (including NTLMv2). If you want to add NTLMv2 authentication support to something this is what you want to use. See the code for details. Note that JCIFS does not implement the acceptor side of NTLM authentication. + /// </remarks> + public class NtlmContext + { + internal NtlmPasswordAuthentication Auth; + + internal int NtlmsspFlags; + + internal string Workstation; + + internal bool isEstablished; + + internal byte[] ServerChallenge; + + internal byte[] SigningKey; + + internal string NetbiosName = null; + + internal int State = 1; + + internal LogStream Log; + + public NtlmContext(NtlmPasswordAuthentication auth, bool doSigning) + { + this.Auth = auth; + NtlmsspFlags = NtlmsspFlags | NtlmFlags.NtlmsspRequestTarget | NtlmFlags.NtlmsspNegotiateNtlm2 + | NtlmFlags.NtlmsspNegotiate128; + if (doSigning) + { + NtlmsspFlags |= NtlmFlags.NtlmsspNegotiateSign | NtlmFlags.NtlmsspNegotiateAlwaysSign + | NtlmFlags.NtlmsspNegotiateKeyExch; + } + Workstation = Type1Message.GetDefaultWorkstation(); + Log = LogStream.GetInstance(); + } + + public override string ToString() + { + string ret = "NtlmContext[auth=" + Auth + ",ntlmsspFlags=0x" + Hexdump.ToHexString + (NtlmsspFlags, 8) + ",workstation=" + Workstation + ",isEstablished=" + isEstablished + + ",state=" + State + ",serverChallenge="; + if (ServerChallenge == null) + { + ret += "null"; + } + else + { + ret += Hexdump.ToHexString(ServerChallenge, 0, ServerChallenge.Length * 2); + } + ret += ",signingKey="; + if (SigningKey == null) + { + ret += "null"; + } + else + { + ret += Hexdump.ToHexString(SigningKey, 0, SigningKey.Length * 2); + } + ret += "]"; + return ret; + } + + public virtual bool IsEstablished() + { + return isEstablished; + } + + public virtual byte[] GetServerChallenge() + { + return ServerChallenge; + } + + public virtual byte[] GetSigningKey() + { + return SigningKey; + } + + public virtual string GetNetbiosName() + { + return NetbiosName; + } + + private string GetNtlmsspListItem(byte[] type2Token, int id0) + { + int ri = 58; + for (; ; ) + { + int id = Encdec.Dec_uint16le(type2Token, ri); + int len = Encdec.Dec_uint16le(type2Token, ri + 2); + ri += 4; + if (id == 0 || (ri + len) > type2Token.Length) + { + break; + } + if (id == id0) + { + try + { + return Runtime.GetStringForBytes(type2Token, ri, len, SmbConstants.UniEncoding + ); + } + catch (UnsupportedEncodingException) + { + break; + } + } + ri += len; + } + return null; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual byte[] InitSecContext(byte[] token, int offset, int len) + { + switch (State) + { + case 1: + { + Type1Message msg1 = new Type1Message(NtlmsspFlags, Auth.GetDomain(), Workstation); + token = msg1.ToByteArray(); + if (Log.Level >= 4) + { + Log.WriteLine(msg1); + if (Log.Level >= 6) + { + Hexdump.ToHexdump(Log, token, 0, token.Length); + } + } + State++; + break; + } + + case 2: + { + try + { + Type2Message msg2 = new Type2Message(token); + if (Log.Level >= 4) + { + Log.WriteLine(msg2); + if (Log.Level >= 6) + { + Hexdump.ToHexdump(Log, token, 0, token.Length); + } + } + ServerChallenge = msg2.GetChallenge(); + NtlmsspFlags &= msg2.GetFlags(); + // netbiosName = getNtlmsspListItem(token, 0x0001); + Type3Message msg3 = new Type3Message(msg2, Auth.GetPassword(), Auth.GetDomain(), + Auth.GetUsername(), Workstation, NtlmsspFlags); + token = msg3.ToByteArray(); + if (Log.Level >= 4) + { + Log.WriteLine(msg3); + if (Log.Level >= 6) + { + Hexdump.ToHexdump(Log, token, 0, token.Length); + } + } + if ((NtlmsspFlags & NtlmFlags.NtlmsspNegotiateSign) != 0) + { + SigningKey = msg3.GetMasterKey(); + } + isEstablished = true; + State++; + break; + } + catch (Exception e) + { + throw new SmbException(e.Message, e); + } + } + + default: + { + throw new SmbException("Invalid state"); + } + } + return token; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmPasswordAuthentication.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmPasswordAuthentication.cs new file mode 100644 index 000000000..ec3899fe9 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/NtlmPasswordAuthentication.cs @@ -0,0 +1,807 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + /// <summary>This class stores and encrypts NTLM user credentials.</summary> + /// <remarks> + /// This class stores and encrypts NTLM user credentials. The default + /// credentials are retrieved from the <tt>jcifs.smb.client.domain</tt>, + /// <tt>jcifs.smb.client.username</tt>, and <tt>jcifs.smb.client.password</tt> + /// properties. + /// <p> + /// Read <a href="../../../authhandler.html">jCIFS Exceptions and + /// NtlmAuthenticator</a> for related information. + /// </remarks> + + public sealed class NtlmPasswordAuthentication : Principal + { + private static readonly int LmCompatibility = Config.GetInt("jcifs.smb.lmCompatibility" + , 3); + + private static readonly Random Random = new Random(); + + private static LogStream _log = LogStream.GetInstance(); + + private static readonly byte[] S8 = { unchecked(unchecked(0x4b)), unchecked(unchecked(0x47)), unchecked(unchecked(0x53)), unchecked(unchecked(0x21)), unchecked(unchecked(0x40)), unchecked(unchecked(0x23)), unchecked(unchecked(0x24)), unchecked(unchecked(0x25)) }; + + // KGS!@#$% + private static void E(byte[] key, byte[] data, byte[] e) + { + byte[] key7 = new byte[7]; + byte[] e8 = new byte[8]; + for (int i = 0; i < key.Length / 7; i++) + { + Array.Copy(key, i * 7, key7, 0, 7); + DES des = new DES(key7); + des.Encrypt(data, e8); + Array.Copy(e8, 0, e, i * 8, 8); + } + } + + internal static string DefaultDomain; + + internal static string DefaultUsername; + + internal static string DefaultPassword; + + internal static readonly string Blank = string.Empty; + + public static readonly NtlmPasswordAuthentication Anonymous = new NtlmPasswordAuthentication + (string.Empty, string.Empty, string.Empty); + + internal static void InitDefaults() + { + if (DefaultDomain != null) + { + return; + } + DefaultDomain = Config.GetProperty("jcifs.smb.client.domain", "?"); + DefaultUsername = Config.GetProperty("jcifs.smb.client.username", "GUEST"); + DefaultPassword = Config.GetProperty("jcifs.smb.client.password", Blank); + } + + /// <summary>Generate the ANSI DES hash for the password associated with these credentials. + /// </summary> + /// <remarks>Generate the ANSI DES hash for the password associated with these credentials. + /// </remarks> + public static byte[] GetPreNtlmResponse(string password, byte[] challenge) + { + byte[] p14 = new byte[14]; + byte[] p21 = new byte[21]; + byte[] p24 = new byte[24]; + byte[] passwordBytes; + try + { + passwordBytes = Runtime.GetBytesForString(password.ToUpper(), SmbConstants.OemEncoding); + } + catch (UnsupportedEncodingException uee) + { + throw new RuntimeException("Try setting jcifs.encoding=US-ASCII", uee); + } + int passwordLength = passwordBytes.Length; + // Only encrypt the first 14 bytes of the password for Pre 0.12 NT LM + if (passwordLength > 14) + { + passwordLength = 14; + } + Array.Copy(passwordBytes, 0, p14, 0, passwordLength); + E(p14, S8, p21); + E(p21, challenge, p24); + return p24; + } + + /// <summary>Generate the Unicode MD4 hash for the password associated with these credentials. + /// </summary> + /// <remarks>Generate the Unicode MD4 hash for the password associated with these credentials. + /// </remarks> + public static byte[] GetNtlmResponse(string password, byte[] challenge) + { + byte[] uni = null; + byte[] p21 = new byte[21]; + byte[] p24 = new byte[24]; + try + { + uni = Runtime.GetBytesForString(password, SmbConstants.UniEncoding); + } + catch (UnsupportedEncodingException uee) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(uee, _log); + } + } + Md4 md4 = new Md4(); + md4.Update(uni); + try + { + md4.Digest(p21, 0, 16); + } + catch (Exception ex) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(ex, _log); + } + } + E(p21, challenge, p24); + return p24; + } + + /// <summary>Creates the LMv2 response for the supplied information.</summary> + /// <remarks>Creates the LMv2 response for the supplied information.</remarks> + /// <param name="domain">The domain in which the username exists.</param> + /// <param name="user">The username.</param> + /// <param name="password">The user's password.</param> + /// <param name="challenge">The server challenge.</param> + /// <param name="clientChallenge">The client challenge (nonce).</param> + public static byte[] GetLMv2Response(string domain, string user, string password, + byte[] challenge, byte[] clientChallenge) + { + try + { + byte[] hash = new byte[16]; + byte[] response = new byte[24]; + // The next 2-1/2 lines of this should be placed with nTOWFv1 in place of password + Md4 md4 = new Md4(); + md4.Update(Runtime.GetBytesForString(password, SmbConstants.UniEncoding) + ); + Hmact64 hmac = new Hmact64(md4.Digest()); + hmac.Update(Runtime.GetBytesForString(user.ToUpper(), SmbConstants.UniEncoding + )); + hmac.Update(Runtime.GetBytesForString(domain.ToUpper(), SmbConstants.UniEncoding + )); + hmac = new Hmact64(hmac.Digest()); + hmac.Update(challenge); + hmac.Update(clientChallenge); + hmac.Digest(response, 0, 16); + Array.Copy(clientChallenge, 0, response, 16, 8); + return response; + } + catch (Exception ex) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(ex, _log); + } + return null; + } + } + + public static byte[] GetNtlm2Response(byte[] nTowFv1, byte[] serverChallenge, byte + [] clientChallenge) + { + byte[] sessionHash = new byte[8]; + try + { + MessageDigest md5; + md5 = MessageDigest.GetInstance("MD5"); + md5.Update(serverChallenge); + md5.Update(clientChallenge, 0, 8); + Array.Copy(md5.Digest(), 0, sessionHash, 0, 8); + } + catch (Exception gse) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(gse, _log); + } + throw new RuntimeException("MD5", gse); + } + byte[] key = new byte[21]; + Array.Copy(nTowFv1, 0, key, 0, 16); + byte[] ntResponse = new byte[24]; + E(key, sessionHash, ntResponse); + return ntResponse; + } + + public static byte[] NtowFv1(string password) + { + if (password == null) + { + throw new RuntimeException("Password parameter is required"); + } + try + { + Md4 md4 = new Md4(); + md4.Update(Runtime.GetBytesForString(password, SmbConstants.UniEncoding) + ); + return md4.Digest(); + } + catch (UnsupportedEncodingException uee) + { + throw new RuntimeException(uee.Message); + } + } + + public static byte[] NtowFv2(string domain, string username, string password) + { + try + { + Md4 md4 = new Md4(); + md4.Update(Runtime.GetBytesForString(password, SmbConstants.UniEncoding) + ); + Hmact64 hmac = new Hmact64(md4.Digest()); + hmac.Update(Runtime.GetBytesForString(username.ToUpper(), SmbConstants.UniEncoding + )); + hmac.Update(Runtime.GetBytesForString(domain, SmbConstants.UniEncoding)); + return hmac.Digest(); + } + catch (UnsupportedEncodingException uee) + { + throw new RuntimeException(uee.Message); + } + } + + internal static byte[] ComputeResponse(byte[] responseKey, byte[] serverChallenge + , byte[] clientData, int offset, int length) + { + Hmact64 hmac = new Hmact64(responseKey); + hmac.Update(serverChallenge); + hmac.Update(clientData, offset, length); + byte[] mac = hmac.Digest(); + byte[] ret = new byte[mac.Length + clientData.Length]; + Array.Copy(mac, 0, ret, 0, mac.Length); + Array.Copy(clientData, 0, ret, mac.Length, clientData.Length); + return ret; + } + + public static byte[] GetLMv2Response(byte[] responseKeyLm, byte[] serverChallenge + , byte[] clientChallenge) + { + return ComputeResponse(responseKeyLm, serverChallenge + , clientChallenge, 0, clientChallenge.Length); + } + + public static byte[] GetNtlMv2Response(byte[] responseKeyNt, byte[] serverChallenge + , byte[] clientChallenge, long nanos1601, byte[] targetInfo) + { + int targetInfoLength = targetInfo != null ? targetInfo.Length : 0; + byte[] temp = new byte[28 + targetInfoLength + 4]; + Encdec.Enc_uint32le(unchecked(0x00000101), temp, 0); + // Header + Encdec.Enc_uint32le(unchecked(0x00000000), temp, 4); + // Reserved + Encdec.Enc_uint64le(nanos1601, temp, 8); + Array.Copy(clientChallenge, 0, temp, 16, 8); + Encdec.Enc_uint32le(unchecked(0x00000000), temp, 24); + // Unknown + if (targetInfo != null) + { + Array.Copy(targetInfo, 0, temp, 28, targetInfoLength); + } + Encdec.Enc_uint32le(unchecked(0x00000000), temp, 28 + targetInfoLength); + // mystery bytes! + return ComputeResponse(responseKeyNt, serverChallenge + , temp, 0, temp.Length); + } + + internal static readonly NtlmPasswordAuthentication Null = new NtlmPasswordAuthentication + (string.Empty, string.Empty, string.Empty); + + internal static readonly NtlmPasswordAuthentication Guest = new NtlmPasswordAuthentication + ("?", "GUEST", string.Empty); + + internal static readonly NtlmPasswordAuthentication Default = new NtlmPasswordAuthentication + (null); + + internal string Domain; + + internal string Username; + + internal string Password; + + internal byte[] AnsiHash; + + internal byte[] UnicodeHash; + + internal bool HashesExternal; + + internal byte[] ClientChallenge; + + internal byte[] Challenge; + + /// <summary> + /// Create an <tt>NtlmPasswordAuthentication</tt> object from the userinfo + /// component of an SMB URL like "<tt>domain;user:pass</tt>". + /// </summary> + /// <remarks> + /// Create an <tt>NtlmPasswordAuthentication</tt> object from the userinfo + /// component of an SMB URL like "<tt>domain;user:pass</tt>". This constructor + /// is used internally be jCIFS when parsing SMB URLs. + /// </remarks> + public NtlmPasswordAuthentication(string userInfo) + { + Domain = Username = Password = null; + if (userInfo != null) + { + try + { + userInfo = Unescape(userInfo); + } + catch (UnsupportedEncodingException) + { + } + int i; + int u; + int end; + char c; + end = userInfo.Length; + for (i = 0, u = 0; i < end; i++) + { + c = userInfo[i]; + if (c == ';') + { + Domain = Runtime.Substring(userInfo, 0, i); + u = i + 1; + } + else + { + if (c == ':') + { + Password = Runtime.Substring(userInfo, i + 1); + break; + } + } + } + Username = Runtime.Substring(userInfo, u, i); + } + InitDefaults(); + if (Domain == null) + { + Domain = DefaultDomain; + } + if (Username == null) + { + Username = DefaultUsername; + } + if (Password == null) + { + Password = DefaultPassword; + } + } + + /// <summary> + /// Create an <tt>NtlmPasswordAuthentication</tt> object from a + /// domain, username, and password. + /// </summary> + /// <remarks> + /// Create an <tt>NtlmPasswordAuthentication</tt> object from a + /// domain, username, and password. Parameters that are <tt>null</tt> + /// will be substituted with <tt>jcifs.smb.client.domain</tt>, + /// <tt>jcifs.smb.client.username</tt>, <tt>jcifs.smb.client.password</tt> + /// property values. + /// </remarks> + public NtlmPasswordAuthentication(string domain, string username, string password + ) + { + int ci; + if (username != null) + { + ci = username.IndexOf('@'); + if (ci > 0) + { + domain = Runtime.Substring(username, ci + 1); + username = Runtime.Substring(username, 0, ci); + } + else + { + ci = username.IndexOf('\\'); + if (ci > 0) + { + domain = Runtime.Substring(username, 0, ci); + username = Runtime.Substring(username, ci + 1); + } + } + } + this.Domain = domain; + this.Username = username; + this.Password = password; + InitDefaults(); + if (domain == null) + { + this.Domain = DefaultDomain; + } + if (username == null) + { + this.Username = DefaultUsername; + } + if (password == null) + { + this.Password = DefaultPassword; + } + } + + /// <summary> + /// Create an <tt>NtlmPasswordAuthentication</tt> object with raw password + /// hashes. + /// </summary> + /// <remarks> + /// Create an <tt>NtlmPasswordAuthentication</tt> object with raw password + /// hashes. This is used exclusively by the <tt>jcifs.http.NtlmSsp</tt> + /// class which is in turn used by NTLM HTTP authentication functionality. + /// </remarks> + public NtlmPasswordAuthentication(string domain, string username, byte[] challenge + , byte[] ansiHash, byte[] unicodeHash) + { + if (domain == null || username == null || ansiHash == null || unicodeHash == null) + { + throw new ArgumentException("External credentials cannot be null"); + } + this.Domain = domain; + this.Username = username; + Password = null; + this.Challenge = challenge; + this.AnsiHash = ansiHash; + this.UnicodeHash = unicodeHash; + HashesExternal = true; + } + + /// <summary>Returns the domain.</summary> + /// <remarks>Returns the domain.</remarks> + public string GetDomain() + { + return Domain; + } + + /// <summary>Returns the username.</summary> + /// <remarks>Returns the username.</remarks> + public string GetUsername() + { + return Username; + } + + /// <summary> + /// Returns the password in plain text or <tt>null</tt> if the raw password + /// hashes were used to construct this <tt>NtlmPasswordAuthentication</tt> + /// object which will be the case when NTLM HTTP Authentication is + /// used. + /// </summary> + /// <remarks> + /// Returns the password in plain text or <tt>null</tt> if the raw password + /// hashes were used to construct this <tt>NtlmPasswordAuthentication</tt> + /// object which will be the case when NTLM HTTP Authentication is + /// used. There is no way to retrieve a users password in plain text unless + /// it is supplied by the user at runtime. + /// </remarks> + public string GetPassword() + { + return Password; + } + + /// <summary> + /// Return the domain and username in the format: + /// <tt>domain\\username</tt>. + /// </summary> + /// <remarks> + /// Return the domain and username in the format: + /// <tt>domain\\username</tt>. This is equivalent to <tt>toString()</tt>. + /// </remarks> + public new string GetName() + { + bool d = Domain.Length > 0 && Domain.Equals("?") == false; + return d ? Domain + "\\" + Username : Username; + } + + /// <summary>Computes the 24 byte ANSI password hash given the 8 byte server challenge. + /// </summary> + /// <remarks>Computes the 24 byte ANSI password hash given the 8 byte server challenge. + /// </remarks> + public byte[] GetAnsiHash(byte[] challenge) + { + if (HashesExternal) + { + return AnsiHash; + } + switch (LmCompatibility) + { + case 0: + case 1: + { + return GetPreNtlmResponse(Password, challenge); + } + + case 2: + { + return GetNtlmResponse(Password, challenge); + } + + case 3: + case 4: + case 5: + { + if (ClientChallenge == null) + { + ClientChallenge = new byte[8]; + Random.NextBytes(ClientChallenge); + } + return GetLMv2Response(Domain, Username, Password, challenge, ClientChallenge); + } + + default: + { + return GetPreNtlmResponse(Password, challenge); + } + } + } + + /// <summary>Computes the 24 byte Unicode password hash given the 8 byte server challenge. + /// </summary> + /// <remarks>Computes the 24 byte Unicode password hash given the 8 byte server challenge. + /// </remarks> + public byte[] GetUnicodeHash(byte[] challenge) + { + if (HashesExternal) + { + return UnicodeHash; + } + switch (LmCompatibility) + { + case 0: + case 1: + case 2: + { + return GetNtlmResponse(Password, challenge); + } + + case 3: + case 4: + case 5: + { + return new byte[0]; + } + + default: + { + return GetNtlmResponse(Password, challenge); + } + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public byte[] GetSigningKey(byte[] challenge) + { + switch (LmCompatibility) + { + case 0: + case 1: + case 2: + { + byte[] signingKey = new byte[40]; + GetUserSessionKey(challenge, signingKey, 0); + Array.Copy(GetUnicodeHash(challenge), 0, signingKey, 16, 24); + return signingKey; + } + + case 3: + case 4: + case 5: + { + throw new SmbException("NTLMv2 requires extended security (jcifs.smb.client.useExtendedSecurity must be true if jcifs.smb.lmCompatibility >= 3)" + ); + } + } + return null; + } + + /// <summary>Returns the effective user session key.</summary> + /// <remarks>Returns the effective user session key.</remarks> + /// <param name="challenge">The server challenge.</param> + /// <returns> + /// A <code>byte[]</code> containing the effective user session key, + /// used in SMB MAC signing and NTLMSSP signing and sealing. + /// </returns> + public byte[] GetUserSessionKey(byte[] challenge) + { + if (HashesExternal) + { + return null; + } + byte[] key = new byte[16]; + try + { + GetUserSessionKey(challenge, key, 0); + } + catch (Exception ex) + { + if (_log.Level > 0) + { + Runtime.PrintStackTrace(ex, _log); + } + } + return key; + } + + /// <summary>Calculates the effective user session key.</summary> + /// <remarks>Calculates the effective user session key.</remarks> + /// <param name="challenge">The server challenge.</param> + /// <param name="dest"> + /// The destination array in which the user session key will be + /// placed. + /// </param> + /// <param name="offset"> + /// The offset in the destination array at which the + /// session key will start. + /// </param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal void GetUserSessionKey(byte[] challenge, byte[] dest, int offset) + { + if (HashesExternal) + { + return; + } + try + { + Md4 md4 = new Md4(); + md4.Update(Runtime.GetBytesForString(Password, SmbConstants.UniEncoding) + ); + switch (LmCompatibility) + { + case 0: + case 1: + case 2: + { + md4.Update(md4.Digest()); + md4.Digest(dest, offset, 16); + break; + } + + case 3: + case 4: + case 5: + { + if (ClientChallenge == null) + { + ClientChallenge = new byte[8]; + Random.NextBytes(ClientChallenge); + } + Hmact64 hmac = new Hmact64(md4.Digest()); + hmac.Update(Runtime.GetBytesForString(Username.ToUpper(), SmbConstants.UniEncoding + )); + hmac.Update(Runtime.GetBytesForString(Domain.ToUpper(), SmbConstants.UniEncoding + )); + byte[] ntlmv2Hash = hmac.Digest(); + hmac = new Hmact64(ntlmv2Hash); + hmac.Update(challenge); + hmac.Update(ClientChallenge); + Hmact64 userKey = new Hmact64(ntlmv2Hash); + userKey.Update(hmac.Digest()); + userKey.Digest(dest, offset, 16); + break; + } + + default: + { + md4.Update(md4.Digest()); + md4.Digest(dest, offset, 16); + break; + } + } + } + catch (Exception e) + { + throw new SmbException(string.Empty, e); + } + } + + /// <summary> + /// Compares two <tt>NtlmPasswordAuthentication</tt> objects for + /// equality. + /// </summary> + /// <remarks> + /// Compares two <tt>NtlmPasswordAuthentication</tt> objects for + /// equality. Two <tt>NtlmPasswordAuthentication</tt> objects are equal if + /// their caseless domain and username fields are equal and either both hashes are external and they are equal or both internally supplied passwords are equal. If one <tt>NtlmPasswordAuthentication</tt> object has external hashes (meaning negotiated via NTLM HTTP Authentication) and the other does not they will not be equal. This is technically not correct however the server 8 byte challage would be required to compute and compare the password hashes but that it not available with this method. + /// </remarks> + public override bool Equals(object obj) + { + if (obj is NtlmPasswordAuthentication) + { + NtlmPasswordAuthentication ntlm = (NtlmPasswordAuthentication + )obj; + if (ntlm.Domain.ToUpper().Equals(Domain.ToUpper()) && ntlm.Username.ToUpper().Equals + (Username.ToUpper())) + { + if (HashesExternal && ntlm.HashesExternal) + { + + return Arrays.Equals(AnsiHash, ntlm.AnsiHash) && Arrays.Equals(UnicodeHash, ntlm. + UnicodeHash); + } + if (!HashesExternal && Password.Equals(ntlm.Password)) + { + return true; + } + } + } + return false; + } + + /// <summary>Return the upcased username hash code.</summary> + /// <remarks>Return the upcased username hash code.</remarks> + public override int GetHashCode() + { + return GetName().ToUpper().GetHashCode(); + } + + /// <summary> + /// Return the domain and username in the format: + /// <tt>domain\\username</tt>. + /// </summary> + /// <remarks> + /// Return the domain and username in the format: + /// <tt>domain\\username</tt>. This is equivalent to <tt>getName()</tt>. + /// </remarks> + public override string ToString() + { + return GetName(); + } + + /// <exception cref="System.FormatException"></exception> + /// <exception cref="UnsupportedEncodingException"></exception> + internal static string Unescape(string str) + { + char ch; + int i; + int j; + int state; + int len; + char[] @out; + byte[] b = new byte[1]; + if (str == null) + { + return null; + } + len = str.Length; + @out = new char[len]; + state = 0; + for (i = j = 0; i < len; i++) + { + switch (state) + { + case 0: + { + ch = str[i]; + if (ch == '%') + { + state = 1; + } + else + { + @out[j++] = ch; + } + break; + } + + case 1: + { + b[0] = unchecked((byte)(Convert.ToInt32(Runtime.Substring(str, i, + i + 2), 16) & unchecked(0xFF))); + @out[j++] = (Runtime.GetStringForBytes(b, 0, 1, "ASCII"))[0]; + i++; + state = 0; + break; + } + } + } + return new string(@out, 0, j); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Principal.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Principal.cs new file mode 100644 index 000000000..14a5479e3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Principal.cs @@ -0,0 +1,28 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public class Principal + { + private string _name = ""; + + public string GetName() + { + return _name; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SID.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SID.cs new file mode 100644 index 000000000..a6ad59fb1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SID.cs @@ -0,0 +1,900 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using SharpCifs.Dcerpc; +using SharpCifs.Dcerpc.Msrpc; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; +using Hashtable = SharpCifs.Util.Sharpen.Hashtable; //not System.Collections.Hashtable + +namespace SharpCifs.Smb +{ + /// <summary> + /// A Windows SID is a numeric identifier used to represent Windows + /// accounts. + /// </summary> + /// <remarks> + /// A Windows SID is a numeric identifier used to represent Windows + /// accounts. SIDs are commonly represented using a textual format such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt> but they may + /// also be resolved to yield the name of the associated Windows account + /// such as <tt>Administrators</tt> or <tt>MYDOM\alice</tt>. + /// <p> + /// Consider the following output of <tt>examples/SidLookup.java</tt>: + /// <pre> + /// toString: S-1-5-21-4133388617-793952518-2001621813-512 + /// toDisplayString: WNET\Domain Admins + /// getType: 2 + /// getTypeText: Domain group + /// getDomainName: WNET + /// getAccountName: Domain Admins + /// </pre> + /// </remarks> + public class Sid : Rpc.SidT + { + public const int SidTypeUseNone = Lsarpc.SidNameUseNone; + + public const int SidTypeUser = Lsarpc.SidNameUser; + + public const int SidTypeDomGrp = Lsarpc.SidNameDomGrp; + + public const int SidTypeDomain = Lsarpc.SidNameDomain; + + public const int SidTypeAlias = Lsarpc.SidNameAlias; + + public const int SidTypeWknGrp = Lsarpc.SidNameWknGrp; + + public const int SidTypeDeleted = Lsarpc.SidNameDeleted; + + public const int SidTypeInvalid = Lsarpc.SidNameInvalid; + + public const int SidTypeUnknown = Lsarpc.SidNameUnknown; + + internal static readonly string[] SidTypeNames = { "0", "User", "Domain group" + , "Domain", "Local group", "Builtin group", "Deleted", "Invalid", "Unknown" }; + + public const int SidFlagResolveSids = unchecked(0x0001); + + public static Sid Everyone; + + public static Sid CreatorOwner; + + public static Sid SYSTEM; + + static Sid() + { + try + { + Everyone = new Sid("S-1-1-0"); + CreatorOwner = new Sid("S-1-3-0"); + SYSTEM = new Sid("S-1-5-18"); + } + catch (SmbException) + { + } + } + + internal static Hashtable SidCache = new Hashtable(); + + /// <exception cref="System.IO.IOException"></exception> + internal static void ResolveSids(DcerpcHandle handle, LsaPolicyHandle policyHandle + , Sid[] sids) + { + MsrpcLookupSids rpc = new MsrpcLookupSids(policyHandle, sids); + handle.Sendrecv(rpc); + switch (rpc.Retval) + { + case 0: + case NtStatus.NtStatusNoneMapped: + case unchecked(0x00000107): + { + // NT_STATUS_SOME_NOT_MAPPED + break; + } + + default: + { + throw new SmbException(rpc.Retval, false); + } + } + for (int si = 0; si < sids.Length; si++) + { + sids[si].Type = rpc.Names.Names[si].SidType; + sids[si].DomainName = null; + switch (sids[si].Type) + { + case SidTypeUser: + case SidTypeDomGrp: + case SidTypeDomain: + case SidTypeAlias: + case SidTypeWknGrp: + { + int sidIndex = rpc.Names.Names[si].SidIndex; + Rpc.Unicode_string ustr = rpc.Domains.Domains[sidIndex].Name; + sids[si].DomainName = (new UnicodeString(ustr, false)).ToString(); + break; + } + } + sids[si].AcctName = (new UnicodeString(rpc.Names.Names[si].Name, false)).ToString + (); + sids[si].OriginServer = null; + sids[si].OriginAuth = null; + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal static void ResolveSids0(string authorityServerName, NtlmPasswordAuthentication + auth, Sid[] sids) + { + DcerpcHandle handle = null; + LsaPolicyHandle policyHandle = null; + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + "[\\PIPE\\lsarpc]" + , auth); + string server = authorityServerName; + int dot = server.IndexOf('.'); + if (dot > 0 && char.IsDigit(server[0]) == false) + { + server = Runtime.Substring(server, 0, dot); + } + policyHandle = new LsaPolicyHandle(handle, "\\\\" + server, unchecked(0x00000800)); + ResolveSids(handle, policyHandle, sids); + } + finally + { + if (handle != null) + { + if (policyHandle != null) + { + policyHandle.Close(); + } + handle.Close(); + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public static void ResolveSids(string authorityServerName, NtlmPasswordAuthentication + auth, Sid[] sids, int offset, int length) + { + List<object> list = new List<object>();//new List<object>(sids.Length); + int si; + lock (SidCache) + { + for (si = 0; si < length; si++) + { + Sid sid = (Sid)SidCache.Get(sids[offset + si]); + if (sid != null) + { + sids[offset + si].Type = sid.Type; + sids[offset + si].DomainName = sid.DomainName; + sids[offset + si].AcctName = sid.AcctName; + } + else + { + list.Add(sids[offset + si]); + } + } + if (list.Count > 0) + { + //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]); + sids = (Sid[])list.ToArray(); + ResolveSids0(authorityServerName, auth, sids); + for (si = 0; si < sids.Length; si++) + { + SidCache.Put(sids[si], sids[si]); + } + } + } + } + + /// <summary>Resolve an array of SIDs using a cache and at most one MSRPC request.</summary> + /// <remarks> + /// Resolve an array of SIDs using a cache and at most one MSRPC request. + /// <p> + /// This method will attempt + /// to resolve SIDs using a cache and cache the results of any SIDs that + /// required resolving with the authority. SID cache entries are currently not + /// expired because under normal circumstances SID information never changes. + /// </remarks> + /// <param name="authorityServerName">The hostname of the server that should be queried. For maximum efficiency this should be the hostname of a domain controller however a member server will work as well and a domain controller may not return names for SIDs corresponding to local accounts for which the domain controller is not an authority. + /// </param> + /// <param name="auth">The credentials that should be used to communicate with the named server. As usual, <tt>null</tt> indicates that default credentials should be used. + /// </param> + /// <param name="sids">The SIDs that should be resolved. After this function is called, the names associated with the SIDs may be queried with the <tt>toDisplayString</tt>, <tt>getDomainName</tt>, and <tt>getAccountName</tt> methods. + /// </param> + /// <exception cref="System.IO.IOException"></exception> + public static void ResolveSids(string authorityServerName, NtlmPasswordAuthentication + auth, Sid[] sids) + { + List<object> list = new List<object>();//new List<object>(sids.Length); + int si; + lock (SidCache) + { + for (si = 0; si < sids.Length; si++) + { + Sid sid = (Sid)SidCache.Get(sids[si]); + if (sid != null) + { + sids[si].Type = sid.Type; + sids[si].DomainName = sid.DomainName; + sids[si].AcctName = sid.AcctName; + } + else + { + list.Add(sids[si]); + } + } + if (list.Count > 0) + { + //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]); + sids = (Sid[]) list.ToArray(); + ResolveSids0(authorityServerName, auth, sids); + for (si = 0; si < sids.Length; si++) + { + SidCache.Put(sids[si], sids[si]); + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public static Sid GetServerSid(string server, NtlmPasswordAuthentication + auth) + { + DcerpcHandle handle = null; + LsaPolicyHandle policyHandle = null; + Lsarpc.LsarDomainInfo info = new Lsarpc.LsarDomainInfo(); + MsrpcQueryInformationPolicy rpc; + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + server + "[\\PIPE\\lsarpc]", auth); + // NetApp doesn't like the 'generic' access mask values + policyHandle = new LsaPolicyHandle(handle, null, unchecked(0x00000001)); + rpc = new MsrpcQueryInformationPolicy(policyHandle, Lsarpc.PolicyInfoAccountDomain + , info); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } + return new Sid(info.Sid, SidTypeDomain, (new UnicodeString + (info.Name, false)).ToString(), null, false); + } + finally + { + if (handle != null) + { + if (policyHandle != null) + { + policyHandle.Close(); + } + handle.Close(); + } + } + } + } + + public static byte[] ToByteArray(Rpc.SidT sid) + { + byte[] dst = new byte[1 + 1 + 6 + sid.SubAuthorityCount * 4]; + int di = 0; + dst[di++] = sid.Revision; + dst[di++] = sid.SubAuthorityCount; + Array.Copy(sid.IdentifierAuthority, 0, dst, di, 6); + di += 6; + for (int ii = 0; ii < sid.SubAuthorityCount; ii++) + { + Encdec.Enc_uint32le(sid.SubAuthority[ii], dst, di); + di += 4; + } + return dst; + } + + internal int Type; + + internal string DomainName; + + internal string AcctName; + + internal string OriginServer; + + internal NtlmPasswordAuthentication OriginAuth; + + public Sid(byte[] src, int si) + { + Revision = src[si++]; + SubAuthorityCount = src[si++]; + IdentifierAuthority = new byte[6]; + Array.Copy(src, si, IdentifierAuthority, 0, 6); + si += 6; + if (SubAuthorityCount > 100) + { + throw new RuntimeException("Invalid SID sub_authority_count"); + } + SubAuthority = new int[SubAuthorityCount]; + for (int i = 0; i < SubAuthorityCount; i++) + { + SubAuthority[i] = ServerMessageBlock.ReadInt4(src, si); + si += 4; + } + } + + /// <summary> + /// Construct a SID from it's textual representation such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </summary> + /// <remarks> + /// Construct a SID from it's textual representation such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </remarks> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public Sid(string textual) + { + StringTokenizer st = new StringTokenizer(textual, "-"); + if (st.CountTokens() < 3 || !st.NextToken().Equals("S")) + { + // need S-N-M + throw new SmbException("Bad textual SID format: " + textual); + } + Revision = byte.Parse(st.NextToken()); + string tmp = st.NextToken(); + long id = 0; + if (tmp.StartsWith("0x")) + { + //id = long.Parse(Sharpen.Runtime.Substring(tmp, 2), 16); + id = long.Parse(Runtime.Substring(tmp, 2)); + } + else + { + id = long.Parse(tmp); + } + IdentifierAuthority = new byte[6]; + for (int i = 5; id > 0; i--) + { + IdentifierAuthority[i] = unchecked((byte)(id % 256)); + id >>= 8; + } + SubAuthorityCount = unchecked((byte)st.CountTokens()); + if (SubAuthorityCount > 0) + { + SubAuthority = new int[SubAuthorityCount]; + for (int i1 = 0; i1 < SubAuthorityCount; i1++) + { + SubAuthority[i1] = (int)(long.Parse(st.NextToken()) & unchecked(0xFFFFFFFFL)); + } + } + } + + /// <summary> + /// Construct a SID from a domain SID and an RID + /// (relative identifier). + /// </summary> + /// <remarks> + /// Construct a SID from a domain SID and an RID + /// (relative identifier). For example, a domain SID + /// <tt>S-1-5-21-1496946806-2192648263-3843101252</tt> and RID <tt>1029</tt> would + /// yield the SID <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </remarks> + public Sid(Sid domsid, int rid) + { + Revision = domsid.Revision; + IdentifierAuthority = domsid.IdentifierAuthority; + SubAuthorityCount = unchecked((byte)(domsid.SubAuthorityCount + 1)); + SubAuthority = new int[SubAuthorityCount]; + int i; + for (i = 0; i < domsid.SubAuthorityCount; i++) + { + SubAuthority[i] = domsid.SubAuthority[i]; + } + SubAuthority[i] = rid; + } + + public Sid(Rpc.SidT sid, int type, string domainName, string acctName, bool decrementAuthority + ) + { + Revision = sid.Revision; + SubAuthorityCount = sid.SubAuthorityCount; + IdentifierAuthority = sid.IdentifierAuthority; + SubAuthority = sid.SubAuthority; + this.Type = type; + this.DomainName = domainName; + this.AcctName = acctName; + if (decrementAuthority) + { + SubAuthorityCount--; + SubAuthority = new int[SubAuthorityCount]; + for (int i = 0; i < SubAuthorityCount; i++) + { + SubAuthority[i] = sid.SubAuthority[i]; + } + } + } + + public virtual Sid GetDomainSid() + { + return new Sid(this, SidTypeDomain, DomainName, null, GetType() + != SidTypeDomain); + } + + public virtual int GetRid() + { + if (GetType() == SidTypeDomain) + { + throw new ArgumentException("This SID is a domain sid"); + } + return SubAuthority[SubAuthorityCount - 1]; + } + + /// <summary>Returns the type of this SID indicating the state or type of account.</summary> + /// <remarks> + /// Returns the type of this SID indicating the state or type of account. + /// <p> + /// SID types are described in the following table. + /// <tt> + /// <table> + /// <tr><th>Type</th><th>Name</th></tr> + /// <tr><td>SID_TYPE_USE_NONE</td><td>0</td></tr> + /// <tr><td>SID_TYPE_USER</td><td>User</td></tr> + /// <tr><td>SID_TYPE_DOM_GRP</td><td>Domain group</td></tr> + /// <tr><td>SID_TYPE_DOMAIN</td><td>Domain</td></tr> + /// <tr><td>SID_TYPE_ALIAS</td><td>Local group</td></tr> + /// <tr><td>SID_TYPE_WKN_GRP</td><td>Builtin group</td></tr> + /// <tr><td>SID_TYPE_DELETED</td><td>Deleted</td></tr> + /// <tr><td>SID_TYPE_INVALID</td><td>Invalid</td></tr> + /// <tr><td>SID_TYPE_UNKNOWN</td><td>Unknown</td></tr> + /// </table> + /// </tt> + /// </remarks> + public virtual int GetType() + { + if (OriginServer != null) + { + ResolveWeak(); + } + return Type; + } + + /// <summary> + /// Return text represeting the SID type suitable for display to + /// users. + /// </summary> + /// <remarks> + /// Return text represeting the SID type suitable for display to + /// users. Text includes 'User', 'Domain group', 'Local group', etc. + /// </remarks> + public virtual string GetTypeText() + { + if (OriginServer != null) + { + ResolveWeak(); + } + return SidTypeNames[Type]; + } + + /// <summary> + /// Return the domain name of this SID unless it could not be + /// resolved in which case the numeric representation is returned. + /// </summary> + /// <remarks> + /// Return the domain name of this SID unless it could not be + /// resolved in which case the numeric representation is returned. + /// </remarks> + public virtual string GetDomainName() + { + if (OriginServer != null) + { + ResolveWeak(); + } + if (Type == SidTypeUnknown) + { + string full = ToString(); + return Runtime.Substring(full, 0, full.Length - GetAccountName().Length - + 1); + } + return DomainName; + } + + /// <summary> + /// Return the sAMAccountName of this SID unless it could not + /// be resolved in which case the numeric RID is returned. + /// </summary> + /// <remarks> + /// Return the sAMAccountName of this SID unless it could not + /// be resolved in which case the numeric RID is returned. If this + /// SID is a domain SID, this method will return an empty String. + /// </remarks> + public virtual string GetAccountName() + { + if (OriginServer != null) + { + ResolveWeak(); + } + if (Type == SidTypeUnknown) + { + return string.Empty + SubAuthority[SubAuthorityCount - 1]; + } + if (Type == SidTypeDomain) + { + return string.Empty; + } + return AcctName; + } + + public override int GetHashCode() + { + int hcode = IdentifierAuthority[5]; + for (int i = 0; i < SubAuthorityCount; i++) + { + hcode += 65599 * SubAuthority[i]; + } + return hcode; + } + + public override bool Equals(object obj) + { + if (obj is Sid) + { + Sid sid = (Sid)obj; + if (sid == this) + { + return true; + } + if (sid.SubAuthorityCount == SubAuthorityCount) + { + int i = SubAuthorityCount; + while (i-- > 0) + { + if (sid.SubAuthority[i] != SubAuthority[i]) + { + return false; + } + } + for (i = 0; i < 6; i++) + { + if (sid.IdentifierAuthority[i] != IdentifierAuthority[i]) + { + return false; + } + } + return sid.Revision == Revision; + } + } + return false; + } + + /// <summary> + /// Return the numeric representation of this sid such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </summary> + /// <remarks> + /// Return the numeric representation of this sid such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </remarks> + public override string ToString() + { + string ret = "S-" + (Revision & unchecked(0xFF)) + "-"; + if (IdentifierAuthority[0] != unchecked(0) || IdentifierAuthority[1] != unchecked( + 0)) + { + ret += "0x"; + ret += Hexdump.ToHexString(IdentifierAuthority, 0, 6); + } + else + { + int shift = 0; + long id = 0; + for (int i = 5; i > 1; i--) + { + id += (IdentifierAuthority[i] & unchecked(0xFFL)) << shift; + shift += 8; + } + ret += id; + } + for (int i1 = 0; i1 < SubAuthorityCount; i1++) + { + ret += "-" + (SubAuthority[i1] & unchecked(0xFFFFFFFFL)); + } + return ret; + } + + /// <summary> + /// Return a String representing this SID ideal for display to + /// users. + /// </summary> + /// <remarks> + /// Return a String representing this SID ideal for display to + /// users. This method should return the same text that the ACL + /// editor in Windows would display. + /// <p> + /// Specifically, if the SID has + /// been resolved and it is not a domain SID or builtin account, + /// the full DOMAIN\name form of the account will be + /// returned (e.g. MYDOM\alice or MYDOM\Domain Users). + /// If the SID has been resolved but it is is a domain SID, + /// only the domain name will be returned (e.g. MYDOM). + /// If the SID has been resolved but it is a builtin account, + /// only the name component will be returned (e.g. SYSTEM). + /// If the sid cannot be resolved the numeric representation from + /// toString() is returned. + /// </remarks> + public virtual string ToDisplayString() + { + if (OriginServer != null) + { + ResolveWeak(); + } + if (DomainName != null) + { + string str; + if (Type == SidTypeDomain) + { + str = DomainName; + } + else + { + if (Type == SidTypeWknGrp || DomainName.Equals("BUILTIN")) + { + if (Type == SidTypeUnknown) + { + str = ToString(); + } + else + { + str = AcctName; + } + } + else + { + str = DomainName + "\\" + AcctName; + } + } + return str; + } + return ToString(); + } + + /// <summary>Manually resolve this SID.</summary> + /// <remarks> + /// Manually resolve this SID. Normally SIDs are automatically + /// resolved. However, if a SID is constructed explicitly using a SID + /// constructor, JCIFS will have no knowledge of the server that created the + /// SID and therefore cannot possibly resolve it automatically. In this case, + /// this method will be necessary. + /// </remarks> + /// <param name="authorityServerName">The FQDN of the server that is an authority for the SID. + /// </param> + /// <param name="auth">Credentials suitable for accessing the SID's information.</param> + /// <exception cref="System.IO.IOException"></exception> + public virtual void Resolve(string authorityServerName, NtlmPasswordAuthentication + auth) + { + Sid[] sids = new Sid[1]; + sids[0] = this; + ResolveSids(authorityServerName, auth, sids); + } + + internal virtual void ResolveWeak() + { + if (OriginServer != null) + { + try + { + Resolve(OriginServer, OriginAuth); + } + catch (IOException) + { + } + finally + { + OriginServer = null; + OriginAuth = null; + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal static Sid[] GetGroupMemberSids0(DcerpcHandle handle, SamrDomainHandle + domainHandle, Sid domsid, int rid, int flags) + { + SamrAliasHandle aliasHandle = null; + Lsarpc.LsarSidArray sidarray = new Lsarpc.LsarSidArray(); + MsrpcGetMembersInAlias rpc = null; + try + { + aliasHandle = new SamrAliasHandle(handle, domainHandle, unchecked(0x0002000c), rid); + rpc = new MsrpcGetMembersInAlias(aliasHandle, sidarray); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } + Sid[] sids = new Sid[rpc.Sids.NumSids]; + string originServer = handle.GetServer(); + NtlmPasswordAuthentication originAuth = (NtlmPasswordAuthentication)handle.GetPrincipal + (); + for (int i = 0; i < sids.Length; i++) + { + sids[i] = new Sid(rpc.Sids.Sids[i].Sid, 0, null, null, false); + sids[i].OriginServer = originServer; + sids[i].OriginAuth = originAuth; + } + if (sids.Length > 0 && (flags & SidFlagResolveSids) != 0) + { + ResolveSids(originServer, originAuth, sids); + } + return sids; + } + finally + { + if (aliasHandle != null) + { + aliasHandle.Close(); + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual Sid[] GetGroupMemberSids(string authorityServerName, NtlmPasswordAuthentication + auth, int flags) + { + if (Type != SidTypeDomGrp && Type != SidTypeAlias) + { + return new Sid[0]; + } + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + Sid domsid = GetDomainSid(); + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + "[\\PIPE\\samr]" + , auth); + policyHandle = new SamrPolicyHandle(handle, authorityServerName, unchecked(0x00000030)); + domainHandle = new SamrDomainHandle(handle, policyHandle, unchecked(0x00000200), domsid); + return GetGroupMemberSids0(handle, domainHandle, domsid, GetRid(), + flags); + } + finally + { + if (handle != null) + { + if (policyHandle != null) + { + if (domainHandle != null) + { + domainHandle.Close(); + } + policyHandle.Close(); + } + handle.Close(); + } + } + } + } + + /// <summary> + /// This specialized method returns a Map of users and local groups for the + /// target server where keys are SIDs representing an account and each value + /// is an List<object> of SIDs represents the local groups that the account is + /// a member of. + /// </summary> + /// <remarks> + /// This specialized method returns a Map of users and local groups for the + /// target server where keys are SIDs representing an account and each value + /// is an List<object> of SIDs represents the local groups that the account is + /// a member of. + /// <p/> + /// This method is designed to assist with computing access control for a + /// given user when the target object's ACL has local groups. Local groups + /// are not listed in a user's group membership (e.g. as represented by the + /// tokenGroups constructed attribute retrived via LDAP). + /// <p/> + /// Domain groups nested inside a local group are currently not expanded. In + /// this case the key (SID) type will be SID_TYPE_DOM_GRP rather than + /// SID_TYPE_USER. + /// </remarks> + /// <param name="authorityServerName">The server from which the local groups will be queried. + /// </param> + /// <param name="auth">The credentials required to query groups and group members.</param> + /// <param name="flags"> + /// Flags that control the behavior of the operation. When all + /// name associated with SIDs will be required, the SID_FLAG_RESOLVE_SIDS + /// flag should be used which causes all group member SIDs to be resolved + /// together in a single more efficient operation. + /// </param> + /// <exception cref="System.IO.IOException"></exception> + internal static Hashtable GetLocalGroupsMap(string authorityServerName, NtlmPasswordAuthentication + auth, int flags) + { + Sid domsid = GetServerSid(authorityServerName, auth); + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + Samr.SamrSamArray sam = new Samr.SamrSamArray(); + MsrpcEnumerateAliasesInDomain rpc; + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + "[\\PIPE\\samr]" + , auth); + policyHandle = new SamrPolicyHandle(handle, authorityServerName, unchecked(0x02000000)); + domainHandle = new SamrDomainHandle(handle, policyHandle, unchecked(0x02000000), domsid); + rpc = new MsrpcEnumerateAliasesInDomain(domainHandle, unchecked(0xFFFF), sam + ); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } + Hashtable map = new Hashtable(); + for (int ei = 0; ei < rpc.Sam.Count; ei++) + { + Samr.SamrSamEntry entry = rpc.Sam.Entries[ei]; + Sid[] mems = GetGroupMemberSids0(handle, domainHandle, domsid + , entry.Idx, flags); + Sid groupSid = new Sid(domsid, entry.Idx); + groupSid.Type = SidTypeAlias; + groupSid.DomainName = domsid.GetDomainName(); + groupSid.AcctName = (new UnicodeString(entry.Name, false)).ToString(); + for (int mi = 0; mi < mems.Length; mi++) + { + List<object> groups = (List<object>)map.Get(mems[mi]); + if (groups == null) + { + groups = new List<object>(); + map.Put(mems[mi], groups); + } + if (!groups.Contains(groupSid)) + { + groups.Add(groupSid); + } + } + } + return map; + } + finally + { + if (handle != null) + { + if (policyHandle != null) + { + if (domainHandle != null) + { + domainHandle.Close(); + } + policyHandle.Close(); + } + handle.Close(); + } + } + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SecurityDescriptor.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SecurityDescriptor.cs new file mode 100644 index 000000000..8a424a019 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SecurityDescriptor.cs @@ -0,0 +1,101 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; + +namespace SharpCifs.Smb +{ + public class SecurityDescriptor + { + public int Type; + + public Ace[] Aces; + + public SecurityDescriptor() + { + } + + /// <exception cref="System.IO.IOException"></exception> + public SecurityDescriptor(byte[] buffer, int bufferIndex, int len) + { + Decode(buffer, bufferIndex, len); + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual int Decode(byte[] buffer, int bufferIndex, int len) + { + int start = bufferIndex; + bufferIndex++; + // revision + bufferIndex++; + Type = ServerMessageBlock.ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + ServerMessageBlock.ReadInt4(buffer, bufferIndex); + // offset to owner sid + bufferIndex += 4; + ServerMessageBlock.ReadInt4(buffer, bufferIndex); + // offset to group sid + bufferIndex += 4; + ServerMessageBlock.ReadInt4(buffer, bufferIndex); + // offset to sacl + bufferIndex += 4; + int daclOffset = ServerMessageBlock.ReadInt4(buffer, bufferIndex); + bufferIndex = start + daclOffset; + bufferIndex++; + // revision + bufferIndex++; + int size = ServerMessageBlock.ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + int numAces = ServerMessageBlock.ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + if (numAces > 4096) + { + throw new IOException("Invalid SecurityDescriptor"); + } + if (daclOffset != 0) + { + Aces = new Ace[numAces]; + for (int i = 0; i < numAces; i++) + { + Aces[i] = new Ace(); + bufferIndex += Aces[i].Decode(buffer, bufferIndex); + } + } + else + { + Aces = null; + } + return bufferIndex - start; + } + + public override string ToString() + { + string ret = "SecurityDescriptor:\n"; + if (Aces != null) + { + for (int ai = 0; ai < Aces.Length; ai++) + { + ret += Aces[ai] + "\n"; + } + } + else + { + ret += "NULL"; + } + return ret; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/ServerMessageBlock.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/ServerMessageBlock.cs new file mode 100644 index 000000000..cb38c89fa --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/ServerMessageBlock.cs @@ -0,0 +1,692 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; +using SharpCifs.Util.Transport; + +namespace SharpCifs.Smb +{ + public abstract class ServerMessageBlock: Response + { + internal static LogStream Log = LogStream.GetInstance(); + + internal static long Ticks1601 = new DateTime(1601, 1, 1).Ticks; + + internal static readonly byte[] Header = { 0xFF, (byte)('S'), (byte)('M'), + (byte)('B'), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + internal static void WriteInt2(long val, byte[] dst, int dstIndex) + { + dst[dstIndex] = unchecked((byte)(val)); + dst[++dstIndex] = unchecked((byte)(val >> 8)); + } + + internal static void WriteInt4(long val, byte[] dst, int dstIndex) + { + dst[dstIndex] = unchecked((byte)(val)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >> 8)); + } + + internal static int ReadInt2(byte[] src, int srcIndex) + { + return unchecked(src[srcIndex] & 0xFF) + ((src[srcIndex + 1] & 0xFF) << 8); + } + + internal static int ReadInt4(byte[] src, int srcIndex) + { + return unchecked(src[srcIndex] & 0xFF) + ((src[srcIndex + 1] & 0xFF) << 8) + ((src[srcIndex + 2] + & 0xFF) << 16) + ((src[srcIndex + 3] & 0xFF) << 24); + } + + internal static long ReadInt8(byte[] src, int srcIndex) + { + return unchecked(ReadInt4(src, srcIndex) & unchecked(0xFFFFFFFFL)) + unchecked((long)(ReadInt4 + (src, srcIndex + 4)) << 32); + } + + internal static void WriteInt8(long val, byte[] dst, int dstIndex) + { + dst[dstIndex] = unchecked((byte)(val)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >>= 8)); + dst[++dstIndex] = unchecked((byte)(val >> 8)); + } + + internal static long ReadTime(byte[] src, int srcIndex) + { + int low = ReadInt4(src, srcIndex); + int hi = ReadInt4(src, srcIndex + 4); + long t = ((long)hi << (int)32L) | (low & unchecked((long)(0xFFFFFFFFL))); + t = (t / 10000L - SmbConstants.MillisecondsBetween1970And1601); + return t; + } + + internal static void WriteTime(long t, byte[] dst, int dstIndex) + { + if (t != 0L) + { + t = (t + SmbConstants.MillisecondsBetween1970And1601) * 10000L; + } + WriteInt8(t, dst, dstIndex); + } + + internal static long ReadUTime(byte[] buffer, int bufferIndex) + { + return ReadInt4(buffer, bufferIndex) * 1000L; + } + + internal static void WriteUTime(long t, byte[] dst, int dstIndex) + { + if (t == 0L || t == unchecked((long)(0xFFFFFFFFFFFFFFFFL))) + { + WriteInt4(unchecked((int)(0xFFFFFFFF)), dst, dstIndex); + return; + } + // t isn't in DST either + WriteInt4((int)(t / 1000L), dst, dstIndex); + } + + internal const byte SmbComCreateDirectory = 0x00; + + internal const byte SmbComDeleteDirectory = 0x01; + + internal const byte SmbComClose = 0x04; + + internal const byte SmbComDelete = 0x06; + + internal const byte SmbComRename = 0x07; + + internal const byte SmbComQueryInformation = 0x08; + + internal const byte SmbComWrite = 0x0B; + + internal const byte SmbComCheckDirectory = 0x10; + + internal const byte SmbComTransaction = 0x25; + + internal const byte SmbComTransactionSecondary = 0x26; + + internal const byte SmbComMove = 0x2A; + + internal const byte SmbComEcho = 0x2B; + + internal const byte SmbComOpenAndx = 0x2D; + + internal const byte SmbComReadAndx = 0x2E; + + internal const byte SmbComWriteAndx = 0x2F; + + internal const byte SmbComTransaction2 = 0x32; + + internal const byte SmbComFindClose2 = 0x34; + + internal const byte SmbComTreeDisconnect = 0x71; + + internal const byte SmbComNegotiate = 0x72; + + internal const byte SmbComSessionSetupAndx = 0x73; + + internal const byte SmbComLogoffAndx = 0x74; + + internal const byte SmbComTreeConnectAndx = 0x75; + + internal const byte SmbComNtTransact = 0xA0; + + internal const byte SmbComNtTransactSecondary = 0xA1; + + internal const byte SmbComNtCreateAndx = 0xA2; + + internal byte Command; + + internal byte Flags; + + internal int HeaderStart; + + internal int Length; + + internal int BatchLevel; + + internal int ErrorCode; + + internal int Flags2; + + internal int Tid; + + internal int Pid; + + internal int Uid; + + internal int Mid; + + internal int WordCount; + + internal int ByteCount; + + internal bool UseUnicode; + + internal bool Received; + + internal bool ExtendedSecurity; + + internal long ResponseTimeout = 1; + + internal int SignSeq; + + internal bool VerifyFailed; + + internal NtlmPasswordAuthentication Auth = null; + + internal string Path; + + internal SigningDigest Digest; + + internal ServerMessageBlock Response; + + public ServerMessageBlock() + { + Flags = unchecked((byte)(SmbConstants.FlagsPathNamesCaseless | SmbConstants.FlagsPathNamesCanonicalized + )); + Pid = SmbConstants.Pid; + BatchLevel = 0; + } + + internal virtual void Reset() + { + Flags = unchecked((byte)(SmbConstants.FlagsPathNamesCaseless | SmbConstants.FlagsPathNamesCanonicalized + )); + Flags2 = 0; + ErrorCode = 0; + Received = false; + Digest = null; + } + + internal virtual int WriteString(string str, byte[] dst, int dstIndex) + { + return WriteString(str, dst, dstIndex, UseUnicode); + } + + internal virtual int WriteString(string str, byte[] dst, int dstIndex, bool useUnicode + ) + { + int start = dstIndex; + try + { + if (useUnicode) + { + // Unicode requires word alignment + if (((dstIndex - HeaderStart) % 2) != 0) + { + dst[dstIndex++] = (byte)('\0'); + } + Array.Copy(Runtime.GetBytesForString(str, SmbConstants.UniEncoding), 0, dst, dstIndex + , str.Length * 2); + dstIndex += str.Length * 2; + dst[dstIndex++] = (byte)('\0'); + dst[dstIndex++] = (byte)('\0'); + } + else + { + byte[] b = Runtime.GetBytesForString(str, SmbConstants.OemEncoding); + Array.Copy(b, 0, dst, dstIndex, b.Length); + dstIndex += b.Length; + dst[dstIndex++] = (byte)('\0'); + } + } + catch (UnsupportedEncodingException uee) + { + if (Log.Level > 1) + { + Runtime.PrintStackTrace(uee, Log); + } + } + return dstIndex - start; + } + + internal virtual string ReadString(byte[] src, int srcIndex) + { + return ReadString(src, srcIndex, 256, UseUnicode); + } + + internal virtual string ReadString(byte[] src, int srcIndex, int maxLen, bool useUnicode + ) + { + int len = 0; + string str = null; + try + { + if (useUnicode) + { + // Unicode requires word alignment + if (((srcIndex - HeaderStart) % 2) != 0) + { + srcIndex++; + } + while (src[srcIndex + len] != 0x00 || src[srcIndex + + len + 1] != 0x00) + { + len += 2; + if (len > maxLen) + { + if (Log.Level > 0) + { + Hexdump.ToHexdump(Console.Error, src, srcIndex, maxLen < 128 ? maxLen + 8 : + 128); + } + throw new RuntimeException("zero termination not found"); + } + } + str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.UniEncoding); + } + else + { + while (src[srcIndex + len] != 0x00) + { + len++; + if (len > maxLen) + { + if (Log.Level > 0) + { + Hexdump.ToHexdump(Console.Error, src, srcIndex, maxLen < 128 ? maxLen + 8 : + 128); + } + throw new RuntimeException("zero termination not found"); + } + } + str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.OemEncoding); + } + } + catch (UnsupportedEncodingException uee) + { + if (Log.Level > 1) + { + Runtime.PrintStackTrace(uee, Log); + } + } + return str; + } + + internal virtual string ReadString(byte[] src, int srcIndex, int srcEnd, int maxLen + , bool useUnicode) + { + int len = 0; + string str = null; + try + { + if (useUnicode) + { + // Unicode requires word alignment + if (((srcIndex - HeaderStart) % 2) != 0) + { + srcIndex++; + } + for (len = 0; (srcIndex + len + 1) < srcEnd; len += 2) + { + if (src[srcIndex + len] == 0x00 && src[srcIndex + + len + 1] == 0x00) + { + break; + } + if (len > maxLen) + { + if (Log.Level > 0) + { + Hexdump.ToHexdump(Console.Error, src, srcIndex, maxLen < 128 ? maxLen + 8 : + 128); + } + throw new RuntimeException("zero termination not found"); + } + } + str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.UniEncoding); + } + else + { + for (len = 0; srcIndex < srcEnd; len++) + { + if (src[srcIndex + len] == 0x00) + { + break; + } + if (len > maxLen) + { + if (Log.Level > 0) + { + Hexdump.ToHexdump(Console.Error, src, srcIndex, maxLen < 128 ? maxLen + 8 : + 128); + } + throw new RuntimeException("zero termination not found"); + } + } + str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.OemEncoding); + } + } + catch (UnsupportedEncodingException uee) + { + if (Log.Level > 1) + { + Runtime.PrintStackTrace(uee, Log); + } + } + return str; + } + + internal virtual int StringWireLength(string str, int offset) + { + int len = str.Length + 1; + if (UseUnicode) + { + len = str.Length * 2 + 2; + len = (offset % 2) != 0 ? len + 1 : len; + } + return len; + } + + internal virtual int ReadStringLength(byte[] src, int srcIndex, int max) + { + int len = 0; + while (src[srcIndex + len] != 0x00) + { + if (len++ > max) + { + throw new RuntimeException("zero termination not found: " + this); + } + } + return len; + } + + internal virtual int Encode(byte[] dst, int dstIndex) + { + int start = HeaderStart = dstIndex; + dstIndex += WriteHeaderWireFormat(dst, dstIndex); + WordCount = WriteParameterWordsWireFormat(dst, dstIndex + 1); + dst[dstIndex++] = unchecked((byte)((WordCount / 2) & 0xFF)); + dstIndex += WordCount; + WordCount /= 2; + ByteCount = WriteBytesWireFormat(dst, dstIndex + 2); + dst[dstIndex++] = unchecked((byte)(ByteCount & 0xFF)); + dst[dstIndex++] = unchecked((byte)((ByteCount >> 8) & 0xFF)); + dstIndex += ByteCount; + Length = dstIndex - start; + if (Digest != null) + { + Digest.Sign(dst, HeaderStart, Length, this, Response); + } + return Length; + } + + internal virtual int Decode(byte[] buffer, int bufferIndex) + { + int start = HeaderStart = bufferIndex; + bufferIndex += ReadHeaderWireFormat(buffer, bufferIndex); + WordCount = buffer[bufferIndex++]; + if (WordCount != 0) + { + int n; + if ((n = ReadParameterWordsWireFormat(buffer, bufferIndex)) != WordCount * 2) + { + if (Log.Level >= 5) + { + Log.WriteLine("wordCount * 2=" + (WordCount * 2) + " but readParameterWordsWireFormat returned " + + n); + } + } + bufferIndex += WordCount * 2; + } + ByteCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if (ByteCount != 0) + { + int n; + if ((n = ReadBytesWireFormat(buffer, bufferIndex)) != ByteCount) + { + if (Log.Level >= 5) + { + Log.WriteLine("byteCount=" + ByteCount + " but readBytesWireFormat returned " + n + ); + } + } + // Don't think we can rely on n being correct here. Must use byteCount. + // Last paragraph of section 3.13.3 eludes to this. + bufferIndex += ByteCount; + } + Length = bufferIndex - start; + return Length; + } + + internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex) + { + Array.Copy(Header, 0, dst, dstIndex, Header.Length); + dst[dstIndex + SmbConstants.CmdOffset] = Command; + dst[dstIndex + SmbConstants.FlagsOffset] = Flags; + WriteInt2(Flags2, dst, dstIndex + SmbConstants.FlagsOffset + 1); + dstIndex += SmbConstants.TidOffset; + WriteInt2(Tid, dst, dstIndex); + WriteInt2(Pid, dst, dstIndex + 2); + WriteInt2(Uid, dst, dstIndex + 4); + WriteInt2(Mid, dst, dstIndex + 6); + return SmbConstants.HeaderLength; + } + + internal virtual int ReadHeaderWireFormat(byte[] buffer, int bufferIndex) + { + Command = buffer[bufferIndex + SmbConstants.CmdOffset]; + ErrorCode = ReadInt4(buffer, bufferIndex + SmbConstants.ErrorCodeOffset); + Flags = buffer[bufferIndex + SmbConstants.FlagsOffset]; + Flags2 = ReadInt2(buffer, bufferIndex + SmbConstants.FlagsOffset + 1); + Tid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset); + Pid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset + 2); + Uid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset + 4); + Mid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset + 6); + return SmbConstants.HeaderLength; + } + + internal virtual bool IsResponse() + { + return (Flags & SmbConstants.FlagsResponse) == SmbConstants.FlagsResponse; + } + + internal abstract int WriteParameterWordsWireFormat(byte[] dst, int dstIndex); + + internal abstract int WriteBytesWireFormat(byte[] dst, int dstIndex); + + internal abstract int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ); + + internal abstract int ReadBytesWireFormat(byte[] buffer, int bufferIndex); + + public override int GetHashCode() + { + return Mid; + } + + public override bool Equals(object obj) + { + return obj is ServerMessageBlock && ((ServerMessageBlock)obj) + .Mid == Mid; + } + + public override string ToString() + { + string c; + switch (Command) + { + case SmbComNegotiate: + { + c = "SMB_COM_NEGOTIATE"; + break; + } + + case SmbComSessionSetupAndx: + { + c = "SMB_COM_SESSION_SETUP_ANDX"; + break; + } + + case SmbComTreeConnectAndx: + { + c = "SMB_COM_TREE_CONNECT_ANDX"; + break; + } + + case SmbComQueryInformation: + { + c = "SMB_COM_QUERY_INFORMATION"; + break; + } + + case SmbComCheckDirectory: + { + c = "SMB_COM_CHECK_DIRECTORY"; + break; + } + + case SmbComTransaction: + { + c = "SMB_COM_TRANSACTION"; + break; + } + + case SmbComTransaction2: + { + c = "SMB_COM_TRANSACTION2"; + break; + } + + case SmbComTransactionSecondary: + { + c = "SMB_COM_TRANSACTION_SECONDARY"; + break; + } + + case SmbComFindClose2: + { + c = "SMB_COM_FIND_CLOSE2"; + break; + } + + case SmbComTreeDisconnect: + { + c = "SMB_COM_TREE_DISCONNECT"; + break; + } + + case SmbComLogoffAndx: + { + c = "SMB_COM_LOGOFF_ANDX"; + break; + } + + case SmbComEcho: + { + c = "SMB_COM_ECHO"; + break; + } + + case SmbComMove: + { + c = "SMB_COM_MOVE"; + break; + } + + case SmbComRename: + { + c = "SMB_COM_RENAME"; + break; + } + + case SmbComDelete: + { + c = "SMB_COM_DELETE"; + break; + } + + case SmbComDeleteDirectory: + { + c = "SMB_COM_DELETE_DIRECTORY"; + break; + } + + case SmbComNtCreateAndx: + { + c = "SMB_COM_NT_CREATE_ANDX"; + break; + } + + case SmbComOpenAndx: + { + c = "SMB_COM_OPEN_ANDX"; + break; + } + + case SmbComReadAndx: + { + c = "SMB_COM_READ_ANDX"; + break; + } + + case SmbComClose: + { + c = "SMB_COM_CLOSE"; + break; + } + + case SmbComWriteAndx: + { + c = "SMB_COM_WRITE_ANDX"; + break; + } + + case SmbComCreateDirectory: + { + c = "SMB_COM_CREATE_DIRECTORY"; + break; + } + + case SmbComNtTransact: + { + c = "SMB_COM_NT_TRANSACT"; + break; + } + + case SmbComNtTransactSecondary: + { + c = "SMB_COM_NT_TRANSACT_SECONDARY"; + break; + } + + default: + { + c = "UNKNOWN"; + break; + } + } + string str = ErrorCode == 0 ? "0" : SmbException.GetMessageByCode(ErrorCode); + return "command=" + c + ",received=" + Received + ",errorCode=" + str + + ",flags=0x" + Hexdump.ToHexString(Flags & 0xFF, 4) + ",flags2=0x" + + Hexdump.ToHexString(Flags2, 4) + ",signSeq=" + SignSeq + ",tid=" + Tid + ",pid=" + + Pid + ",uid=" + Uid + ",mid=" + Mid + ",wordCount=" + WordCount + ",byteCount=" + + ByteCount; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SigningDigest.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SigningDigest.cs new file mode 100644 index 000000000..9f57e887b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SigningDigest.cs @@ -0,0 +1,257 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + /// <summary>To filter 0 len updates and for debugging</summary> + public class SigningDigest + { + internal static LogStream Log = LogStream.GetInstance(); + + private MessageDigest _digest; + + private byte[] _macSigningKey; + + private bool _bypass; + + private int _updates; + + private int _signSequence; + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public SigningDigest(byte[] macSigningKey, bool bypass) + { + try + { + _digest = MessageDigest.GetInstance("MD5"); + } + catch (NoSuchAlgorithmException ex) + { + if (Log.Level > 0) + { + Runtime.PrintStackTrace(ex, Log); + } + throw new SmbException("MD5", ex); + } + this._macSigningKey = macSigningKey; + this._bypass = bypass; + _updates = 0; + _signSequence = 0; + if (Log.Level >= 5) + { + Log.WriteLine("macSigningKey:"); + Hexdump.ToHexdump(Log, macSigningKey, 0, macSigningKey.Length); + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public SigningDigest(SmbTransport transport, NtlmPasswordAuthentication auth) + { + try + { + _digest = MessageDigest.GetInstance("MD5"); + } + catch (NoSuchAlgorithmException ex) + { + if (Log.Level > 0) + { + Runtime.PrintStackTrace(ex, Log); + } + throw new SmbException("MD5", ex); + } + try + { + switch (SmbConstants.LmCompatibility) + { + case 0: + case 1: + case 2: + { + _macSigningKey = new byte[40]; + auth.GetUserSessionKey(transport.Server.EncryptionKey, _macSigningKey, 0); + Array.Copy(auth.GetUnicodeHash(transport.Server.EncryptionKey), 0, _macSigningKey + , 16, 24); + break; + } + + case 3: + case 4: + case 5: + { + _macSigningKey = new byte[16]; + auth.GetUserSessionKey(transport.Server.EncryptionKey, _macSigningKey, 0); + break; + } + + default: + { + _macSigningKey = new byte[40]; + auth.GetUserSessionKey(transport.Server.EncryptionKey, _macSigningKey, 0); + Array.Copy(auth.GetUnicodeHash(transport.Server.EncryptionKey), 0, _macSigningKey + , 16, 24); + break; + } + } + } + catch (Exception ex) + { + throw new SmbException(string.Empty, ex); + } + if (Log.Level >= 5) + { + Log.WriteLine("LM_COMPATIBILITY=" + SmbConstants.LmCompatibility); + Hexdump.ToHexdump(Log, _macSigningKey, 0, _macSigningKey.Length); + } + } + + public virtual void Update(byte[] input, int offset, int len) + { + if (Log.Level >= 5) + { + Log.WriteLine("update: " + _updates + " " + offset + ":" + len); + Hexdump.ToHexdump(Log, input, offset, Math.Min(len, 256)); + Log.Flush(); + } + if (len == 0) + { + return; + } + _digest.Update(input, offset, len); + _updates++; + } + + public virtual byte[] Digest() + { + byte[] b; + b = _digest.Digest(); + if (Log.Level >= 5) + { + Log.WriteLine("digest: "); + Hexdump.ToHexdump(Log, b, 0, b.Length); + Log.Flush(); + } + _updates = 0; + return b; + } + + /// <summary>Performs MAC signing of the SMB.</summary> + /// <remarks> + /// Performs MAC signing of the SMB. This is done as follows. + /// The signature field of the SMB is overwritted with the sequence number; + /// The MD5 digest of the MAC signing key + the entire SMB is taken; + /// The first 8 bytes of this are placed in the signature field. + /// </remarks> + /// <param name="data">The data.</param> + /// <param name="offset">The starting offset at which the SMB header begins.</param> + /// <param name="length">The length of the SMB data starting at offset.</param> + internal virtual void Sign(byte[] data, int offset, int length, ServerMessageBlock + request, ServerMessageBlock response) + { + request.SignSeq = _signSequence; + if (response != null) + { + response.SignSeq = _signSequence + 1; + response.VerifyFailed = false; + } + try + { + Update(_macSigningKey, 0, _macSigningKey.Length); + int index = offset + SmbConstants.SignatureOffset; + for (int i = 0; i < 8; i++) + { + data[index + i] = 0; + } + ServerMessageBlock.WriteInt4(_signSequence, data, index); + Update(data, offset, length); + Array.Copy(Digest(), 0, data, index, 8); + if (_bypass) + { + _bypass = false; + Array.Copy(Runtime.GetBytesForString("BSRSPYL "), 0, data, index, + 8); + } + } + catch (Exception ex) + { + if (Log.Level > 0) + { + Runtime.PrintStackTrace(ex, Log); + } + } + finally + { + _signSequence += 2; + } + } + + /// <summary>Performs MAC signature verification.</summary> + /// <remarks> + /// Performs MAC signature verification. This calculates the signature + /// of the SMB and compares it to the signature field on the SMB itself. + /// </remarks> + /// <param name="data">The data.</param> + /// <param name="offset">The starting offset at which the SMB header begins.</param> + /// <param name="length">The length of the SMB data starting at offset.</param> + internal virtual bool Verify(byte[] data, int offset, ServerMessageBlock response + ) + { + Update(_macSigningKey, 0, _macSigningKey.Length); + int index = offset; + Update(data, index, SmbConstants.SignatureOffset); + index += SmbConstants.SignatureOffset; + byte[] sequence = new byte[8]; + ServerMessageBlock.WriteInt4(response.SignSeq, sequence, 0); + Update(sequence, 0, sequence.Length); + index += 8; + if (response.Command == ServerMessageBlock.SmbComReadAndx) + { + SmbComReadAndXResponse raxr = (SmbComReadAndXResponse)response; + int length = response.Length - raxr.DataLength; + Update(data, index, length - SmbConstants.SignatureOffset - 8); + Update(raxr.B, raxr.Off, raxr.DataLength); + } + else + { + Update(data, index, response.Length - SmbConstants.SignatureOffset - 8); + } + byte[] signature = Digest(); + for (int i = 0; i < 8; i++) + { + if (signature[i] != data[offset + SmbConstants.SignatureOffset + i]) + { + if (Log.Level >= 2) + { + Log.WriteLine("signature verification failure"); + Hexdump.ToHexdump(Log, signature, 0, 8); + Hexdump.ToHexdump(Log, data, offset + SmbConstants.SignatureOffset, 8); + } + return response.VerifyFailed = true; + } + } + return response.VerifyFailed = false; + } + + public override string ToString() + { + return "LM_COMPATIBILITY=" + SmbConstants.LmCompatibility + " MacSigningKey=" + Hexdump.ToHexString + (_macSigningKey, 0, _macSigningKey.Length); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbAuthException.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbAuthException.cs new file mode 100644 index 000000000..defaea71b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbAuthException.cs @@ -0,0 +1,36 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + /// <summary> + /// The <code>SmbAuthException</code> encapsulates the variety of + /// authentication related error codes returned by an SMB server. + /// </summary> + /// <remarks> + /// The <code>SmbAuthException</code> encapsulates the variety of + /// authentication related error codes returned by an SMB server. + /// <p> + /// See <a href="../../../authhandler.html">jCIFS Exceptions and NtlmAuthenticator</a> for more information about <code>SmbAuthException</code>. + /// </remarks> + + public class SmbAuthException : SmbException + { + internal SmbAuthException(int errcode) : base(errcode, null) + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComBlankResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComBlankResponse.cs new file mode 100644 index 000000000..2295de5b9 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComBlankResponse.cs @@ -0,0 +1,47 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComBlankResponse : ServerMessageBlock + { + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComBlankResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComClose.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComClose.cs new file mode 100644 index 000000000..4a160f518 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComClose.cs @@ -0,0 +1,62 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComClose : ServerMessageBlock + { + private int _fid; + + private long _lastWriteTime; + + internal SmbComClose(int fid, long lastWriteTime) + { + this._fid = fid; + this._lastWriteTime = lastWriteTime; + Command = SmbComClose; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + WriteInt2(_fid, dst, dstIndex); + dstIndex += 2; + WriteUTime(_lastWriteTime, dst, dstIndex); + return 6; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComClose[" + base.ToString() + ",fid=" + _fid + ",lastWriteTime=" + + _lastWriteTime + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComCreateDirectory.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComCreateDirectory.cs new file mode 100644 index 000000000..7549db01a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComCreateDirectory.cs @@ -0,0 +1,57 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComCreateDirectory : ServerMessageBlock + { + internal SmbComCreateDirectory(string directoryName) + { + Path = directoryName; + Command = SmbComCreateDirectory; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dst[dstIndex++] = unchecked(unchecked(0x04)); + dstIndex += WriteString(Path, dst, dstIndex); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComCreateDirectory[" + base.ToString() + ",directoryName=" + + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComDelete.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComDelete.cs new file mode 100644 index 000000000..d055d2446 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComDelete.cs @@ -0,0 +1,63 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class SmbComDelete : ServerMessageBlock + { + private int _searchAttributes; + + internal SmbComDelete(string fileName) + { + Path = fileName; + Command = SmbComDelete; + _searchAttributes = SmbConstants.AttrHidden | SmbConstants.AttrHidden | SmbConstants.AttrSystem; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + WriteInt2(_searchAttributes, dst, dstIndex); + return 2; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dst[dstIndex++] = unchecked(unchecked(0x04)); + dstIndex += WriteString(Path, dst, dstIndex); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComDelete[" + base.ToString() + ",searchAttributes=0x" + Hexdump + .ToHexString(_searchAttributes, 4) + ",fileName=" + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComDeleteDirectory.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComDeleteDirectory.cs new file mode 100644 index 000000000..240139a17 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComDeleteDirectory.cs @@ -0,0 +1,57 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComDeleteDirectory : ServerMessageBlock + { + internal SmbComDeleteDirectory(string directoryName) + { + Path = directoryName; + Command = SmbComDeleteDirectory; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dst[dstIndex++] = unchecked(unchecked(0x04)); + dstIndex += WriteString(Path, dst, dstIndex); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComDeleteDirectory[" + base.ToString() + ",directoryName=" + + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComFindClose2.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComFindClose2.cs new file mode 100644 index 000000000..9b7c0c765 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComFindClose2.cs @@ -0,0 +1,56 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComFindClose2 : ServerMessageBlock + { + private int _sid; + + internal SmbComFindClose2(int sid) + { + this._sid = sid; + Command = SmbComFindClose2; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + WriteInt2(_sid, dst, dstIndex); + return 2; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComFindClose2[" + base.ToString() + ",sid=" + _sid + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComLogoffAndX.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComLogoffAndX.cs new file mode 100644 index 000000000..8f88ccd57 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComLogoffAndX.cs @@ -0,0 +1,52 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComLogoffAndX : AndXServerMessageBlock + { + internal SmbComLogoffAndX(ServerMessageBlock andx) : base(andx) + { + Command = SmbComLogoffAndx; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComLogoffAndX[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNTCreateAndX.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNTCreateAndX.cs new file mode 100644 index 000000000..26b5ba63a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNTCreateAndX.cs @@ -0,0 +1,193 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class SmbComNtCreateAndX : AndXServerMessageBlock + { + internal const int FileSupersede = unchecked(0x0); + + internal const int FileOpen = unchecked(0x1); + + internal const int FileCreate = unchecked(0x2); + + internal const int FileOpenIf = unchecked(0x3); + + internal const int FileOverwrite = unchecked(0x4); + + internal const int FileOverwriteIf = unchecked(0x5); + + internal const int FileWriteThrough = unchecked(0x00000002); + + internal const int FileSequentialOnly = unchecked(0x00000004); + + internal const int FileSynchronousIoAlert = unchecked(0x00000010); + + internal const int FileSynchronousIoNonalert = unchecked(0x00000020); + + internal const int SecurityContextTracking = unchecked(0x01); + + internal const int SecurityEffectiveOnly = unchecked(0x02); + + private int _rootDirectoryFid; + + private int _extFileAttributes; + + private int _shareAccess; + + private int _createDisposition; + + private int _createOptions; + + private int _impersonationLevel; + + private long _allocationSize; + + private byte _securityFlags; + + private int _namelenIndex; + + internal int Flags0; + + internal int DesiredAccess; + + internal SmbComNtCreateAndX(string name, int flags, int access, int shareAccess, + int extFileAttributes, int createOptions, ServerMessageBlock andx) : base(andx) + { + // share access specified in SmbFile + // create disposition + // create options + // security flags + Path = name; + Command = SmbComNtCreateAndx; + DesiredAccess = access; + DesiredAccess |= SmbConstants.FileReadData | SmbConstants.FileReadEa | SmbConstants.FileReadAttributes; + // extFileAttributes + this._extFileAttributes = extFileAttributes; + // shareAccess + this._shareAccess = shareAccess; + // createDisposition + if ((flags & SmbFile.OTrunc) == SmbFile.OTrunc) + { + // truncate the file + if ((flags & SmbFile.OCreat) == SmbFile.OCreat) + { + // create it if necessary + _createDisposition = FileOverwriteIf; + } + else + { + _createDisposition = FileOverwrite; + } + } + else + { + // don't truncate the file + if ((flags & SmbFile.OCreat) == SmbFile.OCreat) + { + // create it if necessary + if ((flags & SmbFile.OExcl) == SmbFile.OExcl) + { + // fail if already exists + _createDisposition = FileCreate; + } + else + { + _createDisposition = FileOpenIf; + } + } + else + { + _createDisposition = FileOpen; + } + } + if ((createOptions & unchecked(0x0001)) == 0) + { + this._createOptions = createOptions | unchecked(0x0040); + } + else + { + this._createOptions = createOptions; + } + _impersonationLevel = unchecked(0x02); + // As seen on NT :~) + _securityFlags = unchecked(unchecked(0x03)); + } + + // SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dst[dstIndex++] = unchecked(unchecked(0x00)); + // name length without counting null termination + _namelenIndex = dstIndex; + dstIndex += 2; + WriteInt4(Flags0, dst, dstIndex); + dstIndex += 4; + WriteInt4(_rootDirectoryFid, dst, dstIndex); + dstIndex += 4; + WriteInt4(DesiredAccess, dst, dstIndex); + dstIndex += 4; + WriteInt8(_allocationSize, dst, dstIndex); + dstIndex += 8; + WriteInt4(_extFileAttributes, dst, dstIndex); + dstIndex += 4; + WriteInt4(_shareAccess, dst, dstIndex); + dstIndex += 4; + WriteInt4(_createDisposition, dst, dstIndex); + dstIndex += 4; + WriteInt4(_createOptions, dst, dstIndex); + dstIndex += 4; + WriteInt4(_impersonationLevel, dst, dstIndex); + dstIndex += 4; + dst[dstIndex++] = _securityFlags; + return dstIndex - start; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int n; + n = WriteString(Path, dst, dstIndex); + WriteInt2((UseUnicode ? Path.Length * 2 : n), dst, _namelenIndex); + return n; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComNTCreateAndX[" + base.ToString() + ",flags=0x" + Hexdump + .ToHexString(Flags0, 2) + ",rootDirectoryFid=" + _rootDirectoryFid + ",desiredAccess=0x" + + Hexdump.ToHexString(DesiredAccess, 4) + ",allocationSize=" + _allocationSize + + ",extFileAttributes=0x" + Hexdump.ToHexString(_extFileAttributes, 4) + ",shareAccess=0x" + + Hexdump.ToHexString(_shareAccess, 4) + ",createDisposition=0x" + Hexdump.ToHexString + (_createDisposition, 4) + ",createOptions=0x" + Hexdump.ToHexString(_createOptions + , 8) + ",impersonationLevel=0x" + Hexdump.ToHexString(_impersonationLevel, 4) + ",securityFlags=0x" + + Hexdump.ToHexString(_securityFlags, 2) + ",name=" + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNTCreateAndXResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNTCreateAndXResponse.cs new file mode 100644 index 000000000..4a007bdc5 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNTCreateAndXResponse.cs @@ -0,0 +1,116 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComNtCreateAndXResponse : AndXServerMessageBlock + { + internal const int ExclusiveOplockGranted = 1; + + internal const int BatchOplockGranted = 2; + + internal const int LevelIiOplockGranted = 3; + + internal byte OplockLevel; + + internal int Fid; + + internal int CreateAction; + + internal int ExtFileAttributes; + + internal int FileType; + + internal int DeviceState; + + internal long CreationTime; + + internal long LastAccessTime; + + internal long LastWriteTime; + + internal long ChangeTime; + + internal long AllocationSize; + + internal long EndOfFile; + + internal bool Directory; + + internal bool IsExtended; + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + OplockLevel = buffer[bufferIndex++]; + Fid = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + CreateAction = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + CreationTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + LastAccessTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + LastWriteTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + ChangeTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + ExtFileAttributes = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + AllocationSize = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + EndOfFile = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + FileType = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + DeviceState = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Directory = (buffer[bufferIndex++] & unchecked(0xFF)) > 0; + return bufferIndex - start; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComNTCreateAndXResponse[" + base.ToString() + ",oplockLevel=" + + OplockLevel + ",fid=" + Fid + ",createAction=0x" + Hexdump.ToHexString(CreateAction + , 4) + ",creationTime=" + Extensions.CreateDate(CreationTime) + ",lastAccessTime=" + + Extensions.CreateDate(LastAccessTime) + ",lastWriteTime=" + Extensions.CreateDate + (LastWriteTime) + ",changeTime=" + Extensions.CreateDate(ChangeTime) + ",extFileAttributes=0x" + + Hexdump.ToHexString(ExtFileAttributes, 4) + ",allocationSize=" + AllocationSize + + ",endOfFile=" + EndOfFile + ",fileType=" + FileType + ",deviceState=" + DeviceState + + ",directory=" + Directory + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNegotiate.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNegotiate.cs new file mode 100644 index 000000000..499bffbd9 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNegotiate.cs @@ -0,0 +1,70 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComNegotiate : ServerMessageBlock + { + private const string Dialects = "\u0002NT LM 0.12\u0000"; + + public SmbComNegotiate() + { + Command = SmbComNegotiate; + Flags2 = SmbConstants.DefaultFlags2; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + byte[] dialects; + try + { + //dialects = Runtime.GetBytesForString(Dialects, "ASCII"); + dialects = Runtime.GetBytesForString(Dialects, "UTF-8"); + } + catch (UnsupportedEncodingException) + { + return 0; + } + Array.Copy(dialects, 0, dst, dstIndex, dialects.Length); + return dialects.Length; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComNegotiate[" + base.ToString() + ",wordCount=" + WordCount + + ",dialects=NT LM 0.12]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNegotiateResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNegotiateResponse.cs new file mode 100644 index 000000000..c4cd1c129 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNegotiateResponse.cs @@ -0,0 +1,164 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComNegotiateResponse : ServerMessageBlock + { + internal int DialectIndex; + + internal SmbTransport.ServerData Server; + + internal SmbComNegotiateResponse(SmbTransport.ServerData server) + { + this.Server = server; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + DialectIndex = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if (DialectIndex > 10) + { + return bufferIndex - start; + } + Server.SecurityMode = buffer[bufferIndex++] & unchecked(0xFF); + Server.Security = Server.SecurityMode & unchecked(0x01); + Server.EncryptedPasswords = (Server.SecurityMode & unchecked(0x02)) == unchecked( + 0x02); + Server.SignaturesEnabled = (Server.SecurityMode & unchecked(0x04)) == unchecked( + 0x04); + Server.SignaturesRequired = (Server.SecurityMode & unchecked(0x08)) == unchecked( + 0x08); + Server.MaxMpxCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Server.MaxNumberVcs = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Server.MaxBufferSize = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + Server.MaxRawSize = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + Server.SessionKey = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + Server.Capabilities = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + Server.ServerTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + Server.ServerTimeZone = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Server.EncryptionKeyLength = buffer[bufferIndex++] & unchecked(0xFF); + return bufferIndex - start; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + int start = bufferIndex; + if ((Server.Capabilities & SmbConstants.CapExtendedSecurity) == 0) + { + Server.EncryptionKey = new byte[Server.EncryptionKeyLength]; + Array.Copy(buffer, bufferIndex, Server.EncryptionKey, 0, Server.EncryptionKeyLength + ); + bufferIndex += Server.EncryptionKeyLength; + if (ByteCount > Server.EncryptionKeyLength) + { + int len = 0; + // TODO: we can use new string routine here + try + { + if ((Flags2 & SmbConstants.Flags2Unicode) == SmbConstants.Flags2Unicode) + { + while (buffer[bufferIndex + len] != unchecked(unchecked(0x00)) || buffer + [bufferIndex + len + 1] != unchecked(unchecked(0x00))) + { + len += 2; + if (len > 256) + { + throw new RuntimeException("zero termination not found"); + } + } + Server.OemDomainName = Runtime.GetStringForBytes(buffer, bufferIndex, len + , SmbConstants.UniEncoding); + } + else + { + while (buffer[bufferIndex + len] != unchecked(unchecked(0x00))) + { + len++; + if (len > 256) + { + throw new RuntimeException("zero termination not found"); + } + } + Server.OemDomainName = Runtime.GetStringForBytes(buffer, bufferIndex, len + , SmbConstants.OemEncoding); + } + } + catch (UnsupportedEncodingException uee) + { + if (Log.Level > 1) + { + Runtime.PrintStackTrace(uee, Log); + } + } + bufferIndex += len; + } + else + { + Server.OemDomainName = ""; + } + } + else + { + Server.Guid = new byte[16]; + Array.Copy(buffer, bufferIndex, Server.Guid, 0, 16); + Server.OemDomainName = ""; + } + // ignore SPNEGO token for now ... + return bufferIndex - start; + } + + public override string ToString() + { + return "SmbComNegotiateResponse[" + base.ToString() + ",wordCount=" + + WordCount + ",dialectIndex=" + DialectIndex + ",securityMode=0x" + Hexdump.ToHexString + (Server.SecurityMode, 1) + ",security=" + (Server.Security == SmbConstants.SecurityShare ? "share" + : "user") + ",encryptedPasswords=" + Server.EncryptedPasswords + ",maxMpxCount=" + + Server.MaxMpxCount + ",maxNumberVcs=" + Server.MaxNumberVcs + ",maxBufferSize=" + + Server.MaxBufferSize + ",maxRawSize=" + Server.MaxRawSize + ",sessionKey=0x" + + Hexdump.ToHexString(Server.SessionKey, 8) + ",capabilities=0x" + Hexdump.ToHexString + (Server.Capabilities, 8) + ",serverTime=" + Extensions.CreateDate(Server + .ServerTime) + ",serverTimeZone=" + Server.ServerTimeZone + ",encryptionKeyLength=" + + Server.EncryptionKeyLength + ",byteCount=" + ByteCount + ",oemDomainName=" + + Server.OemDomainName + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNtTransaction.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNtTransaction.cs new file mode 100644 index 000000000..b5d2cf947 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNtTransaction.cs @@ -0,0 +1,93 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal abstract class SmbComNtTransaction : SmbComTransaction + { + private const int NttPrimarySetupOffset = 69; + + private const int NttSecondaryParameterOffset = 51; + + internal const int NtTransactQuerySecurityDesc = 6; + + internal int Function; + + public SmbComNtTransaction() + { + // relative to headerStart + primarySetupOffset = NttPrimarySetupOffset; + secondaryParameterOffset = NttSecondaryParameterOffset; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + if (Command != SmbComNtTransactSecondary) + { + dst[dstIndex++] = MaxSetupCount; + } + else + { + dst[dstIndex++] = unchecked(unchecked(0x00)); + } + // Reserved + dst[dstIndex++] = unchecked(unchecked(0x00)); + // Reserved + dst[dstIndex++] = unchecked(unchecked(0x00)); + // Reserved + WriteInt4(TotalParameterCount, dst, dstIndex); + dstIndex += 4; + WriteInt4(TotalDataCount, dst, dstIndex); + dstIndex += 4; + if (Command != SmbComNtTransactSecondary) + { + WriteInt4(MaxParameterCount, dst, dstIndex); + dstIndex += 4; + WriteInt4(MaxDataCount, dst, dstIndex); + dstIndex += 4; + } + WriteInt4(ParameterCount, dst, dstIndex); + dstIndex += 4; + WriteInt4((ParameterCount == 0 ? 0 : ParameterOffset), dst, dstIndex); + dstIndex += 4; + if (Command == SmbComNtTransactSecondary) + { + WriteInt4(ParameterDisplacement, dst, dstIndex); + dstIndex += 4; + } + WriteInt4(DataCount, dst, dstIndex); + dstIndex += 4; + WriteInt4((DataCount == 0 ? 0 : DataOffset), dst, dstIndex); + dstIndex += 4; + if (Command == SmbComNtTransactSecondary) + { + WriteInt4(DataDisplacement, dst, dstIndex); + dstIndex += 4; + dst[dstIndex++] = unchecked(unchecked(0x00)); + } + else + { + // Reserved1 + dst[dstIndex++] = unchecked((byte)SetupCount); + WriteInt2(Function, dst, dstIndex); + dstIndex += 2; + dstIndex += WriteSetupWireFormat(dst, dstIndex); + } + return dstIndex - start; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNtTransactionResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNtTransactionResponse.cs new file mode 100644 index 000000000..88d73528a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComNtTransactionResponse.cs @@ -0,0 +1,63 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal abstract class SmbComNtTransactionResponse : SmbComTransactionResponse + { + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + buffer[bufferIndex++] = unchecked(unchecked(0x00)); + // Reserved + buffer[bufferIndex++] = unchecked(unchecked(0x00)); + // Reserved + buffer[bufferIndex++] = unchecked(unchecked(0x00)); + // Reserved + TotalParameterCount = ReadInt4(buffer, bufferIndex); + if (BufDataStart == 0) + { + BufDataStart = TotalParameterCount; + } + bufferIndex += 4; + TotalDataCount = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + ParameterCount = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + ParameterOffset = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + ParameterDisplacement = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + DataCount = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + DataOffset = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + DataDisplacement = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + SetupCount = buffer[bufferIndex] & unchecked(0xFF); + bufferIndex += 2; + if (SetupCount != 0) + { + if (Log.Level >= 3) + { + Log.WriteLine("setupCount is not zero: " + SetupCount); + } + } + return bufferIndex - start; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComOpenAndX.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComOpenAndX.cs new file mode 100644 index 000000000..de11e2a6a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComOpenAndX.cs @@ -0,0 +1,190 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComOpenAndX : AndXServerMessageBlock + { + private const int FlagsReturnAdditionalInfo = 0x01; + + private const int FlagsRequestOplock = 0x02; + + private const int FlagsRequestBatchOplock = 0x04; + + private const int SharingCompatibility = 0x00; + + private const int SharingDenyReadWriteExecute = 0x10; + + private const int SharingDenyWrite = 0x20; + + private const int SharingDenyReadExecute = 0x30; + + private const int SharingDenyNone = 0x40; + + private const int DoNotCache = 0x1000; + + private const int WriteThrough = 0x4000; + + private const int OpenFnCreate = 0x10; + + private const int OpenFnFailIfExists = 0x00; + + private const int OpenFnOpen = 0x01; + + private const int OpenFnTrunc = 0x02; + + private static readonly int BatchLimit = Config.GetInt("jcifs.smb.client.OpenAndX.ReadAndX" + , 1); + + internal int flags; + + internal int DesiredAccess; + + internal int SearchAttributes; + + internal int FileAttributes; + + internal int CreationTime; + + internal int OpenFunction; + + internal int AllocationSize; + + internal SmbComOpenAndX(string fileName, int access, int flags, ServerMessageBlock + andx) : base(andx) + { + // flags (not the same as flags constructor argument) + // Access Mode Encoding for desiredAccess + // bit 12 + // bit 14 + // flags is NOT the same as flags member + Path = fileName; + Command = SmbComOpenAndx; + DesiredAccess = access & 0x3; + if (DesiredAccess == 0x3) + { + DesiredAccess = 0x2; + } + DesiredAccess |= SharingDenyNone; + DesiredAccess &= ~0x1; + // Win98 doesn't like GENERIC_READ ?! -- get Access Denied. + // searchAttributes + SearchAttributes = SmbConstants.AttrDirectory | SmbConstants.AttrHidden | SmbConstants.AttrSystem; + // fileAttributes + FileAttributes = 0; + // openFunction + if ((flags & SmbFile.OTrunc) == SmbFile.OTrunc) + { + // truncate the file + if ((flags & SmbFile.OCreat) == SmbFile.OCreat) + { + // create it if necessary + OpenFunction = OpenFnTrunc | OpenFnCreate; + } + else + { + OpenFunction = OpenFnTrunc; + } + } + else + { + // don't truncate the file + if ((flags & SmbFile.OCreat) == SmbFile.OCreat) + { + // create it if necessary + if ((flags & SmbFile.OExcl) == SmbFile.OExcl) + { + // fail if already exists + OpenFunction = OpenFnCreate | OpenFnFailIfExists; + } + else + { + OpenFunction = OpenFnCreate | OpenFnOpen; + } + } + else + { + OpenFunction = OpenFnOpen; + } + } + } + + internal override int GetBatchLimit(byte command) + { + return command == SmbComReadAndx ? BatchLimit : 0; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(flags, dst, dstIndex); + dstIndex += 2; + WriteInt2(DesiredAccess, dst, dstIndex); + dstIndex += 2; + WriteInt2(SearchAttributes, dst, dstIndex); + dstIndex += 2; + WriteInt2(FileAttributes, dst, dstIndex); + dstIndex += 2; + CreationTime = 0; + WriteInt4(CreationTime, dst, dstIndex); + dstIndex += 4; + WriteInt2(OpenFunction, dst, dstIndex); + dstIndex += 2; + WriteInt4(AllocationSize, dst, dstIndex); + dstIndex += 4; + for (int i = 0; i < 8; i++) + { + dst[dstIndex++] = 0x00; + } + return dstIndex - start; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + if (UseUnicode) + { + dst[dstIndex++] = (byte)('\0'); + } + dstIndex += WriteString(Path, dst, dstIndex); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComOpenAndX[" + base.ToString() + ",flags=0x" + Hexdump.ToHexString + (flags, 2) + ",desiredAccess=0x" + Hexdump.ToHexString(DesiredAccess, 4) + ",searchAttributes=0x" + + Hexdump.ToHexString(SearchAttributes, 4) + ",fileAttributes=0x" + Hexdump.ToHexString + (FileAttributes, 4) + ",creationTime=" + Extensions.CreateDate(CreationTime + ) + ",openFunction=0x" + Hexdump.ToHexString(OpenFunction, 2) + ",allocationSize=" + + AllocationSize + ",fileName=" + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComOpenAndXResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComOpenAndXResponse.cs new file mode 100644 index 000000000..9c49d19a8 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComOpenAndXResponse.cs @@ -0,0 +1,87 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComOpenAndXResponse : AndXServerMessageBlock + { + internal int Fid; + + internal int FileAttributes; + + internal int DataSize; + + internal int GrantedAccess; + + internal int FileType; + + internal int DeviceState; + + internal int Action; + + internal int ServerFid; + + internal long LastWriteTime; + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + Fid = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + FileAttributes = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + LastWriteTime = ReadUTime(buffer, bufferIndex); + bufferIndex += 4; + DataSize = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + GrantedAccess = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + FileType = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + DeviceState = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Action = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + ServerFid = ReadInt4(buffer, bufferIndex); + bufferIndex += 6; + return bufferIndex - start; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComOpenAndXResponse[" + base.ToString() + ",fid=" + Fid + ",fileAttributes=" + + FileAttributes + ",lastWriteTime=" + LastWriteTime + ",dataSize=" + DataSize + + ",grantedAccess=" + GrantedAccess + ",fileType=" + FileType + ",deviceState=" + + DeviceState + ",action=" + Action + ",serverFid=" + ServerFid + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComQueryInformation.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComQueryInformation.cs new file mode 100644 index 000000000..a528dbb11 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComQueryInformation.cs @@ -0,0 +1,57 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComQueryInformation : ServerMessageBlock + { + internal SmbComQueryInformation(string filename) + { + Path = filename; + Command = SmbComQueryInformation; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dst[dstIndex++] = 0x04; + dstIndex += WriteString(Path, dst, dstIndex); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComQueryInformation[" + base.ToString() + ",filename=" + Path + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComQueryInformationResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComQueryInformationResponse.cs new file mode 100644 index 000000000..040f081f0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComQueryInformationResponse.cs @@ -0,0 +1,95 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComQueryInformationResponse : ServerMessageBlock, IInfo + { + private int _fileAttributes = 0x0000; + + private long _lastWriteTime; + + private long _serverTimeZoneOffset; + + private int _fileSize; + + internal SmbComQueryInformationResponse(long serverTimeZoneOffset) + { + this._serverTimeZoneOffset = serverTimeZoneOffset; + Command = SmbComQueryInformation; + } + + public virtual int GetAttributes() + { + return _fileAttributes; + } + + public virtual long GetCreateTime() + { + return _lastWriteTime + _serverTimeZoneOffset; + } + + public virtual long GetLastWriteTime() + { + return _lastWriteTime + _serverTimeZoneOffset; + } + + public virtual long GetSize() + { + return _fileSize; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + if (WordCount == 0) + { + return 0; + } + _fileAttributes = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _lastWriteTime = ReadUTime(buffer, bufferIndex); + bufferIndex += 4; + _fileSize = ReadInt4(buffer, bufferIndex); + return 20; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComQueryInformationResponse[" + base.ToString() + ",fileAttributes=0x" + + Hexdump.ToHexString(_fileAttributes, 4) + ",lastWriteTime=" + Extensions.CreateDate + (_lastWriteTime) + ",fileSize=" + _fileSize + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComReadAndX.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComReadAndX.cs new file mode 100644 index 000000000..e75179700 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComReadAndX.cs @@ -0,0 +1,107 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComReadAndX : AndXServerMessageBlock + { + private static readonly int BatchLimit = Config.GetInt("jcifs.smb.client.ReadAndX.Close" + , 1); + + private long _offset; + + private int _fid; + + private int _openTimeout; + + internal int MaxCount; + + internal int MinCount; + + internal int Remaining; + + public SmbComReadAndX() : base(null) + { + Command = SmbComReadAndx; + _openTimeout = unchecked((int)(0xFFFFFFFF)); + } + + internal SmbComReadAndX(int fid, long offset, int maxCount, ServerMessageBlock andx + ) : base(andx) + { + this._fid = fid; + this._offset = offset; + this.MaxCount = MinCount = maxCount; + Command = SmbComReadAndx; + _openTimeout = unchecked((int)(0xFFFFFFFF)); + } + + internal virtual void SetParam(int fid, long offset, int maxCount) + { + this._fid = fid; + this._offset = offset; + this.MaxCount = MinCount = maxCount; + } + + internal override int GetBatchLimit(byte command) + { + return command == SmbComClose ? BatchLimit : 0; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_fid, dst, dstIndex); + dstIndex += 2; + WriteInt4(_offset, dst, dstIndex); + dstIndex += 4; + WriteInt2(MaxCount, dst, dstIndex); + dstIndex += 2; + WriteInt2(MinCount, dst, dstIndex); + dstIndex += 2; + WriteInt4(_openTimeout, dst, dstIndex); + dstIndex += 4; + WriteInt2(Remaining, dst, dstIndex); + dstIndex += 2; + WriteInt4(_offset >> 32, dst, dstIndex); + dstIndex += 4; + return dstIndex - start; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComReadAndX[" + base.ToString() + ",fid=" + _fid + ",offset=" + + _offset + ",maxCount=" + MaxCount + ",minCount=" + MinCount + ",openTimeout=" + + _openTimeout + ",remaining=" + Remaining + ",offset=" + _offset + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComReadAndXResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComReadAndXResponse.cs new file mode 100644 index 000000000..4d857aa2c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComReadAndXResponse.cs @@ -0,0 +1,87 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComReadAndXResponse : AndXServerMessageBlock + { + internal byte[] B; + + internal int Off; + + internal int DataCompactionMode; + + internal int DataLength; + + internal int DataOffset; + + public SmbComReadAndXResponse() + { + } + + internal SmbComReadAndXResponse(byte[] b, int off) + { + this.B = b; + this.Off = off; + } + + internal virtual void SetParam(byte[] b, int off) + { + this.B = b; + this.Off = off; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + bufferIndex += 2; + // reserved + DataCompactionMode = ReadInt2(buffer, bufferIndex); + bufferIndex += 4; + // 2 reserved + DataLength = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + DataOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 12; + // 10 reserved + return bufferIndex - start; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + // handled special in SmbTransport.doRecv() + return 0; + } + + public override string ToString() + { + return "SmbComReadAndXResponse[" + base.ToString() + ",dataCompactionMode=" + + DataCompactionMode + ",dataLength=" + DataLength + ",dataOffset=" + DataOffset + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComRename.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComRename.cs new file mode 100644 index 000000000..0ac57dd3e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComRename.cs @@ -0,0 +1,75 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class SmbComRename : ServerMessageBlock + { + private int _searchAttributes; + + private string _oldFileName; + + private string _newFileName; + + internal SmbComRename(string oldFileName, string newFileName) + { + Command = SmbComRename; + this._oldFileName = oldFileName; + this._newFileName = newFileName; + _searchAttributes = SmbConstants.AttrHidden | SmbConstants.AttrSystem | SmbConstants.AttrDirectory; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + WriteInt2(_searchAttributes, dst, dstIndex); + return 2; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dst[dstIndex++] = unchecked(unchecked(0x04)); + dstIndex += WriteString(_oldFileName, dst, dstIndex); + dst[dstIndex++] = unchecked(unchecked(0x04)); + if (UseUnicode) + { + dst[dstIndex++] = unchecked((byte)('\0')); + } + dstIndex += WriteString(_newFileName, dst, dstIndex); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComRename[" + base.ToString() + ",searchAttributes=0x" + Hexdump + .ToHexString(_searchAttributes, 4) + ",oldFileName=" + _oldFileName + ",newFileName=" + + _newFileName + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComSessionSetupAndX.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComSessionSetupAndX.cs new file mode 100644 index 000000000..a1642391c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComSessionSetupAndX.cs @@ -0,0 +1,234 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Ported to C# by J. Arturo <webmaster at komodosoft.net> +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComSessionSetupAndX : AndXServerMessageBlock + { + private static readonly int BatchLimit = Config.GetInt("jcifs.smb.client.SessionSetupAndX.TreeConnectAndX" + , 1); + + private static readonly bool DisablePlainTextPasswords = Config.GetBoolean("jcifs.smb.client.disablePlainTextPasswords" + , true); + + private byte[] _lmHash; + + private byte[] _ntHash; + + private byte[] _blob; + + private int _sessionKey; + + private int _capabilities; + + private string _accountName; + + private string _primaryDomain; + + internal SmbSession Session; + + internal object Cred; + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal SmbComSessionSetupAndX(SmbSession session, ServerMessageBlock andx, object + cred) : base(andx) + { + Command = SmbComSessionSetupAndx; + this.Session = session; + this.Cred = cred; + _sessionKey = session.transport.SessionKey; + _capabilities = session.transport.Capabilities; + if (session.transport.Server.Security == SmbConstants.SecurityUser) + { + if (cred is NtlmPasswordAuthentication) + { + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred; + if (auth == NtlmPasswordAuthentication.Anonymous) + { + _lmHash = new byte[0]; + _ntHash = new byte[0]; + _capabilities &= ~SmbConstants.CapExtendedSecurity; + } + else + { + if (session.transport.Server.EncryptedPasswords) + { + _lmHash = auth.GetAnsiHash(session.transport.Server.EncryptionKey); + _ntHash = auth.GetUnicodeHash(session.transport.Server.EncryptionKey); + // prohibit HTTP auth attempts for the null session + if (_lmHash.Length == 0 && _ntHash.Length == 0) + { + throw new RuntimeException("Null setup prohibited."); + } + } + else + { + if (DisablePlainTextPasswords) + { + throw new RuntimeException("Plain text passwords are disabled"); + } + if (UseUnicode) + { + // plain text + string password = auth.GetPassword(); + _lmHash = new byte[0]; + _ntHash = new byte[(password.Length + 1) * 2]; + WriteString(password, _ntHash, 0); + } + else + { + // plain text + string password = auth.GetPassword(); + _lmHash = new byte[(password.Length + 1) * 2]; + _ntHash = new byte[0]; + WriteString(password, _lmHash, 0); + } + } + } + _accountName = auth.Username; + if (UseUnicode) + { + _accountName = _accountName.ToUpper(); + } + _primaryDomain = auth.Domain.ToUpper(); + } + else + { + if (cred is byte[]) + { + _blob = (byte[])cred; + } + else + { + throw new SmbException("Unsupported credential type"); + } + } + } + else + { + if (session.transport.Server.Security == SmbConstants.SecurityShare) + { + if (cred is NtlmPasswordAuthentication) + { + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred; + _lmHash = new byte[0]; + _ntHash = new byte[0]; + _accountName = auth.Username; + if (UseUnicode) + { + _accountName = _accountName.ToUpper(); + } + _primaryDomain = auth.Domain.ToUpper(); + } + else + { + throw new SmbException("Unsupported credential type"); + } + } + else + { + throw new SmbException("Unsupported"); + } + } + } + + internal override int GetBatchLimit(byte command) + { + return command == SmbComTreeConnectAndx ? BatchLimit : 0; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(Session.transport.SndBufSize, dst, dstIndex); + dstIndex += 2; + WriteInt2(Session.transport.MaxMpxCount, dst, dstIndex); + dstIndex += 2; + WriteInt2(SmbConstants.VcNumber, dst, dstIndex); + dstIndex += 2; + WriteInt4(_sessionKey, dst, dstIndex); + dstIndex += 4; + if (_blob != null) + { + WriteInt2(_blob.Length, dst, dstIndex); + dstIndex += 2; + } + else + { + WriteInt2(_lmHash.Length, dst, dstIndex); + dstIndex += 2; + WriteInt2(_ntHash.Length, dst, dstIndex); + dstIndex += 2; + } + dst[dstIndex++] = unchecked(unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + WriteInt4(_capabilities, dst, dstIndex); + dstIndex += 4; + return dstIndex - start; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + if (_blob != null) + { + Array.Copy(_blob, 0, dst, dstIndex, _blob.Length); + dstIndex += _blob.Length; + } + else + { + Array.Copy(_lmHash, 0, dst, dstIndex, _lmHash.Length); + dstIndex += _lmHash.Length; + Array.Copy(_ntHash, 0, dst, dstIndex, _ntHash.Length); + dstIndex += _ntHash.Length; + dstIndex += WriteString(_accountName, dst, dstIndex); + dstIndex += WriteString(_primaryDomain, dst, dstIndex); + } + dstIndex += WriteString(SmbConstants.NativeOs, dst, dstIndex); + dstIndex += WriteString(SmbConstants.NativeLanman, dst, dstIndex); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + string result = "SmbComSessionSetupAndX[" + base.ToString() + ",snd_buf_size=" + + Session.transport.SndBufSize + ",maxMpxCount=" + Session.transport.MaxMpxCount + + ",VC_NUMBER=" + SmbConstants.VcNumber + ",sessionKey=" + _sessionKey + ",lmHash.length=" + + (_lmHash == null ? 0 : _lmHash.Length) + ",ntHash.length=" + (_ntHash == null ? + 0 : _ntHash.Length) + ",capabilities=" + _capabilities + ",accountName=" + _accountName + + ",primaryDomain=" + _primaryDomain + ",NATIVE_OS=" + SmbConstants.NativeOs + + ",NATIVE_LANMAN=" + SmbConstants.NativeLanman + "]"; + return result; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComSessionSetupAndXResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComSessionSetupAndXResponse.cs new file mode 100644 index 000000000..a3b80a669 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComSessionSetupAndXResponse.cs @@ -0,0 +1,92 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Smb +{ + internal class SmbComSessionSetupAndXResponse : AndXServerMessageBlock + { + private string _nativeOs = string.Empty; + + private string _nativeLanMan = string.Empty; + + private string _primaryDomain = string.Empty; + + internal bool IsLoggedInAsGuest; + + internal byte[] Blob; + + internal SmbComSessionSetupAndXResponse(ServerMessageBlock andx) : base(andx) + { + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + IsLoggedInAsGuest = (buffer[bufferIndex] & 0x01) == 0x01 ? true : false; + bufferIndex += 2; + if (ExtendedSecurity) + { + int blobLength = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Blob = new byte[blobLength]; + } + return bufferIndex - start; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + int start = bufferIndex; + if (ExtendedSecurity) + { + Array.Copy(buffer, bufferIndex, Blob, 0, Blob.Length); + bufferIndex += Blob.Length; + } + _nativeOs = ReadString(buffer, bufferIndex); + bufferIndex += StringWireLength(_nativeOs, bufferIndex); + _nativeLanMan = ReadString(buffer, bufferIndex, start + ByteCount, 255, UseUnicode + ); + bufferIndex += StringWireLength(_nativeLanMan, bufferIndex); + if (!ExtendedSecurity) + { + _primaryDomain = ReadString(buffer, bufferIndex, start + ByteCount, 255, UseUnicode + ); + bufferIndex += StringWireLength(_primaryDomain, bufferIndex); + } + return bufferIndex - start; + } + + public override string ToString() + { + string result = "SmbComSessionSetupAndXResponse[" + base.ToString() + + ",isLoggedInAsGuest=" + IsLoggedInAsGuest + ",nativeOs=" + _nativeOs + ",nativeLanMan=" + + _nativeLanMan + ",primaryDomain=" + _primaryDomain + "]"; + return result; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTransaction.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTransaction.cs new file mode 100644 index 000000000..b3aeaaf7d --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTransaction.cs @@ -0,0 +1,346 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal abstract class SmbComTransaction : ServerMessageBlock + { + private static readonly int DefaultMaxDataCount = Config.GetInt("jcifs.smb.client.transaction_buf_size" + , TransactionBufSize) - 512; + + private const int PrimarySetupOffset = 61; + + private const int SecondaryParameterOffset = 51; + + private const int DisconnectTid = unchecked(0x01); + + private const int OneWayTransaction = unchecked(0x02); + + private const int PaddingSize = 2; + + private int _flags = unchecked(0x00); + + private int _fid; + + private int _pad; + + private int _pad1; + + private bool _hasMore = true; + + private bool _isPrimary = true; + + private int _bufParameterOffset; + + private int _bufDataOffset; + + internal const int TransactionBufSize = unchecked(0xFFFF); + + internal const byte Trans2FindFirst2 = unchecked(unchecked(0x01)); + + internal const byte Trans2FindNext2 = unchecked(unchecked(0x02)); + + internal const byte Trans2QueryFsInformation = unchecked(unchecked(0x03)); + + internal const byte Trans2QueryPathInformation = unchecked(unchecked(0x05)); + + internal const byte Trans2GetDfsReferral = unchecked(unchecked(0x10)); + + internal const byte Trans2SetFileInformation = unchecked(unchecked(0x08)); + + internal const int NetShareEnum = unchecked(0x0000); + + internal const int NetServerEnum2 = unchecked(0x0068); + + internal const int NetServerEnum3 = unchecked(0x00D7); + + internal const byte TransPeekNamedPipe = unchecked(unchecked(0x23 + )); + + internal const byte TransWaitNamedPipe = unchecked(unchecked(0x53 + )); + + internal const byte TransCallNamedPipe = unchecked(unchecked(0x54 + )); + + internal const byte TransTransactNamedPipe = unchecked(unchecked(0x26)); + + protected internal int primarySetupOffset; + + protected internal int secondaryParameterOffset; + + protected internal int ParameterCount; + + protected internal int ParameterOffset; + + protected internal int ParameterDisplacement; + + protected internal int DataCount; + + protected internal int DataOffset; + + protected internal int DataDisplacement; + + internal int TotalParameterCount; + + internal int TotalDataCount; + + internal int MaxParameterCount; + + internal int MaxDataCount = DefaultMaxDataCount; + + internal byte MaxSetupCount; + + internal int Timeout = 0; + + internal int SetupCount = 1; + + internal byte SubCommand; + + internal string Name = string.Empty; + + internal int MaxBufferSize; + + internal byte[] TxnBuf; + + public SmbComTransaction() + { + // relative to headerStart + // set in SmbTransport.sendTransaction() before nextElement called + MaxParameterCount = 1024; + primarySetupOffset = PrimarySetupOffset; + secondaryParameterOffset = SecondaryParameterOffset; + } + + internal override void Reset() + { + base.Reset(); + _isPrimary = _hasMore = true; + } + + internal virtual void Reset(int key, string lastName) + { + Reset(); + } + + public virtual bool MoveNext() + { + return _hasMore; + } + + public virtual object Current() + { + if (_isPrimary) + { + _isPrimary = false; + ParameterOffset = primarySetupOffset + (SetupCount * 2) + 2; + if (Command != SmbComNtTransact) + { + if (Command == SmbComTransaction && IsResponse() == false) + { + ParameterOffset += StringWireLength(Name, ParameterOffset); + } + } + else + { + if (Command == SmbComNtTransact) + { + ParameterOffset += 2; + } + } + _pad = ParameterOffset % PaddingSize; + _pad = _pad == 0 ? 0 : PaddingSize - _pad; + ParameterOffset += _pad; + TotalParameterCount = WriteParametersWireFormat(TxnBuf, _bufParameterOffset); + _bufDataOffset = TotalParameterCount; + // data comes right after data + int available = MaxBufferSize - ParameterOffset; + ParameterCount = Math.Min(TotalParameterCount, available); + available -= ParameterCount; + DataOffset = ParameterOffset + ParameterCount; + _pad1 = DataOffset % PaddingSize; + _pad1 = _pad1 == 0 ? 0 : PaddingSize - _pad1; + DataOffset += _pad1; + TotalDataCount = WriteDataWireFormat(TxnBuf, _bufDataOffset); + DataCount = Math.Min(TotalDataCount, available); + } + else + { + if (Command != SmbComNtTransact) + { + Command = SmbComTransactionSecondary; + } + else + { + Command = SmbComNtTransactSecondary; + } + // totalParameterCount and totalDataCount are set ok from primary + ParameterOffset = SecondaryParameterOffset; + if ((TotalParameterCount - ParameterDisplacement) > 0) + { + _pad = ParameterOffset % PaddingSize; + _pad = _pad == 0 ? 0 : PaddingSize - _pad; + ParameterOffset += _pad; + } + // caclulate parameterDisplacement before calculating new parameterCount + ParameterDisplacement += ParameterCount; + int available = MaxBufferSize - ParameterOffset - _pad; + ParameterCount = Math.Min(TotalParameterCount - ParameterDisplacement, available); + available -= ParameterCount; + DataOffset = ParameterOffset + ParameterCount; + _pad1 = DataOffset % PaddingSize; + _pad1 = _pad1 == 0 ? 0 : PaddingSize - _pad1; + DataOffset += _pad1; + DataDisplacement += DataCount; + available -= _pad1; + DataCount = Math.Min(TotalDataCount - DataDisplacement, available); + } + if ((ParameterDisplacement + ParameterCount) >= TotalParameterCount && (DataDisplacement + + DataCount) >= TotalDataCount) + { + _hasMore = false; + } + return this; + + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(TotalParameterCount, dst, dstIndex); + dstIndex += 2; + WriteInt2(TotalDataCount, dst, dstIndex); + dstIndex += 2; + if (Command != SmbComTransactionSecondary) + { + WriteInt2(MaxParameterCount, dst, dstIndex); + dstIndex += 2; + WriteInt2(MaxDataCount, dst, dstIndex); + dstIndex += 2; + dst[dstIndex++] = MaxSetupCount; + dst[dstIndex++] = unchecked(unchecked(0x00)); + // Reserved1 + WriteInt2(_flags, dst, dstIndex); + dstIndex += 2; + WriteInt4(Timeout, dst, dstIndex); + dstIndex += 4; + dst[dstIndex++] = unchecked(unchecked(0x00)); + // Reserved2 + dst[dstIndex++] = unchecked(unchecked(0x00)); + } + WriteInt2(ParameterCount, dst, dstIndex); + dstIndex += 2; + // writeInt2(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex ); + WriteInt2(ParameterOffset, dst, dstIndex); + dstIndex += 2; + if (Command == SmbComTransactionSecondary) + { + WriteInt2(ParameterDisplacement, dst, dstIndex); + dstIndex += 2; + } + WriteInt2(DataCount, dst, dstIndex); + dstIndex += 2; + WriteInt2((DataCount == 0 ? 0 : DataOffset), dst, dstIndex); + dstIndex += 2; + if (Command == SmbComTransactionSecondary) + { + WriteInt2(DataDisplacement, dst, dstIndex); + dstIndex += 2; + } + else + { + dst[dstIndex++] = unchecked((byte)SetupCount); + dst[dstIndex++] = unchecked(unchecked(0x00)); + // Reserved3 + dstIndex += WriteSetupWireFormat(dst, dstIndex); + } + return dstIndex - start; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + int p = _pad; + if (Command == SmbComTransaction && IsResponse() == false) + { + dstIndex += WriteString(Name, dst, dstIndex); + } + if (ParameterCount > 0) + { + while (p-- > 0) + { + dst[dstIndex++] = unchecked(unchecked(0x00)); + } + // Pad + Array.Copy(TxnBuf, _bufParameterOffset, dst, dstIndex, ParameterCount); + dstIndex += ParameterCount; + } + if (DataCount > 0) + { + p = _pad1; + while (p-- > 0) + { + dst[dstIndex++] = unchecked(unchecked(0x00)); + } + // Pad1 + Array.Copy(TxnBuf, _bufDataOffset, dst, dstIndex, DataCount); + _bufDataOffset += DataCount; + dstIndex += DataCount; + } + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + internal abstract int WriteSetupWireFormat(byte[] dst, int dstIndex); + + internal abstract int WriteParametersWireFormat(byte[] dst, int dstIndex); + + internal abstract int WriteDataWireFormat(byte[] dst, int dstIndex); + + internal abstract int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ); + + internal abstract int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len); + + internal abstract int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len); + + public override string ToString() + { + return base.ToString() + ",totalParameterCount=" + TotalParameterCount + + ",totalDataCount=" + TotalDataCount + ",maxParameterCount=" + MaxParameterCount + + ",maxDataCount=" + MaxDataCount + ",maxSetupCount=" + (int)MaxSetupCount + ",flags=0x" + + Hexdump.ToHexString(_flags, 2) + ",timeout=" + Timeout + ",parameterCount=" + + ParameterCount + ",parameterOffset=" + ParameterOffset + ",parameterDisplacement=" + + ParameterDisplacement + ",dataCount=" + DataCount + ",dataOffset=" + DataOffset + + ",dataDisplacement=" + DataDisplacement + ",setupCount=" + SetupCount + ",pad=" + + _pad + ",pad1=" + _pad1; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTransactionResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTransactionResponse.cs new file mode 100644 index 000000000..35f87594d --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTransactionResponse.cs @@ -0,0 +1,206 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Smb +{ + internal abstract class SmbComTransactionResponse : ServerMessageBlock + { + private const int SetupOffset = 61; + + private const int DisconnectTid = unchecked(0x01); + + private const int OneWayTransaction = unchecked(0x02); + + private int _pad; + + private int _pad1; + + private bool _parametersDone; + + private bool _dataDone; + + protected internal int TotalParameterCount; + + protected internal int TotalDataCount; + + protected internal int ParameterCount; + + protected internal int ParameterOffset; + + protected internal int ParameterDisplacement; + + protected internal int DataOffset; + + protected internal int DataDisplacement; + + protected internal int SetupCount; + + protected internal int BufParameterStart; + + protected internal int BufDataStart; + + internal int DataCount; + + internal byte SubCommand; + + internal bool HasMore = true; + + internal bool IsPrimary = true; + + internal byte[] TxnBuf; + + internal int Status; + + internal int NumEntries; + + internal IFileEntry[] Results; + + public SmbComTransactionResponse() + { + // relative to headerStart + TxnBuf = null; + } + + internal override void Reset() + { + base.Reset(); + BufDataStart = 0; + IsPrimary = HasMore = true; + _parametersDone = _dataDone = false; + } + + public virtual bool MoveNext() + { + return ErrorCode == 0 && HasMore; + } + + public virtual object Current() + { + if (IsPrimary) + { + IsPrimary = false; + } + return this; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + TotalParameterCount = ReadInt2(buffer, bufferIndex); + if (BufDataStart == 0) + { + BufDataStart = TotalParameterCount; + } + bufferIndex += 2; + TotalDataCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 4; + // Reserved + ParameterCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + ParameterOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + ParameterDisplacement = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + DataCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + DataOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + DataDisplacement = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + SetupCount = buffer[bufferIndex] & unchecked(0xFF); + bufferIndex += 2; + if (SetupCount != 0) + { + if (Log.Level > 2) + { + Log.WriteLine("setupCount is not zero: " + SetupCount); + } + } + return bufferIndex - start; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + _pad = _pad1 = 0; + int n; + if (ParameterCount > 0) + { + bufferIndex += _pad = ParameterOffset - (bufferIndex - HeaderStart); + Array.Copy(buffer, bufferIndex, TxnBuf, BufParameterStart + ParameterDisplacement + , ParameterCount); + bufferIndex += ParameterCount; + } + if (DataCount > 0) + { + bufferIndex += _pad1 = DataOffset - (bufferIndex - HeaderStart); + Array.Copy(buffer, bufferIndex, TxnBuf, BufDataStart + DataDisplacement, + DataCount); + bufferIndex += DataCount; + } + if (!_parametersDone && (ParameterDisplacement + ParameterCount) == TotalParameterCount) + { + _parametersDone = true; + } + if (!_dataDone && (DataDisplacement + DataCount) == TotalDataCount) + { + _dataDone = true; + } + if (_parametersDone && _dataDone) + { + HasMore = false; + ReadParametersWireFormat(TxnBuf, BufParameterStart, TotalParameterCount); + ReadDataWireFormat(TxnBuf, BufDataStart, TotalDataCount); + } + return _pad + ParameterCount + _pad1 + DataCount; + } + + internal abstract int WriteSetupWireFormat(byte[] dst, int dstIndex); + + internal abstract int WriteParametersWireFormat(byte[] dst, int dstIndex); + + internal abstract int WriteDataWireFormat(byte[] dst, int dstIndex); + + internal abstract int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ); + + internal abstract int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len); + + internal abstract int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len); + + public override string ToString() + { + return base.ToString() + ",totalParameterCount=" + TotalParameterCount + + ",totalDataCount=" + TotalDataCount + ",parameterCount=" + ParameterCount + ",parameterOffset=" + + ParameterOffset + ",parameterDisplacement=" + ParameterDisplacement + ",dataCount=" + + DataCount + ",dataOffset=" + DataOffset + ",dataDisplacement=" + DataDisplacement + + ",setupCount=" + SetupCount + ",pad=" + _pad + ",pad1=" + _pad1; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeConnectAndX.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeConnectAndX.cs new file mode 100644 index 000000000..67ad04f5f --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeConnectAndX.cs @@ -0,0 +1,226 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComTreeConnectAndX : AndXServerMessageBlock + { + private static readonly bool DisablePlainTextPasswords = Config.GetBoolean("jcifs.smb.client.disablePlainTextPasswords" + , true); + + private SmbSession _session; + + private bool _disconnectTid = false; + + private string _service; + + private byte[] _password; + + private int _passwordLength; + + internal string path; + + private static byte[] _batchLimits = { 1, 1, 1, 1, 1, 1, 1, 1, 0 }; + + static SmbComTreeConnectAndX() + { + string s; + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.CheckDirectory")) != + null) + { + _batchLimits[0] = byte.Parse(s); + } + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.CreateDirectory")) + != null) + { + _batchLimits[2] = byte.Parse(s); + } + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.Delete")) != null) + { + _batchLimits[3] = byte.Parse(s); + } + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.DeleteDirectory")) + != null) + { + _batchLimits[4] = byte.Parse(s); + } + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.OpenAndX")) != null) + { + _batchLimits[5] = byte.Parse(s); + } + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.Rename")) != null) + { + _batchLimits[6] = byte.Parse(s); + } + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.Transaction")) != null) + { + _batchLimits[7] = byte.Parse(s); + } + if ((s = Config.GetProperty("jcifs.smb.client.TreeConnectAndX.QueryInformation")) + != null) + { + _batchLimits[8] = byte.Parse(s); + } + } + + internal SmbComTreeConnectAndX(SmbSession session, string path, string service, ServerMessageBlock + andx) : base(andx) + { + this._session = session; + this.path = path; + this._service = service; + Command = SmbComTreeConnectAndx; + } + + internal override int GetBatchLimit(byte command) + { + int c = command & unchecked(0xFF); + switch (c) + { + case SmbComCheckDirectory: + { + // why isn't this just return batchLimits[c]? + return _batchLimits[0]; + } + + case SmbComCreateDirectory: + { + return _batchLimits[2]; + } + + case SmbComDelete: + { + return _batchLimits[3]; + } + + case SmbComDeleteDirectory: + { + return _batchLimits[4]; + } + + case SmbComOpenAndx: + { + return _batchLimits[5]; + } + + case SmbComRename: + { + return _batchLimits[6]; + } + + case SmbComTransaction: + { + return _batchLimits[7]; + } + + case SmbComQueryInformation: + { + return _batchLimits[8]; + } + } + return 0; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + if (_session.transport.Server.Security == SmbConstants.SecurityShare && (_session.Auth.HashesExternal + || _session.Auth.Password.Length > 0)) + { + if (_session.transport.Server.EncryptedPasswords) + { + // encrypted + _password = _session.Auth.GetAnsiHash(_session.transport.Server.EncryptionKey); + _passwordLength = _password.Length; + } + else + { + if (DisablePlainTextPasswords) + { + throw new RuntimeException("Plain text passwords are disabled"); + } + // plain text + _password = new byte[(_session.Auth.Password.Length + 1) * 2]; + _passwordLength = WriteString(_session.Auth.Password, _password, 0); + } + } + else + { + // no password in tree connect + _passwordLength = 1; + } + dst[dstIndex++] = _disconnectTid ? unchecked((byte)unchecked(0x01)) : unchecked( + (byte)unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + WriteInt2(_passwordLength, dst, dstIndex); + return 4; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + if (_session.transport.Server.Security == SmbConstants.SecurityShare && (_session.Auth.HashesExternal + || _session.Auth.Password.Length > 0)) + { + Array.Copy(_password, 0, dst, dstIndex, _passwordLength); + dstIndex += _passwordLength; + } + else + { + // no password in tree connect + dst[dstIndex++] = unchecked(unchecked(0x00)); + } + dstIndex += WriteString(path, dst, dstIndex); + try + { +// Array.Copy(Runtime.GetBytesForString(_service, "ASCII"), 0, dst, dstIndex + //, _service.Length); + Array.Copy(Runtime.GetBytesForString(_service, "UTF-8"), 0, dst, dstIndex + , _service.Length); + } + catch (UnsupportedEncodingException) + { + return 0; + } + dstIndex += _service.Length; + dst[dstIndex++] = unchecked((byte)('\0')); + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + string result = "SmbComTreeConnectAndX[" + base.ToString() + ",disconnectTid=" + + _disconnectTid + ",passwordLength=" + _passwordLength + ",password=" + Hexdump. + ToHexString(_password, _passwordLength, 0) + ",path=" + path + ",service=" + _service + + "]"; + return result; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeConnectAndXResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeConnectAndXResponse.cs new file mode 100644 index 000000000..add660b26 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeConnectAndXResponse.cs @@ -0,0 +1,84 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class SmbComTreeConnectAndXResponse : AndXServerMessageBlock + { + private const int SmbSupportSearchBits = unchecked(0x0001); + + private const int SmbShareIsInDfs = unchecked(0x0002); + + internal bool SupportSearchBits; + + internal bool ShareIsInDfs; + + internal string Service; + + internal string NativeFileSystem = string.Empty; + + internal SmbComTreeConnectAndXResponse(ServerMessageBlock andx) : base(andx) + { + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + SupportSearchBits = (buffer[bufferIndex] & SmbSupportSearchBits) == SmbSupportSearchBits; + ShareIsInDfs = (buffer[bufferIndex] & SmbShareIsInDfs) == SmbShareIsInDfs; + return 2; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + int start = bufferIndex; + int len = ReadStringLength(buffer, bufferIndex, 32); + try + { + //Service = Runtime.GetStringForBytes(buffer, bufferIndex, len, "ASCII"); + Service = Runtime.GetStringForBytes(buffer, bufferIndex, len, "UTF-8"); + } + catch (UnsupportedEncodingException) + { + return 0; + } + bufferIndex += len + 1; + // win98 observed not returning nativeFileSystem + return bufferIndex - start; + } + + public override string ToString() + { + string result = "SmbComTreeConnectAndXResponse[" + base.ToString() + ",supportSearchBits=" + + SupportSearchBits + ",shareIsInDfs=" + ShareIsInDfs + ",service=" + Service + + ",nativeFileSystem=" + NativeFileSystem + "]"; + return result; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeDisconnect.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeDisconnect.cs new file mode 100644 index 000000000..d9eb5b2eb --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComTreeDisconnect.cs @@ -0,0 +1,52 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComTreeDisconnect : ServerMessageBlock + { + public SmbComTreeDisconnect() + { + Command = SmbComTreeDisconnect; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComTreeDisconnect[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWrite.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWrite.cs new file mode 100644 index 000000000..418a69d1d --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWrite.cs @@ -0,0 +1,106 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Smb +{ + internal class SmbComWrite : ServerMessageBlock + { + private int _fid; + + private int _count; + + private int _offset; + + private int _remaining; + + private int _off; + + private byte[] _b; + + public SmbComWrite() + { + Command = SmbComWrite; + } + + internal SmbComWrite(int fid, int offset, int remaining, byte[] b, int off, int len + ) + { + this._fid = fid; + _count = len; + this._offset = offset; + this._remaining = remaining; + this._b = b; + this._off = off; + Command = SmbComWrite; + } + + internal virtual void SetParam(int fid, long offset, int remaining, byte[] b, int + off, int len) + { + this._fid = fid; + this._offset = (int)(offset & unchecked(0xFFFFFFFFL)); + this._remaining = remaining; + this._b = b; + this._off = off; + _count = len; + Digest = null; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_fid, dst, dstIndex); + dstIndex += 2; + WriteInt2(_count, dst, dstIndex); + dstIndex += 2; + WriteInt4(_offset, dst, dstIndex); + dstIndex += 4; + WriteInt2(_remaining, dst, dstIndex); + dstIndex += 2; + return dstIndex - start; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + dst[dstIndex++] = 0x01; + WriteInt2(_count, dst, dstIndex); + dstIndex += 2; + Array.Copy(_b, _off, dst, dstIndex, _count); + dstIndex += _count; + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComWrite[" + base.ToString() + ",fid=" + _fid + ",count=" + + _count + ",offset=" + _offset + ",remaining=" + _remaining + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteAndX.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteAndX.cs new file mode 100644 index 000000000..b182fd7ff --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteAndX.cs @@ -0,0 +1,150 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Smb +{ + internal class SmbComWriteAndX : AndXServerMessageBlock + { + private static readonly int ReadAndxBatchLimit = Config.GetInt("jcifs.smb.client.WriteAndX.ReadAndX" + , 1); + + private static readonly int CloseBatchLimit = Config.GetInt("jcifs.smb.client.WriteAndX.Close" + , 1); + + private int _fid; + + private int _remaining; + + private int _dataLength; + + private int _dataOffset; + + private int _off; + + private byte[] _b; + + private long _offset; + + private int _pad; + + internal int WriteMode; + + public SmbComWriteAndX() : base(null) + { + Command = SmbComWriteAndx; + } + + internal SmbComWriteAndX(int fid, long offset, int remaining, byte[] b, int off, + int len, ServerMessageBlock andx) : base(andx) + { + this._fid = fid; + this._offset = offset; + this._remaining = remaining; + this._b = b; + this._off = off; + _dataLength = len; + Command = SmbComWriteAndx; + } + + internal virtual void SetParam(int fid, long offset, int remaining, byte[] b, int + off, int len) + { + this._fid = fid; + this._offset = offset; + this._remaining = remaining; + this._b = b; + this._off = off; + _dataLength = len; + Digest = null; + } + + internal override int GetBatchLimit(byte command) + { + if (command == SmbComReadAndx) + { + return ReadAndxBatchLimit; + } + if (command == SmbComClose) + { + return CloseBatchLimit; + } + return 0; + } + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + _dataOffset = (dstIndex - HeaderStart) + 26; + // 26 = off from here to pad + _pad = (_dataOffset - HeaderStart) % 4; + _pad = _pad == 0 ? 0 : 4 - _pad; + _dataOffset += _pad; + WriteInt2(_fid, dst, dstIndex); + dstIndex += 2; + WriteInt4(_offset, dst, dstIndex); + dstIndex += 4; + for (int i = 0; i < 4; i++) + { + dst[dstIndex++] = 0xFF; + } + WriteInt2(WriteMode, dst, dstIndex); + dstIndex += 2; + WriteInt2(_remaining, dst, dstIndex); + dstIndex += 2; + dst[dstIndex++] = 0x00; + dst[dstIndex++] =0x00; + WriteInt2(_dataLength, dst, dstIndex); + dstIndex += 2; + WriteInt2(_dataOffset, dst, dstIndex); + dstIndex += 2; + WriteInt4(_offset >> 32, dst, dstIndex); + dstIndex += 4; + return dstIndex - start; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + while (_pad-- > 0) + { + dst[dstIndex++] = 0xEE; + } + Array.Copy(_b, _off, dst, dstIndex, _dataLength); + dstIndex += _dataLength; + return dstIndex - start; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + return 0; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComWriteAndX[" + base.ToString() + ",fid=" + _fid + ",offset=" + + _offset + ",writeMode=" + WriteMode + ",remaining=" + _remaining + ",dataLength=" + + _dataLength + ",dataOffset=" + _dataOffset + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteAndXResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteAndXResponse.cs new file mode 100644 index 000000000..c6749b6cb --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteAndXResponse.cs @@ -0,0 +1,50 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComWriteAndXResponse : AndXServerMessageBlock + { + internal long Count; + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + Count = ReadInt2(buffer, bufferIndex) & unchecked(0xFFFFL); + return 8; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComWriteAndXResponse[" + base.ToString() + ",count=" + Count + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteResponse.cs new file mode 100644 index 000000000..785d406c1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbComWriteResponse.cs @@ -0,0 +1,50 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class SmbComWriteResponse : ServerMessageBlock + { + internal long Count; + + internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex + ) + { + Count = ReadInt2(buffer, bufferIndex) & unchecked(0xFFFFL); + return 8; + } + + internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) + { + return 0; + } + + public override string ToString() + { + return "SmbComWriteResponse[" + base.ToString() + ",count=" + Count + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbConstants.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbConstants.cs new file mode 100644 index 000000000..0793c7541 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbConstants.cs @@ -0,0 +1,302 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Collections.Generic; +using System.Net; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal static class SmbConstants + { + public static readonly int DefaultPort = 445; + + public static readonly int DefaultMaxMpxCount = 10; + + public static readonly int DefaultResponseTimeout = 30000; + + public static readonly int DefaultSoTimeout = 35000; + + public static readonly int DefaultRcvBufSize = 60416; + + public static readonly int DefaultSndBufSize = 16644; + + public static readonly int DefaultSsnLimit = 250; + + public static readonly int DefaultConnTimeout = 35000; + + public static readonly IPAddress Laddr = Config.GetLocalHost(); + + public static readonly int Lport = Config.GetInt("jcifs.smb.client.lport", 0); + + public static readonly int MaxMpxCount = Config.GetInt("jcifs.smb.client.maxMpxCount", DefaultMaxMpxCount + ); + + public static readonly int SndBufSize = Config.GetInt("jcifs.smb.client.snd_buf_size", DefaultSndBufSize + ); + + public static readonly int RcvBufSize = Config.GetInt("jcifs.smb.client.rcv_buf_size", DefaultRcvBufSize + ); + + public static readonly bool UseUnicode = Config.GetBoolean("jcifs.smb.client.useUnicode", + true); + + public static readonly bool ForceUnicode = Config.GetBoolean("jcifs.smb.client.useUnicode" + , false); + + public static readonly bool UseNtstatus = Config.GetBoolean("jcifs.smb.client.useNtStatus" + , true); + + public static readonly bool Signpref = Config.GetBoolean("jcifs.smb.client.signingPreferred" + , false); + + public static readonly bool UseNtsmbs = Config.GetBoolean("jcifs.smb.client.useNTSmbs", true + ); + + public static readonly bool UseExtsec = Config.GetBoolean("jcifs.smb.client.useExtendedSecurity" + , true); + + public static readonly string NetbiosHostname = Config.GetProperty("jcifs.netbios.hostname" + , null); + + public static readonly int LmCompatibility = Config.GetInt("jcifs.smb.lmCompatibility", 3); + + public static readonly int FlagsNone = unchecked(0x00); + + public static readonly int FlagsLockAndReadWriteAndUnlock = unchecked(0x01); + + public static readonly int FlagsReceiveBufferPosted = unchecked(0x02); + + public static readonly int FlagsPathNamesCaseless = unchecked(0x08); + + public static readonly int FlagsPathNamesCanonicalized = unchecked(0x10); + + public static readonly int FlagsOplockRequestedOrGranted = unchecked(0x20); + + public static readonly int FlagsNotifyOfModifyAction = unchecked(0x40); + + public static readonly int FlagsResponse = unchecked(0x80); + + public static readonly int Flags2None = unchecked(0x0000); + + public static readonly int Flags2LongFilenames = unchecked(0x0001); + + public static readonly int Flags2ExtendedAttributes = unchecked(0x0002); + + public static readonly int Flags2SecuritySignatures = unchecked(0x0004); + + public static readonly int Flags2ExtendedSecurityNegotiation = unchecked(0x0800); + + public static readonly int Flags2ResolvePathsInDfs = unchecked(0x1000); + + public static readonly int Flags2PermitReadIfExecutePerm = unchecked(0x2000); + + public static readonly int Flags2Status32 = unchecked(0x4000); + + public static readonly int Flags2Unicode = unchecked(0x8000); + + public static readonly int CapNone = unchecked(0x0000); + + public static readonly int CapRawMode = unchecked(0x0001); + + public static readonly int CapMpxMode = unchecked(0x0002); + + public static readonly int CapUnicode = unchecked(0x0004); + + public static readonly int CapLargeFiles = unchecked(0x0008); + + public static readonly int CapNtSmbs = unchecked(0x0010); + + public static readonly int CapRpcRemoteApis = unchecked(0x0020); + + public static readonly int CapStatus32 = unchecked(0x0040); + + public static readonly int CapLevelIiOplocks = unchecked(0x0080); + + public static readonly int CapLockAndRead = unchecked(0x0100); + + public static readonly int CapNtFind = unchecked(0x0200); + + public static readonly int CapDfs = unchecked(0x1000); + + public static readonly int CapExtendedSecurity = unchecked((int)(0x80000000)); + + public static readonly int AttrReadonly = unchecked(0x01); + + public static readonly int AttrHidden = unchecked(0x02); + + public static readonly int AttrSystem = unchecked(0x04); + + public static readonly int AttrVolume = unchecked(0x08); + + public static readonly int AttrDirectory = unchecked(0x10); + + public static readonly int AttrArchive = unchecked(0x20); + + public static readonly int AttrCompressed = unchecked(0x800); + + public static readonly int AttrNormal = unchecked(0x080); + + public static readonly int AttrTemporary = unchecked(0x100); + + public static readonly int FileReadData = unchecked(0x00000001); + + public static readonly int FileWriteData = unchecked(0x00000002); + + public static readonly int FileAppendData = unchecked(0x00000004); + + public static readonly int FileReadEa = unchecked(0x00000008); + + public static readonly int FileWriteEa = unchecked(0x00000010); + + public static readonly int FileExecute = unchecked(0x00000020); + + public static readonly int FileDelete = unchecked(0x00000040); + + public static readonly int FileReadAttributes = unchecked(0x00000080); + + public static readonly int FileWriteAttributes = unchecked(0x00000100); + + public static readonly int Delete = unchecked(0x00010000); + + public static readonly int ReadControl = unchecked(0x00020000); + + public static readonly int WriteDac = unchecked(0x00040000); + + public static readonly int WriteOwner = unchecked(0x00080000); + + public static readonly int Synchronize = unchecked(0x00100000); + + public static readonly int GenericAll = unchecked(0x10000000); + + public static readonly int GenericExecute = unchecked(0x20000000); + + public static readonly int GenericWrite = unchecked(0x40000000); + + public static readonly int GenericRead = unchecked((int)(0x80000000)); + + public static readonly int FlagsTargetMustBeFile = unchecked(0x0001); + + public static readonly int FlagsTargetMustBeDirectory = unchecked(0x0002); + + public static readonly int FlagsCopyTargetModeAscii = unchecked(0x0004); + + public static readonly int FlagsCopySourceModeAscii = unchecked(0x0008); + + public static readonly int FlagsVerifyAllWrites = unchecked(0x0010); + + public static readonly int FlagsTreeCopy = unchecked(0x0020); + + public static readonly int OpenFunctionFailIfExists = unchecked(0x0000); + + public static readonly int OpenFunctionOverwriteIfExists = unchecked(0x0020); + + public static readonly int Pid = (int)(new Random().NextDouble() * 65536d); + + public static readonly int SecurityShare = unchecked(0x00); + + public static readonly int SecurityUser = unchecked(0x01); + + public static readonly int CmdOffset = 4; + + public static readonly int ErrorCodeOffset = 5; + + public static readonly int FlagsOffset = 9; + + public static readonly int SignatureOffset = 14; + + public static readonly int TidOffset = 24; + + public static readonly int HeaderLength = 32; + + public static readonly long MillisecondsBetween1970And1601 = 11644473600000L; + + public static readonly TimeZoneInfo Tz = TimeZoneInfo.Local; + + public static readonly bool UseBatching = Config.GetBoolean("jcifs.smb.client.useBatching" + , true); + + public static readonly string OemEncoding = Config.GetProperty("jcifs.encoding", Config.DefaultOemEncoding + ); + + public static readonly string UniEncoding = "UTF-16LE"; + + public static readonly int DefaultFlags2 = Flags2LongFilenames | Flags2ExtendedAttributes + | (UseExtsec ? Flags2ExtendedSecurityNegotiation : 0) | (Signpref ? Flags2SecuritySignatures + : 0) | (UseNtstatus ? Flags2Status32 : 0) | (UseUnicode ? Flags2Unicode : 0 + ); + + public static readonly int DefaultCapabilities = (UseNtsmbs ? CapNtSmbs : 0) | (UseNtstatus + ? CapStatus32 : 0) | (UseUnicode ? CapUnicode : 0) | CapDfs; + + public static readonly int Flags2 = Config.GetInt("jcifs.smb.client.flags2", DefaultFlags2 + ); + + public static readonly int Capabilities = Config.GetInt("jcifs.smb.client.capabilities", DefaultCapabilities + ); + + public static readonly bool TcpNodelay = Config.GetBoolean("jcifs.smb.client.tcpNoDelay", + false); + + public static readonly int ResponseTimeout = Config.GetInt("jcifs.smb.client.responseTimeout" + , DefaultResponseTimeout); + + public static readonly List<SmbTransport> Connections = new List<SmbTransport>(); + + public static readonly int SsnLimit = Config.GetInt("jcifs.smb.client.ssnLimit", DefaultSsnLimit + ); + + public static readonly int SoTimeout = Config.GetInt("jcifs.smb.client.soTimeout", DefaultSoTimeout + ); + + public static readonly int ConnTimeout = Config.GetInt("jcifs.smb.client.connTimeout", DefaultConnTimeout + ); + + public static readonly string NativeOs = Config.GetProperty("jcifs.smb.client.nativeOs", Runtime + .GetProperty("os.name")); + + public static readonly string NativeLanman = Config.GetProperty("jcifs.smb.client.nativeLanMan" + , "jCIFS"); + + public static readonly int VcNumber = 1; + + public static SmbTransport NullTransport = new SmbTransport(null, 0, null, 0); + // file attribute encoding + // extended file attribute encoding(others same as above) + // access mask encoding + // 1 + // 2 + // 3 + // 4 + // 5 + // 6 + // 7 + // 8 + // 9 + // 16 + // 17 + // 18 + // 19 + // 20 + // 28 + // 29 + // 30 + // 31 + // flags for move and copy + // open function + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbException.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbException.cs new file mode 100644 index 000000000..ea8a0b846 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbException.cs @@ -0,0 +1,212 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + /// <summary> + /// There are hundreds of error codes that may be returned by a CIFS + /// server. + /// </summary> + /// <remarks> + /// There are hundreds of error codes that may be returned by a CIFS + /// server. Rather than represent each with it's own <code>Exception</code> + /// class, this class represents all of them. For many of the popular + /// error codes, constants and text messages like "The device is not ready" + /// are provided. + /// <p> + /// The jCIFS client maps DOS error codes to NTSTATUS codes. This means that + /// the user may recieve a different error from a legacy server than that of + /// a newer varient such as Windows NT and above. If you should encounter + /// such a case, please report it to jcifs at samba dot org and we will + /// change the mapping. + /// </remarks> + + public class SmbException : IOException + { + + internal static string GetMessageByCode(int errcode) + { + if (errcode == 0) + { + return "NT_STATUS_SUCCESS"; + } + if ((errcode & unchecked((int)(0xC0000000))) == unchecked((int)(0xC0000000))) + { + int min = 1; + int max = NtStatus.NtStatusCodes.Length - 1; + while (max >= min) + { + int mid = (min + max) / 2; + if (errcode > NtStatus.NtStatusCodes[mid]) + { + min = mid + 1; + } + else + { + if (errcode < NtStatus.NtStatusCodes[mid]) + { + max = mid - 1; + } + else + { + return NtStatus.NtStatusMessages[mid]; + } + } + } + } + else + { + int min = 0; + int max = DosError.DosErrorCodes.Length - 1; + while (max >= min) + { + int mid = (min + max) / 2; + if (errcode > DosError.DosErrorCodes[mid][0]) + { + min = mid + 1; + } + else + { + if (errcode < DosError.DosErrorCodes[mid][0]) + { + max = mid - 1; + } + else + { + return DosError.DosErrorMessages[mid]; + } + } + } + } + return "0x" + Hexdump.ToHexString(errcode, 8); + } + + internal static int GetStatusByCode(int errcode) + { + if ((errcode & unchecked((int)(0xC0000000))) != 0) + { + return errcode; + } + int min = 0; + int max = DosError.DosErrorCodes.Length - 1; + while (max >= min) + { + int mid = (min + max) / 2; + if (errcode > DosError.DosErrorCodes[mid][0]) + { + min = mid + 1; + } + else + { + if (errcode < DosError.DosErrorCodes[mid][0]) + { + max = mid - 1; + } + else + { + return DosError.DosErrorCodes[mid][1]; + } + } + } + return NtStatus.NtStatusUnsuccessful; + } + + internal static string GetMessageByWinerrCode(int errcode) + { + int min = 0; + int max = WinError.WinerrCodes.Length - 1; + while (max >= min) + { + int mid = (min + max) / 2; + if (errcode > WinError.WinerrCodes[mid]) + { + min = mid + 1; + } + else + { + if (errcode < WinError.WinerrCodes[mid]) + { + max = mid - 1; + } + else + { + return WinError.WinerrMessages[mid]; + } + } + } + return errcode + string.Empty; + } + + private int _status; + + private Exception _rootCause; + + public SmbException() + { + } + + internal SmbException(int errcode, Exception rootCause) : base(GetMessageByCode(errcode + )) + { + _status = GetStatusByCode(errcode); + this._rootCause = rootCause; + } + + public SmbException(string msg) : base(msg) + { + _status = NtStatus.NtStatusUnsuccessful; + } + + public SmbException(string msg, Exception rootCause) : base(msg) + { + this._rootCause = rootCause; + _status = NtStatus.NtStatusUnsuccessful; + } + + public SmbException(int errcode, bool winerr) : base(winerr ? GetMessageByWinerrCode + (errcode) : GetMessageByCode(errcode)) + { + _status = winerr ? errcode : GetStatusByCode(errcode); + } + + public virtual int GetNtStatus() + { + return _status; + } + + public virtual Exception GetRootCause() + { + return _rootCause; + } + + public override string ToString() + { + if (_rootCause != null) + { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Runtime.PrintStackTrace(_rootCause, pw); + return base.ToString() + "\n" + sw; + } + return base.ToString(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFile.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFile.cs new file mode 100644 index 000000000..151ec35c4 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFile.cs @@ -0,0 +1,3755 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using SharpCifs.Dcerpc; +using SharpCifs.Dcerpc.Msrpc; +using SharpCifs.Netbios; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + /// <summary>This class represents a resource on an SMB network.</summary> + /// <remarks> + /// This class represents a resource on an SMB network. Mainly these + /// resources are files and directories however an <code>SmbFile</code> + /// may also refer to servers and workgroups. If the resource is a file or + /// directory the methods of <code>SmbFile</code> follow the behavior of + /// the well known + /// <see cref="FilePath">Sharpen.FilePath</see> + /// class. One fundamental difference + /// is the usage of a URL scheme [1] to specify the target file or + /// directory. SmbFile URLs have the following syntax: + /// <blockquote><pre> + /// smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]] + /// </pre></blockquote> + /// This example: + /// <blockquote><pre> + /// smb://storage15/public/foo.txt + /// </pre></blockquote> + /// would reference the file <code>foo.txt</code> in the share + /// <code>public</code> on the server <code>storage15</code>. In addition + /// to referencing files and directories, jCIFS can also address servers, + /// and workgroups. + /// <p> + /// <font color="#800000"><i>Important: all SMB URLs that represent + /// workgroups, servers, shares, or directories require a trailing slash '/'. + /// </i></font> + /// <p> + /// When using the <tt>java.net.URL</tt> class with + /// 'smb://' URLs it is necessary to first call the static + /// <tt>jcifs.Config.registerSmbURLHandler();</tt> method. This is required + /// to register the SMB protocol handler. + /// <p> + /// The userinfo component of the SMB URL (<tt>domain;user:pass</tt>) must + /// be URL encoded if it contains reserved characters. According to RFC 2396 + /// these characters are non US-ASCII characters and most meta characters + /// however jCIFS will work correctly with anything but '@' which is used + /// to delimit the userinfo component from the server and '%' which is the + /// URL escape character itself. + /// <p> + /// The server + /// component may a traditional NetBIOS name, a DNS name, or IP + /// address. These name resolution mechanisms and their resolution order + /// can be changed (See <a href="../../../resolver.html">Setting Name + /// Resolution Properties</a>). The servername and path components are + /// not case sensitive but the domain, username, and password components + /// are. It is also likely that properties must be specified for jcifs + /// to function (See <a href="../../overview-summary.html#scp">Setting + /// JCIFS Properties</a>). Here are some examples of SMB URLs with brief + /// descriptions of what they do: + /// <p>[1] This URL scheme is based largely on the <i>SMB + /// Filesharing URL Scheme</i> IETF draft. + /// <p><table border="1" cellpadding="3" cellspacing="0" width="100%"> + /// <tr bgcolor="#ccccff"> + /// <td colspan="2"><b>SMB URL Examples</b></td> + /// <tr><td width="20%"><b>URL</b></td><td><b>Description</b></td></tr> + /// <tr><td width="20%"><code>smb://users-nyc;miallen:mypass@angus/tmp/</code></td><td> + /// This URL references a share called <code>tmp</code> on the server + /// <code>angus</code> as user <code>miallen</code> who's password is + /// <code>mypass</code>. + /// </td></tr> + /// <tr><td width="20%"> + /// <code>smb://Administrator:P%40ss@msmith1/c/WINDOWS/Desktop/foo.txt</code></td><td> + /// A relativly sophisticated example that references a file + /// <code>msmith1</code>'s desktop as user <code>Administrator</code>. Notice the '@' is URL encoded with the '%40' hexcode escape. + /// </td></tr> + /// <tr><td width="20%"><code>smb://angus/</code></td><td> + /// This references only a server. The behavior of some methods is different + /// in this context(e.g. you cannot <code>delete</code> a server) however + /// as you might expect the <code>list</code> method will list the available + /// shares on this server. + /// </td></tr> + /// <tr><td width="20%"><code>smb://myworkgroup/</code></td><td> + /// This syntactically is identical to the above example. However if + /// <code>myworkgroup</code> happends to be a workgroup(which is indeed + /// suggested by the name) the <code>list</code> method will return + /// a list of servers that have registered themselves as members of + /// <code>myworkgroup</code>. + /// </td></tr> + /// <tr><td width="20%"><code>smb://</code></td><td> + /// Just as <code>smb://server/</code> lists shares and + /// <code>smb://workgroup/</code> lists servers, the <code>smb://</code> + /// URL lists all available workgroups on a netbios LAN. Again, + /// in this context many methods are not valid and return default + /// values(e.g. <code>isHidden</code> will always return false). + /// </td></tr> + /// <tr><td width="20%"><code>smb://angus.foo.net/d/jcifs/pipes.doc</code></td><td> + /// The server name may also be a DNS name as it is in this example. See + /// <a href="../../../resolver.html">Setting Name Resolution Properties</a> + /// for details. + /// </td></tr> + /// <tr><td width="20%"><code>smb://192.168.1.15/ADMIN$/</code></td><td> + /// The server name may also be an IP address. See <a + /// href="../../../resolver.html">Setting Name Resolution Properties</a> + /// for details. + /// </td></tr> + /// <tr><td width="20%"> + /// <code>smb://domain;username:password@server/share/path/to/file.txt</code></td><td> + /// A prototypical example that uses all the fields. + /// </td></tr> + /// <tr><td width="20%"><code>smb://myworkgroup/angus/ <-- ILLEGAL </code></td><td> + /// Despite the hierarchial relationship between workgroups, servers, and + /// filesystems this example is not valid. + /// </td></tr> + /// <tr><td width="20%"> + /// <code>smb://server/share/path/to/dir <-- ILLEGAL </code></td><td> + /// URLs that represent workgroups, servers, shares, or directories require a trailing slash '/'. + /// </td></tr> + /// <tr><td width="20%"> + /// <code>smb://MYGROUP/?SERVER=192.168.10.15</code></td><td> + /// SMB URLs support some query string parameters. In this example + /// the <code>SERVER</code> parameter is used to override the + /// server name service lookup to contact the server 192.168.10.15 + /// (presumably known to be a master + /// browser) for the server list in workgroup <code>MYGROUP</code>. + /// </td></tr> + /// </table> + /// <p>A second constructor argument may be specified to augment the URL + /// for better programmatic control when processing many files under + /// a common base. This is slightly different from the corresponding + /// <code>java.io.File</code> usage; a '/' at the beginning of the second + /// parameter will still use the server component of the first parameter. The + /// examples below illustrate the resulting URLs when this second contructor + /// argument is used. + /// <p><table border="1" cellpadding="3" cellspacing="0" width="100%"> + /// <tr bgcolor="#ccccff"> + /// <td colspan="3"> + /// <b>Examples Of SMB URLs When Augmented With A Second Constructor Parameter</b></td> + /// <tr><td width="20%"> + /// <b>First Parameter</b></td><td><b>Second Parameter</b></td><td><b>Result</b></td></tr> + /// <tr><td width="20%"><code> + /// smb://host/share/a/b/ + /// </code></td><td width="20%"><code> + /// c/d/ + /// </code></td><td><code> + /// smb://host/share/a/b/c/d/ + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb://host/share/foo/bar/ + /// </code></td><td width="20%"><code> + /// /share2/zig/zag + /// </code></td><td><code> + /// smb://host/share2/zig/zag + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb://host/share/foo/bar/ + /// </code></td><td width="20%"><code> + /// ../zip/ + /// </code></td><td><code> + /// smb://host/share/foo/zip/ + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb://host/share/zig/zag + /// </code></td><td width="20%"><code> + /// smb://foo/bar/ + /// </code></td><td><code> + /// smb://foo/bar/ + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb://host/share/foo/ + /// </code></td><td width="20%"><code> + /// ../.././.././../foo/ + /// </code></td><td><code> + /// smb://host/foo/ + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb://host/share/zig/zag + /// </code></td><td width="20%"><code> + /// / + /// </code></td><td><code> + /// smb://host/ + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb://server/ + /// </code></td><td width="20%"><code> + /// ../ + /// </code></td><td><code> + /// smb://server/ + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb:// + /// </code></td><td width="20%"><code> + /// myworkgroup/ + /// </code></td><td><code> + /// smb://myworkgroup/ + /// </code></td></tr> + /// <tr><td width="20%"><code> + /// smb://myworkgroup/ + /// </code></td><td width="20%"><code> + /// angus/ + /// </code></td><td><code> + /// smb://myworkgroup/angus/ <-- ILLEGAL<br />(But if you first create an <tt>SmbFile</tt> with 'smb://workgroup/' and use and use it as the first parameter to a constructor that accepts it with a second <tt>String</tt> parameter jCIFS will factor out the 'workgroup'.) + /// </code></td></tr> + /// </table> + /// <p>Instances of the <code>SmbFile</code> class are immutable; that is, + /// once created, the abstract pathname represented by an SmbFile object + /// will never change. + /// </remarks> + /// <seealso cref="FilePath">Sharpen.FilePath</seealso> + public class SmbFile : UrlConnection + { + internal const int ORdonly = 0x01; + + internal const int OWronly = 0x02; + + internal const int ORdwr = 0x03; + + internal const int OAppend = 0x04; + + internal const int OCreat = 0x0010; + + internal const int OExcl = 0x0020; + + internal const int OTrunc = 0x0040; + + /// <summary> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients (including other threads making calls into jCIFS) + /// will not be permitted to access the target file and will receive "The + /// file is being accessed by another process" message. + /// </summary> + /// <remarks> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients (including other threads making calls into jCIFS) + /// will not be permitted to access the target file and will receive "The + /// file is being accessed by another process" message. + /// </remarks> + public const int FileNoShare = 0x00; + + /// <summary> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients will be permitted to read from the target file while + /// this file is open. + /// </summary> + /// <remarks> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients will be permitted to read from the target file while + /// this file is open. This constant may be logically OR'd with other share + /// access flags. + /// </remarks> + public const int FileShareRead = 0x01; + + /// <summary> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients will be permitted to write to the target file while + /// this file is open. + /// </summary> + /// <remarks> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients will be permitted to write to the target file while + /// this file is open. This constant may be logically OR'd with other share + /// access flags. + /// </remarks> + public const int FileShareWrite = 0x02; + + /// <summary> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients will be permitted to delete the target file while + /// this file is open. + /// </summary> + /// <remarks> + /// When specified as the <tt>shareAccess</tt> constructor parameter, + /// other SMB clients will be permitted to delete the target file while + /// this file is open. This constant may be logically OR'd with other share + /// access flags. + /// </remarks> + public const int FileShareDelete = 0x04; + + /// <summary> + /// A file with this bit on as returned by <tt>getAttributes()</tt> or set + /// with <tt>setAttributes()</tt> will be read-only + /// </summary> + public const int AttrReadonly = 0x01; + + /// <summary> + /// A file with this bit on as returned by <tt>getAttributes()</tt> or set + /// with <tt>setAttributes()</tt> will be hidden + /// </summary> + public const int AttrHidden = 0x02; + + /// <summary> + /// A file with this bit on as returned by <tt>getAttributes()</tt> or set + /// with <tt>setAttributes()</tt> will be a system file + /// </summary> + public const int AttrSystem = 0x04; + + /// <summary> + /// A file with this bit on as returned by <tt>getAttributes()</tt> is + /// a volume + /// </summary> + public const int AttrVolume = 0x08; + + /// <summary> + /// A file with this bit on as returned by <tt>getAttributes()</tt> is + /// a directory + /// </summary> + public const int AttrDirectory = 0x10; + + /// <summary> + /// A file with this bit on as returned by <tt>getAttributes()</tt> or set + /// with <tt>setAttributes()</tt> is an archived file + /// </summary> + public const int AttrArchive = 0x20; + + internal const int AttrCompressed = 0x800; + + internal const int AttrNormal = 0x080; + + internal const int AttrTemporary = 0x100; + + internal const int AttrGetMask = 0x7FFF; + + internal const int AttrSetMask = 0x30A7; + + internal const int DefaultAttrExpirationPeriod = 5000; + + internal static readonly int HashDot = ".".GetHashCode(); + + internal static readonly int HashDotDot = "..".GetHashCode(); + + //internal static LogStream log = LogStream.GetInstance(); + public LogStream Log + { + get { return LogStream.GetInstance(); } + } + + internal static long AttrExpirationPeriod; + + internal static bool IgnoreCopyToException; + + static SmbFile() + { + // Open Function Encoding + // create if the file does not exist + // fail if the file exists + // truncate if the file exists + // share access + // file attribute encoding + // extended file attribute encoding(others same as above) + /*try + { + Sharpen.Runtime.GetType("jcifs.Config"); + } + catch (TypeLoadException cnfe) + { + Sharpen.Runtime.PrintStackTrace(cnfe); + }*/ + + AttrExpirationPeriod = Config.GetLong("jcifs.smb.client.attrExpirationPeriod", DefaultAttrExpirationPeriod + ); + IgnoreCopyToException = Config.GetBoolean("jcifs.smb.client.ignoreCopyToException" + , true); + Dfs = new Dfs(); + } + + /// <summary> + /// Returned by + /// <see cref="GetType()">GetType()</see> + /// if the resource this <tt>SmbFile</tt> + /// represents is a regular file or directory. + /// </summary> + public const int TypeFilesystem = 0x01; + + /// <summary> + /// Returned by + /// <see cref="GetType()">GetType()</see> + /// if the resource this <tt>SmbFile</tt> + /// represents is a workgroup. + /// </summary> + public const int TypeWorkgroup = 0x02; + + /// <summary> + /// Returned by + /// <see cref="GetType()">GetType()</see> + /// if the resource this <tt>SmbFile</tt> + /// represents is a server. + /// </summary> + public const int TypeServer = 0x04; + + /// <summary> + /// Returned by + /// <see cref="GetType()">GetType()</see> + /// if the resource this <tt>SmbFile</tt> + /// represents is a share. + /// </summary> + public const int TypeShare = 0x08; + + /// <summary> + /// Returned by + /// <see cref="GetType()">GetType()</see> + /// if the resource this <tt>SmbFile</tt> + /// represents is a named pipe. + /// </summary> + public const int TypeNamedPipe = 0x10; + + /// <summary> + /// Returned by + /// <see cref="GetType()">GetType()</see> + /// if the resource this <tt>SmbFile</tt> + /// represents is a printer. + /// </summary> + public const int TypePrinter = 0x20; + + /// <summary> + /// Returned by + /// <see cref="GetType()">GetType()</see> + /// if the resource this <tt>SmbFile</tt> + /// represents is a communications device. + /// </summary> + public const int TypeComm = 0x40; + + private string _canon; + + private string _share; + + private long _createTime; + + private long _lastModified; + + private int _attributes; + + private long _attrExpiration; + + private long _size; + + private long _sizeExpiration; + + private bool _isExists; + + private int _shareAccess = FileShareRead | FileShareWrite | FileShareDelete; + + private bool _enableDfs = Config.GetBoolean("jcifs.smb.client.enabledfs", false); + + private SmbComBlankResponse _blankResp; + + private DfsReferral _dfsReferral; + + protected internal static Dfs Dfs; + + internal NtlmPasswordAuthentication Auth; + + internal SmbTree Tree; + + internal string Unc; + + internal int Fid; + + internal int Type; + + internal bool Opened; + + internal int TreeNum; + + public bool EnableDfs + { + get { return _enableDfs; } + set { _enableDfs = value; } + } + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such as + /// a file or directory. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such as + /// a file or directory. See the description and examples of smb URLs above. + /// </remarks> + /// <param name="url">A URL string</param> + /// <exception cref="System.UriFormatException"> + /// If the <code>parent</code> and <code>child</code> parameters + /// do not follow the prescribed syntax + /// </exception> + public SmbFile(string url) + : this(new Uri(url)) + { + } + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. The second parameter is a relative path from + /// the <code>parent SmbFile</code>. See the description above for examples + /// of using the second <code>name</code> parameter. + /// </remarks> + /// <param name="context">A base <code>SmbFile</code></param> + /// <param name="name">A path string relative to the <code>parent</code> paremeter</param> + /// <exception cref="System.UriFormatException"> + /// If the <code>parent</code> and <code>child</code> parameters + /// do not follow the prescribed syntax + /// </exception> + /// <exception cref="UnknownHostException">If the server or workgroup of the <tt>context</tt> file cannot be determined + /// </exception> + public SmbFile(SmbFile context, string name) + : this(context.IsWorkgroup0 + () ? new Uri("smb://" + name) : new Uri(context.Url.AbsoluteUri + name), + context.Auth) + { + + this._enableDfs = context.EnableDfs; + + if (!context.IsWorkgroup0()) + { + Addresses = context.Addresses; + + if (context._share != null) + { + Tree = context.Tree; + _dfsReferral = context._dfsReferral; + } + } + } + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. The second parameter is a relative path from + /// the <code>parent</code>. See the description above for examples of + /// using the second <code>chile</code> parameter. + /// </remarks> + /// <param name="context">A URL string</param> + /// <param name="name">A path string relative to the <code>context</code> paremeter</param> + /// <exception cref="System.UriFormatException"> + /// If the <code>context</code> and <code>name</code> parameters + /// do not follow the prescribed syntax + /// </exception> + /*public SmbFile(string context, string name) + : this(new Uri(new Uri(null, context), name)) + { + }*/ + + public SmbFile(string context, string name) + : this(new Uri(context + name)) + { + + } + + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. + /// </remarks> + /// <param name="url">A URL string</param> + /// <param name="auth">The credentials the client should use for authentication</param> + /// <exception cref="System.UriFormatException">If the <code>url</code> parameter does not follow the prescribed syntax + /// </exception> + public SmbFile(string url, NtlmPasswordAuthentication auth) + : this(new Uri(url, UriKind.RelativeOrAbsolute), + auth) + { + + } + + /// <summary>Constructs an SmbFile representing a file on an SMB network.</summary> + /// <remarks> + /// Constructs an SmbFile representing a file on an SMB network. The + /// <tt>shareAccess</tt> parameter controls what permissions other + /// clients have when trying to access the same file while this instance + /// is still open. This value is either <tt>FILE_NO_SHARE</tt> or any + /// combination of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>, + /// and <tt>FILE_SHARE_DELETE</tt> logically OR'd together. + /// </remarks> + /// <param name="url">A URL string</param> + /// <param name="auth">The credentials the client should use for authentication</param> + /// <param name="shareAccess">Specifies what access other clients have while this file is open. + /// </param> + /// <exception cref="System.UriFormatException">If the <code>url</code> parameter does not follow the prescribed syntax + /// </exception> + public SmbFile(string url, NtlmPasswordAuthentication auth, int shareAccess) + : this + (new Uri(url), auth) + { + // Initially null; set by getUncPath; dir must end with '/' + // Can be null + // For getDfsPath() and getServerWithDfs() + // Cannot be null + // Initially null + // Initially null; set by getUncPath; never ends with '/' + // Initially 0; set by open() + if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != + 0) + { + throw new RuntimeException("Illegal shareAccess parameter"); + } + this._shareAccess = shareAccess; + } + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. The second parameter is a relative path from + /// the <code>context</code>. See the description above for examples of + /// using the second <code>name</code> parameter. + /// </remarks> + /// <param name="context">A URL string</param> + /// <param name="name">A path string relative to the <code>context</code> paremeter</param> + /// <param name="auth">The credentials the client should use for authentication</param> + /// <exception cref="System.UriFormatException"> + /// If the <code>context</code> and <code>name</code> parameters + /// do not follow the prescribed syntax + /// </exception> + public SmbFile(string context, string name, NtlmPasswordAuthentication auth) + : this + (new Uri(context + name) + , auth) + { + + } + + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. The second parameter is a relative path from + /// the <code>context</code>. See the description above for examples of + /// using the second <code>name</code> parameter. The <tt>shareAccess</tt> + /// parameter controls what permissions other clients have when trying + /// to access the same file while this instance is still open. This + /// value is either <tt>FILE_NO_SHARE</tt> or any combination + /// of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>, and + /// <tt>FILE_SHARE_DELETE</tt> logically OR'd together. + /// </remarks> + /// <param name="context">A URL string</param> + /// <param name="name">A path string relative to the <code>context</code> paremeter</param> + /// <param name="auth">The credentials the client should use for authentication</param> + /// <param name="shareAccess">Specifies what access other clients have while this file is open. + /// </param> + /// <exception cref="System.UriFormatException"> + /// If the <code>context</code> and <code>name</code> parameters + /// do not follow the prescribed syntax + /// </exception> + public SmbFile(string context, string name, NtlmPasswordAuthentication auth, int + shareAccess) + : this(new Uri(context + name), auth) + { + if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != + 0) + { + throw new RuntimeException("Illegal shareAccess parameter"); + } + this._shareAccess = shareAccess; + } + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory. The second parameter is a relative path from + /// the <code>context</code>. See the description above for examples of + /// using the second <code>name</code> parameter. The <tt>shareAccess</tt> + /// parameter controls what permissions other clients have when trying + /// to access the same file while this instance is still open. This + /// value is either <tt>FILE_NO_SHARE</tt> or any combination + /// of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>, and + /// <tt>FILE_SHARE_DELETE</tt> logically OR'd together. + /// </remarks> + /// <param name="context">A base <code>SmbFile</code></param> + /// <param name="name">A path string relative to the <code>context</code> file path</param> + /// <param name="shareAccess">Specifies what access other clients have while this file is open. + /// </param> + /// <exception cref="System.UriFormatException"> + /// If the <code>context</code> and <code>name</code> parameters + /// do not follow the prescribed syntax + /// </exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFile(SmbFile context, string name, int shareAccess) + : this(context.IsWorkgroup0() ? new Uri("smb://" + name) : new Uri( + context.Url.AbsoluteUri + name), context.Auth) + { + if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != + 0) + { + throw new RuntimeException("Illegal shareAccess parameter"); + } + + if (!context.IsWorkgroup0()) + { + this.Addresses = context.Addresses; + + if (context._share != null || context.Tree != null) + { + Tree = context.Tree; + _dfsReferral = context._dfsReferral; + } + } + + this._shareAccess = shareAccess; + this._enableDfs = context.EnableDfs; + } + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory from a <tt>URL</tt> object. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory from a <tt>URL</tt> object. + /// </remarks> + /// <param name="url">The URL of the target resource</param> + protected SmbFile(Uri url) + : this(url, new NtlmPasswordAuthentication(url.GetUserInfo + ())) + { + } + + /// <summary> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory from a <tt>URL</tt> object and an + /// <tt>NtlmPasswordAuthentication</tt> object. + /// </summary> + /// <remarks> + /// Constructs an SmbFile representing a resource on an SMB network such + /// as a file or directory from a <tt>URL</tt> object and an + /// <tt>NtlmPasswordAuthentication</tt> object. + /// </remarks> + /// <param name="url">The URL of the target resource</param> + /// <param name="auth">The credentials the client should use for authentication</param> + public SmbFile(Uri url, NtlmPasswordAuthentication auth) + { + this.Auth = auth ?? new NtlmPasswordAuthentication(url.GetUserInfo()); + Url = url; + GetUncPath0(); + } + + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + /*internal SmbFile(Jcifs.Smb.SmbFile context, string name, int type, int attributes + , long createTime, long lastModified, long size) + : this(context.IsWorkgroup0() ? + new Uri(null, "smb://" + name + "/") : new Uri(context.url, + name + ((attributes & ATTR_DIRECTORY) > 0 ? "/" : string.Empty)))*/ + internal SmbFile(SmbFile context, string name, int type, int attributes + , long createTime, long lastModified, long size) + : this(context.IsWorkgroup0() ? + new Uri("smb://" + name + "/") : new Uri(context.Url.AbsoluteUri + + name + ((attributes & AttrDirectory) > 0 ? "/" : string.Empty))) + { + Auth = context.Auth; + if (context._share != null) + { + Tree = context.Tree; + _dfsReferral = context._dfsReferral; + } + int last = name.Length - 1; + if (name[last] == '/') + { + name = Runtime.Substring(name, 0, last); + } + if (context._share == null) + { + Unc = "\\"; + } + else + { + if (context.Unc.Equals("\\")) + { + Unc = '\\' + name; + } + else + { + Unc = context.Unc + '\\' + name; + } + } + + if (!context.IsWorkgroup0()) + { + Addresses = context.Addresses; + } + + this._enableDfs = context.EnableDfs; + + this.Type = type; + this._attributes = attributes; + this._createTime = createTime; + this._lastModified = lastModified; + this._size = size; + _isExists = true; + _attrExpiration = _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; + } + + private SmbComBlankResponse Blank_resp() + { + if (_blankResp == null) + { + _blankResp = new SmbComBlankResponse(); + } + return _blankResp; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void ResolveDfs(ServerMessageBlock request) + { + if (!_enableDfs) + { + Connect0(); + return; + } + + if (request is SmbComClose) + { + return; + } + Connect0(); + DfsReferral dr = Dfs.Resolve(Tree.Session.transport.TconHostName, Tree.Share, Unc + , Auth); + if (dr != null) + { + string service = null; + if (request != null) + { + switch (request.Command) + { + case ServerMessageBlock.SmbComTransaction: + case ServerMessageBlock.SmbComTransaction2: + { + switch (((SmbComTransaction)request).SubCommand & 0xFF) + { + case SmbComTransaction.Trans2GetDfsReferral: + { + break; + } + + default: + { + service = "A:"; + break; + } + } + break; + } + + default: + { + service = "A:"; + break; + } + } + } + DfsReferral start = dr; + SmbException se = null; + do + { + try + { + if (Log.Level >= 2) + { + Log.WriteLine("DFS redirect: " + dr); + } + UniAddress addr = UniAddress.GetByName(dr.Server); + SmbTransport trans = SmbTransport.GetSmbTransport(addr, Url.Port); + trans.Connect(); + Tree = trans.GetSmbSession(Auth).GetSmbTree(dr.Share, service); + if (dr != start && dr.Key != null) + { + dr.Map.Put(dr.Key, dr); + } + se = null; + break; + } + catch (IOException ioe) + { + if (ioe is SmbException) + { + se = (SmbException)ioe; + } + else + { + se = new SmbException(dr.Server, ioe); + } + } + dr = dr.Next; + } + while (dr != start); + if (se != null) + { + throw se; + } + if (Log.Level >= 3) + { + Log.WriteLine(dr); + } + _dfsReferral = dr; + if (dr.PathConsumed < 0) + { + dr.PathConsumed = 0; + } + else + { + if (dr.PathConsumed > Unc.Length) + { + dr.PathConsumed = Unc.Length; + } + } + string dunc = Runtime.Substring(Unc, dr.PathConsumed); + if (dunc.Equals(string.Empty)) + { + dunc = "\\"; + } + if (!dr.Path.Equals(string.Empty)) + { + dunc = "\\" + dr.Path + dunc; + } + Unc = dunc; + if (request != null && request.Path != null && request.Path.EndsWith("\\") && dunc + .EndsWith("\\") == false) + { + dunc += "\\"; + } + if (request != null) + { + request.Path = dunc; + request.Flags2 |= SmbConstants.Flags2ResolvePathsInDfs; + } + } + else + { + if (Tree.InDomainDfs && !(request is NtTransQuerySecurityDesc) && !(request is SmbComClose + ) && !(request is SmbComFindClose2)) + { + throw new SmbException(NtStatus.NtStatusNotFound, false); + } + if (request != null) + { + request.Flags2 &= ~SmbConstants.Flags2ResolvePathsInDfs; + } + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response + ) + { + for (; ; ) + { + ResolveDfs(request); + try + { + Tree.Send(request, response); + break; + } + catch (DfsReferral dre) + { + if (dre.ResolveHashes) + { + throw; + } + request.Reset(); + } + } + } + + internal static string QueryLookup(string query, string param) + { + char[] instr = query.ToCharArray(); + int i; + int ch; + int st; + int eq; + st = eq = 0; + for (i = 0; i < instr.Length; i++) + { + ch = instr[i]; + if (ch == '&') + { + if (eq > st) + { + string p = new string(instr, st, eq - st); + if (Runtime.EqualsIgnoreCase(p, param)) + { + eq++; + return new string(instr, eq, i - eq); + } + } + st = i + 1; + } + else + { + if (ch == '=') + { + eq = i; + } + } + } + if (eq > st) + { + string p = new string(instr, st, eq - st); + if (Runtime.EqualsIgnoreCase(p, param)) + { + eq++; + return new string(instr, eq, instr.Length - eq); + } + } + return null; + } + + internal UniAddress[] Addresses; + + internal int AddressIndex; + + /// <exception cref="UnknownHostException"></exception> + internal virtual UniAddress GetAddress() + { + if (AddressIndex == 0) + { + return GetFirstAddress(); + } + return Addresses[AddressIndex - 1]; + } + + /// <exception cref="UnknownHostException"></exception> + internal virtual UniAddress GetFirstAddress() + { + AddressIndex = 0; + string host = Url.GetHost(); + string path = Url.AbsolutePath; + string query = Url.GetQuery(); + + if (Addresses != null && Addresses.Length > 0) + { + return GetNextAddress(); + } + + if (query != null) + { + string server = QueryLookup(query, "server"); + if (!string.IsNullOrEmpty(server)) + { + Addresses = new UniAddress[1]; + Addresses[0] = UniAddress.GetByName(server); + return GetNextAddress(); + } + string address = QueryLookup(query, "address"); + if (!string.IsNullOrEmpty(address)) + { + byte[] ip = Extensions.GetAddressByName(address).GetAddressBytes(); + Addresses = new UniAddress[1]; + //addresses[0] = new UniAddress(IPAddress.Parse(host, ip)); + Addresses[0] = new UniAddress(IPAddress.Parse(host)); + return GetNextAddress(); + } + } + if (host.Length == 0) + { + try + { + NbtAddress addr = NbtAddress.GetByName(NbtAddress.MasterBrowserName, 0x01, null); + Addresses = new UniAddress[1]; + Addresses[0] = UniAddress.GetByName(addr.GetHostAddress()); + } + catch (UnknownHostException uhe) + { + NtlmPasswordAuthentication.InitDefaults(); + if (NtlmPasswordAuthentication.DefaultDomain.Equals("?")) + { + throw; + } + Addresses = UniAddress.GetAllByName(NtlmPasswordAuthentication.DefaultDomain, true + ); + } + } + else + { + if (path.Length == 0 || path.Equals("/")) + { + Addresses = UniAddress.GetAllByName(host, true); + } + else + { + Addresses = UniAddress.GetAllByName(host, false); + } + } + return GetNextAddress(); + } + + internal virtual UniAddress GetNextAddress() + { + UniAddress addr = null; + if (AddressIndex < Addresses.Length) + { + addr = Addresses[AddressIndex++]; + } + return addr; + } + + internal virtual bool HasNextAddress() + { + return AddressIndex < Addresses.Length; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Connect0() + { + try + { + Connect(); + } + catch (UnknownHostException uhe) + { + throw new SmbException("Failed to connect to server", uhe); + } + catch (SmbException se) + { + throw; + } + catch (IOException ioe) + { + throw new SmbException("Failed to connect to server", ioe); + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual void DoConnect() + { + SmbTransport trans; + UniAddress addr; + addr = GetAddress(); + + if (Tree != null && Tree.Session.transport.Address.Equals(addr)) + { + trans = Tree.Session.transport; + } + else + { + trans = SmbTransport.GetSmbTransport(addr, Url.Port); + Tree = trans.GetSmbSession(Auth).GetSmbTree(_share, null); + } + + + string hostName = GetServerWithDfs(); + if (_enableDfs) + { + Tree.InDomainDfs = Dfs.Resolve(hostName, Tree.Share, null, Auth) != null; + } + if (Tree.InDomainDfs) + { + Tree.ConnectionState = 2; + } + try + { + if (Log.Level >= 3) + { + Log.WriteLine("doConnect: " + addr); + } + Tree.TreeConnect(null, null); + } + catch (SmbAuthException sae) + { + NtlmPasswordAuthentication a; + SmbSession ssn; + if (_share == null) + { + // IPC$ - try "anonymous" credentials + ssn = trans.GetSmbSession(NtlmPasswordAuthentication.Null); + Tree = ssn.GetSmbTree(null, null); + Tree.TreeConnect(null, null); + } + else + { + if ((a = NtlmAuthenticator.RequestNtlmPasswordAuthentication(Url.ToString(), sae) + ) != null) + { + Auth = a; + ssn = trans.GetSmbSession(Auth); + Tree = ssn.GetSmbTree(_share, null); + Tree.InDomainDfs = Dfs.Resolve(hostName, Tree.Share, null, Auth) != null; + if (Tree.InDomainDfs) + { + Tree.ConnectionState = 2; + } + Tree.TreeConnect(null, null); + } + else + { + if (Log.Level >= 1 && HasNextAddress()) + { + Runtime.PrintStackTrace(sae, Log); + } + throw; + } + } + } + } + + /// <summary>It is not necessary to call this method directly.</summary> + /// <remarks> + /// It is not necessary to call this method directly. This is the + /// <tt>URLConnection</tt> implementation of <tt>connect()</tt>. + /// </remarks> + /// <exception cref="System.IO.IOException"></exception> + public void Connect() + { + SmbTransport trans; + SmbSession ssn; + UniAddress addr; + if (IsConnected()) + { + return; + } + GetUncPath0(); + GetFirstAddress(); + for (; ; ) + { + try + { + DoConnect(); + return; + } + catch (SmbAuthException sae) + { + throw; + } + catch (SmbException se) + { + // Prevents account lockout on servers with multiple IPs + if (GetNextAddress() == null) + { + throw; + } + else + { + RemoveCurrentAddress(); + } + + if (Log.Level >= 3) + { + Runtime.PrintStackTrace(se, Log); + } + } + } + } + + internal virtual bool IsConnected() + { + return Tree != null && Tree.ConnectionState == 2; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual int Open0(int flags, int access, int attrs, int options) + { + int f; + Connect0(); + if (Log.Level >= 3) + { + Log.WriteLine("open0: " + Unc); + } + if (Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs)) + { + SmbComNtCreateAndXResponse response = new SmbComNtCreateAndXResponse(); + SmbComNtCreateAndX request = new SmbComNtCreateAndX(Unc, flags, access, _shareAccess + , attrs, options, null); + if (this is SmbNamedPipe) + { + request.Flags0 |= 0x16; + request.DesiredAccess |= 0x20000; + response.IsExtended = true; + } + Send(request, response); + f = response.Fid; + _attributes = response.ExtFileAttributes & AttrGetMask; + _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; + _isExists = true; + } + else + { + SmbComOpenAndXResponse response = new SmbComOpenAndXResponse(); + Send(new SmbComOpenAndX(Unc, access, flags, null), response); + f = response.Fid; + } + return f; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Open(int flags, int access, int attrs, int options) + { + if (IsOpen()) + { + return; + } + Fid = Open0(flags, access, attrs, options); + Opened = true; + TreeNum = Tree.TreeNum; + } + + internal virtual bool IsOpen() + { + bool ans = Opened && IsConnected() && TreeNum == Tree.TreeNum; + return ans; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Close(int f, long lastWriteTime) + { + if (Log.Level >= 3) + { + Log.WriteLine("close: " + f); + } + Send(new SmbComClose(f, lastWriteTime), Blank_resp()); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Close(long lastWriteTime) + { + if (IsOpen() == false) + { + return; + } + Close(Fid, lastWriteTime); + Opened = false; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Close() + { + Close(0L); + } + + /// <summary> + /// Returns the <tt>NtlmPasswordAuthentication</tt> object used as + /// credentials with this file or pipe. + /// </summary> + /// <remarks> + /// Returns the <tt>NtlmPasswordAuthentication</tt> object used as + /// credentials with this file or pipe. This can be used to retrieve the + /// username for example: + /// <tt> + /// String username = f.getPrincipal().getName(); + /// </tt> + /// The <tt>Principal</tt> object returned will never be <tt>null</tt> + /// however the username can be <tt>null</tt> indication anonymous + /// credentials were used (e.g. some IPC$ services). + /// </remarks> + public virtual Principal GetPrincipal() + { + return Auth; + } + + /// <summary>Returns the last component of the target URL.</summary> + /// <remarks> + /// Returns the last component of the target URL. This will + /// effectively be the name of the file or directory represented by this + /// <code>SmbFile</code> or in the case of URLs that only specify a server + /// or workgroup, the server or workgroup will be returned. The name of + /// the root URL <code>smb://</code> is also <code>smb://</code>. If this + /// <tt>SmbFile</tt> refers to a workgroup, server, share, or directory, + /// the name will include a trailing slash '/' so that composing new + /// <tt>SmbFile</tt>s will maintain the trailing slash requirement. + /// </remarks> + /// <returns> + /// The last component of the URL associated with this SMB + /// resource or <code>smb://</code> if the resource is <code>smb://</code> + /// itself. + /// </returns> + public virtual string GetName() + { + GetUncPath0(); + if (_canon.Length > 1) + { + int i = _canon.Length - 2; + while (_canon[i] != '/') + { + i--; + } + return Runtime.Substring(_canon, i + 1); + } + if (_share != null) + { + return _share + '/'; + } + if (Url.GetHost().Length > 0) + { + return Url.GetHost() + '/'; + } + return "smb://"; + } + + /// <summary> + /// Everything but the last component of the URL representing this SMB + /// resource is effectivly it's parent. + /// </summary> + /// <remarks> + /// Everything but the last component of the URL representing this SMB + /// resource is effectivly it's parent. The root URL <code>smb://</code> + /// does not have a parent. In this case <code>smb://</code> is returned. + /// </remarks> + /// <returns> + /// The parent directory of this SMB resource or + /// <code>smb://</code> if the resource refers to the root of the URL + /// hierarchy which incedentally is also <code>smb://</code>. + /// </returns> + public virtual string GetParent() + { + string str = Url.Authority; + if (str.Length > 0) + { + StringBuilder sb = new StringBuilder("smb://"); + sb.Append(str); + GetUncPath0(); + if (_canon.Length > 1) + { + sb.Append(_canon); + } + else + { + sb.Append('/'); + } + str = sb.ToString(); + int i = str.Length - 2; + while (str[i] != '/') + { + i--; + } + return Runtime.Substring(str, 0, i + 1); + } + return "smb://"; + } + + /// <summary>Returns the full uncanonicalized URL of this SMB resource.</summary> + /// <remarks> + /// Returns the full uncanonicalized URL of this SMB resource. An + /// <code>SmbFile</code> constructed with the result of this method will + /// result in an <code>SmbFile</code> that is equal to the original. + /// </remarks> + /// <returns>The uncanonicalized full URL of this SMB resource.</returns> + public virtual string GetPath() + { + return Url.ToString(); + } + + internal virtual string GetUncPath0() + { + if (Unc == null) + { + char[] instr = Url.LocalPath.ToCharArray(); + char[] outstr = new char[instr.Length]; + int length = instr.Length; + int i; + int o; + int state; + + state = 0; + o = 0; + for (i = 0; i < length; i++) + { + switch (state) + { + case 0: + { + if (instr[i] != '/') + { + return null; + } + outstr[o++] = instr[i]; + state = 1; + break; + } + + case 1: + { + if (instr[i] == '/') + { + break; + } + if (instr[i] == '.' && ((i + 1) >= length || instr[i + 1] == '/')) + { + i++; + break; + } + if ((i + 1) < length && instr[i] == '.' && instr[i + 1] == '.' && ((i + 2) >= length + || instr[i + 2] == '/')) + { + i += 2; + if (o == 1) + { + break; + } + do + { + o--; + } + while (o > 1 && outstr[o - 1] != '/'); + break; + } + state = 2; + goto case 2; + } + + case 2: + { + if (instr[i] == '/') + { + state = 1; + } + outstr[o++] = instr[i]; + break; + } + } + } + _canon = new string(outstr, 0, o); + if (o > 1) + { + o--; + i = _canon.IndexOf('/', 1); + if (i < 0) + { + _share = Runtime.Substring(_canon, 1); + Unc = "\\"; + } + else + { + if (i == o) + { + _share = Runtime.Substring(_canon, 1, i); + Unc = "\\"; + } + else + { + _share = Runtime.Substring(_canon, 1, i); + Unc = Runtime.Substring(_canon, i, outstr[o] == '/' ? o : o + 1); + Unc = Unc.Replace('/', '\\'); + } + } + } + else + { + _share = null; + Unc = "\\"; + } + } + return Unc; + } + + /// <summary>Retuns the Windows UNC style path with backslashs intead of forward slashes. + /// </summary> + /// <remarks>Retuns the Windows UNC style path with backslashs intead of forward slashes. + /// </remarks> + /// <returns>The UNC path.</returns> + public virtual string GetUncPath() + { + GetUncPath0(); + if (_share == null) + { + return "\\\\" + Url.GetHost(); + } + return "\\\\" + Url.GetHost() + _canon.Replace('/', '\\'); + } + + /// <summary> + /// Returns the full URL of this SMB resource with '.' and '..' components + /// factored out. + /// </summary> + /// <remarks> + /// Returns the full URL of this SMB resource with '.' and '..' components + /// factored out. An <code>SmbFile</code> constructed with the result of + /// this method will result in an <code>SmbFile</code> that is equal to + /// the original. + /// </remarks> + /// <returns>The canonicalized URL of this SMB resource.</returns> + public virtual string GetCanonicalPath() + { + string str = Url.Authority; + GetUncPath0(); + if (str.Length > 0) + { + return "smb://" + Url.Authority + _canon; + } + return "smb://"; + } + + /// <summary>Retrieves the share associated with this SMB resource.</summary> + /// <remarks> + /// Retrieves the share associated with this SMB resource. In + /// the case of <code>smb://</code>, <code>smb://workgroup/</code>, + /// and <code>smb://server/</code> URLs which do not specify a share, + /// <code>null</code> will be returned. + /// </remarks> + /// <returns>The share component or <code>null</code> if there is no share</returns> + public virtual string GetShare() + { + return _share; + } + + internal virtual string GetServerWithDfs() + { + if (_dfsReferral != null) + { + return _dfsReferral.Server; + } + return GetServer(); + } + + /// <summary>Retrieve the hostname of the server for this SMB resource.</summary> + /// <remarks> + /// Retrieve the hostname of the server for this SMB resource. If this + /// <code>SmbFile</code> references a workgroup, the name of the workgroup + /// is returned. If this <code>SmbFile</code> refers to the root of this + /// SMB network hierarchy, <code>null</code> is returned. + /// </remarks> + /// <returns> + /// The server or workgroup name or <code>null</code> if this + /// <code>SmbFile</code> refers to the root <code>smb://</code> resource. + /// </returns> + public virtual string GetServer() + { + string str = Url.GetHost(); + if (str.Length == 0) + { + return null; + } + return str; + } + + /// <summary>Returns type of of object this <tt>SmbFile</tt> represents.</summary> + /// <remarks>Returns type of of object this <tt>SmbFile</tt> represents.</remarks> + /// <returns> + /// <tt>TYPE_FILESYSTEM, TYPE_WORKGROUP, TYPE_SERVER, TYPE_SHARE, + /// TYPE_PRINTER, TYPE_NAMED_PIPE</tt>, or <tt>TYPE_COMM</tt>. + /// </returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public new virtual int GetType() + { + if (Type == 0) + { + if (GetUncPath0().Length > 1) + { + Type = TypeFilesystem; + } + else + { + if (_share != null) + { + // treeConnect good enough to test service type + Connect0(); + if (_share.Equals("IPC$")) + { + Type = TypeNamedPipe; + } + else + { + if (Tree.Service.Equals("LPT1:")) + { + Type = TypePrinter; + } + else + { + if (Tree.Service.Equals("COMM")) + { + Type = TypeComm; + } + else + { + Type = TypeShare; + } + } + } + } + else + { + if (string.IsNullOrEmpty(Url.Authority)) + { + Type = TypeWorkgroup; + } + else + { + UniAddress addr; + try + { + addr = GetAddress(); + } + catch (UnknownHostException uhe) + { + throw new SmbException(Url.ToString(), uhe); + } + if (addr.GetAddress() is NbtAddress) + { + int code = ((NbtAddress)addr.GetAddress()).GetNameType(); + if (code == 0x1d || code == 0x1b) + { + Type = TypeWorkgroup; + return Type; + } + } + Type = TypeServer; + } + } + } + } + return Type; + } + + /// <exception cref="UnknownHostException"></exception> + internal virtual bool IsWorkgroup0() + { + if (Type == TypeWorkgroup || Url.GetHost().Length == 0) + { + Type = TypeWorkgroup; + return true; + } + GetUncPath0(); + if (_share == null) + { + UniAddress addr = GetAddress(); + if (addr.GetAddress() is NbtAddress) + { + int code = ((NbtAddress)addr.GetAddress()).GetNameType(); + if (code == 0x1d || code == 0x1b) + { + Type = TypeWorkgroup; + return true; + } + } + Type = TypeServer; + } + return false; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual IInfo QueryPath(string path, int infoLevel) + { + Connect0(); + if (Log.Level >= 3) + { + Log.WriteLine("queryPath: " + path); + } + if (Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs)) + { + Trans2QueryPathInformationResponse response = new Trans2QueryPathInformationResponse + (infoLevel); + Send(new Trans2QueryPathInformation(path, infoLevel), response); + return response.Info; + } + else + { + SmbComQueryInformationResponse response = new SmbComQueryInformationResponse(Tree + .Session.transport.Server.ServerTimeZone * 1000 * 60L); + Send(new SmbComQueryInformation(path), response); + return response; + } + } + + /// <summary>Tests to see if the SMB resource exists.</summary> + /// <remarks> + /// Tests to see if the SMB resource exists. If the resource refers + /// only to a server, this method determines if the server exists on the + /// network and is advertising SMB services. If this resource refers to + /// a workgroup, this method determines if the workgroup name is valid on + /// the local SMB network. If this <code>SmbFile</code> refers to the root + /// <code>smb://</code> resource <code>true</code> is always returned. If + /// this <code>SmbFile</code> is a traditional file or directory, it will + /// be queried for on the specified server as expected. + /// </remarks> + /// <returns> + /// <code>true</code> if the resource exists or is alive or + /// <code>false</code> otherwise + /// </returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual bool Exists() + { + if (_attrExpiration > Runtime.CurrentTimeMillis()) + { + return _isExists; + } + _attributes = AttrReadonly | AttrDirectory; + _createTime = 0L; + _lastModified = 0L; + _isExists = false; + try + { + if (Url.GetHost().Length == 0) + { + } + else + { + if (_share == null) + { + if (GetType() == TypeWorkgroup) + { + UniAddress.GetByName(Url.GetHost(), true); + } + else + { + UniAddress.GetByName(Url.GetHost()).GetHostName(); + } + } + else + { + if (GetUncPath0().Length == 1 || Runtime.EqualsIgnoreCase(_share, "IPC$")) + { + Connect0(); + } + else + { + // treeConnect is good enough + IInfo info = QueryPath(GetUncPath0(), Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO + ); + _attributes = info.GetAttributes(); + _createTime = info.GetCreateTime(); + _lastModified = info.GetLastWriteTime(); + } + } + } + _isExists = true; + } + catch (UnknownHostException) + { + } + catch (SmbException se) + { + switch (se.GetNtStatus()) + { + case NtStatus.NtStatusNoSuchFile: + case NtStatus.NtStatusObjectNameInvalid: + case NtStatus.NtStatusObjectNameNotFound: + case NtStatus.NtStatusObjectPathNotFound: + { + break; + } + + default: + { + throw; + } + } + } + _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; + return _isExists; + } + + /// <summary> + /// Tests to see if the file this <code>SmbFile</code> represents can be + /// read. + /// </summary> + /// <remarks> + /// Tests to see if the file this <code>SmbFile</code> represents can be + /// read. Because any file, directory, or other resource can be read if it + /// exists, this method simply calls the <code>exists</code> method. + /// </remarks> + /// <returns><code>true</code> if the file is read-only</returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual bool CanRead() + { + if (GetType() == TypeNamedPipe) + { + // try opening the pipe for reading? + return true; + } + return Exists(); + } + + // try opening and catch sharing violation? + /// <summary> + /// Tests to see if the file this <code>SmbFile</code> represents + /// exists and is not marked read-only. + /// </summary> + /// <remarks> + /// Tests to see if the file this <code>SmbFile</code> represents + /// exists and is not marked read-only. By default, resources are + /// considered to be read-only and therefore for <code>smb://</code>, + /// <code>smb://workgroup/</code>, and <code>smb://server/</code> resources + /// will be read-only. + /// </remarks> + /// <returns> + /// <code>true</code> if the resource exists is not marked + /// read-only + /// </returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual bool CanWrite() + { + if (GetType() == TypeNamedPipe) + { + // try opening the pipe for writing? + return true; + } + return Exists() && (_attributes & AttrReadonly) == 0; + } + + /// <summary>Tests to see if the file this <code>SmbFile</code> represents is a directory. + /// </summary> + /// <remarks>Tests to see if the file this <code>SmbFile</code> represents is a directory. + /// </remarks> + /// <returns><code>true</code> if this <code>SmbFile</code> is a directory</returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual bool IsDirectory() + { + if (GetUncPath0().Length == 1) + { + return true; + } + if (!Exists()) + { + return false; + } + return (_attributes & AttrDirectory) == AttrDirectory; + } + + /// <summary>Tests to see if the file this <code>SmbFile</code> represents is not a directory. + /// </summary> + /// <remarks>Tests to see if the file this <code>SmbFile</code> represents is not a directory. + /// </remarks> + /// <returns><code>true</code> if this <code>SmbFile</code> is not a directory</returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual bool IsFile() + { + if (GetUncPath0().Length == 1) + { + return false; + } + Exists(); + return (_attributes & AttrDirectory) == 0; + } + + /// <summary> + /// Tests to see if the file this SmbFile represents is marked as + /// hidden. + /// </summary> + /// <remarks> + /// Tests to see if the file this SmbFile represents is marked as + /// hidden. This method will also return true for shares with names that + /// end with '$' such as <code>IPC$</code> or <code>C$</code>. + /// </remarks> + /// <returns><code>true</code> if the <code>SmbFile</code> is marked as being hidden</returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual bool IsHidden() + { + if (_share == null) + { + return false; + } + if (GetUncPath0().Length == 1) + { + if (_share.EndsWith("$")) + { + return true; + } + return false; + } + Exists(); + return (_attributes & AttrHidden) == AttrHidden; + } + + /// <summary> + /// If the path of this <code>SmbFile</code> falls within a DFS volume, + /// this method will return the referral path to which it maps. + /// </summary> + /// <remarks> + /// If the path of this <code>SmbFile</code> falls within a DFS volume, + /// this method will return the referral path to which it maps. Otherwise + /// <code>null</code> is returned. + /// </remarks> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual string GetDfsPath() + { + ResolveDfs(null); + if (_dfsReferral == null) + { + return null; + } + string path = "smb:/" + _dfsReferral.Server + "/" + _dfsReferral.Share + Unc; + path = path.Replace('\\', '/'); + if (IsDirectory()) + { + path += '/'; + } + return path; + } + + /// <summary>Retrieve the time this <code>SmbFile</code> was created.</summary> + /// <remarks> + /// Retrieve the time this <code>SmbFile</code> was created. The value + /// returned is suitable for constructing a + /// <see cref="System.DateTime">System.DateTime</see> + /// object + /// (i.e. seconds since Epoch 1970). Times should be the same as those + /// reported using the properties dialog of the Windows Explorer program. + /// For Win95/98/Me this is actually the last write time. It is currently + /// not possible to retrieve the create time from files on these systems. + /// </remarks> + /// <returns> + /// The number of milliseconds since the 00:00:00 GMT, January 1, + /// 1970 as a <code>long</code> value + /// </returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual long CreateTime() + { + if (GetUncPath0().Length > 1) + { + Exists(); + return _createTime; + } + return 0L; + } + + /// <summary> + /// Retrieve the last time the file represented by this + /// <code>SmbFile</code> was modified. + /// </summary> + /// <remarks> + /// Retrieve the last time the file represented by this + /// <code>SmbFile</code> was modified. The value returned is suitable for + /// constructing a + /// <see cref="System.DateTime">System.DateTime</see> + /// object (i.e. seconds since Epoch + /// 1970). Times should be the same as those reported using the properties + /// dialog of the Windows Explorer program. + /// </remarks> + /// <returns> + /// The number of milliseconds since the 00:00:00 GMT, January 1, + /// 1970 as a <code>long</code> value + /// </returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual long LastModified() + { + if (GetUncPath0().Length > 1) + { + Exists(); + return _lastModified; + } + return 0L; + } + + /// <summary>List the contents of this SMB resource.</summary> + /// <remarks> + /// List the contents of this SMB resource. The list returned by this + /// method will be; + /// <ul> + /// <li> files and directories contained within this resource if the + /// resource is a normal disk file directory, + /// <li> all available NetBIOS workgroups or domains if this resource is + /// the top level URL <code>smb://</code>, + /// <li> all servers registered as members of a NetBIOS workgroup if this + /// resource refers to a workgroup in a <code>smb://workgroup/</code> URL, + /// <li> all browseable shares of a server including printers, IPC + /// services, or disk volumes if this resource is a server URL in the form + /// <code>smb://server/</code>, + /// <li> or <code>null</code> if the resource cannot be resolved. + /// </ul> + /// </remarks> + /// <returns> + /// A <code>String[]</code> array of files and directories, + /// workgroups, servers, or shares depending on the context of the + /// resource URL + /// </returns> + /// <exception cref="SmbException"></exception> + public virtual string[] List() + { + return List("*", AttrDirectory | AttrHidden | AttrSystem, null, null); + } + + /// <summary>List the contents of this SMB resource.</summary> + /// <remarks> + /// List the contents of this SMB resource. The list returned will be + /// identical to the list returned by the parameterless <code>list()</code> + /// method minus filenames filtered by the specified filter. + /// </remarks> + /// <param name="filter">a filename filter to exclude filenames from the results</param> + /// <exception cref="SmbException"># @return An array of filenames</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual string[] List(ISmbFilenameFilter filter) + { + return List("*", AttrDirectory | AttrHidden | AttrSystem, filter, null); + } + + /// <summary> + /// List the contents of this SMB resource as an array of + /// <code>SmbFile</code> objects. + /// </summary> + /// <remarks> + /// List the contents of this SMB resource as an array of + /// <code>SmbFile</code> objects. This method is much more efficient than + /// the regular <code>list</code> method when querying attributes of each + /// file in the result set. + /// <p> + /// The list of <code>SmbFile</code>s returned by this method will be; + /// <ul> + /// <li> files and directories contained within this resource if the + /// resource is a normal disk file directory, + /// <li> all available NetBIOS workgroups or domains if this resource is + /// the top level URL <code>smb://</code>, + /// <li> all servers registered as members of a NetBIOS workgroup if this + /// resource refers to a workgroup in a <code>smb://workgroup/</code> URL, + /// <li> all browseable shares of a server including printers, IPC + /// services, or disk volumes if this resource is a server URL in the form + /// <code>smb://server/</code>, + /// <li> or <code>null</code> if the resource cannot be resolved. + /// </ul> + /// </remarks> + /// <returns> + /// An array of <code>SmbFile</code> objects representing file + /// and directories, workgroups, servers, or shares depending on the context + /// of the resource URL + /// </returns> + /// <exception cref="SmbException"></exception> + public virtual SmbFile[] ListFiles() + { + return ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, null); + } + + /// <summary> + /// The CIFS protocol provides for DOS "wildcards" to be used as + /// a performance enhancement. + /// </summary> + /// <remarks> + /// The CIFS protocol provides for DOS "wildcards" to be used as + /// a performance enhancement. The client does not have to filter + /// the names and the server does not have to return all directory + /// entries. + /// <p> + /// The wildcard expression may consist of two special meta + /// characters in addition to the normal filename characters. The '*' + /// character matches any number of characters in part of a name. If + /// the expression begins with one or more '?'s then exactly that + /// many characters will be matched whereas if it ends with '?'s + /// it will match that many characters <i>or less</i>. + /// <p> + /// Wildcard expressions will not filter workgroup names or server names. + /// <blockquote><pre> + /// winnt> ls c?o + /// clock.avi -rw-- 82944 Mon Oct 14 1996 1:38 AM + /// Cookies drw-- 0 Fri Nov 13 1998 9:42 PM + /// 2 items in 5ms + /// </pre></blockquote> + /// </remarks> + /// <param name="wildcard">a wildcard expression</param> + /// <exception cref="SmbException">SmbException</exception> + /// <returns> + /// An array of <code>SmbFile</code> objects representing file + /// and directories, workgroups, servers, or shares depending on the context + /// of the resource URL + /// </returns> + /// <exception cref="SmbException"></exception> + public virtual SmbFile[] ListFiles(string wildcard) + { + return ListFiles(wildcard, AttrDirectory | AttrHidden | AttrSystem, null, null + ); + } + + /// <summary>List the contents of this SMB resource.</summary> + /// <remarks> + /// List the contents of this SMB resource. The list returned will be + /// identical to the list returned by the parameterless <code>listFiles()</code> + /// method minus files filtered by the specified filename filter. + /// </remarks> + /// <param name="filter">a filter to exclude files from the results</param> + /// <returns>An array of <tt>SmbFile</tt> objects</returns> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual SmbFile[] ListFiles(ISmbFilenameFilter filter) + { + return ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, filter, null); + } + + /// <summary>List the contents of this SMB resource.</summary> + /// <remarks> + /// List the contents of this SMB resource. The list returned will be + /// identical to the list returned by the parameterless <code>listFiles()</code> + /// method minus filenames filtered by the specified filter. + /// </remarks> + /// <param name="filter">a file filter to exclude files from the results</param> + /// <returns>An array of <tt>SmbFile</tt> objects</returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual SmbFile[] ListFiles(ISmbFileFilter filter) + { + return ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, filter); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual string[] List(string wildcard, int searchAttributes, ISmbFilenameFilter + fnf, ISmbFileFilter ff) + { + List<object> list = new List<object>(); + DoEnum(list, false, wildcard, searchAttributes, fnf, ff); + + return Collections.ToArray<string>(list); //Collections.ToArray<string>(list); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual SmbFile[] ListFiles(string wildcard, int searchAttributes + , ISmbFilenameFilter fnf, ISmbFileFilter ff) + { + List<object> list = new List<object>(); + DoEnum(list, true, wildcard, searchAttributes, fnf, ff); + + return Collections.ToArray<SmbFile>(list); //Collections.ToArray<SmbFile>(list); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void DoEnum(List<object> list, bool files, string wildcard, int searchAttributes + , ISmbFilenameFilter fnf, ISmbFileFilter ff) + { + if (ff != null && ff is DosFileFilter) + { + DosFileFilter dff = (DosFileFilter)ff; + if (dff.Wildcard != null) + { + wildcard = dff.Wildcard; + } + searchAttributes = dff.Attributes; + } + try + { + int hostlen = Url.GetHost() != null ? Url.GetHost().Length : 0; + if (hostlen == 0 || GetType() == TypeWorkgroup) + { + DoNetServerEnum(list, files, wildcard, searchAttributes, fnf, ff); + } + else + { + if (_share == null) + { + DoShareEnum(list, files, wildcard, searchAttributes, fnf, ff); + } + else + { + DoFindFirstNext(list, files, wildcard, searchAttributes, fnf, ff); + } + } + } + catch (UnknownHostException uhe) + { + throw new SmbException(Url.ToString(), uhe); + } + catch (UriFormatException mue) + { + throw new SmbException(Url.ToString(), mue); + } + } + + private void RemoveCurrentAddress() + { + if (AddressIndex >= 1) + { + UniAddress[] aux = new UniAddress[Addresses.Length - 1]; + + Array.Copy(Addresses, 1, aux, 0, Addresses.Length - 1); + + Addresses = aux; + AddressIndex--; + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="UnknownHostException"></exception> + /// <exception cref="System.UriFormatException"></exception> + internal virtual void DoShareEnum(List<object> list, bool files, string wildcard, int + searchAttributes, ISmbFilenameFilter fnf, ISmbFileFilter ff) + { + string p = Url.AbsolutePath; + IOException last = null; + IFileEntry[] entries; + UniAddress addr; + IFileEntry e; + Hashtable map; + if (p.LastIndexOf('/') != (p.Length - 1)) + { + throw new SmbException(Url + " directory must end with '/'"); + } + if (GetType() != TypeServer) + { + throw new SmbException("The requested list operations is invalid: " + Url); + } + map = new Hashtable(); + if (_enableDfs && Dfs.IsTrustedDomain(GetServer(), Auth)) + { + try + { + entries = DoDfsRootEnum(); + for (int ei = 0; ei < entries.Length; ei++) + { + e = entries[ei]; + if (map.ContainsKey(e) == false) + { + map.Put(e, e); + } + } + } + catch (IOException ioe) + { + if (Log.Level >= 4) + { + Runtime.PrintStackTrace(ioe, Log); + } + } + } + addr = GetFirstAddress(); + while (addr != null) + { + try + { + last = null; + + DoConnect(); + try + { + entries = DoMsrpcShareEnum(); + } + catch (IOException ioe) + { + if (Log.Level >= 3) + { + Runtime.PrintStackTrace(ioe, Log); + } + entries = DoNetShareEnum(); + } + for (int ei = 0; ei < entries.Length; ei++) + { + e = entries[ei]; + if (map.ContainsKey(e) == false) + { + map.Put(e, e); + } + } + break; + } + catch (IOException ioe) + { + if (Log.Level >= 3) + { + Runtime.PrintStackTrace(ioe, Log); + } + last = ioe; + + if (!(ioe is SmbAuthException)) + { + RemoveCurrentAddress(); + + addr = GetNextAddress(); + } + else + { + break; + } + } + + } + if (last != null && map.Count == 0) + { + if (last is SmbException == false) + { + throw new SmbException(Url.ToString(), last); + } + throw (SmbException)last; + } + //Iterator iter = map.Keys.Iterator(); + //while (iter.HasNext()) + foreach (var item in map.Keys) + { + e = (IFileEntry)item; + string name = e.GetName(); + if (fnf != null && fnf.Accept(this, name) == false) + { + continue; + } + if (name.Length > 0) + { + // if !files we don't need to create SmbFiles here + SmbFile f = new SmbFile(this, name, e.GetType(), AttrReadonly + | AttrDirectory, 0L, 0L, 0L); + if (ff != null && ff.Accept(f) == false) + { + continue; + } + if (files) + { + list.Add(f); + } + else + { + list.Add(name); + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual IFileEntry[] DoDfsRootEnum() + { + MsrpcDfsRootEnum rpc; + DcerpcHandle handle = null; + IFileEntry[] entries; + handle = DcerpcHandle.GetHandle("ncacn_np:" + GetAddress().GetHostAddress() + "[\\PIPE\\netdfs]" + , Auth); + try + { + rpc = new MsrpcDfsRootEnum(GetServer()); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, true); + } + return rpc.GetEntries(); + } + finally + { + try + { + handle.Close(); + } + catch (IOException ioe) + { + if (Log.Level >= 4) + { + Runtime.PrintStackTrace(ioe, Log); + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual IFileEntry[] DoMsrpcShareEnum() + { + MsrpcShareEnum rpc; + DcerpcHandle handle; + rpc = new MsrpcShareEnum(Url.GetHost()); + handle = DcerpcHandle.GetHandle("ncacn_np:" + GetAddress().GetHostAddress() + "[\\PIPE\\srvsvc]" + , Auth); + try + { + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, true); + } + return rpc.GetEntries(); + } + finally + { + try + { + handle.Close(); + } + catch (IOException ioe) + { + if (Log.Level >= 4) + { + Runtime.PrintStackTrace(ioe, Log); + } + } + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual IFileEntry[] DoNetShareEnum() + { + SmbComTransaction req = new NetShareEnum(); + SmbComTransactionResponse resp = new NetShareEnumResponse(); + Send(req, resp); + if (resp.Status != WinError.ErrorSuccess) + { + throw new SmbException(resp.Status, true); + } + return resp.Results; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="UnknownHostException"></exception> + /// <exception cref="System.UriFormatException"></exception> + internal virtual void DoNetServerEnum(List<object> list, bool files, string wildcard + , int searchAttributes, ISmbFilenameFilter fnf, ISmbFileFilter ff) + { + int listType = Url.GetHost().Length == 0 ? 0 : GetType(); + SmbComTransaction req; + SmbComTransactionResponse resp; + if (listType == 0) + { + Connect0(); + req = new NetServerEnum2(Tree.Session.transport.Server.OemDomainName, NetServerEnum2 + .SvTypeDomainEnum); + resp = new NetServerEnum2Response(); + } + else + { + if (listType == TypeWorkgroup) + { + req = new NetServerEnum2(Url.GetHost(), NetServerEnum2.SvTypeAll); + resp = new NetServerEnum2Response(); + } + else + { + throw new SmbException("The requested list operations is invalid: " + Url); + } + } + bool more; + do + { + int n; + Send(req, resp); + if (resp.Status != WinError.ErrorSuccess && resp.Status != WinError.ErrorMoreData) + { + throw new SmbException(resp.Status, true); + } + more = resp.Status == WinError.ErrorMoreData; + n = more ? resp.NumEntries - 1 : resp.NumEntries; + for (int i = 0; i < n; i++) + { + IFileEntry e = resp.Results[i]; + string name = e.GetName(); + if (fnf != null && fnf.Accept(this, name) == false) + { + continue; + } + if (name.Length > 0) + { + // if !files we don't need to create SmbFiles here + SmbFile f = new SmbFile(this, name, e.GetType(), AttrReadonly + | AttrDirectory, 0L, 0L, 0L); + if (ff != null && ff.Accept(f) == false) + { + continue; + } + if (files) + { + list.Add(f); + } + else + { + list.Add(name); + } + } + } + if (GetType() != TypeWorkgroup) + { + break; + } + req.SubCommand = unchecked(SmbComTransaction.NetServerEnum3); + req.Reset(0, ((NetServerEnum2Response)resp).LastName); + resp.Reset(); + } + while (more); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="UnknownHostException"></exception> + /// <exception cref="System.UriFormatException"></exception> + internal virtual void DoFindFirstNext(List<object> list, bool files, string wildcard + , int searchAttributes, ISmbFilenameFilter fnf, ISmbFileFilter ff) + { + SmbComTransaction req; + Trans2FindFirst2Response resp; + int sid; + string path = GetUncPath0(); + string p = Url.AbsolutePath; + if (p.LastIndexOf('/') != (p.Length - 1)) + { + throw new SmbException(Url + " directory must end with '/'"); + } + req = new Trans2FindFirst2(path, wildcard, searchAttributes); + resp = new Trans2FindFirst2Response(); + if (Log.Level >= 3) + { + Log.WriteLine("doFindFirstNext: " + req.Path); + } + Send(req, resp); + sid = resp.Sid; + req = new Trans2FindNext2(sid, resp.ResumeKey, resp.LastName); + resp.SubCommand = SmbComTransaction.Trans2FindNext2; + for (; ; ) + { + for (int i = 0; i < resp.NumEntries; i++) + { + IFileEntry e = resp.Results[i]; + string name = e.GetName(); + if (name.Length < 3) + { + int h = name.GetHashCode(); + if (h == HashDot || h == HashDotDot) + { + if (name.Equals(".") || name.Equals("..")) + { + continue; + } + } + } + if (fnf != null && fnf.Accept(this, name) == false) + { + continue; + } + if (name.Length > 0) + { + SmbFile f = new SmbFile(this, name, TypeFilesystem, e.GetAttributes + (), e.CreateTime(), e.LastModified(), e.Length()); + if (ff != null && ff.Accept(f) == false) + { + continue; + } + if (files) + { + list.Add(f); + } + else + { + list.Add(name); + } + } + } + if (resp.IsEndOfSearch || resp.NumEntries == 0) + { + break; + } + req.Reset(resp.ResumeKey, resp.LastName); + resp.Reset(); + Send(req, resp); + } + try + { + Send(new SmbComFindClose2(sid), Blank_resp()); + } + catch (SmbException se) + { + if (Log.Level >= 4) + { + Runtime.PrintStackTrace(se, Log); + } + } + } + + /// <summary> + /// Changes the name of the file this <code>SmbFile</code> represents to the name + /// designated by the <code>SmbFile</code> argument. + /// </summary> + /// <remarks> + /// Changes the name of the file this <code>SmbFile</code> represents to the name + /// designated by the <code>SmbFile</code> argument. + /// <p/> + /// <i>Remember: <code>SmbFile</code>s are immutible and therefore + /// the path associated with this <code>SmbFile</code> object will not + /// change). To access the renamed file it is necessary to construct a + /// new <tt>SmbFile</tt></i>. + /// </remarks> + /// <param name="dest">An <code>SmbFile</code> that represents the new pathname</param> + /// <exception cref="System.ArgumentNullException">If the <code>dest</code> argument is <code>null</code> + /// </exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void RenameTo(SmbFile dest) + { + if (GetUncPath0().Length == 1 || dest.GetUncPath0().Length == 1) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + ResolveDfs(null); + dest.ResolveDfs(null); + if (!Tree.Equals(dest.Tree)) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + if (Log.Level >= 3) + { + Log.WriteLine("renameTo: " + Unc + " -> " + dest.Unc); + } + _attrExpiration = _sizeExpiration = 0; + dest._attrExpiration = 0; + Send(new SmbComRename(Unc, dest.Unc), Blank_resp()); + } + + internal class WriterThread : Thread + { + internal byte[] B; + + internal int N; + + internal long Off; + + internal bool Ready; + + internal SmbFile Dest; + + internal SmbException E; + + internal bool UseNtSmbs; + + internal SmbComWriteAndX Reqx; + + internal SmbComWrite Req; + + internal ServerMessageBlock Resp; + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public WriterThread(SmbFile enclosing) + : base("JCIFS-WriterThread") + { + this._enclosing = enclosing; + UseNtSmbs = this._enclosing.Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs); + if (UseNtSmbs) + { + Reqx = new SmbComWriteAndX(); + Resp = new SmbComWriteAndXResponse(); + } + else + { + Req = new SmbComWrite(); + Resp = new SmbComWriteResponse(); + } + Ready = false; + } + + internal virtual void Write(byte[] b, int n, SmbFile dest, long off) + { + lock (this) + { + this.B = b; + this.N = n; + this.Dest = dest; + this.Off = off; + Ready = false; + Runtime.Notify(this); + } + } + + public override void Run() + { + lock (this) + { + try + { + for (; ; ) + { + Runtime.Notify(this); + Ready = true; + while (Ready) + { + Runtime.Wait(this); + } + if (N == -1) + { + return; + } + if (UseNtSmbs) + { + Reqx.SetParam(Dest.Fid, Off, N, B, 0, N); + Dest.Send(Reqx, Resp); + } + else + { + Req.SetParam(Dest.Fid, Off, N, B, 0, N); + Dest.Send(Req, Resp); + } + } + } + catch (SmbException e) + { + this.E = e; + } + catch (Exception x) + { + E = new SmbException("WriterThread", x); + } + Runtime.Notify(this); + } + } + + private readonly SmbFile _enclosing; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void CopyTo0(SmbFile dest, byte[][] b, int bsize, WriterThread + w, SmbComReadAndX req, SmbComReadAndXResponse resp) + { + int i; + if (_attrExpiration < Runtime.CurrentTimeMillis()) + { + _attributes = AttrReadonly | AttrDirectory; + _createTime = 0L; + _lastModified = 0L; + _isExists = false; + IInfo info = QueryPath(GetUncPath0(), Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO + ); + _attributes = info.GetAttributes(); + _createTime = info.GetCreateTime(); + _lastModified = info.GetLastWriteTime(); + _isExists = true; + _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; + } + if (IsDirectory()) + { + SmbFile[] files; + SmbFile ndest; + string path = dest.GetUncPath0(); + if (path.Length > 1) + { + try + { + dest.Mkdir(); + dest.SetPathInformation(_attributes, _createTime, _lastModified); + } + catch (SmbException se) + { + if (se.GetNtStatus() != NtStatus.NtStatusAccessDenied && se.GetNtStatus() != NtStatus + .NtStatusObjectNameCollision) + { + throw; + } + } + } + files = ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, null); + try + { + for (i = 0; i < files.Length; i++) + { + ndest = new SmbFile(dest, files[i].GetName(), files[i].Type, files[i]._attributes, + files[i]._createTime, files[i]._lastModified, files[i]._size); + files[i].CopyTo0(ndest, b, bsize, w, req, resp); + } + } + catch (UnknownHostException uhe) + { + throw new SmbException(Url.ToString(), uhe); + } + catch (UriFormatException mue) + { + throw new SmbException(Url.ToString(), mue); + } + } + else + { + long off; + try + { + Open(ORdonly, 0, AttrNormal, 0); + try + { + dest.Open(OCreat | OWronly | OTrunc, SmbConstants.FileWriteData | + SmbConstants.FileWriteAttributes, _attributes, 0); + } + catch (SmbAuthException sae) + { + if ((dest._attributes & AttrReadonly) != 0) + { + dest.SetPathInformation(dest._attributes & ~AttrReadonly, 0L, 0L); + dest.Open(OCreat | OWronly | OTrunc, SmbConstants.FileWriteData | + SmbConstants.FileWriteAttributes, _attributes, 0); + } + else + { + throw; + } + } + i = 0; + off = 0L; + for (; ; ) + { + req.SetParam(Fid, off, bsize); + resp.SetParam(b[i], 0); + Send(req, resp); + lock (w) + { + if (w.E != null) + { + throw w.E; + } + while (!w.Ready) + { + try + { + Runtime.Wait(w); + } + catch (Exception ie) + { + throw new SmbException(dest.Url.ToString(), ie); + } + } + if (w.E != null) + { + throw w.E; + } + if (resp.DataLength <= 0) + { + break; + } + w.Write(b[i], resp.DataLength, dest, off); + } + i = i == 1 ? 0 : 1; + off += resp.DataLength; + } + dest.Send(new Trans2SetFileInformation(dest.Fid, _attributes, _createTime, _lastModified + ), new Trans2SetFileInformationResponse()); + dest.Close(0L); + } + catch (SmbException se) + { + if (IgnoreCopyToException == false) + { + throw new SmbException("Failed to copy file from [" + ToString() + "] to [" + + dest + "]", se); + } + if (Log.Level > 1) + { + Runtime.PrintStackTrace(se, Log); + } + } + finally + { + Close(); + } + } + } + + /// <summary> + /// This method will copy the file or directory represented by this + /// <tt>SmbFile</tt> and it's sub-contents to the location specified by the + /// <tt>dest</tt> parameter. + /// </summary> + /// <remarks> + /// This method will copy the file or directory represented by this + /// <tt>SmbFile</tt> and it's sub-contents to the location specified by the + /// <tt>dest</tt> parameter. This file and the destination file do not + /// need to be on the same host. This operation does not copy extended + /// file attibutes such as ACLs but it does copy regular attributes as + /// well as create and last write times. This method is almost twice as + /// efficient as manually copying as it employs an additional write + /// thread to read and write data concurrently. + /// <p/> + /// It is not possible (nor meaningful) to copy entire workgroups or + /// servers. + /// </remarks> + /// <param name="dest">the destination file or directory</param> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void CopyTo(SmbFile dest) + { + SmbComReadAndX req; + SmbComReadAndXResponse resp; + WriterThread w; + int bsize; + byte[][] b; + if (_share == null || dest._share == null) + { + throw new SmbException("Invalid operation for workgroups or servers"); + } + req = new SmbComReadAndX(); + resp = new SmbComReadAndXResponse(); + Connect0(); + dest.Connect0(); + ResolveDfs(null); + try + { + if (GetAddress().Equals(dest.GetAddress()) && _canon.RegionMatches(true, 0, dest._canon + , 0, Math.Min(_canon.Length, dest._canon.Length))) + { + throw new SmbException("Source and destination paths overlap."); + } + } + catch (UnknownHostException) + { + } + w = new WriterThread(this); + w.SetDaemon(true); + w.Start(); + SmbTransport t1 = Tree.Session.transport; + SmbTransport t2 = dest.Tree.Session.transport; + if (t1.SndBufSize < t2.SndBufSize) + { + t2.SndBufSize = t1.SndBufSize; + } + else + { + t1.SndBufSize = t2.SndBufSize; + } + bsize = Math.Min(t1.RcvBufSize - 70, t1.SndBufSize - 70); + b = new[] { new byte[bsize], new byte[bsize] }; + try + { + CopyTo0(dest, b, bsize, w, req, resp); + } + finally + { + w.Write(null, -1, null, 0); + } + } + + /// <summary> + /// This method will delete the file or directory specified by this + /// <code>SmbFile</code>. + /// </summary> + /// <remarks> + /// This method will delete the file or directory specified by this + /// <code>SmbFile</code>. If the target is a directory, the contents of + /// the directory will be deleted as well. If a file within the directory or + /// it's sub-directories is marked read-only, the read-only status will + /// be removed and the file will be deleted. + /// </remarks> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Delete() + { + Exists(); + GetUncPath0(); + Delete(Unc); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Delete(string fileName) + { + if (GetUncPath0().Length == 1) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + if (Runtime.CurrentTimeMillis() > _attrExpiration) + { + _attributes = AttrReadonly | AttrDirectory; + _createTime = 0L; + _lastModified = 0L; + _isExists = false; + IInfo info = QueryPath(GetUncPath0(), Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO + ); + _attributes = info.GetAttributes(); + _createTime = info.GetCreateTime(); + _lastModified = info.GetLastWriteTime(); + _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; + _isExists = true; + } + if ((_attributes & AttrReadonly) != 0) + { + SetReadWrite(); + } + if (Log.Level >= 3) + { + Log.WriteLine("delete: " + fileName); + } + if ((_attributes & AttrDirectory) != 0) + { + try + { + SmbFile[] l = ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, null + ); + for (int i = 0; i < l.Length; i++) + { + l[i].Delete(); + } + } + catch (SmbException se) + { + if (se.GetNtStatus() != NtStatus.NtStatusNoSuchFile) + { + throw; + } + } + Send(new SmbComDeleteDirectory(fileName), Blank_resp()); + } + else + { + Send(new SmbComDelete(fileName), Blank_resp()); + } + _attrExpiration = _sizeExpiration = 0; + } + + /// <summary>Returns the length of this <tt>SmbFile</tt> in bytes.</summary> + /// <remarks> + /// Returns the length of this <tt>SmbFile</tt> in bytes. If this object + /// is a <tt>TYPE_SHARE</tt> the total capacity of the disk shared in + /// bytes is returned. If this object is a directory or a type other than + /// <tt>TYPE_SHARE</tt>, 0L is returned. + /// </remarks> + /// <returns> + /// The length of the file in bytes or 0 if this + /// <code>SmbFile</code> is not a file. + /// </returns> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual long Length() + { + if (_sizeExpiration > Runtime.CurrentTimeMillis()) + { + return _size; + } + if (GetType() == TypeShare) + { + Trans2QueryFsInformationResponse response; + int level = Trans2QueryFsInformationResponse.SMB_INFO_ALLOCATION; + response = new Trans2QueryFsInformationResponse(level); + Send(new Trans2QueryFsInformation(level), response); + _size = response.Info.GetCapacity(); + } + else + { + if (GetUncPath0().Length > 1 && Type != TypeNamedPipe) + { + IInfo info = QueryPath(GetUncPath0(), Trans2QueryPathInformationResponse.SMB_QUERY_FILE_STANDARD_INFO + ); + _size = info.GetSize(); + } + else + { + _size = 0L; + } + } + _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; + return _size; + } + + /// <summary> + /// This method returns the free disk space in bytes of the drive this share + /// represents or the drive on which the directory or file resides. + /// </summary> + /// <remarks> + /// This method returns the free disk space in bytes of the drive this share + /// represents or the drive on which the directory or file resides. Objects + /// other than <tt>TYPE_SHARE</tt> or <tt>TYPE_FILESYSTEM</tt> will result + /// in 0L being returned. + /// </remarks> + /// <returns> + /// the free disk space in bytes of the drive on which this file or + /// directory resides + /// </returns> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual long GetDiskFreeSpace() + { + if (GetType() == TypeShare || Type == TypeFilesystem) + { + int level = Trans2QueryFsInformationResponse.SmbFsFullSizeInformation; + try + { + return QueryFsInformation(level); + } + catch (SmbException ex) + { + switch (ex.GetNtStatus()) + { + case NtStatus.NtStatusInvalidInfoClass: + case NtStatus.NtStatusUnsuccessful: + { + // NetApp Filer + // SMB_FS_FULL_SIZE_INFORMATION not supported by the server. + level = Trans2QueryFsInformationResponse.SMB_INFO_ALLOCATION; + return QueryFsInformation(level); + } + } + throw; + } + } + return 0L; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + private long QueryFsInformation(int level) + { + Trans2QueryFsInformationResponse response; + response = new Trans2QueryFsInformationResponse(level); + Send(new Trans2QueryFsInformation(level), response); + if (Type == TypeShare) + { + _size = response.Info.GetCapacity(); + _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; + } + return response.Info.GetFree(); + } + + /// <summary> + /// Creates a directory with the path specified by this + /// <code>SmbFile</code>. + /// </summary> + /// <remarks> + /// Creates a directory with the path specified by this + /// <code>SmbFile</code>. For this method to be successful, the target + /// must not already exist. This method will fail when + /// used with <code>smb://</code>, <code>smb://workgroup/</code>, + /// <code>smb://server/</code>, or <code>smb://server/share/</code> URLs + /// because workgroups, servers, and shares cannot be dynamically created + /// (although in the future it may be possible to create shares). + /// </remarks> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Mkdir() + { + string path = GetUncPath0(); + if (path.Length == 1) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + if (Log.Level >= 3) + { + Log.WriteLine("mkdir: " + path); + } + Send(new SmbComCreateDirectory(path), Blank_resp()); + _attrExpiration = _sizeExpiration = 0; + } + + /// <summary> + /// Creates a directory with the path specified by this <tt>SmbFile</tt> + /// and any parent directories that do not exist. + /// </summary> + /// <remarks> + /// Creates a directory with the path specified by this <tt>SmbFile</tt> + /// and any parent directories that do not exist. This method will fail + /// when used with <code>smb://</code>, <code>smb://workgroup/</code>, + /// <code>smb://server/</code>, or <code>smb://server/share/</code> URLs + /// because workgroups, servers, and shares cannot be dynamically created + /// (although in the future it may be possible to create shares). + /// </remarks> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Mkdirs() + { + SmbFile parent; + try + { + parent = new SmbFile(GetParent(), Auth); + } + catch (IOException) + { + return; + } + if (parent.Exists() == false) + { + parent.Mkdirs(); + } + Mkdir(); + } + + /// <summary>Create a new file but fail if it already exists.</summary> + /// <remarks> + /// Create a new file but fail if it already exists. The check for + /// existance of the file and it's creation are an atomic operation with + /// respect to other filesystem activities. + /// </remarks> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void CreateNewFile() + { + if (GetUncPath0().Length == 1) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + Close(Open0(ORdwr | OCreat | OExcl, 0, AttrNormal, 0), 0L); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void SetPathInformation(int attrs, long ctime, long mtime) + { + int f; + int dir; + Exists(); + dir = _attributes & AttrDirectory; + f = Open0(ORdonly, SmbConstants.FileWriteAttributes, dir, dir != 0 ? 0x0001 + : 0x0040); + Send(new Trans2SetFileInformation(f, attrs | dir, ctime, mtime), new Trans2SetFileInformationResponse + ()); + Close(f, 0L); + _attrExpiration = 0; + } + + /// <summary>Set the create time of the file.</summary> + /// <remarks> + /// Set the create time of the file. The time is specified as milliseconds + /// from Jan 1, 1970 which is the same as that which is returned by the + /// <tt>createTime()</tt> method. + /// <p/> + /// This method does not apply to workgroups, servers, or shares. + /// </remarks> + /// <param name="time">the create time as milliseconds since Jan 1, 1970</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void SetCreateTime(long time) + { + if (GetUncPath0().Length == 1) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + SetPathInformation(0, time, 0L); + } + + /// <summary>Set the last modified time of the file.</summary> + /// <remarks> + /// Set the last modified time of the file. The time is specified as milliseconds + /// from Jan 1, 1970 which is the same as that which is returned by the + /// <tt>lastModified()</tt>, <tt>getLastModified()</tt>, and <tt>getDate()</tt> methods. + /// <p/> + /// This method does not apply to workgroups, servers, or shares. + /// </remarks> + /// <param name="time">the last modified time as milliseconds since Jan 1, 1970</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void SetLastModified(long time) + { + if (GetUncPath0().Length == 1) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + SetPathInformation(0, 0L, time); + } + + /// <summary>Return the attributes of this file.</summary> + /// <remarks> + /// Return the attributes of this file. Attributes are represented as a + /// bitset that must be masked with <tt>ATTR_*</tt> constants to determine + /// if they are set or unset. The value returned is suitable for use with + /// the <tt>setAttributes()</tt> method. + /// </remarks> + /// <returns>the <tt>ATTR_*</tt> attributes associated with this file</returns> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual int GetAttributes() + { + if (GetUncPath0().Length == 1) + { + return 0; + } + Exists(); + return _attributes & AttrGetMask; + } + + /// <summary>Set the attributes of this file.</summary> + /// <remarks> + /// Set the attributes of this file. Attributes are composed into a + /// bitset by bitwise ORing the <tt>ATTR_*</tt> constants. Setting the + /// value returned by <tt>getAttributes</tt> will result in both files + /// having the same attributes. + /// </remarks> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void SetAttributes(int attrs) + { + if (GetUncPath0().Length == 1) + { + throw new SmbException("Invalid operation for workgroups, servers, or shares"); + } + SetPathInformation(attrs & AttrSetMask, 0L, 0L); + } + + /// <summary>Make this file read-only.</summary> + /// <remarks> + /// Make this file read-only. This is shorthand for <tt>setAttributes( + /// getAttributes() | ATTR_READ_ONLY )</tt>. + /// </remarks> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void SetReadOnly() + { + SetAttributes(GetAttributes() | AttrReadonly); + } + + /// <summary>Turn off the read-only attribute of this file.</summary> + /// <remarks> + /// Turn off the read-only attribute of this file. This is shorthand for + /// <tt>setAttributes( getAttributes() & ~ATTR_READONLY )</tt>. + /// </remarks> + /// <exception cref="SmbException">SmbException</exception> + /// <exception cref="SmbException"></exception> + public virtual void SetReadWrite() + { + SetAttributes(GetAttributes() & ~AttrReadonly); + } + + /// <summary> + /// Returns a + /// <see cref="System.Uri">System.Uri</see> + /// for this <code>SmbFile</code>. The + /// <code>URL</code> may be used as any other <code>URL</code> might to + /// access an SMB resource. Currently only retrieving data and information + /// is supported (i.e. no <tt>doOutput</tt>). + /// </summary> + /// <returns> + /// A new <code> + /// <see cref="System.Uri">System.Uri</see> + /// </code> for this <code>SmbFile</code> + /// </returns> + /// <exception cref="System.UriFormatException">System.UriFormatException</exception> + [Obsolete(@"Use getURL() instead")] + public virtual Uri ToUrl() + { + return Url; + } + + /// <summary> + /// Computes a hashCode for this file based on the URL string and IP + /// address if the server. + /// </summary> + /// <remarks> + /// Computes a hashCode for this file based on the URL string and IP + /// address if the server. The hashing function uses the hashcode of the + /// server address, the canonical representation of the URL, and does not + /// compare authentication information. In essance, two + /// <code>SmbFile</code> objects that refer to + /// the same file should generate the same hashcode provided it is possible + /// to make such a determination. + /// </remarks> + /// <returns>A hashcode for this abstract file</returns> + /// <exception cref="SmbException">SmbException</exception> + public override int GetHashCode() + { + int hash; + try + { + hash = GetAddress().GetHashCode(); + } + catch (UnknownHostException) + { + hash = GetServer().ToUpper().GetHashCode(); + } + GetUncPath0(); + return hash + _canon.ToUpper().GetHashCode(); + } + + protected internal virtual bool PathNamesPossiblyEqual(string path1, string path2 + ) + { + int p1; + int p2; + int l1; + int l2; + // if unsure return this method returns true + p1 = path1.LastIndexOf('/'); + p2 = path2.LastIndexOf('/'); + l1 = path1.Length - p1; + l2 = path2.Length - p2; + // anything with dots voids comparison + if (l1 > 1 && path1[p1 + 1] == '.') + { + return true; + } + if (l2 > 1 && path2[p2 + 1] == '.') + { + return true; + } + return l1 == l2 && path1.RegionMatches(true, p1, path2, p2, l1); + } + + /// <summary>Tests to see if two <code>SmbFile</code> objects are equal.</summary> + /// <remarks> + /// Tests to see if two <code>SmbFile</code> objects are equal. Two + /// SmbFile objects are equal when they reference the same SMB + /// resource. More specifically, two <code>SmbFile</code> objects are + /// equals if their server IP addresses are equal and the canonicalized + /// representation of their URLs, minus authentication parameters, are + /// case insensitivly and lexographically equal. + /// <p/> + /// For example, assuming the server <code>angus</code> resolves to the + /// <code>192.168.1.15</code> IP address, the below URLs would result in + /// <code>SmbFile</code>s that are equal. + /// <p><blockquote><pre> + /// smb://192.168.1.15/share/DIR/foo.txt + /// smb://angus/share/data/../dir/foo.txt + /// </pre></blockquote> + /// </remarks> + /// <param name="obj">Another <code>SmbFile</code> object to compare for equality</param> + /// <returns> + /// <code>true</code> if the two objects refer to the same SMB resource + /// and <code>false</code> otherwise + /// </returns> + /// <exception cref="SmbException">SmbException</exception> + public override bool Equals(object obj) + { + if (obj is SmbFile) + { + SmbFile f = (SmbFile)obj; + bool ret; + if (this == f) + { + return true; + } + if (PathNamesPossiblyEqual(Url.AbsolutePath, f.Url.AbsolutePath)) + { + GetUncPath0(); + f.GetUncPath0(); + if (Runtime.EqualsIgnoreCase(_canon, f._canon)) + { + try + { + ret = GetAddress().Equals(f.GetAddress()); + } + catch (UnknownHostException) + { + ret = Runtime.EqualsIgnoreCase(GetServer(), f.GetServer()); + } + return ret; + } + } + } + return false; + } + + /// <summary>Returns the string representation of this SmbFile object.</summary> + /// <remarks> + /// Returns the string representation of this SmbFile object. This will + /// be the same as the URL used to construct this <code>SmbFile</code>. + /// This method will return the same value + /// as <code>getPath</code>. + /// </remarks> + /// <returns>The original URL representation of this SMB resource</returns> + /// <exception cref="SmbException">SmbException</exception> + public override string ToString() + { + return Url.ToString(); + } + + /// <summary>This URLConnection method just returns the result of <tt>length()</tt>.</summary> + /// <remarks>This URLConnection method just returns the result of <tt>length()</tt>.</remarks> + /// <returns>the length of this file or 0 if it refers to a directory</returns> + public int GetContentLength() + { + try + { + return (int)(Length() & unchecked(0xFFFFFFFFL)); + } + catch (SmbException) + { + } + return 0; + } + + /// <summary>This URLConnection method just returns the result of <tt>lastModified</tt>. + /// </summary> + /// <remarks>This URLConnection method just returns the result of <tt>lastModified</tt>. + /// </remarks> + /// <returns>the last modified data as milliseconds since Jan 1, 1970</returns> + public long GetDate() + { + try + { + return LastModified(); + } + catch (SmbException) + { + } + return 0L; + } + + /// <summary>This URLConnection method just returns the result of <tt>lastModified</tt>. + /// </summary> + /// <remarks>This URLConnection method just returns the result of <tt>lastModified</tt>. + /// </remarks> + /// <returns>the last modified data as milliseconds since Jan 1, 1970</returns> + public long GetLastModified() + { + try + { + return LastModified(); + } + catch (SmbException) + { + } + return 0L; + } + + /// <summary>This URLConnection method just returns a new <tt>SmbFileInputStream</tt> created with this file. + /// </summary> + /// <remarks>This URLConnection method just returns a new <tt>SmbFileInputStream</tt> created with this file. + /// </remarks> + /// <exception cref="System.IO.IOException">thrown by <tt>SmbFileInputStream</tt> constructor + /// </exception> + public InputStream GetInputStream() + { + return new SmbFileInputStream(this); + } + + /// <summary>This URLConnection method just returns a new <tt>SmbFileOutputStream</tt> created with this file. + /// </summary> + /// <remarks>This URLConnection method just returns a new <tt>SmbFileOutputStream</tt> created with this file. + /// </remarks> + /// <exception cref="System.IO.IOException">thrown by <tt>SmbFileOutputStream</tt> constructor + /// </exception> + public OutputStream GetOutputStream() + { + return new SmbFileOutputStream(this); + } + + /// <exception cref="System.IO.IOException"></exception> + private void ProcessAces(Ace[] aces, bool resolveSids) + { + string server = GetServerWithDfs(); + int ai; + if (resolveSids) + { + Sid[] sids = new Sid[aces.Length]; + string[] names = null; + for (ai = 0; ai < aces.Length; ai++) + { + sids[ai] = aces[ai].Sid; + } + for (int off = 0; off < sids.Length; off += 64) + { + int len = sids.Length - off; + if (len > 64) + { + len = 64; + } + Sid.ResolveSids(server, Auth, sids, off, len); + } + } + else + { + for (ai = 0; ai < aces.Length; ai++) + { + aces[ai].Sid.OriginServer = server; + aces[ai].Sid.OriginAuth = Auth; + } + } + } + + /// <summary> + /// Return an array of Access Control Entry (ACE) objects representing + /// the security descriptor associated with this file or directory. + /// </summary> + /// <remarks> + /// Return an array of Access Control Entry (ACE) objects representing + /// the security descriptor associated with this file or directory. + /// If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned. + /// </remarks> + /// <param name="resolveSids"> + /// Attempt to resolve the SIDs within each ACE form + /// their numeric representation to their corresponding account names. + /// </param> + /// <exception cref="System.IO.IOException"></exception> + public virtual Ace[] GetSecurity(bool resolveSids) + { + int f; + Ace[] aces; + f = Open0(ORdonly, SmbConstants.ReadControl, 0, IsDirectory() ? 1 : 0); + NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc(f, 0x04); + NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse( + ); + try + { + Send(request, response); + } + finally + { + Close(f, 0L); + } + aces = response.SecurityDescriptor.Aces; + if (aces != null) + { + ProcessAces(aces, resolveSids); + } + return aces; + } + + /// <summary> + /// Return an array of Access Control Entry (ACE) objects representing + /// the share permissions on the share exporting this file or directory. + /// </summary> + /// <remarks> + /// Return an array of Access Control Entry (ACE) objects representing + /// the share permissions on the share exporting this file or directory. + /// If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned. + /// <p> + /// Note that this is different from calling <tt>getSecurity</tt> on a + /// share. There are actually two different ACLs for shares - the ACL on + /// the share and the ACL on the folder being shared. + /// Go to <i>Computer Management</i> + /// > <i>System Tools</i> > <i>Shared Folders</i> > <i>Shares</i> and + /// look at the <i>Properties</i> for a share. You will see two tabs - one + /// for "Share Permissions" and another for "Security". These correspond to + /// the ACLs returned by <tt>getShareSecurity</tt> and <tt>getSecurity</tt> + /// respectively. + /// </remarks> + /// <param name="resolveSids"> + /// Attempt to resolve the SIDs within each ACE form + /// their numeric representation to their corresponding account names. + /// </param> + /// <exception cref="System.IO.IOException"></exception> + public virtual Ace[] GetShareSecurity(bool resolveSids) + { + string p = Url.AbsolutePath; + MsrpcShareGetInfo rpc; + DcerpcHandle handle; + Ace[] aces; + ResolveDfs(null); + string server = GetServerWithDfs(); + rpc = new MsrpcShareGetInfo(server, Tree.Share); + handle = DcerpcHandle.GetHandle("ncacn_np:" + server + "[\\PIPE\\srvsvc]", Auth); + try + { + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, true); + } + aces = rpc.GetSecurity(); + if (aces != null) + { + ProcessAces(aces, resolveSids); + } + } + finally + { + try + { + handle.Close(); + } + catch (IOException ioe) + { + if (Log.Level >= 1) + { + Runtime.PrintStackTrace(ioe, Log); + } + } + } + return aces; + } + + /// <summary> + /// Return an array of Access Control Entry (ACE) objects representing + /// the security descriptor associated with this file or directory. + /// </summary> + /// <remarks> + /// Return an array of Access Control Entry (ACE) objects representing + /// the security descriptor associated with this file or directory. + /// <p> + /// Initially, the SIDs within each ACE will not be resolved however when + /// <tt>getType()</tt>, <tt>getDomainName()</tt>, <tt>getAccountName()</tt>, + /// or <tt>toString()</tt> is called, the names will attempt to be + /// resolved. If the names cannot be resolved (e.g. due to temporary + /// network failure), the said methods will return default values (usually + /// <tt>S-X-Y-Z</tt> strings of fragments of). + /// <p> + /// Alternatively <tt>getSecurity(true)</tt> may be used to resolve all + /// SIDs together and detect network failures. + /// </remarks> + /// <exception cref="System.IO.IOException"></exception> + public virtual Ace[] GetSecurity() + { + return GetSecurity(false); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileExtensions.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileExtensions.cs new file mode 100644 index 000000000..2ebcfa20f --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileExtensions.cs @@ -0,0 +1,133 @@ +// SmbFileExtensions.cs implementation by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +using System; +using System.Threading.Tasks; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + public static class SmbFileExtensions + { + /// <summary> + /// Get file's creation date converted to local timezone + /// </summary> + /// <param name="smbFile"></param> + /// <returns></returns> + public static DateTime GetLocalCreateTime(this SmbFile smbFile) + { + return TimeZoneInfo.ConvertTime(Extensions.CreateDateFromUTC(smbFile.CreateTime()), + TimeZoneInfo.Local); + } + + /// <summary> + /// Get file's last modified date converted to local timezone + /// </summary> + /// <param name="smbFile"></param> + /// <returns></returns> + public static DateTime GetLocalLastModified(this SmbFile smbFile) + { + return TimeZoneInfo.ConvertTime(Extensions.CreateDateFromUTC(smbFile.LastModified()), + TimeZoneInfo.Local); + } + + + /// <summary> + /// List files async + /// </summary> + /// <param name="smbFile"></param> + /// <returns></returns> + public static Task<SmbFile[]> ListFilesAsync(this SmbFile smbFile) + { + return Task.Run(() => smbFile.ListFiles()); + } + + /// <summary> + /// List files async + /// </summary> + /// <param name="smbFile"></param> + /// <param name="wildcard"></param> + /// <returns></returns> + public static Task<SmbFile[]> ListFilesAsync(this SmbFile smbFile, string wildcard) + { + return Task.Run(() => smbFile.ListFiles(wildcard)); + } + + /// <summary> + /// List files async + /// </summary> + /// <param name="smbFile"></param> + /// <returns></returns> + public static Task<string[]> ListAsync(this SmbFile smbFile) + { + return Task.Run(() => smbFile.List()); + } + + /// <summary> + /// MkDir async method + /// </summary> + /// <param name="smbFile"></param> + /// <returns></returns> + public static Task MkDirAsync(this SmbFile smbFile) + { + return Task.Run(() => smbFile.Mkdir()); + } + + + /// <summary> + /// Delete file async + /// </summary> + /// <param name="smbFile"></param> + /// <returns></returns> + public static Task DeleteAsync(this SmbFile smbFile) + { + return Task.Run(() => smbFile.Delete()); + } + + /// <summary> + /// Rename file async + /// </summary> + /// <param name="smbFile"></param> + /// <param name="destination"></param> + /// <returns></returns> + public static Task RenameToAsync(this SmbFile smbFile, SmbFile destination) + { + return Task.Run(() => smbFile.RenameTo(destination)); + } + + /// <summary> + /// Get input stream async + /// </summary> + /// <param name="smbFile"></param> + /// <returns></returns> + public static Task<InputStream> GetInputStreamAsync(this SmbFile smbFile) + { + return Task.Run(() => smbFile.GetInputStream()); + } + + + /// <summary> + /// Get output stream async + /// </summary> + /// <param name="smbFile"></param> + /// <param name="append"></param> + /// <returns></returns> + public static Task<OutputStream> GetOutputStreamAsync(this SmbFile smbFile, bool append = false) + { + return Task.Run(() => new SmbFileOutputStream(smbFile, append) as OutputStream); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileFilter.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileFilter.cs new file mode 100644 index 000000000..196bfc1b6 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileFilter.cs @@ -0,0 +1,24 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public interface ISmbFileFilter + { + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + bool Accept(SmbFile file); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileInputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileInputStream.cs new file mode 100644 index 000000000..a9a0ea112 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileInputStream.cs @@ -0,0 +1,339 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Util.Sharpen; +using SharpCifs.Util.Transport; + +namespace SharpCifs.Smb +{ + /// <summary>This InputStream can read bytes from a file on an SMB file server.</summary> + /// <remarks>This InputStream can read bytes from a file on an SMB file server. Offsets are 64 bits. + /// </remarks> + public class SmbFileInputStream : InputStream + { + private long _fp; + + private int _readSize; + + private int _openFlags; + + private int _access; + + private byte[] _tmp = new byte[1]; + + internal SmbFile File; + + /// <summary> + /// Creates an + /// <see cref="System.IO.InputStream">System.IO.InputStream</see> + /// for reading bytes from a file on + /// an SMB server addressed by the <code>url</code> parameter. See + /// <see cref="SmbFile">SmbFile</see> + /// for a detailed description and examples of the smb + /// URL syntax. + /// </summary> + /// <param name="url">An smb URL string representing the file to read from</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFileInputStream(string url) : this(new SmbFile(url)) + { + } + + /// <summary> + /// Creates an + /// <see cref="System.IO.InputStream">System.IO.InputStream</see> + /// for reading bytes from a file on + /// an SMB server represented by the + /// <see cref="SmbFile">SmbFile</see> + /// parameter. See + /// <see cref="SmbFile">SmbFile</see> + /// for a detailed description and examples of + /// the smb URL syntax. + /// </summary> + /// <param name="file">An <code>SmbFile</code> specifying the file to read from</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFileInputStream(SmbFile file) : this(file, SmbFile.ORdonly) + { + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + internal SmbFileInputStream(SmbFile file, int openFlags) + { + this.File = file; + this._openFlags = openFlags & 0xFFFF; + _access = ((int)(((uint)openFlags) >> 16)) & 0xFFFF; + if (file.Type != SmbFile.TypeNamedPipe) + { + file.Open(openFlags, _access, SmbFile.AttrNormal, 0); + this._openFlags &= ~(SmbFile.OCreat | SmbFile.OTrunc); + } + else + { + file.Connect0(); + } + _readSize = Math.Min(file.Tree.Session.transport.RcvBufSize - 70, file.Tree.Session + .transport.Server.MaxBufferSize - 70); + } + + protected internal virtual IOException SeToIoe(SmbException se) + { + IOException ioe = se; + Exception root = se.GetRootCause(); + if (root is TransportException) + { + ioe = (TransportException)root; + root = ((TransportException)ioe).GetRootCause(); + } + if (root is Exception) + { + ioe = new IOException(root.Message); + ioe.InitCause(root); + } + return ioe; + } + + /// <summary>Closes this input stream and releases any system resources associated with the stream. + /// </summary> + /// <remarks>Closes this input stream and releases any system resources associated with the stream. + /// </remarks> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override void Close() + { + try + { + File.Close(); + _tmp = null; + } + catch (SmbException se) + { + throw SeToIoe(se); + } + } + + /// <summary>Reads a byte of data from this input stream.</summary> + /// <remarks>Reads a byte of data from this input stream.</remarks> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override int Read() + { + // need oplocks to cache otherwise use BufferedInputStream + if (Read(_tmp, 0, 1) == -1) + { + return -1; + } + return _tmp[0] & unchecked(0xFF); + } + + /// <summary>Reads up to b.length bytes of data from this input stream into an array of bytes. + /// </summary> + /// <remarks>Reads up to b.length bytes of data from this input stream into an array of bytes. + /// </remarks> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override int Read(byte[] b) + { + return Read(b, 0, b.Length); + } + + /// <summary>Reads up to len bytes of data from this input stream into an array of bytes. + /// </summary> + /// <remarks>Reads up to len bytes of data from this input stream into an array of bytes. + /// </remarks> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override int Read(byte[] b, int off, int len) + { + return ReadDirect(b, off, len); + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual int ReadDirect(byte[] b, int off, int len) + { + if (len <= 0) + { + return 0; + } + + long start = _fp; + if (_tmp == null) + { + throw new IOException("Bad file descriptor"); + } + + // ensure file is open + File.Open(_openFlags, _access, SmbFile.AttrNormal, 0); + if (File.Log.Level >= 4) + { + File.Log.WriteLine("read: fid=" + File.Fid + ",off=" + off + ",len=" + len); + } + + SmbComReadAndXResponse response = new SmbComReadAndXResponse(b, off); + if (File.Type == SmbFile.TypeNamedPipe) + { + response.ResponseTimeout = 0; + } + + int r; + int n; + do + { + r = len > _readSize ? _readSize : len; + if (File.Log.Level >= 4) + { + File.Log.WriteLine("read: len=" + len + ",r=" + r + ",fp=" + _fp); + } + + try + { + SmbComReadAndX request = new SmbComReadAndX(File.Fid, _fp, r, null); + if (File.Type == SmbFile.TypeNamedPipe) + { + request.MinCount = request.MaxCount = request.Remaining = 1024; + } + //œǂݍł炵B + File.Send(request, response); + } + catch (SmbException se) + { + if (File.Type == SmbFile.TypeNamedPipe && se.GetNtStatus() == NtStatus.NtStatusPipeBroken) + { + return -1; + } + throw SeToIoe(se); + } + + if ((n = response.DataLength) <= 0) + { + return (int)((_fp - start) > 0L ? _fp - start : -1); + } + + _fp += n; + len -= n; + response.Off += n; + } + while (len > 0 && n == r); + + + return (int)(_fp - start); + } + + /// <summary>This stream class is unbuffered.</summary> + /// <remarks> + /// This stream class is unbuffered. Therefore this method will always + /// return 0 for streams connected to regular files. However, a + /// stream created from a Named Pipe this method will query the server using a + /// "peek named pipe" operation and return the number of available bytes + /// on the server. + /// </remarks> + /// <exception cref="System.IO.IOException"></exception> + public override int Available() + { + SmbNamedPipe pipe; + TransPeekNamedPipe req; + TransPeekNamedPipeResponse resp; + if (File.Type != SmbFile.TypeNamedPipe) + { + return 0; + } + try + { + pipe = (SmbNamedPipe)File; + File.Open(SmbFile.OExcl, pipe.PipeType & 0xFF0000, SmbFile.AttrNormal + , 0); + req = new TransPeekNamedPipe(File.Unc, File.Fid); + resp = new TransPeekNamedPipeResponse(pipe); + pipe.Send(req, resp); + if (resp.status == TransPeekNamedPipeResponse.StatusDisconnected || resp.status + == TransPeekNamedPipeResponse.StatusServerEndClosed) + { + File.Opened = false; + return 0; + } + return resp.Available; + } + catch (SmbException se) + { + throw SeToIoe(se); + } + } + + /// <summary>Skip n bytes of data on this stream.</summary> + /// <remarks> + /// Skip n bytes of data on this stream. This operation will not result + /// in any IO with the server. Unlink <tt>InputStream</tt> value less than + /// the one provided will not be returned if it exceeds the end of the file + /// (if this is a problem let us know). + /// </remarks> + /// <exception cref="System.IO.IOException"></exception> + public override long Skip(long n) + { + if (n > 0) + { + _fp += n; + return n; + } + return 0; + } + + + /// <summary> + /// Position in Stream + /// </summary> + /// <remarks> + /// Add by dobes + /// mod interface to WrappedSystemStream readable, for random access. + /// </remarks> + internal override long Position { + get { return this._fp; } + set + { + var tmpPos = value; + var length = File.Length(); + if (tmpPos < 0) + tmpPos = 0; + else if (length < tmpPos) + tmpPos = length; + this._fp = tmpPos; + } + } + + /// <summary> + /// + /// </summary> + /// <returns></returns> + /// <remarks> + /// Add by dobes + /// mod interface to WrappedSystemStream readable, for random access. + /// </remarks> + internal override bool CanSeek() + { + return (File.Length() >= 0); + } + + /// <summary> + /// Get file length + /// </summary> + public override long Length + { + get { return File.Length(); } + } + + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileOutputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileOutputStream.cs new file mode 100644 index 000000000..58c704dd7 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFileOutputStream.cs @@ -0,0 +1,335 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + /// <summary>This <code>OutputStream</code> can write bytes to a file on an SMB file server. + /// </summary> + /// <remarks>This <code>OutputStream</code> can write bytes to a file on an SMB file server. + /// </remarks> + public class SmbFileOutputStream : OutputStream + { + private SmbFile _file; + + private bool _append; + + private bool _useNtSmbs; + + private int _openFlags; + + private int _access; + + private int _writeSize; + + private long _fp; + + private byte[] _tmp = new byte[1]; + + private SmbComWriteAndX _reqx; + + private SmbComWriteAndXResponse _rspx; + + private SmbComWrite _req; + + private SmbComWriteResponse _rsp; + + /// <summary> + /// Creates an + /// <see cref="System.IO.OutputStream">System.IO.OutputStream</see> + /// for writing to a file + /// on an SMB server addressed by the URL parameter. See + /// <see cref="SmbFile">SmbFile</see> + /// for a detailed description and examples of + /// the smb URL syntax. + /// </summary> + /// <param name="url">An smb URL string representing the file to write to</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFileOutputStream(string url) : this(url, false) + { + } + + /// <summary> + /// Creates an + /// <see cref="System.IO.OutputStream">System.IO.OutputStream</see> + /// for writing bytes to a file on + /// an SMB server represented by the + /// <see cref="SmbFile">SmbFile</see> + /// parameter. See + /// <see cref="SmbFile">SmbFile</see> + /// for a detailed description and examples of + /// the smb URL syntax. + /// </summary> + /// <param name="file">An <code>SmbFile</code> specifying the file to write to</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFileOutputStream(SmbFile file) : this(file, false) + { + } + + /// <summary> + /// Creates an + /// <see cref="System.IO.OutputStream">System.IO.OutputStream</see> + /// for writing bytes to a file on an + /// SMB server addressed by the URL parameter. See + /// <see cref="SmbFile">SmbFile</see> + /// for a detailed description and examples of the smb URL syntax. If the + /// second argument is <code>true</code>, then bytes will be written to the + /// end of the file rather than the beginning. + /// </summary> + /// <param name="url">An smb URL string representing the file to write to</param> + /// <param name="append">Append to the end of file</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFileOutputStream(string url, bool append) : this(new SmbFile(url), append + ) + { + } + + /// <summary> + /// Creates an + /// <see cref="System.IO.OutputStream">System.IO.OutputStream</see> + /// for writing bytes to a file + /// on an SMB server addressed by the <code>SmbFile</code> parameter. See + /// <see cref="SmbFile">SmbFile</see> + /// for a detailed description and examples of + /// the smb URL syntax. If the second argument is <code>true</code>, then + /// bytes will be written to the end of the file rather than the beginning. + /// </summary> + /// <param name="file">An <code>SmbFile</code> representing the file to write to</param> + /// <param name="append">Append to the end of file</param> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFileOutputStream(SmbFile file, bool append) : this(file, append, append + ? SmbFile.OCreat | SmbFile.OWronly | SmbFile.OAppend : SmbFile.OCreat | SmbFile + .OWronly | SmbFile.OTrunc) + { + } + + /// <summary> + /// Creates an + /// <see cref="System.IO.OutputStream">System.IO.OutputStream</see> + /// for writing bytes to a file + /// on an SMB server addressed by the <code>SmbFile</code> parameter. See + /// <see cref="SmbFile">SmbFile</see> + /// for a detailed description and examples of + /// the smb URL syntax. + /// <p> + /// The second parameter specifies how the file should be shared. If + /// <code>SmbFile.FILE_NO_SHARE</code> is specified the client will + /// have exclusive access to the file. An additional open command + /// from jCIFS or another application will fail with the "file is being + /// accessed by another process" error. The <code>FILE_SHARE_READ</code>, + /// <code>FILE_SHARE_WRITE</code>, and <code>FILE_SHARE_DELETE</code> may be + /// combined with the bitwise OR '|' to specify that other peocesses may read, + /// write, and/or delete the file while the jCIFS user has the file open. + /// </summary> + /// <param name="url">An smb URL representing the file to write to</param> + /// <param name="shareAccess">File sharing flag: <code>SmbFile.FILE_NOSHARE</code> or any combination of <code>SmbFile.FILE_READ</code>, <code>SmbFile.FILE_WRITE</code>, and <code>SmbFile.FILE_DELETE</code> + /// </param> + /// <exception cref="Jcifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbFileOutputStream(string url, int shareAccess) : this(new SmbFile(url, string.Empty + , null, shareAccess), false) + { + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + internal SmbFileOutputStream(SmbFile file, bool append, int openFlags) + { + this._file = file; + this._append = append; + this._openFlags = openFlags; + _access = ((int)(((uint)openFlags) >> 16)) & 0xFFFF; + if (append) + { + try + { + _fp = file.Length(); + } + catch (SmbAuthException sae) + { + throw; + } + catch (SmbException) + { + _fp = 0L; + } + } + if (file is SmbNamedPipe && file.Unc.StartsWith("\\pipe\\")) + { + file.Unc = Runtime.Substring(file.Unc, 5); + file.Send(new TransWaitNamedPipe("\\pipe" + file.Unc), new TransWaitNamedPipeResponse + ()); + } + file.Open(openFlags, _access | SmbConstants.FileWriteData, SmbFile.AttrNormal, + 0); + this._openFlags &= ~(SmbFile.OCreat | SmbFile.OTrunc); + _writeSize = file.Tree.Session.transport.SndBufSize - 70; + _useNtSmbs = file.Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs + ); + if (_useNtSmbs) + { + _reqx = new SmbComWriteAndX(); + _rspx = new SmbComWriteAndXResponse(); + } + else + { + _req = new SmbComWrite(); + _rsp = new SmbComWriteResponse(); + } + } + + /// <summary> + /// Closes this output stream and releases any system resources associated + /// with it. + /// </summary> + /// <remarks> + /// Closes this output stream and releases any system resources associated + /// with it. + /// </remarks> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override void Close() + { + _file.Close(); + _tmp = null; + } + + /// <summary>Writes the specified byte to this file output stream.</summary> + /// <remarks>Writes the specified byte to this file output stream.</remarks> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override void Write(int b) + { + _tmp[0] = unchecked((byte)b); + Write(_tmp, 0, 1); + } + + /// <summary> + /// Writes b.length bytes from the specified byte array to this + /// file output stream. + /// </summary> + /// <remarks> + /// Writes b.length bytes from the specified byte array to this + /// file output stream. + /// </remarks> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override void Write(byte[] b) + { + Write(b, 0, b.Length); + } + + public virtual bool IsOpen() + { + return _file.IsOpen(); + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual void EnsureOpen() + { + // ensure file is open + if (_file.IsOpen() == false) + { + _file.Open(_openFlags, _access | SmbConstants.FileWriteData, SmbFile.AttrNormal, + 0); + if (_append) + { + _fp = _file.Length(); + } + } + } + + /// <summary> + /// Writes len bytes from the specified byte array starting at + /// offset off to this file output stream. + /// </summary> + /// <remarks> + /// Writes len bytes from the specified byte array starting at + /// offset off to this file output stream. + /// </remarks> + /// <param name="b">The array</param> + /// <exception cref="System.IO.IOException">if a network error occurs</exception> + public override void Write(byte[] b, int off, int len) + { + if (_file.IsOpen() == false && _file is SmbNamedPipe) + { + _file.Send(new TransWaitNamedPipe("\\pipe" + _file.Unc), new TransWaitNamedPipeResponse + ()); + } + WriteDirect(b, off, len, 0); + } + + /// <summary>Just bypasses TransWaitNamedPipe - used by DCERPC bind.</summary> + /// <remarks>Just bypasses TransWaitNamedPipe - used by DCERPC bind.</remarks> + /// <exception cref="System.IO.IOException"></exception> + public virtual void WriteDirect(byte[] b, int off, int len, int flags) + { + if (len <= 0) + { + return; + } + if (_tmp == null) + { + throw new IOException("Bad file descriptor"); + } + EnsureOpen(); + /*if (file.log.level >= 4) + { + file.log.WriteLine("write: fid=" + file.fid + ",off=" + off + ",len=" + len); + }*/ + int w; + do + { + w = len > _writeSize ? _writeSize : len; + if (_useNtSmbs) + { + _reqx.SetParam(_file.Fid, _fp, len - w, b, off, w); + if ((flags & 1) != 0) + { + _reqx.SetParam(_file.Fid, _fp, len, b, off, w); + _reqx.WriteMode = 0x8; + } + else + { + _reqx.WriteMode = 0; + } + _file.Send(_reqx, _rspx); + _fp += _rspx.Count; + len -= (int)_rspx.Count; + off += (int)_rspx.Count; + } + else + { + _req.SetParam(_file.Fid, _fp, len - w, b, off, w); + _fp += _rsp.Count; + len -= (int)_rsp.Count; + off += (int)_rsp.Count; + _file.Send(_req, _rsp); + } + } + while (len > 0); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFilenameFilter.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFilenameFilter.cs new file mode 100644 index 000000000..b66dc133a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbFilenameFilter.cs @@ -0,0 +1,24 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public interface ISmbFilenameFilter + { + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + bool Accept(SmbFile dir, string name); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbNamedPipe.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbNamedPipe.cs new file mode 100644 index 000000000..f09e16cca --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbNamedPipe.cs @@ -0,0 +1,210 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + /// <summary> + /// This class will allow a Java program to read and write data to Named + /// Pipes and Transact NamedPipes. + /// </summary> + /// <remarks> + /// This class will allow a Java program to read and write data to Named + /// Pipes and Transact NamedPipes. + /// <p>There are three Win32 function calls provided by the Windows SDK + /// that are important in the context of using jCIFS. They are: + /// <ul> + /// <li> <code>CallNamedPipe</code> A message-type pipe call that opens, + /// writes to, reads from, and closes the pipe in a single operation. + /// <li> <code>TransactNamedPipe</code> A message-type pipe call that + /// writes to and reads from an existing pipe descriptor in one operation. + /// <li> <code>CreateFile</code>, <code>ReadFile</code>, + /// <code>WriteFile</code>, and <code>CloseFile</code> A byte-type pipe can + /// be opened, written to, read from and closed using the standard Win32 + /// file operations. + /// </ul> + /// <p>The jCIFS API maps all of these operations into the standard Java + /// <code>XxxputStream</code> interface. A special <code>PIPE_TYPE</code> + /// flags is necessary to distinguish which type of Named Pipe behavior + /// is desired. + /// <p><table border="1" cellpadding="3" cellspacing="0" width="100%"> + /// <tr bgcolor="#ccccff"> + /// <td colspan="2"><b><code>SmbNamedPipe</code> Constructor Examples</b></td> + /// <tr><td width="20%"><b>Code Sample</b></td><td><b>Description</b></td></tr> + /// <tr><td width="20%"><pre> + /// new SmbNamedPipe( "smb://server/IPC$/PIPE/foo", + /// SmbNamedPipe.PIPE_TYPE_RDWR | + /// SmbNamedPipe.PIPE_TYPE_CALL ); + /// </pre></td><td> + /// Open the Named Pipe foo for reading and writing. The pipe will behave like the <code>CallNamedPipe</code> interface. + /// </td></tr> + /// <tr><td width="20%"><pre> + /// new SmbNamedPipe( "smb://server/IPC$/foo", + /// SmbNamedPipe.PIPE_TYPE_RDWR | + /// SmbNamedPipe.PIPE_TYPE_TRANSACT ); + /// </pre></td><td> + /// Open the Named Pipe foo for reading and writing. The pipe will behave like the <code>TransactNamedPipe</code> interface. + /// </td></tr> + /// <tr><td width="20%"><pre> + /// new SmbNamedPipe( "smb://server/IPC$/foo", + /// SmbNamedPipe.PIPE_TYPE_RDWR ); + /// </pre></td><td> + /// Open the Named Pipe foo for reading and writing. The pipe will + /// behave as though the <code>CreateFile</code>, <code>ReadFile</code>, + /// <code>WriteFile</code>, and <code>CloseFile</code> interface was + /// being used. + /// </td></tr> + /// </table> + /// <p>See <a href="../../../pipes.html">Using jCIFS to Connect to Win32 + /// Named Pipes</a> for a detailed description of how to use jCIFS with + /// Win32 Named Pipe server processes. + /// </remarks> + public class SmbNamedPipe : SmbFile + { + /// <summary>The pipe should be opened read-only.</summary> + /// <remarks>The pipe should be opened read-only.</remarks> + public const int PipeTypeRdonly = ORdonly; + + /// <summary>The pipe should be opened only for writing.</summary> + /// <remarks>The pipe should be opened only for writing.</remarks> + public const int PipeTypeWronly = OWronly; + + /// <summary>The pipe should be opened for both reading and writing.</summary> + /// <remarks>The pipe should be opened for both reading and writing.</remarks> + public const int PipeTypeRdwr = ORdwr; + + /// <summary>Pipe operations should behave like the <code>CallNamedPipe</code> Win32 Named Pipe function. + /// </summary> + /// <remarks>Pipe operations should behave like the <code>CallNamedPipe</code> Win32 Named Pipe function. + /// </remarks> + public const int PipeTypeCall = unchecked(0x0100); + + /// <summary>Pipe operations should behave like the <code>TransactNamedPipe</code> Win32 Named Pipe function. + /// </summary> + /// <remarks>Pipe operations should behave like the <code>TransactNamedPipe</code> Win32 Named Pipe function. + /// </remarks> + public const int PipeTypeTransact = unchecked(0x0200); + + public const int PipeTypeDceTransact = unchecked(0x0200) | unchecked(0x0400); + + internal InputStream PipeIn; + + internal OutputStream PipeOut; + + internal int PipeType; + + /// <summary> + /// Open the Named Pipe resource specified by the url + /// parameter. + /// </summary> + /// <remarks> + /// Open the Named Pipe resource specified by the url + /// parameter. The pipeType parameter should be at least one of + /// the <code>PIPE_TYPE</code> flags combined with the bitwise OR + /// operator <code>|</code>. See the examples listed above. + /// </remarks> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbNamedPipe(string url, int pipeType) : base(url) + { + this.PipeType = pipeType; + Type = TypeNamedPipe; + } + + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbNamedPipe(string url, int pipeType, NtlmPasswordAuthentication auth) : + base(url, auth) + { + this.PipeType = pipeType; + Type = TypeNamedPipe; + } + + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbNamedPipe(Uri url, int pipeType, NtlmPasswordAuthentication auth) : base + (url, auth) + { + this.PipeType = pipeType; + Type = TypeNamedPipe; + } + + /// <summary> + /// Return the <code>InputStream</code> used to read information + /// from this pipe instance. + /// </summary> + /// <remarks> + /// Return the <code>InputStream</code> used to read information + /// from this pipe instance. Presumably data would first be written + /// to the <code>OutputStream</code> associated with this Named + /// Pipe instance although this is not a requirement (e.g. a + /// read-only named pipe would write data to this stream on + /// connection). Reading from this stream may block. Therefore it + /// may be necessary that an addition thread be used to read and + /// write to a Named Pipe. + /// </remarks> + /// <exception cref="System.IO.IOException"></exception> + public virtual InputStream GetNamedPipeInputStream() + { + if (PipeIn == null) + { + if ((PipeType & PipeTypeCall) == PipeTypeCall || (PipeType & PipeTypeTransact + ) == PipeTypeTransact) + { + PipeIn = new TransactNamedPipeInputStream(this); + } + else + { + PipeIn = new SmbFileInputStream(this, (PipeType & unchecked((int)(0xFFFF00FF))) | + OExcl); + } + } + return PipeIn; + } + + /// <summary> + /// Return the <code>OutputStream</code> used to write + /// information to this pipe instance. + /// </summary> + /// <remarks> + /// Return the <code>OutputStream</code> used to write + /// information to this pipe instance. The act of writing data + /// to this stream will result in response data recieved in the + /// <code>InputStream</code> associated with this Named Pipe + /// instance (unless of course it does not elicite a response or the pipe is write-only). + /// </remarks> + /// <exception cref="System.IO.IOException"></exception> + public virtual OutputStream GetNamedPipeOutputStream() + { + if (PipeOut == null) + { + if ((PipeType & PipeTypeCall) == PipeTypeCall || (PipeType & PipeTypeTransact + ) == PipeTypeTransact) + { + PipeOut = new TransactNamedPipeOutputStream(this); + } + else + { + PipeOut = new SmbFileOutputStream(this, false, (PipeType & unchecked((int)(0xFFFF00FF + ))) | OExcl); + } + } + return PipeOut; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbRandomAccessFile.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbRandomAccessFile.cs new file mode 100644 index 000000000..445a0656c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbRandomAccessFile.cs @@ -0,0 +1,506 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using System.Text; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + public class SmbRandomAccessFile //: DataOutput, DataInput + { + private const int WriteOptions = unchecked(0x0842); + + private SmbFile _file; + + private long _fp; + + private int _openFlags; + + private int _access; + + private int _readSize; + + private int _writeSize; + + private int _ch; + + private int _options; + + private byte[] _tmp = new byte[8]; + + private SmbComWriteAndXResponse _writeAndxResp; + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbRandomAccessFile(string url, string mode, int shareAccess) : this(new SmbFile + (url, string.Empty, null, shareAccess), mode) + { + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + public SmbRandomAccessFile(SmbFile file, string mode) + { + this._file = file; + if (mode.Equals("r")) + { + _openFlags = SmbFile.OCreat | SmbFile.ORdonly; + } + else + { + if (mode.Equals("rw")) + { + _openFlags = SmbFile.OCreat | SmbFile.ORdwr | SmbFile.OAppend; + _writeAndxResp = new SmbComWriteAndXResponse(); + _options = WriteOptions; + _access = SmbConstants.FileReadData | SmbConstants.FileWriteData; + } + else + { + throw new ArgumentException("Invalid mode"); + } + } + file.Open(_openFlags, _access, SmbFile.AttrNormal, _options); + _readSize = file.Tree.Session.transport.RcvBufSize - 70; + _writeSize = file.Tree.Session.transport.SndBufSize - 70; + _fp = 0L; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual int Read() + { + if (Read(_tmp, 0, 1) == -1) + { + return -1; + } + return _tmp[0] & unchecked(0xFF); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual int Read(byte[] b) + { + return Read(b, 0, b.Length); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual int Read(byte[] b, int off, int len) + { + if (len <= 0) + { + return 0; + } + long start = _fp; + // ensure file is open + if (_file.IsOpen() == false) + { + _file.Open(_openFlags, 0, SmbFile.AttrNormal, _options); + } + int r; + int n; + SmbComReadAndXResponse response = new SmbComReadAndXResponse(b, off); + do + { + r = len > _readSize ? _readSize : len; + _file.Send(new SmbComReadAndX(_file.Fid, _fp, r, null), response); + if ((n = response.DataLength) <= 0) + { + return (int)((_fp - start) > 0L ? _fp - start : -1); + } + _fp += n; + len -= n; + response.Off += n; + } + while (len > 0 && n == r); + return (int)(_fp - start); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void ReadFully(byte[] b) + { + ReadFully(b, 0, b.Length); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void ReadFully(byte[] b, int off, int len) + { + int n = 0; + int count; + do + { + count = Read(b, off + n, len - n); + if (count < 0) + { + throw new SmbException("EOF"); + } + n += count; + _fp += count; + } + while (n < len); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual int SkipBytes(int n) + { + if (n > 0) + { + _fp += n; + return n; + } + return 0; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Write(int b) + { + _tmp[0] = unchecked((byte)b); + Write(_tmp, 0, 1); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Write(byte[] b) + { + Write(b, 0, b.Length); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Write(byte[] b, int off, int len) + { + if (len <= 0) + { + return; + } + // ensure file is open + if (_file.IsOpen() == false) + { + _file.Open(_openFlags, 0, SmbFile.AttrNormal, _options); + } + int w; + do + { + w = len > _writeSize ? _writeSize : len; + _file.Send(new SmbComWriteAndX(_file.Fid, _fp, len - w, b, off, w, null), _writeAndxResp + ); + _fp += _writeAndxResp.Count; + len -= (int)_writeAndxResp.Count; + off += (int)_writeAndxResp.Count; + } + while (len > 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual long GetFilePointer() + { + return _fp; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Seek(long pos) + { + _fp = pos; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual long Length() + { + return _file.Length(); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void SetLength(long newLength) + { + // ensure file is open + if (_file.IsOpen() == false) + { + _file.Open(_openFlags, 0, SmbFile.AttrNormal, _options); + } + SmbComWriteResponse rsp = new SmbComWriteResponse(); + _file.Send(new SmbComWrite(_file.Fid, (int)(newLength & unchecked(0xFFFFFFFFL)), 0, _tmp, 0, 0), rsp); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Close() + { + _file.Close(); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public bool ReadBoolean() + { + if ((Read(_tmp, 0, 1)) < 0) + { + throw new SmbException("EOF"); + } + return _tmp[0] != unchecked(unchecked(0x00)); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public byte ReadByte() + { + if ((Read(_tmp, 0, 1)) < 0) + { + throw new SmbException("EOF"); + } + return _tmp[0]; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public int ReadUnsignedByte() + { + if ((Read(_tmp, 0, 1)) < 0) + { + throw new SmbException("EOF"); + } + return _tmp[0] & unchecked(0xFF); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public short ReadShort() + { + if ((Read(_tmp, 0, 2)) < 0) + { + throw new SmbException("EOF"); + } + return Encdec.Dec_uint16be(_tmp, 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public int ReadUnsignedShort() + { + if ((Read(_tmp, 0, 2)) < 0) + { + throw new SmbException("EOF"); + } + return Encdec.Dec_uint16be(_tmp, 0) & unchecked(0xFFFF); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public char ReadChar() + { + if ((Read(_tmp, 0, 2)) < 0) + { + throw new SmbException("EOF"); + } + return (char)Encdec.Dec_uint16be(_tmp, 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public int ReadInt() + { + if ((Read(_tmp, 0, 4)) < 0) + { + throw new SmbException("EOF"); + } + return Encdec.Dec_uint32be(_tmp, 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public long ReadLong() + { + if ((Read(_tmp, 0, 8)) < 0) + { + throw new SmbException("EOF"); + } + return Encdec.Dec_uint64be(_tmp, 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public float ReadFloat() + { + if ((Read(_tmp, 0, 4)) < 0) + { + throw new SmbException("EOF"); + } + return Encdec.Dec_floatbe(_tmp, 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public double ReadDouble() + { + if ((Read(_tmp, 0, 8)) < 0) + { + throw new SmbException("EOF"); + } + return Encdec.Dec_doublebe(_tmp, 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public string ReadLine() + { + StringBuilder input = new StringBuilder(); + int c = -1; + bool eol = false; + while (!eol) + { + switch (c = Read()) + { + case -1: + case '\n': + { + eol = true; + break; + } + + case '\r': + { + eol = true; + long cur = _fp; + if (Read() != '\n') + { + _fp = cur; + } + break; + } + + default: + { + input.Append((char)c); + break; + } + } + } + if ((c == -1) && (input.Length == 0)) + { + return null; + } + return input.ToString(); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public string ReadUtf() + { + int size = ReadUnsignedShort(); + byte[] b = new byte[size]; + Read(b, 0, size); + try + { + return Encdec.Dec_utf8(b, 0, size); + } + catch (IOException ioe) + { + throw new SmbException(string.Empty, ioe); + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteBoolean(bool v) + { + _tmp[0] = unchecked((byte)(v ? 1 : 0)); + Write(_tmp, 0, 1); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteByte(int v) + { + _tmp[0] = unchecked((byte)v); + Write(_tmp, 0, 1); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteShort(int v) + { + Encdec.Enc_uint16be((short)v, _tmp, 0); + Write(_tmp, 0, 2); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteChar(int v) + { + Encdec.Enc_uint16be((short)v, _tmp, 0); + Write(_tmp, 0, 2); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteInt(int v) + { + Encdec.Enc_uint32be(v, _tmp, 0); + Write(_tmp, 0, 4); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteLong(long v) + { + Encdec.Enc_uint64be(v, _tmp, 0); + Write(_tmp, 0, 8); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteFloat(float v) + { + Encdec.Enc_floatbe(v, _tmp, 0); + Write(_tmp, 0, 4); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteDouble(double v) + { + Encdec.Enc_doublebe(v, _tmp, 0); + Write(_tmp, 0, 8); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteBytes(string s) + { + byte[] b = Runtime.GetBytesForString(s); + Write(b, 0, b.Length); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /* public void WriteChars(string s) + { + int clen = s.Length; + int blen = 2 * clen; + byte[] b = new byte[blen]; + char[] c = new char[clen]; + Sharpen.Runtime.GetCharsForString(s, 0, clen, c, 0); + for (int i = 0, j = 0; i < clen; i++) + { + b[j++] = unchecked((byte)((char)(((uchar)c[i]) >> 8))); + b[j++] = unchecked((byte)((char)(((uchar)c[i]) >> 0))); + } + Write(b, 0, blen); + }*/ + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public void WriteUtf(string str) + { + int len = str.Length; + int ch; + int size = 0; + byte[] dst; + for (int i = 0; i < len; i++) + { + ch = str[i]; + size += ch > unchecked(0x07F) ? (ch > unchecked(0x7FF) ? 3 : 2) : 1; + } + dst = new byte[size]; + WriteShort(size); + try + { + Encdec.Enc_utf8(str, dst, 0, size); + } + catch (IOException ioe) + { + throw new SmbException(string.Empty, ioe); + } + Write(dst, 0, size); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbSession.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbSession.cs new file mode 100644 index 000000000..6dc5087d0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbSession.cs @@ -0,0 +1,570 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using SharpCifs.Netbios; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + public sealed class SmbSession + { + private static readonly string LogonShare = Config.GetProperty("jcifs.smb.client.logonShare" + , null); + + private static readonly int LookupRespLimit = Config.GetInt("jcifs.netbios.lookupRespLimit" + , 3); + + private static readonly string Domain = Config.GetProperty("jcifs.smb.client.domain" + , null); + + private static readonly string Username = Config.GetProperty("jcifs.smb.client.username" + , null); + + private static readonly int CachePolicy = Config.GetInt("jcifs.netbios.cachePolicy" + , 60 * 10) * 60; + + internal static NbtAddress[] DcList; + + internal static long DcListExpiration; + + internal static int DcListCounter; + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + private static NtlmChallenge Interrogate(NbtAddress addr) + { + UniAddress dc = new UniAddress(addr); + SmbTransport trans = SmbTransport.GetSmbTransport(dc, 0); + if (Username == null) + { + trans.Connect(); + if (SmbTransport.LogStatic.Level >= 3) + { + SmbTransport.LogStatic.WriteLine("Default credentials (jcifs.smb.client.username/password)" + + " not specified. SMB signing may not work propertly." + " Skipping DC interrogation." + ); + } + } + else + { + SmbSession ssn = trans.GetSmbSession(NtlmPasswordAuthentication.Default + ); + ssn.GetSmbTree(LogonShare, null).TreeConnect(null, null); + } + return new NtlmChallenge(trans.Server.EncryptionKey, dc); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="UnknownHostException"></exception> + public static NtlmChallenge GetChallengeForDomain() + { + if (Domain == null) + { + throw new SmbException("A domain was not specified"); + } + lock (Domain) + { + long now = Runtime.CurrentTimeMillis(); + int retry = 1; + do + { + if (DcListExpiration < now) + { + NbtAddress[] list = NbtAddress.GetAllByName(Domain, 0x1C, null, + null); + DcListExpiration = now + CachePolicy * 1000L; + if (list != null && list.Length > 0) + { + DcList = list; + } + else + { + DcListExpiration = now + 1000 * 60 * 15; + if (SmbTransport.LogStatic.Level >= 2) + { + SmbTransport.LogStatic.WriteLine("Failed to retrieve DC list from WINS"); + } + } + } + int max = Math.Min(DcList.Length, LookupRespLimit); + for (int j = 0; j < max; j++) + { + int i = DcListCounter++ % max; + if (DcList[i] != null) + { + try + { + return Interrogate(DcList[i]); + } + catch (SmbException se) + { + if (SmbTransport.LogStatic.Level >= 2) + { + SmbTransport.LogStatic.WriteLine("Failed validate DC: " + DcList[i]); + if (SmbTransport.LogStatic.Level > 2) + { + Runtime.PrintStackTrace(se, SmbTransport.LogStatic); + } + } + } + DcList[i] = null; + } + } + DcListExpiration = 0; + } + while (retry-- > 0); + DcListExpiration = now + 1000 * 60 * 15; + } + throw new UnknownHostException("Failed to negotiate with a suitable domain controller for " + + Domain); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="UnknownHostException"></exception> + public static byte[] GetChallenge(UniAddress dc) + { + return GetChallenge(dc, 0); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="UnknownHostException"></exception> + public static byte[] GetChallenge(UniAddress dc, int port) + { + SmbTransport trans = SmbTransport.GetSmbTransport(dc, port); + trans.Connect(); + return trans.Server.EncryptionKey; + } + + /// <summary> + /// Authenticate arbitrary credentials represented by the + /// <tt>NtlmPasswordAuthentication</tt> object against the domain controller + /// specified by the <tt>UniAddress</tt> parameter. + /// </summary> + /// <remarks> + /// Authenticate arbitrary credentials represented by the + /// <tt>NtlmPasswordAuthentication</tt> object against the domain controller + /// specified by the <tt>UniAddress</tt> parameter. If the credentials are + /// not accepted, an <tt>SmbAuthException</tt> will be thrown. If an error + /// occurs an <tt>SmbException</tt> will be thrown. If the credentials are + /// valid, the method will return without throwing an exception. See the + /// last <a href="../../../faq.html">FAQ</a> question. + /// <p> + /// See also the <tt>jcifs.smb.client.logonShare</tt> property. + /// </remarks> + /// <exception cref="SmbException"></exception> + public static void Logon(UniAddress dc, NtlmPasswordAuthentication auth) + { + Logon(dc, -1, auth); + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public static void Logon(UniAddress dc, int port, NtlmPasswordAuthentication auth + ) + { + SmbTree tree = SmbTransport.GetSmbTransport(dc, port).GetSmbSession(auth).GetSmbTree + (LogonShare, null); + if (LogonShare == null) + { + tree.TreeConnect(null, null); + } + else + { + Trans2FindFirst2 req = new Trans2FindFirst2("\\", "*", SmbFile.AttrDirectory); + Trans2FindFirst2Response resp = new Trans2FindFirst2Response(); + tree.Send(req, resp); + } + } + + internal int ConnectionState; + + internal int Uid; + + internal List<object> Trees; + + private UniAddress _address; + + private int _port; + + private int _localPort; + + private IPAddress _localAddr; + + internal SmbTransport transport; + + internal NtlmPasswordAuthentication Auth; + + internal long Expiration; + + internal string NetbiosName; + + internal SmbSession(UniAddress address, int port, IPAddress localAddr, int localPort + , NtlmPasswordAuthentication auth) + { + // Transport parameters allows trans to be removed from CONNECTIONS + this._address = address; + this._port = port; + this._localAddr = localAddr; + this._localPort = localPort; + this.Auth = auth; + Trees = new List<object>(); + ConnectionState = 0; + } + + internal SmbTree GetSmbTree(string share, string service) + { + lock (this) + { + SmbTree t; + if (share == null) + { + share = "IPC$"; + } + /*for (IEnumeration e = trees.GetEnumerator(); e.MoveNext(); ) + { + t = (SmbTree)e.Current; + if (t.Matches(share, service)) + { + return t; + } + }*/ + foreach (var e in Trees) + { + t = (SmbTree)e; + if (t.Matches(share, service)) + { + return t; + } + } + + t = new SmbTree(this, share, service); + Trees.Add(t); + return t; + } + } + + internal bool Matches(NtlmPasswordAuthentication auth) + { + return this.Auth == auth || this.Auth.Equals(auth); + } + + internal SmbTransport Transport() + { + lock (this) + { + if (transport == null) + { + transport = SmbTransport.GetSmbTransport(_address, _port, _localAddr, _localPort, null + ); + } + return transport; + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal void Send(ServerMessageBlock request, ServerMessageBlock response) + { + lock (Transport()) + { + if (response != null) + { + response.Received = false; + } + Expiration = Runtime.CurrentTimeMillis() + SmbConstants.SoTimeout; + SessionSetup(request, response); + if (response != null && response.Received) + { + return; + } + if (request is SmbComTreeConnectAndX) + { + SmbComTreeConnectAndX tcax = (SmbComTreeConnectAndX)request; + if (NetbiosName != null && tcax.path.EndsWith("\\IPC$")) + { + tcax.path = "\\\\" + NetbiosName + "\\IPC$"; + } + } + request.Uid = Uid; + request.Auth = Auth; + try + { + transport.Send(request, response); + } + catch (SmbException se) + { + if (request is SmbComTreeConnectAndX) + { + Logoff(true); + } + request.Digest = null; + throw; + } + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal void SessionSetup(ServerMessageBlock andx, ServerMessageBlock andxResponse + ) + { + lock (Transport()) + { + NtlmContext nctx = null; + SmbException ex = null; + SmbComSessionSetupAndX request; + SmbComSessionSetupAndXResponse response; + byte[] token = new byte[0]; + int state = 10; + while (ConnectionState != 0) + { + if (ConnectionState == 2 || ConnectionState == 3) + { + // connected or disconnecting + return; + } + try + { + Runtime.Wait(transport); + } + catch (Exception ie) + { + throw new SmbException(ie.Message, ie); + } + } + ConnectionState = 1; + // trying ... + try + { + transport.Connect(); + if (transport.Log.Level >= 4) + { + transport.Log.WriteLine("sessionSetup: accountName=" + Auth.Username + ",primaryDomain=" + + Auth.Domain); + } + Uid = 0; + do + { + switch (state) + { + case 10: + { + if (Auth != NtlmPasswordAuthentication.Anonymous && transport.HasCapability(SmbConstants + .CapExtendedSecurity)) + { + state = 20; + break; + } + request = new SmbComSessionSetupAndX(this, andx, Auth); + response = new SmbComSessionSetupAndXResponse(andxResponse); + if (transport.IsSignatureSetupRequired(Auth)) + { + if (Auth.HashesExternal && NtlmPasswordAuthentication.DefaultPassword != NtlmPasswordAuthentication + .Blank) + { + transport.GetSmbSession(NtlmPasswordAuthentication.Default).GetSmbTree(LogonShare + , null).TreeConnect(null, null); + } + else + { + byte[] signingKey = Auth.GetSigningKey(transport.Server.EncryptionKey); + request.Digest = new SigningDigest(signingKey, false); + } + } + request.Auth = Auth; + try + { + transport.Send(request, response); + } + catch (SmbAuthException sae) + { + throw; + } + catch (SmbException se) + { + ex = se; + } + if (response.IsLoggedInAsGuest && Runtime.EqualsIgnoreCase("GUEST", Auth. + Username) == false && transport.Server.Security != SmbConstants.SecurityShare && + Auth != NtlmPasswordAuthentication.Anonymous) + { + throw new SmbAuthException(NtStatus.NtStatusLogonFailure); + } + if (ex != null) + { + throw ex; + } + Uid = response.Uid; + if (request.Digest != null) + { + transport.Digest = request.Digest; + } + ConnectionState = 2; + state = 0; + break; + } + + case 20: + { + if (nctx == null) + { + bool doSigning = (transport.Flags2 & SmbConstants.Flags2SecuritySignatures + ) != 0; + nctx = new NtlmContext(Auth, doSigning); + } + if (SmbTransport.LogStatic.Level >= 4) + { + SmbTransport.LogStatic.WriteLine(nctx); + } + if (nctx.IsEstablished()) + { + NetbiosName = nctx.GetNetbiosName(); + ConnectionState = 2; + state = 0; + break; + } + try + { + token = nctx.InitSecContext(token, 0, token.Length); + } + catch (SmbException se) + { + try + { + transport.Disconnect(true); + } + catch (IOException) + { + } + Uid = 0; + throw; + } + if (token != null) + { + request = new SmbComSessionSetupAndX(this, null, token); + response = new SmbComSessionSetupAndXResponse(null); + if (transport.IsSignatureSetupRequired(Auth)) + { + byte[] signingKey = nctx.GetSigningKey(); + if (signingKey != null) + { + request.Digest = new SigningDigest(signingKey, true); + } + } + request.Uid = Uid; + Uid = 0; + try + { + transport.Send(request, response); + } + catch (SmbAuthException sae) + { + throw; + } + catch (SmbException se) + { + ex = se; + try + { + transport.Disconnect(true); + } + catch (Exception) + { + } + } + if (response.IsLoggedInAsGuest && Runtime.EqualsIgnoreCase("GUEST", Auth. + Username) == false) + { + throw new SmbAuthException(NtStatus.NtStatusLogonFailure); + } + if (ex != null) + { + throw ex; + } + Uid = response.Uid; + if (request.Digest != null) + { + transport.Digest = request.Digest; + } + token = response.Blob; + } + break; + } + + default: + { + throw new SmbException("Unexpected session setup state: " + state); + } + } + } + while (state != 0); + } + catch (SmbException se) + { + Logoff(true); + ConnectionState = 0; + throw; + } + finally + { + Runtime.NotifyAll(transport); + } + } + } + + internal void Logoff(bool inError) + { + lock (Transport()) + { + if (ConnectionState != 2) + { + // not-connected + return; + } + ConnectionState = 3; + // disconnecting + NetbiosName = null; + + foreach (SmbTree t in Trees) + { + t.TreeDisconnect(inError); + } + + if (!inError && transport.Server.Security != SmbConstants.SecurityShare) + { + SmbComLogoffAndX request = new SmbComLogoffAndX(null); + request.Uid = Uid; + try + { + transport.Send(request, null); + } + catch (SmbException) + { + } + Uid = 0; + } + ConnectionState = 0; + Runtime.NotifyAll(transport); + } + } + + public override string ToString() + { + return "SmbSession[accountName=" + Auth.Username + ",primaryDomain=" + Auth.Domain + + ",uid=" + Uid + ",connectionState=" + ConnectionState + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbShareInfo.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbShareInfo.cs new file mode 100644 index 000000000..811c76794 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbShareInfo.cs @@ -0,0 +1,104 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + public class SmbShareInfo : IFileEntry + { + protected internal string NetName; + + protected internal int Type; + + protected internal string Remark; + + public SmbShareInfo() + { + } + + public SmbShareInfo(string netName, int type, string remark) + { + this.NetName = netName; + this.Type = type; + this.Remark = remark; + } + + public virtual string GetName() + { + return NetName; + } + + public new virtual int GetType() + { + switch (Type & unchecked(0xFFFF)) + { + case 1: + { + return SmbFile.TypePrinter; + } + + case 3: + { + return SmbFile.TypeNamedPipe; + } + } + return SmbFile.TypeShare; + } + + public virtual int GetAttributes() + { + return SmbFile.AttrReadonly | SmbFile.AttrDirectory; + } + + public virtual long CreateTime() + { + return 0L; + } + + public virtual long LastModified() + { + return 0L; + } + + public virtual long Length() + { + return 0L; + } + + public override bool Equals(object obj) + { + if (obj is SmbShareInfo) + { + SmbShareInfo si = (SmbShareInfo)obj; + return NetName.Equals(si.NetName); + } + return false; + } + + public override int GetHashCode() + { + int hashCode = NetName.GetHashCode(); + return hashCode; + } + + public override string ToString() + { + return "SmbShareInfo[" + "netName=" + NetName + ",type=0x" + Hexdump.ToHexString + (Type, 8) + ",remark=" + Remark + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTransport.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTransport.cs new file mode 100644 index 000000000..800d6d9bc --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTransport.cs @@ -0,0 +1,977 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using SharpCifs.Netbios; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; +using SharpCifs.Util.Transport; + +namespace SharpCifs.Smb +{ + public class SmbTransport : Transport + { + internal static readonly byte[] Buf = new byte[0xFFFF]; + + internal static readonly SmbComNegotiate NegotiateRequest = new SmbComNegotiate( + ); + + internal static LogStream LogStatic = LogStream.GetInstance(); + + internal static Hashtable DfsRoots = null; + + + internal static SmbTransport GetSmbTransport(UniAddress address, int port + ) + { + lock (typeof(SmbTransport)) + { + return GetSmbTransport(address, port, SmbConstants.Laddr, SmbConstants.Lport, null); + } + } + + internal static SmbTransport GetSmbTransport(UniAddress address, int port + , IPAddress localAddr, int localPort, string hostName) + { + lock (typeof(SmbTransport)) + { + SmbTransport conn; + + lock (SmbConstants.Connections) + { + if (SmbConstants.SsnLimit != 1) + { + conn = + SmbConstants.Connections.FirstOrDefault( + c => + c.Matches(address, port, localAddr, localPort, hostName) && + (SmbConstants.SsnLimit == + 0 || c.Sessions.Count < SmbConstants.SsnLimit)); + + if (conn != null) + { + return conn; + } + + } + + conn = new SmbTransport(address, port, localAddr, localPort); + SmbConstants.Connections.Insert(0, conn); + } + return conn; + } + } + + internal class ServerData + { + internal byte Flags; + + internal int Flags2; + + internal int MaxMpxCount; + + internal int MaxBufferSize; + + internal int SessionKey; + + internal int Capabilities; + + internal string OemDomainName; + + internal int SecurityMode; + + internal int Security; + + internal bool EncryptedPasswords; + + internal bool SignaturesEnabled; + + internal bool SignaturesRequired; + + internal int MaxNumberVcs; + + internal int MaxRawSize; + + internal long ServerTime; + + internal int ServerTimeZone; + + internal int EncryptionKeyLength; + + internal byte[] EncryptionKey; + + internal byte[] Guid; + + internal ServerData(SmbTransport enclosing) + { + this._enclosing = enclosing; + } + + private readonly SmbTransport _enclosing; + } + + internal IPAddress LocalAddr; + + internal int LocalPort; + + internal UniAddress Address; + + internal SocketEx Socket; + + internal int Port; + + internal int Mid; + + internal OutputStream Out; + + internal InputStream In; + + internal byte[] Sbuf = new byte[512]; + + internal SmbComBlankResponse Key = new SmbComBlankResponse(); + + internal long SessionExpiration = Runtime.CurrentTimeMillis() + SmbConstants.SoTimeout; + + internal List<object> Referrals = new List<object>(); + + internal SigningDigest Digest; + + internal List<SmbSession> Sessions = new List<SmbSession>(); + + internal ServerData Server; + + internal int Flags2 = SmbConstants.Flags2; + + internal int MaxMpxCount = SmbConstants.MaxMpxCount; + + internal int SndBufSize = SmbConstants.SndBufSize; + + internal int RcvBufSize = SmbConstants.RcvBufSize; + + internal int Capabilities = SmbConstants.Capabilities; + + internal int SessionKey = 0x00000000; + + internal bool UseUnicode = SmbConstants.UseUnicode; + + internal string TconHostName; + + internal SmbTransport(UniAddress address, int port, IPAddress localAddr, int localPort + ) + { + Server = new ServerData(this); + this.Address = address; + this.Port = port; + this.LocalAddr = localAddr; + this.LocalPort = localPort; + } + + internal virtual SmbSession GetSmbSession() + { + lock (this) + { + return GetSmbSession(new NtlmPasswordAuthentication(null, null, null)); + } + } + + internal virtual SmbSession GetSmbSession(NtlmPasswordAuthentication auth) + { + lock (this) + { + SmbSession ssn; + long now; + + ssn = Sessions.FirstOrDefault(s => s.Matches(auth)); + if (ssn != null) + { + ssn.Auth = auth; + return ssn; + } + + if (SmbConstants.SoTimeout > 0 && SessionExpiration < (now = Runtime.CurrentTimeMillis())) + { + SessionExpiration = now + SmbConstants.SoTimeout; + + foreach (var session in Sessions.Where(s => s.Expiration < now)) + { + session.Logoff(false); + } + } + ssn = new SmbSession(Address, Port, LocalAddr, LocalPort, auth); + ssn.transport = this; + Sessions.Add(ssn); + return ssn; + } + } + + internal virtual bool Matches(UniAddress address, int port, IPAddress localAddr, + int localPort, string hostName) + { + if (hostName == null) + { + hostName = address.GetHostName(); + } + return (TconHostName == null || Runtime.EqualsIgnoreCase(hostName, TconHostName)) && address.Equals(this.Address) && (port == -1 || port == this.Port + || (port == 445 && this.Port == 139)) && (localAddr == this.LocalAddr || (localAddr + != null && localAddr.Equals(this.LocalAddr))) && localPort == this.LocalPort; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual bool HasCapability(int cap) + { + try + { + Connect(SmbConstants.ResponseTimeout); + } + catch (IOException ioe) + { + throw new SmbException(ioe.Message, ioe); + } + return (Capabilities & cap) == cap; + } + + internal virtual bool IsSignatureSetupRequired(NtlmPasswordAuthentication auth) + { + return (Flags2 & SmbConstants.Flags2SecuritySignatures) != 0 && Digest == + null && auth != NtlmPasswordAuthentication.Null && NtlmPasswordAuthentication.Null + .Equals(auth) == false; + } + + /// <exception cref="System.IO.IOException"></exception> + internal virtual void Ssn139() + { + Name calledName = new Name(Address.FirstCalledName(), 0x20, null + ); + do + { + Socket = new SocketEx(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + if (LocalAddr != null) + { + Socket.Bind2(new IPEndPoint(LocalAddr, LocalPort)); + } + + Socket.Connect(new IPEndPoint(IPAddress.Parse(Address.GetHostAddress()), 139), SmbConstants.ConnTimeout); + Socket.SoTimeOut = SmbConstants.SoTimeout; + + Out = Socket.GetOutputStream(); + In = Socket.GetInputStream(); + SessionServicePacket ssp = new SessionRequestPacket(calledName, NbtAddress.GetLocalName + ()); + Out.Write(Sbuf, 0, ssp.WriteWireFormat(Sbuf, 0)); + if (Readn(In, Sbuf, 0, 4) < 4) + { + try + { + //Socket.`Close` method deleted + //Socket.Close(); + Socket.Dispose(); + } + catch (IOException) + { + } + throw new SmbException("EOF during NetBIOS session request"); + } + switch (Sbuf[0] & 0xFF) + { + case SessionServicePacket.PositiveSessionResponse: + { + if (Log.Level >= 4) + { + Log.WriteLine("session established ok with " + Address); + } + return; + } + + case SessionServicePacket.NegativeSessionResponse: + { + int errorCode = In.Read() & 0xFF; + switch (errorCode) + { + case NbtException.CalledNotPresent: + case NbtException.NotListeningCalled: + { + //Socket.`Close` method deleted + //Socket.Close(); + Socket.Dispose(); + break; + } + + default: + { + Disconnect(true); + throw new NbtException(NbtException.ErrSsnSrvc, errorCode); + } + } + break; + } + + case -1: + { + Disconnect(true); + throw new NbtException(NbtException.ErrSsnSrvc, NbtException.ConnectionRefused + ); + } + + default: + { + Disconnect(true); + throw new NbtException(NbtException.ErrSsnSrvc, 0); + } + } + } + while ((calledName.name = Address.NextCalledName()) != null); + throw new IOException("Failed to establish session with " + Address); + } + + /// <exception cref="System.IO.IOException"></exception> + private void Negotiate(int port, ServerMessageBlock resp) + { + lock (Sbuf) + { + if (port == 139) + { + Ssn139(); + } + else + { + if (port == -1) + { + port = SmbConstants.DefaultPort; + } + // 445 + Socket = new SocketEx(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + if (LocalAddr != null) + { + Socket.Bind2(new IPEndPoint(LocalAddr, LocalPort)); + } + + Socket.Connect(new IPEndPoint(IPAddress.Parse(Address.GetHostAddress()), port), SmbConstants.ConnTimeout); + Socket.SoTimeOut = SmbConstants.SoTimeout; + Out = Socket.GetOutputStream(); + In = Socket.GetInputStream(); + } + if (++Mid == 32000) + { + Mid = 1; + } + NegotiateRequest.Mid = Mid; + int n = NegotiateRequest.Encode(Sbuf, 4); + Encdec.Enc_uint32be(n & 0xFFFF, Sbuf, 0); + if (Log.Level >= 4) + { + Log.WriteLine(NegotiateRequest); + if (Log.Level >= 6) + { + Hexdump.ToHexdump(Log, Sbuf, 4, n); + } + } + Out.Write(Sbuf, 0, 4 + n); + Out.Flush(); + if (PeekKey() == null) + { + throw new IOException("transport closed in negotiate"); + } + int size = Encdec.Dec_uint16be(Sbuf, 2) & 0xFFFF; + if (size < 33 || (4 + size) > Sbuf.Length) + { + throw new IOException("Invalid payload size: " + size); + } + Readn(In, Sbuf, 4 + 32, size - 32); + resp.Decode(Sbuf, 4); + if (Log.Level >= 4) + { + Log.WriteLine(resp); + if (Log.Level >= 6) + { + Hexdump.ToHexdump(Log, Sbuf, 4, n); + } + } + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public virtual void Connect() + { + try + { + base.Connect(SmbConstants.ResponseTimeout); + } + catch (TransportException te) + { + throw new SmbException("Failed to connect: " + Address, te); + } + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void DoConnect() + { + SmbComNegotiateResponse resp = new SmbComNegotiateResponse(Server); + try + { + Negotiate(Port, resp); + } + catch (ConnectException) + { + Port = (Port == -1 || Port == SmbConstants.DefaultPort) ? 139 : SmbConstants.DefaultPort; + Negotiate(Port, resp); + } + if (resp.DialectIndex > 10) + { + throw new SmbException("This client does not support the negotiated dialect."); + } + if ((Server.Capabilities & SmbConstants.CapExtendedSecurity) != SmbConstants.CapExtendedSecurity && Server + .EncryptionKeyLength != 8 && SmbConstants.LmCompatibility == 0) + { + throw new SmbException("Unexpected encryption key length: " + Server.EncryptionKeyLength + ); + } + TconHostName = Address.GetHostName(); + if (Server.SignaturesRequired || (Server.SignaturesEnabled && SmbConstants.Signpref)) + { + Flags2 |= SmbConstants.Flags2SecuritySignatures; + } + else + { + Flags2 &= 0xFFFF ^ SmbConstants.Flags2SecuritySignatures; + } + MaxMpxCount = Math.Min(MaxMpxCount, Server.MaxMpxCount); + if (MaxMpxCount < 1) + { + MaxMpxCount = 1; + } + SndBufSize = Math.Min(SndBufSize, Server.MaxBufferSize); + Capabilities &= Server.Capabilities; + if ((Server.Capabilities & SmbConstants.CapExtendedSecurity) == SmbConstants.CapExtendedSecurity) + { + Capabilities |= SmbConstants.CapExtendedSecurity; + } + // & doesn't copy high bit + if ((Capabilities & SmbConstants.CapUnicode) == 0) + { + // server doesn't want unicode + if (SmbConstants.ForceUnicode) + { + Capabilities |= SmbConstants.CapUnicode; + } + else + { + UseUnicode = false; + Flags2 &= 0xFFFF ^ SmbConstants.Flags2Unicode; + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void DoDisconnect(bool hard) + { + try + { + foreach (var ssn in Sessions) + { + ssn.Logoff(hard); + } + + Out.Close(); + In.Close(); + + //Socket.`Close` method deleted + //Socket.Close(); + Socket.Dispose(); + } + finally + { + Digest = null; + Socket = null; + TconHostName = null; + } + + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void MakeKey(ServerMessageBlock request) + { + if (++Mid == 32000) + { + Mid = 1; + } + request.Mid = Mid; + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override ServerMessageBlock PeekKey() + { + int n; + do + { + if ((n = Readn(In, Sbuf, 0, 4)) < 4) + { + return null; + } + } + while (Sbuf[0] == 0x85); + if ((n = Readn(In, Sbuf, 4, 32)) < 32) + { + return null; + } + if (Log.Level >= 4) + { + Log.WriteLine("New data read: " + this); + Hexdump.ToHexdump(Log, Sbuf, 4, 32); + } + for (; ; ) + { + if (Sbuf[0] == 0x00 && Sbuf[1] == 0x00 && + Sbuf[4] == 0xFF && + Sbuf[5] == 'S' && + Sbuf[6] == 'M' && + Sbuf[7] == 'B') + { + break; + } + for (int i = 0; i < 35; i++) + { + Sbuf[i] = Sbuf[i + 1]; + } + int b; + if ((b = In.Read()) == -1) + { + return null; + } + Sbuf[35] = unchecked((byte)b); + } + Key.Mid = Encdec.Dec_uint16le(Sbuf, 34) & 0xFFFF; + return Key; + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void DoSend(ServerMessageBlock request) + { + lock (Buf) + { + ServerMessageBlock smb = request; + int n = smb.Encode(Buf, 4); + Encdec.Enc_uint32be(n & 0xFFFF, Buf, 0); + if (Log.Level >= 4) + { + do + { + Log.WriteLine(smb); + } + while (smb is AndXServerMessageBlock && (smb = ((AndXServerMessageBlock)smb).Andx + ) != null); + if (Log.Level >= 6) + { + Hexdump.ToHexdump(Log, Buf, 4, n); + } + } + Out.Write(Buf, 0, 4 + n); + } + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal virtual void DoSend0(ServerMessageBlock request) + { + try + { + DoSend(request); + } + catch (IOException ioe) + { + if (Log.Level > 2) + { + Runtime.PrintStackTrace(ioe, Log); + } + try + { + Disconnect(true); + } + catch (IOException ioe2) + { + Runtime.PrintStackTrace(ioe2, Log); + } + throw; + } + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void DoRecv(Response response) + { + ServerMessageBlock resp = (ServerMessageBlock)response; + resp.UseUnicode = UseUnicode; + resp.ExtendedSecurity = (Capabilities & SmbConstants.CapExtendedSecurity) == SmbConstants.CapExtendedSecurity; + lock (Buf) + { + Array.Copy(Sbuf, 0, Buf, 0, 4 + SmbConstants.HeaderLength); + int size = Encdec.Dec_uint16be(Buf, 2) & 0xFFFF; + if (size < (SmbConstants.HeaderLength + 1) || (4 + size) > RcvBufSize) + { + throw new IOException("Invalid payload size: " + size); + } + int errorCode = Encdec.Dec_uint32le(Buf, 9) & unchecked((int)(0xFFFFFFFF)); + if (resp.Command == ServerMessageBlock.SmbComReadAndx && (errorCode == 0 || errorCode + == unchecked((int)(0x80000005)))) + { + // overflow indicator normal for pipe + SmbComReadAndXResponse r = (SmbComReadAndXResponse)resp; + int off = SmbConstants.HeaderLength; + Readn(In, Buf, 4 + off, 27); + off += 27; + resp.Decode(Buf, 4); + int pad = r.DataOffset - off; + if (r.ByteCount > 0 && pad > 0 && pad < 4) + { + Readn(In, Buf, 4 + off, pad); + } + if (r.DataLength > 0) + { + Readn(In, r.B, r.Off, r.DataLength); + } + } + else + { + Readn(In, Buf, 4 + 32, size - 32); + resp.Decode(Buf, 4); + if (resp is SmbComTransactionResponse) + { + ((SmbComTransactionResponse)resp).Current(); + } + } + if (Digest != null && resp.ErrorCode == 0) + { + Digest.Verify(Buf, 4, resp); + } + if (Log.Level >= 4) + { + Log.WriteLine(response); + if (Log.Level >= 6) + { + Hexdump.ToHexdump(Log, Buf, 4, size); + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + protected internal override void DoSkip() + { + int size = Encdec.Dec_uint16be(Sbuf, 2) & 0xFFFF; + if (size < 33 || (4 + size) > RcvBufSize) + { + In.Skip(In.Available()); + } + else + { + In.Skip(size - 32); + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void CheckStatus(ServerMessageBlock req, ServerMessageBlock resp + ) + { + resp.ErrorCode = SmbException.GetStatusByCode(resp.ErrorCode); + switch (resp.ErrorCode) + { + case NtStatus.NtStatusOk: + { + break; + } + + case NtStatus.NtStatusAccessDenied: + case NtStatus.NtStatusWrongPassword: + case NtStatus.NtStatusLogonFailure: + case NtStatus.NtStatusAccountRestriction: + case NtStatus.NtStatusInvalidLogonHours: + case NtStatus.NtStatusInvalidWorkstation: + case NtStatus.NtStatusPasswordExpired: + case NtStatus.NtStatusAccountDisabled: + case NtStatus.NtStatusAccountLockedOut: + case NtStatus.NtStatusTrustedDomainFailure: + { + throw new SmbAuthException(resp.ErrorCode); + } + + case NtStatus.NtStatusPathNotCovered: + { + if (req.Auth == null) + { + throw new SmbException(resp.ErrorCode, null); + } + DfsReferral dr = GetDfsReferrals(req.Auth, req.Path, 1); + if (dr == null) + { + throw new SmbException(resp.ErrorCode, null); + } + SmbFile.Dfs.Insert(req.Path, dr); + throw dr; + } + + case unchecked((int)(0x80000005)): + { + break; + } + + case NtStatus.NtStatusMoreProcessingRequired: + { + break; + } + + default: + { + throw new SmbException(resp.ErrorCode, null); + } + } + if (resp.VerifyFailed) + { + throw new SmbException("Signature verification failed."); + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response + ) + { + Connect(); + request.Flags2 |= Flags2; + request.UseUnicode = UseUnicode; + request.Response = response; + if (request.Digest == null) + { + request.Digest = Digest; + } + try + { + if (response == null) + { + DoSend0(request); + return; + } + if (request is SmbComTransaction) + { + response.Command = request.Command; + SmbComTransaction req = (SmbComTransaction)request; + SmbComTransactionResponse resp = (SmbComTransactionResponse)response; + req.MaxBufferSize = SndBufSize; + resp.Reset(); + try + { + BufferCache.GetBuffers(req, resp); + req.Current(); + if (req.MoveNext()) + { + SmbComBlankResponse interim = new SmbComBlankResponse(); + Sendrecv(req, interim, SmbConstants.ResponseTimeout); + if (interim.ErrorCode != 0) + { + CheckStatus(req, interim); + } + req.Current(); + } + else + { + MakeKey(req); + } + lock (this) + { + response.Received = false; + resp.IsReceived = false; + try + { + ResponseMap.Put(req, resp); + do + { + DoSend0(req); + } + while (req.MoveNext() && req.Current() != null); + long timeout = SmbConstants.ResponseTimeout; + resp.Expiration = Runtime.CurrentTimeMillis() + timeout; + while (resp.MoveNext()) + { + Runtime.Wait(this, timeout); + timeout = resp.Expiration - Runtime.CurrentTimeMillis(); + if (timeout <= 0) + { + throw new TransportException(this + " timedout waiting for response to " + req); + } + } + if (response.ErrorCode != 0) + { + CheckStatus(req, resp); + } + } + catch (Exception ie) + { + if (ie is SmbException) + { + throw; + } + else + { + throw new TransportException(ie); + } + } + finally + { + //Sharpen.Collections.Remove<Hashtable, SmbComTransaction>(response_map, req); + ResponseMap.Remove(req); + } + } + } + finally + { + BufferCache.ReleaseBuffer(req.TxnBuf); + BufferCache.ReleaseBuffer(resp.TxnBuf); + } + } + else + { + response.Command = request.Command; + Sendrecv(request, response, SmbConstants.ResponseTimeout); + } + } + catch (SmbException se) + { + throw; + } + catch (IOException ioe) + { + throw new SmbException(ioe.Message, ioe); + } + CheckStatus(request, response); + } + + public override string ToString() + { + return base.ToString() + "[" + Address + ":" + Port + "]"; + } + + internal virtual void DfsPathSplit(string path, string[] result) + { + int ri = 0; + int rlast = result.Length - 1; + int i = 0; + int b = 0; + int len = path.Length; + do + { + if (ri == rlast) + { + result[rlast] = Runtime.Substring(path, b); + return; + } + if (i == len || path[i] == '\\') + { + result[ri++] = Runtime.Substring(path, b, i); + b = i + 1; + } + } + while (i++ < len); + while (ri < result.Length) + { + result[ri++] = string.Empty; + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual DfsReferral GetDfsReferrals(NtlmPasswordAuthentication auth, string + path, int rn) + { + SmbTree ipc = GetSmbSession(auth).GetSmbTree("IPC$", null); + Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse(); + ipc.Send(new Trans2GetDfsReferral(path), resp); + if (resp.NumReferrals == 0) + { + return null; + } + if (rn == 0 || resp.NumReferrals < rn) + { + rn = resp.NumReferrals; + } + DfsReferral dr = new DfsReferral(); + string[] arr = new string[4]; + long expiration = Runtime.CurrentTimeMillis() + Dfs.Ttl * 1000; + int di = 0; + for (; ; ) + { + dr.ResolveHashes = auth.HashesExternal; + dr.Ttl = resp.Referrals[di].Ttl; + dr.Expiration = expiration; + if (path.Equals(string.Empty)) + { + dr.Server = Runtime.Substring(resp.Referrals[di].Path, 1).ToLower(); + } + else + { + DfsPathSplit(resp.Referrals[di].Node, arr); + dr.Server = arr[1]; + dr.Share = arr[2]; + dr.Path = arr[3]; + } + dr.PathConsumed = resp.PathConsumed; + di++; + if (di == rn) + { + break; + } + dr.Append(new DfsReferral()); + dr = dr.Next; + } + return dr.Next; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual DfsReferral[] __getDfsReferrals(NtlmPasswordAuthentication auth, + string path, int rn) + { + SmbTree ipc = GetSmbSession(auth).GetSmbTree("IPC$", null); + Trans2GetDfsReferralResponse resp = new Trans2GetDfsReferralResponse(); + ipc.Send(new Trans2GetDfsReferral(path), resp); + if (rn == 0 || resp.NumReferrals < rn) + { + rn = resp.NumReferrals; + } + DfsReferral[] drs = new DfsReferral[rn]; + string[] arr = new string[4]; + long expiration = Runtime.CurrentTimeMillis() + Dfs.Ttl * 1000; + for (int di = 0; di < drs.Length; di++) + { + DfsReferral dr = new DfsReferral(); + dr.ResolveHashes = auth.HashesExternal; + dr.Ttl = resp.Referrals[di].Ttl; + dr.Expiration = expiration; + if (path.Equals(string.Empty)) + { + dr.Server = Runtime.Substring(resp.Referrals[di].Path, 1).ToLower(); + } + else + { + DfsPathSplit(resp.Referrals[di].Node, arr); + dr.Server = arr[1]; + dr.Share = arr[2]; + dr.Path = arr[3]; + } + dr.PathConsumed = resp.PathConsumed; + drs[di] = dr; + } + return drs; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTree.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTree.cs new file mode 100644 index 000000000..8dc068c4c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTree.cs @@ -0,0 +1,250 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + class SmbTree + { + private static int _treeConnCounter; + + internal int ConnectionState; + + internal int Tid; + + internal string Share; + + internal string Service = "?????"; + + internal string Service0; + + internal SmbSession Session; + + internal bool InDfs; + + internal bool InDomainDfs; + + internal int TreeNum; + + internal SmbTree(SmbSession session, string share, string service) + { + // used by SmbFile.isOpen + this.Session = session; + this.Share = share.ToUpper(); + if (service != null && service.StartsWith("??") == false) + { + this.Service = service; + } + Service0 = this.Service; + ConnectionState = 0; + } + + internal virtual bool Matches(string share, string service) + { + return Runtime.EqualsIgnoreCase(this.Share, share) && (service == null || + service.StartsWith("??") || Runtime.EqualsIgnoreCase(this.Service, service + )); + } + + public override bool Equals(object obj) + { + if (obj is SmbTree) + { + SmbTree tree = (SmbTree)obj; + return Matches(tree.Share, tree.Service); + } + return false; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response + ) + { + lock (Session.Transport()) + { + if (response != null) + { + response.Received = false; + } + TreeConnect(request, response); + if (request == null || (response != null && response.Received)) + { + return; + } + if (Service.Equals("A:") == false) + { + switch (request.Command) + { + case ServerMessageBlock.SmbComOpenAndx: + case ServerMessageBlock.SmbComNtCreateAndx: + case ServerMessageBlock.SmbComReadAndx: + case ServerMessageBlock.SmbComWriteAndx: + case ServerMessageBlock.SmbComClose: + case ServerMessageBlock.SmbComTreeDisconnect: + { + break; + } + + case ServerMessageBlock.SmbComTransaction: + case ServerMessageBlock.SmbComTransaction2: + { + switch (((SmbComTransaction)request).SubCommand & unchecked(0xFF)) + { + case SmbComTransaction.NetShareEnum: + case SmbComTransaction.NetServerEnum2: + case SmbComTransaction.NetServerEnum3: + case SmbComTransaction.TransPeekNamedPipe: + case SmbComTransaction.TransWaitNamedPipe: + case SmbComTransaction.TransCallNamedPipe: + case SmbComTransaction.TransTransactNamedPipe: + case SmbComTransaction.Trans2GetDfsReferral: + { + break; + } + + default: + { + throw new SmbException("Invalid operation for " + Service + " service"); + } + } + break; + } + + default: + { + throw new SmbException("Invalid operation for " + Service + " service" + request); + } + } + } + request.Tid = Tid; + if (InDfs && !Service.Equals("IPC") && !string.IsNullOrEmpty(request.Path)) + { + request.Flags2 = SmbConstants.Flags2ResolvePathsInDfs; + request.Path = '\\' + Session.Transport().TconHostName + '\\' + Share + request.Path; + } + try + { + Session.Send(request, response); + } + catch (SmbException se) + { + if (se.GetNtStatus() == NtStatus.NtStatusNetworkNameDeleted) + { + TreeDisconnect(true); + } + throw; + } + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void TreeConnect(ServerMessageBlock andx, ServerMessageBlock andxResponse + ) + { + lock (Session.Transport()) + { + string unc; + while (ConnectionState != 0) + { + if (ConnectionState == 2 || ConnectionState == 3) + { + // connected or disconnecting + return; + } + try + { + Runtime.Wait(Session.transport); + } + catch (Exception ie) + { + throw new SmbException(ie.Message, ie); + } + } + ConnectionState = 1; + // trying ... + try + { + Session.transport.Connect(); + unc = "\\\\" + Session.transport.TconHostName + '\\' + Share; + Service = Service0; + if (Session.transport.Log.Level >= 4) + { + Session.transport.Log.WriteLine("treeConnect: unc=" + unc + ",service=" + Service + ); + } + SmbComTreeConnectAndXResponse response = new SmbComTreeConnectAndXResponse(andxResponse + ); + SmbComTreeConnectAndX request = new SmbComTreeConnectAndX(Session, unc, Service, + andx); + Session.Send(request, response); + Tid = response.Tid; + Service = response.Service; + InDfs = response.ShareIsInDfs; + TreeNum = _treeConnCounter++; + ConnectionState = 2; + } + catch (SmbException se) + { + // connected + TreeDisconnect(true); + ConnectionState = 0; + throw; + } + } + } + + internal virtual void TreeDisconnect(bool inError) + { + lock (Session.Transport()) + { + if (ConnectionState != 2) + { + // not-connected + return; + } + ConnectionState = 3; + // disconnecting + if (!inError && Tid != 0) + { + try + { + Send(new SmbComTreeDisconnect(), null); + } + catch (SmbException se) + { + if (Session.transport.Log.Level > 1) + { + Runtime.PrintStackTrace(se, Session.transport.Log); + } + } + } + InDfs = false; + InDomainDfs = false; + ConnectionState = 0; + Runtime.NotifyAll(Session.transport); + } + } + + public override string ToString() + { + return "SmbTree[share=" + Share + ",service=" + Service + ",tid=" + Tid + ",inDfs=" + + InDfs + ",inDomainDfs=" + InDomainDfs + ",connectionState=" + ConnectionState + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindFirst2.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindFirst2.cs new file mode 100644 index 000000000..2ef874882 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindFirst2.cs @@ -0,0 +1,146 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class Trans2FindFirst2 : SmbComTransaction + { + private const int FlagsCloseAfterThisRequest = unchecked(0x01); + + private const int FlagsCloseIfEndReached = unchecked(0x02); + + private const int FlagsReturnResumeKeys = unchecked(0x04); + + private const int FlagsResumeFromPreviousEnd = unchecked(0x08); + + private const int FlagsFindWithBackupIntent = unchecked(0x10); + + private const int DefaultListSize = 65535; + + private const int DefaultListCount = 200; + + private int _searchAttributes; + + private int _flags; + + private int _informationLevel; + + private int _searchStorageType = 0; + + private string _wildcard; + + internal const int SmbInfoStandard = 1; + + internal const int SmbInfoQueryEaSize = 2; + + internal const int SmbInfoQueryEasFromList = 3; + + internal const int SmbFindFileDirectoryInfo = unchecked(0x101); + + internal const int SmbFindFileFullDirectoryInfo = unchecked(0x102); + + internal const int SmbFileNamesInfo = unchecked(0x103); + + internal const int SmbFileBothDirectoryInfo = unchecked(0x104); + + internal static readonly int ListSize = Config.GetInt("jcifs.smb.client.listSize" + , DefaultListSize); + + internal static readonly int ListCount = Config.GetInt("jcifs.smb.client.listCount" + , DefaultListCount); + + internal Trans2FindFirst2(string filename, string wildcard, int searchAttributes) + { + // flags + // information levels + if (filename.Equals("\\")) + { + Path = filename; + } + else + { + Path = filename + "\\"; + } + this._wildcard = wildcard; + this._searchAttributes = searchAttributes & unchecked(0x37); + Command = SmbComTransaction2; + SubCommand = Trans2FindFirst2; + _flags = unchecked(0x00); + _informationLevel = SmbFileBothDirectoryInfo; + TotalDataCount = 0; + MaxParameterCount = 10; + MaxDataCount = ListSize; + MaxSetupCount = 0; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 2; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_searchAttributes, dst, dstIndex); + dstIndex += 2; + WriteInt2(ListCount, dst, dstIndex); + dstIndex += 2; + WriteInt2(_flags, dst, dstIndex); + dstIndex += 2; + WriteInt2(_informationLevel, dst, dstIndex); + dstIndex += 2; + WriteInt4(_searchStorageType, dst, dstIndex); + dstIndex += 4; + dstIndex += WriteString(Path + _wildcard, dst, dstIndex); + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "Trans2FindFirst2[" + base.ToString() + ",searchAttributes=0x" + + Hexdump.ToHexString(_searchAttributes, 2) + ",searchCount=" + ListCount + ",flags=0x" + + Hexdump.ToHexString(_flags, 2) + ",informationLevel=0x" + Hexdump.ToHexString( + _informationLevel, 3) + ",searchStorageType=" + _searchStorageType + ",filename=" + + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindFirst2Response.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindFirst2Response.cs new file mode 100644 index 000000000..71f780ff3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindFirst2Response.cs @@ -0,0 +1,262 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class Trans2FindFirst2Response : SmbComTransactionResponse + { + internal const int SmbInfoStandard = 1; + + internal const int SmbInfoQueryEaSize = 2; + + internal const int SmbInfoQueryEasFromList = 3; + + internal const int SmbFindFileDirectoryInfo = unchecked(0x101); + + internal const int SmbFindFileFullDirectoryInfo = unchecked(0x102); + + internal const int SmbFileNamesInfo = unchecked(0x103); + + internal const int SmbFileBothDirectoryInfo = unchecked(0x104); + + internal class SmbFindFileBothDirectoryInfo : IFileEntry + { + internal int NextEntryOffset; + + internal int FileIndex; + + internal long CreationTime; + + internal long LastAccessTime; + + internal long LastWriteTime; + + internal long ChangeTime; + + internal long EndOfFile; + + internal long AllocationSize; + + internal int ExtFileAttributes; + + internal int FileNameLength; + + internal int EaSize; + + internal int ShortNameLength; + + internal string ShortName; + + internal string Filename; + + // information levels + public virtual string GetName() + { + return Filename; + } + + public virtual int GetType() + { + return SmbFile.TypeFilesystem; + } + + public virtual int GetAttributes() + { + return ExtFileAttributes; + } + + public virtual long CreateTime() + { + return CreationTime; + } + + public virtual long LastModified() + { + return LastWriteTime; + } + + public virtual long Length() + { + return EndOfFile; + } + + public override string ToString() + { + return "SmbFindFileBothDirectoryInfo[" + "nextEntryOffset=" + NextEntryOffset + + ",fileIndex=" + FileIndex + ",creationTime=" + Extensions.CreateDate + (CreationTime) + ",lastAccessTime=" + Extensions.CreateDate(LastAccessTime + ) + ",lastWriteTime=" + Extensions.CreateDate(LastWriteTime) + ",changeTime=" + + Extensions.CreateDate(ChangeTime) + ",endOfFile=" + EndOfFile + + ",allocationSize=" + AllocationSize + ",extFileAttributes=" + ExtFileAttributes + + ",fileNameLength=" + FileNameLength + ",eaSize=" + EaSize + ",shortNameLength=" + + ShortNameLength + ",shortName=" + ShortName + ",filename=" + Filename + + "]"; + } + + internal SmbFindFileBothDirectoryInfo(Trans2FindFirst2Response enclosing) + { + this._enclosing = enclosing; + } + + private readonly Trans2FindFirst2Response _enclosing; + } + + internal int Sid; + + internal bool IsEndOfSearch; + + internal int EaErrorOffset; + + internal int LastNameOffset; + + internal int LastNameBufferIndex; + + internal string LastName; + + internal int ResumeKey; + + public Trans2FindFirst2Response() + { + Command = SmbComTransaction2; + SubCommand = Smb.SmbComTransaction.Trans2FindFirst2; + } + + internal virtual string ReadString(byte[] src, int srcIndex, int len) + { + string str = null; + try + { + if (UseUnicode) + { + // should Unicode alignment be corrected for here? + str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.UniEncoding); + } + else + { + if (len > 0 && src[srcIndex + len - 1] == '\0') + { + len--; + } + str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.OemEncoding + ); + } + } + catch (UnsupportedEncodingException uee) + { + if (Log.Level > 1) + { + Runtime.PrintStackTrace(uee, Log); + } + } + return str; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + int start = bufferIndex; + if (SubCommand == Smb.SmbComTransaction.Trans2FindFirst2) + { + Sid = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + } + NumEntries = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + IsEndOfSearch = (buffer[bufferIndex] & unchecked(0x01)) == unchecked(0x01) ? true : false; + bufferIndex += 2; + EaErrorOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + LastNameOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + return bufferIndex - start; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + int start = bufferIndex; + SmbFindFileBothDirectoryInfo e; + LastNameBufferIndex = bufferIndex + LastNameOffset; + Results = new SmbFindFileBothDirectoryInfo[NumEntries]; + for (int i = 0; i < NumEntries; i++) + { + Results[i] = e = new SmbFindFileBothDirectoryInfo(this); + e.NextEntryOffset = ReadInt4(buffer, bufferIndex); + e.FileIndex = ReadInt4(buffer, bufferIndex + 4); + e.CreationTime = ReadTime(buffer, bufferIndex + 8); + // e.lastAccessTime = readTime( buffer, bufferIndex + 16 ); + e.LastWriteTime = ReadTime(buffer, bufferIndex + 24); + // e.changeTime = readTime( buffer, bufferIndex + 32 ); + e.EndOfFile = ReadInt8(buffer, bufferIndex + 40); + // e.allocationSize = readInt8( buffer, bufferIndex + 48 ); + e.ExtFileAttributes = ReadInt4(buffer, bufferIndex + 56); + e.FileNameLength = ReadInt4(buffer, bufferIndex + 60); + // e.eaSize = readInt4( buffer, bufferIndex + 64 ); + // e.shortNameLength = buffer[bufferIndex + 68] & 0xFF; + // e.shortName = readString( buffer, bufferIndex + 70, e.shortNameLength ); + e.Filename = ReadString(buffer, bufferIndex + 94, e.FileNameLength); + if (LastNameBufferIndex >= bufferIndex && (e.NextEntryOffset == 0 || LastNameBufferIndex + < (bufferIndex + e.NextEntryOffset))) + { + LastName = e.Filename; + ResumeKey = e.FileIndex; + } + bufferIndex += e.NextEntryOffset; + } + //return bufferIndex - start; + return DataCount; + } + + public override string ToString() + { + string c; + if (SubCommand == Smb.SmbComTransaction.Trans2FindFirst2) + { + c = "Trans2FindFirst2Response["; + } + else + { + c = "Trans2FindNext2Response["; + } + return c + base.ToString() + ",sid=" + Sid + ",searchCount=" + NumEntries + + ",isEndOfSearch=" + IsEndOfSearch + ",eaErrorOffset=" + EaErrorOffset + ",lastNameOffset=" + + LastNameOffset + ",lastName=" + LastName + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindNext2.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindNext2.cs new file mode 100644 index 000000000..cb860f799 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2FindNext2.cs @@ -0,0 +1,109 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class Trans2FindNext2 : SmbComTransaction + { + private int _sid; + + private int _informationLevel; + + private int _resumeKey; + + private int _flags; + + private string _filename; + + internal Trans2FindNext2(int sid, int resumeKey, string filename) + { + this._sid = sid; + this._resumeKey = resumeKey; + this._filename = filename; + Command = SmbComTransaction2; + SubCommand = Trans2FindNext2; + _informationLevel = Smb.Trans2FindFirst2.SmbFileBothDirectoryInfo; + _flags = unchecked(0x00); + MaxParameterCount = 8; + MaxDataCount = Smb.Trans2FindFirst2.ListSize; + MaxSetupCount = 0; + } + + internal override void Reset(int resumeKey, string lastName) + { + base.Reset(); + this._resumeKey = resumeKey; + _filename = lastName; + Flags2 = 0; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 2; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_sid, dst, dstIndex); + dstIndex += 2; + WriteInt2(Smb.Trans2FindFirst2.ListCount, dst, dstIndex); + dstIndex += 2; + WriteInt2(_informationLevel, dst, dstIndex); + dstIndex += 2; + WriteInt4(_resumeKey, dst, dstIndex); + dstIndex += 4; + WriteInt2(_flags, dst, dstIndex); + dstIndex += 2; + dstIndex += WriteString(_filename, dst, dstIndex); + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "Trans2FindNext2[" + base.ToString() + ",sid=" + _sid + ",searchCount=" + + Smb.Trans2FindFirst2.ListSize + ",informationLevel=0x" + Hexdump.ToHexString(_informationLevel + , 3) + ",resumeKey=0x" + Hexdump.ToHexString(_resumeKey, 4) + ",flags=0x" + Hexdump + .ToHexString(_flags, 2) + ",filename=" + _filename + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2GetDfsReferral.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2GetDfsReferral.cs new file mode 100644 index 000000000..c83de7973 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2GetDfsReferral.cs @@ -0,0 +1,78 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class Trans2GetDfsReferral : SmbComTransaction + { + private int _maxReferralLevel = 3; + + internal Trans2GetDfsReferral(string filename) + { + Path = filename; + Command = SmbComTransaction2; + SubCommand = Trans2GetDfsReferral; + TotalDataCount = 0; + MaxParameterCount = 0; + MaxDataCount = 4096; + MaxSetupCount = unchecked(unchecked(0x00)); + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 2; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_maxReferralLevel, dst, dstIndex); + dstIndex += 2; + dstIndex += WriteString(Path, dst, dstIndex); + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "Trans2GetDfsReferral[" + base.ToString() + ",maxReferralLevel=0x" + + _maxReferralLevel + ",filename=" + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2GetDfsReferralResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2GetDfsReferralResponse.cs new file mode 100644 index 000000000..5fa4a795d --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2GetDfsReferralResponse.cs @@ -0,0 +1,179 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class Trans2GetDfsReferralResponse : SmbComTransactionResponse + { + internal class Referral + { + private int _version; + + private int _size; + + private int _serverType; + + private int _flags; + + private int _proximity; + + private int _pathOffset; + + private int _altPathOffset; + + private int _nodeOffset; + + private string _altPath; + + internal int Ttl; + + internal string Path; + + internal string Node; + + internal virtual int ReadWireFormat(byte[] buffer, int bufferIndex, int len) + { + int start = bufferIndex; + _version = ReadInt2(buffer, bufferIndex); + if (_version != 3 && _version != 1) + { + throw new RuntimeException("Version " + _version + " referral not supported. Please report this to jcifs at samba dot org." + ); + } + bufferIndex += 2; + _size = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _serverType = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _flags = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if (_version == 3) + { + _proximity = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Ttl = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _pathOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _altPathOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _nodeOffset = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + Path = _enclosing.ReadString(buffer, start + _pathOffset, len, (_enclosing.Flags2 & SmbConstants.Flags2Unicode) != 0); + if (_nodeOffset > 0) + { + Node = _enclosing.ReadString(buffer, start + _nodeOffset, len, (_enclosing.Flags2 & SmbConstants.Flags2Unicode) != 0); + } + } + else + { + if (_version == 1) + { + Node = _enclosing.ReadString(buffer, bufferIndex, len, (_enclosing + .Flags2 & SmbConstants.Flags2Unicode) != 0); + } + } + return _size; + } + + public override string ToString() + { + return "Referral[" + "version=" + _version + ",size=" + _size + + ",serverType=" + _serverType + ",flags=" + _flags + ",proximity=" + _proximity + ",ttl=" + Ttl + ",pathOffset=" + _pathOffset + ",altPathOffset=" + + _altPathOffset + ",nodeOffset=" + _nodeOffset + ",path=" + Path + + ",altPath=" + _altPath + ",node=" + Node + "]"; + } + + internal Referral(Trans2GetDfsReferralResponse enclosing) + { + this._enclosing = enclosing; + } + + private readonly Trans2GetDfsReferralResponse _enclosing; + } + + internal int PathConsumed; + + internal int NumReferrals; + + internal int flags; + + internal Referral[] Referrals; + + public Trans2GetDfsReferralResponse() + { + SubCommand = Smb.SmbComTransaction.Trans2GetDfsReferral; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + int start = bufferIndex; + PathConsumed = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if ((Flags2 & SmbConstants.Flags2Unicode) != 0) + { + PathConsumed /= 2; + } + NumReferrals = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + flags = ReadInt2(buffer, bufferIndex); + bufferIndex += 4; + Referrals = new Referral[NumReferrals]; + for (int ri = 0; ri < NumReferrals; ri++) + { + Referrals[ri] = new Referral(this); + bufferIndex += Referrals[ri].ReadWireFormat(buffer, bufferIndex, len); + } + return bufferIndex - start; + } + + public override string ToString() + { + return "Trans2GetDfsReferralResponse[" + base.ToString() + ",pathConsumed=" + + PathConsumed + ",numReferrals=" + NumReferrals + ",flags=" + flags + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryFSInformation.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryFSInformation.cs new file mode 100644 index 000000000..27b350e53 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryFSInformation.cs @@ -0,0 +1,80 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class Trans2QueryFsInformation : SmbComTransaction + { + private int _informationLevel; + + internal Trans2QueryFsInformation(int informationLevel) + { + Command = SmbComTransaction2; + SubCommand = Trans2QueryFsInformation; + this._informationLevel = informationLevel; + TotalParameterCount = 2; + TotalDataCount = 0; + MaxParameterCount = 0; + MaxDataCount = 800; + MaxSetupCount = 0; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 2; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_informationLevel, dst, dstIndex); + dstIndex += 2; + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "Trans2QueryFSInformation[" + base.ToString() + ",informationLevel=0x" + + Hexdump.ToHexString(_informationLevel, 3) + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryFSInformationResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryFSInformationResponse.cs new file mode 100644 index 000000000..2253e7b6f --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryFSInformationResponse.cs @@ -0,0 +1,192 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class Trans2QueryFsInformationResponse : SmbComTransactionResponse + { + internal const int SMB_INFO_ALLOCATION = 1; + + internal const int SmbQueryFsSizeInfo = unchecked(0x103); + + internal const int SmbFsFullSizeInformation = 1007; + + internal class SmbInfoAllocation : IAllocInfo + { + internal long Alloc; + + internal long Free; + + internal int SectPerAlloc; + + internal int BytesPerSect; + + // information levels + // Also handles SmbQueryFSSizeInfo + public virtual long GetCapacity() + { + return Alloc * SectPerAlloc * BytesPerSect; + } + + public virtual long GetFree() + { + return Free * SectPerAlloc * BytesPerSect; + } + + public override string ToString() + { + return "SmbInfoAllocation[" + "alloc=" + Alloc + ",free=" + Free + ",sectPerAlloc=" + SectPerAlloc + ",bytesPerSect=" + BytesPerSect + + "]"; + } + + internal SmbInfoAllocation(Trans2QueryFsInformationResponse enclosing) + { + this._enclosing = enclosing; + } + + private readonly Trans2QueryFsInformationResponse _enclosing; + } + + private int _informationLevel; + + internal IAllocInfo Info; + + internal Trans2QueryFsInformationResponse(int informationLevel) + { + this._informationLevel = informationLevel; + Command = SmbComTransaction2; + SubCommand = Smb.SmbComTransaction.Trans2QueryFsInformation; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + switch (_informationLevel) + { + case SMB_INFO_ALLOCATION: + { + return ReadSmbInfoAllocationWireFormat(buffer, bufferIndex); + } + + case SmbQueryFsSizeInfo: + { + return ReadSmbQueryFsSizeInfoWireFormat(buffer, bufferIndex); + } + + case SmbFsFullSizeInformation: + { + return ReadFsFullSizeInformationWireFormat(buffer, bufferIndex); + } + + default: + { + return 0; + } + } + } + + internal virtual int ReadSmbInfoAllocationWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + SmbInfoAllocation info = new SmbInfoAllocation + (this); + bufferIndex += 4; + // skip idFileSystem + info.SectPerAlloc = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + info.Alloc = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + info.Free = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + info.BytesPerSect = ReadInt2(buffer, bufferIndex); + bufferIndex += 4; + this.Info = info; + return bufferIndex - start; + } + + internal virtual int ReadSmbQueryFsSizeInfoWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + SmbInfoAllocation info = new SmbInfoAllocation + (this); + info.Alloc = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + info.Free = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + info.SectPerAlloc = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + info.BytesPerSect = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + this.Info = info; + return bufferIndex - start; + } + + internal virtual int ReadFsFullSizeInformationWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + SmbInfoAllocation info = new SmbInfoAllocation + (this); + // Read total allocation units. + info.Alloc = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + // read caller available allocation units + info.Free = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + // skip actual free units + bufferIndex += 8; + info.SectPerAlloc = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + info.BytesPerSect = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + this.Info = info; + return bufferIndex - start; + } + + public override string ToString() + { + return "Trans2QueryFSInformationResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryPathInformation.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryPathInformation.cs new file mode 100644 index 000000000..b3db64790 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryPathInformation.cs @@ -0,0 +1,85 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; + +namespace SharpCifs.Smb +{ + internal class Trans2QueryPathInformation : SmbComTransaction + { + private int _informationLevel; + + internal Trans2QueryPathInformation(string filename, int informationLevel) + { + Path = filename; + this._informationLevel = informationLevel; + Command = SmbComTransaction2; + SubCommand = Trans2QueryPathInformation; + TotalDataCount = 0; + MaxParameterCount = 2; + MaxDataCount = 40; + MaxSetupCount = unchecked(unchecked(0x00)); + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 2; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_informationLevel, dst, dstIndex); + dstIndex += 2; + dst[dstIndex++] = unchecked(unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + dstIndex += WriteString(Path, dst, dstIndex); + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "Trans2QueryPathInformation[" + base.ToString() + ",informationLevel=0x" + + Hexdump.ToHexString(_informationLevel, 3) + ",filename=" + Path + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryPathInformationResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryPathInformationResponse.cs new file mode 100644 index 000000000..50650df62 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2QueryPathInformationResponse.cs @@ -0,0 +1,227 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class Trans2QueryPathInformationResponse : SmbComTransactionResponse + { + internal const int SMB_QUERY_FILE_BASIC_INFO = unchecked(0x101); + + internal const int SMB_QUERY_FILE_STANDARD_INFO = unchecked(0x102); + + internal class SmbQueryFileBasicInfo : IInfo + { + internal long CreateTime; + + internal long LastAccessTime; + + internal long LastWriteTime; + + internal long ChangeTime; + + internal int Attributes; + + // information levels + public virtual int GetAttributes() + { + return Attributes; + } + + public virtual long GetCreateTime() + { + return CreateTime; + } + + public virtual long GetLastWriteTime() + { + return LastWriteTime; + } + + public virtual long GetSize() + { + return 0L; + } + + public override string ToString() + { + return "SmbQueryFileBasicInfo[" + "createTime=" + Extensions.CreateDate + (CreateTime) + ",lastAccessTime=" + Extensions.CreateDate(LastAccessTime + ) + ",lastWriteTime=" + Extensions.CreateDate(LastWriteTime) + ",changeTime=" + + Extensions.CreateDate(ChangeTime) + ",attributes=0x" + Hexdump.ToHexString + (Attributes, 4) + "]"; + } + + internal SmbQueryFileBasicInfo(Trans2QueryPathInformationResponse enclosing) + { + this._enclosing = enclosing; + } + + private readonly Trans2QueryPathInformationResponse _enclosing; + } + + internal class SmbQueryFileStandardInfo : IInfo + { + internal long AllocationSize; + + internal long EndOfFile; + + internal int NumberOfLinks; + + internal bool DeletePending; + + internal bool Directory; + + public virtual int GetAttributes() + { + return 0; + } + + public virtual long GetCreateTime() + { + return 0L; + } + + public virtual long GetLastWriteTime() + { + return 0L; + } + + public virtual long GetSize() + { + return EndOfFile; + } + + public override string ToString() + { + return "SmbQueryInfoStandard[" + "allocationSize=" + AllocationSize + + ",endOfFile=" + EndOfFile + ",numberOfLinks=" + NumberOfLinks + ",deletePending=" + + DeletePending + ",directory=" + Directory + "]"; + } + + internal SmbQueryFileStandardInfo(Trans2QueryPathInformationResponse enclosing) + { + this._enclosing = enclosing; + } + + private readonly Trans2QueryPathInformationResponse _enclosing; + } + + private int _informationLevel; + + internal IInfo Info; + + internal Trans2QueryPathInformationResponse(int informationLevel) + { + this._informationLevel = informationLevel; + SubCommand = Smb.SmbComTransaction.Trans2QueryPathInformation; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + // observed two zero bytes here with at least win98 + return 2; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + switch (_informationLevel) + { + case SMB_QUERY_FILE_BASIC_INFO: + { + return ReadSmbQueryFileBasicInfoWireFormat(buffer, bufferIndex); + } + + case SMB_QUERY_FILE_STANDARD_INFO: + { + return ReadSmbQueryFileStandardInfoWireFormat(buffer, bufferIndex); + } + + default: + { + return 0; + } + } + } + + internal virtual int ReadSmbQueryFileStandardInfoWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + SmbQueryFileStandardInfo info = new SmbQueryFileStandardInfo + (this); + info.AllocationSize = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + info.EndOfFile = ReadInt8(buffer, bufferIndex); + bufferIndex += 8; + info.NumberOfLinks = ReadInt4(buffer, bufferIndex); + bufferIndex += 4; + info.DeletePending = (buffer[bufferIndex++] & unchecked(0xFF)) > 0; + info.Directory = (buffer[bufferIndex++] & unchecked(0xFF)) > 0; + this.Info = info; + return bufferIndex - start; + } + + internal virtual int ReadSmbQueryFileBasicInfoWireFormat(byte[] buffer, int bufferIndex + ) + { + int start = bufferIndex; + SmbQueryFileBasicInfo info = new SmbQueryFileBasicInfo + (this); + info.CreateTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + info.LastAccessTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + info.LastWriteTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + info.ChangeTime = ReadTime(buffer, bufferIndex); + bufferIndex += 8; + info.Attributes = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + this.Info = info; + return bufferIndex - start; + } + + public override string ToString() + { + return "Trans2QueryPathInformationResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2SetFileInformation.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2SetFileInformation.cs new file mode 100644 index 000000000..289cab866 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2SetFileInformation.cs @@ -0,0 +1,105 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class Trans2SetFileInformation : SmbComTransaction + { + internal const int SmbFileBasicInfo = unchecked(0x101); + + private int _fid; + + private int _attributes; + + private long _createTime; + + private long _lastWriteTime; + + internal Trans2SetFileInformation(int fid, int attributes, long createTime, long + lastWriteTime) + { + this._fid = fid; + this._attributes = attributes; + this._createTime = createTime; + this._lastWriteTime = lastWriteTime; + Command = SmbComTransaction2; + SubCommand = Trans2SetFileInformation; + MaxParameterCount = 6; + MaxDataCount = 0; + MaxSetupCount = unchecked(unchecked(0x00)); + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 2; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteInt2(_fid, dst, dstIndex); + dstIndex += 2; + WriteInt2(SmbFileBasicInfo, dst, dstIndex); + dstIndex += 2; + WriteInt2(0, dst, dstIndex); + dstIndex += 2; + return dstIndex - start; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WriteTime(_createTime, dst, dstIndex); + dstIndex += 8; + WriteInt8(0L, dst, dstIndex); + dstIndex += 8; + WriteTime(_lastWriteTime, dst, dstIndex); + dstIndex += 8; + WriteInt8(0L, dst, dstIndex); + dstIndex += 8; + WriteInt2(unchecked(0x80) | _attributes, dst, dstIndex); + dstIndex += 2; + WriteInt8(0L, dst, dstIndex); + dstIndex += 6; + return dstIndex - start; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "Trans2SetFileInformation[" + base.ToString() + ",fid=" + _fid + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2SetFileInformationResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2SetFileInformationResponse.cs new file mode 100644 index 000000000..b21f356b4 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/Trans2SetFileInformationResponse.cs @@ -0,0 +1,63 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class Trans2SetFileInformationResponse : SmbComTransactionResponse + { + public Trans2SetFileInformationResponse() + { + SubCommand = Smb.SmbComTransaction.Trans2SetFileInformation; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "Trans2SetFileInformationResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransCallNamedPipe.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransCallNamedPipe.cs new file mode 100644 index 000000000..404af0aaa --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransCallNamedPipe.cs @@ -0,0 +1,97 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Smb +{ + internal class TransCallNamedPipe : SmbComTransaction + { + private byte[] _pipeData; + + private int _pipeDataOff; + + private int _pipeDataLen; + + internal TransCallNamedPipe(string pipeName, byte[] data, int off, int len) + { + Name = pipeName; + _pipeData = data; + _pipeDataOff = off; + _pipeDataLen = len; + Command = SmbComTransaction; + SubCommand = TransCallNamedPipe; + Timeout = unchecked((int)(0xFFFFFFFF)); + MaxParameterCount = 0; + MaxDataCount = unchecked(0xFFFF); + MaxSetupCount = unchecked(unchecked(0x00)); + SetupCount = 2; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + // this says "Transaction priority" in netmon + dst[dstIndex++] = unchecked(unchecked(0x00)); + // no FID + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 4; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + if ((dst.Length - dstIndex) < _pipeDataLen) + { + if (Log.Level >= 3) + { + Log.WriteLine("TransCallNamedPipe data too long for buffer"); + } + return 0; + } + Array.Copy(_pipeData, _pipeDataOff, dst, dstIndex, _pipeDataLen); + return _pipeDataLen; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "TransCallNamedPipe[" + base.ToString() + ",pipeName=" + Name + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransCallNamedPipeResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransCallNamedPipeResponse.cs new file mode 100644 index 000000000..b86cc7fdb --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransCallNamedPipeResponse.cs @@ -0,0 +1,77 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class TransCallNamedPipeResponse : SmbComTransactionResponse + { + private SmbNamedPipe _pipe; + + internal TransCallNamedPipeResponse(SmbNamedPipe pipe) + { + this._pipe = pipe; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + if (_pipe.PipeIn != null) + { + TransactNamedPipeInputStream @in = (TransactNamedPipeInputStream)_pipe.PipeIn; + lock (@in.Lock) + { + @in.Receive(buffer, bufferIndex, len); + Runtime.Notify(@in.Lock); + } + } + return len; + } + + public override string ToString() + { + return "TransCallNamedPipeResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransPeekNamedPipe.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransPeekNamedPipe.cs new file mode 100644 index 000000000..9b80bbe1e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransPeekNamedPipe.cs @@ -0,0 +1,78 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class TransPeekNamedPipe : SmbComTransaction + { + private int _fid; + + internal TransPeekNamedPipe(string pipeName, int fid) + { + Name = pipeName; + this._fid = fid; + Command = SmbComTransaction; + SubCommand = TransPeekNamedPipe; + Timeout = unchecked((int)(0xFFFFFFFF)); + MaxParameterCount = 6; + MaxDataCount = 1; + MaxSetupCount = unchecked(unchecked(0x00)); + SetupCount = 2; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + // this says "Transaction priority" in netmon + WriteInt2(_fid, dst, dstIndex); + return 4; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "TransPeekNamedPipe[" + base.ToString() + ",pipeName=" + Name + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransPeekNamedPipeResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransPeekNamedPipeResponse.cs new file mode 100644 index 000000000..6bcf2d07e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransPeekNamedPipeResponse.cs @@ -0,0 +1,84 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class TransPeekNamedPipeResponse : SmbComTransactionResponse + { + private SmbNamedPipe _pipe; + + private int _head; + + internal const int StatusDisconnected = 1; + + internal const int StatusListening = 2; + + internal const int StatusConnectionOk = 3; + + internal const int StatusServerEndClosed = 4; + + internal int status; + + internal int Available; + + internal TransPeekNamedPipeResponse(SmbNamedPipe pipe) + { + this._pipe = pipe; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + Available = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + _head = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + status = ReadInt2(buffer, bufferIndex); + return 6; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "TransPeekNamedPipeResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransTransactNamedPipe.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransTransactNamedPipe.cs new file mode 100644 index 000000000..1b6ec9cca --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransTransactNamedPipe.cs @@ -0,0 +1,97 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Smb +{ + internal class TransTransactNamedPipe : SmbComTransaction + { + private byte[] _pipeData; + + private int _pipeFid; + + private int _pipeDataOff; + + private int _pipeDataLen; + + internal TransTransactNamedPipe(int fid, byte[] data, int off, int len) + { + _pipeFid = fid; + _pipeData = data; + _pipeDataOff = off; + _pipeDataLen = len; + Command = SmbComTransaction; + SubCommand = TransTransactNamedPipe; + MaxParameterCount = 0; + MaxDataCount = unchecked(0xFFFF); + MaxSetupCount = unchecked(unchecked(0x00)); + SetupCount = 2; + Name = "\\PIPE\\"; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + WriteInt2(_pipeFid, dst, dstIndex); + dstIndex += 2; + return 4; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + if ((dst.Length - dstIndex) < _pipeDataLen) + { + if (Log.Level >= 3) + { + Log.WriteLine("TransTransactNamedPipe data too long for buffer"); + } + return 0; + } + Array.Copy(_pipeData, _pipeDataOff, dst, dstIndex, _pipeDataLen); + return _pipeDataLen; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "TransTransactNamedPipe[" + base.ToString() + ",pipeFid=" + _pipeFid + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransTransactNamedPipeResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransTransactNamedPipeResponse.cs new file mode 100644 index 000000000..b8d14781c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransTransactNamedPipeResponse.cs @@ -0,0 +1,77 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class TransTransactNamedPipeResponse : SmbComTransactionResponse + { + private SmbNamedPipe _pipe; + + internal TransTransactNamedPipeResponse(SmbNamedPipe pipe) + { + this._pipe = pipe; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + if (_pipe.PipeIn != null) + { + TransactNamedPipeInputStream @in = (TransactNamedPipeInputStream)_pipe.PipeIn; + lock (@in.Lock) + { + @in.Receive(buffer, bufferIndex, len); + Runtime.Notify(@in.Lock); + } + } + return len; + } + + public override string ToString() + { + return "TransTransactNamedPipeResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransWaitNamedPipe.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransWaitNamedPipe.cs new file mode 100644 index 000000000..a184665aa --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransWaitNamedPipe.cs @@ -0,0 +1,76 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class TransWaitNamedPipe : SmbComTransaction + { + internal TransWaitNamedPipe(string pipeName) + { + Name = pipeName; + Command = SmbComTransaction; + SubCommand = TransWaitNamedPipe; + Timeout = unchecked((int)(0xFFFFFFFF)); + MaxParameterCount = 0; + MaxDataCount = 0; + MaxSetupCount = unchecked(unchecked(0x00)); + SetupCount = 2; + } + + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + dst[dstIndex++] = SubCommand; + dst[dstIndex++] = unchecked(unchecked(0x00)); + dst[dstIndex++] = unchecked(unchecked(0x00)); + // no FID + dst[dstIndex++] = unchecked(unchecked(0x00)); + return 4; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "TransWaitNamedPipe[" + base.ToString() + ",pipeName=" + Name + + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransWaitNamedPipeResponse.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransWaitNamedPipeResponse.cs new file mode 100644 index 000000000..a62a82ec7 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransWaitNamedPipeResponse.cs @@ -0,0 +1,59 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class TransWaitNamedPipeResponse : SmbComTransactionResponse + { + // not much to this one is there :~) + internal override int WriteSetupWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteParametersWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int WriteDataWireFormat(byte[] dst, int dstIndex) + { + return 0; + } + + internal override int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len + ) + { + return 0; + } + + internal override int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int + len) + { + return 0; + } + + internal override int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len) + { + return 0; + } + + public override string ToString() + { + return "TransWaitNamedPipeResponse[" + base.ToString() + "]"; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransactNamedPipeInputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransactNamedPipeInputStream.cs new file mode 100644 index 000000000..46d418582 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransactNamedPipeInputStream.cs @@ -0,0 +1,180 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal class TransactNamedPipeInputStream : SmbFileInputStream + { + private const int InitPipeSize = 4096; + + private byte[] _pipeBuf = new byte[InitPipeSize]; + + private int _begIdx; + + private int _nxtIdx; + + private int _used; + + private bool _dcePipe; + + internal object Lock; + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + /// <exception cref="System.UriFormatException"></exception> + /// <exception cref="UnknownHostException"></exception> + internal TransactNamedPipeInputStream(SmbNamedPipe pipe) : base(pipe, (pipe.PipeType + & unchecked((int)(0xFFFF00FF))) | SmbFile.OExcl) + { + _dcePipe = (pipe.PipeType & SmbNamedPipe.PipeTypeDceTransact) != SmbNamedPipe + .PipeTypeDceTransact; + Lock = new object(); + } + + /// <exception cref="System.IO.IOException"></exception> + public override int Read() + { + int result = -1; + lock (Lock) + { + try + { + while (_used == 0) + { + Runtime.Wait(Lock); + } + } + catch (Exception ie) + { + throw new IOException(ie.Message); + } + result = _pipeBuf[_begIdx] & unchecked(0xFF); + _begIdx = (_begIdx + 1) % _pipeBuf.Length; + } + return result; + } + + /// <exception cref="System.IO.IOException"></exception> + public override int Read(byte[] b) + { + return Read(b, 0, b.Length); + } + + /// <exception cref="System.IO.IOException"></exception> + public override int Read(byte[] b, int off, int len) + { + int result = -1; + int i; + if (len <= 0) + { + return 0; + } + lock (Lock) + { + try + { + while (_used == 0) + { + Runtime.Wait(Lock); + } + } + catch (Exception ie) + { + throw new IOException(ie.Message); + } + i = _pipeBuf.Length - _begIdx; + result = len > _used ? _used : len; + if (_used > i && result > i) + { + Array.Copy(_pipeBuf, _begIdx, b, off, i); + off += i; + Array.Copy(_pipeBuf, 0, b, off, result - i); + } + else + { + Array.Copy(_pipeBuf, _begIdx, b, off, result); + } + _used -= result; + _begIdx = (_begIdx + result) % _pipeBuf.Length; + } + return result; + } + + /// <exception cref="System.IO.IOException"></exception> + public override int Available() + { + if (File.Log.Level >= 3) + { + File.Log.WriteLine("Named Pipe available() does not apply to TRANSACT Named Pipes" + ); + } + return 0; + } + + internal virtual int Receive(byte[] b, int off, int len) + { + int i; + if (len > (_pipeBuf.Length - _used)) + { + byte[] tmp; + int newSize; + newSize = _pipeBuf.Length * 2; + if (len > (newSize - _used)) + { + newSize = len + _used; + } + tmp = _pipeBuf; + _pipeBuf = new byte[newSize]; + i = tmp.Length - _begIdx; + if (_used > i) + { + Array.Copy(tmp, _begIdx, _pipeBuf, 0, i); + Array.Copy(tmp, 0, _pipeBuf, i, _used - i); + } + else + { + Array.Copy(tmp, _begIdx, _pipeBuf, 0, _used); + } + _begIdx = 0; + _nxtIdx = _used; + tmp = null; + } + i = _pipeBuf.Length - _nxtIdx; + if (len > i) + { + Array.Copy(b, off, _pipeBuf, _nxtIdx, i); + off += i; + Array.Copy(b, off, _pipeBuf, 0, len - i); + } + else + { + Array.Copy(b, off, _pipeBuf, _nxtIdx, len); + } + _nxtIdx = (_nxtIdx + len) % _pipeBuf.Length; + _used += len; + return len; + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual int Dce_read(byte[] b, int off, int len) + { + return base.Read(b, off, len); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/TransactNamedPipeOutputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransactNamedPipeOutputStream.cs new file mode 100644 index 000000000..d3e8d3e1a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/TransactNamedPipeOutputStream.cs @@ -0,0 +1,86 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + internal class TransactNamedPipeOutputStream : SmbFileOutputStream + { + private string _path; + + private SmbNamedPipe _pipe; + + private byte[] _tmp = new byte[1]; + + private bool _dcePipe; + + /// <exception cref="System.IO.IOException"></exception> + internal TransactNamedPipeOutputStream(SmbNamedPipe pipe) : base(pipe, false, (pipe + .PipeType & unchecked((int)(0xFFFF00FF))) | SmbFile.OExcl) + { + this._pipe = pipe; + _dcePipe = (pipe.PipeType & SmbNamedPipe.PipeTypeDceTransact) == SmbNamedPipe + .PipeTypeDceTransact; + _path = pipe.Unc; + } + + /// <exception cref="System.IO.IOException"></exception> + public override void Close() + { + _pipe.Close(); + } + + /// <exception cref="System.IO.IOException"></exception> + public override void Write(int b) + { + _tmp[0] = unchecked((byte)b); + Write(_tmp, 0, 1); + } + + /// <exception cref="System.IO.IOException"></exception> + public override void Write(byte[] b) + { + Write(b, 0, b.Length); + } + + /// <exception cref="System.IO.IOException"></exception> + public override void Write(byte[] b, int off, int len) + { + if (len < 0) + { + len = 0; + } + if ((_pipe.PipeType & SmbNamedPipe.PipeTypeCall) == SmbNamedPipe.PipeTypeCall) + { + _pipe.Send(new TransWaitNamedPipe(_path), new TransWaitNamedPipeResponse()); + _pipe.Send(new TransCallNamedPipe(_path, b, off, len), new TransCallNamedPipeResponse + (_pipe)); + } + else + { + if ((_pipe.PipeType & SmbNamedPipe.PipeTypeTransact) == SmbNamedPipe.PipeTypeTransact) + { + EnsureOpen(); + TransTransactNamedPipe req = new TransTransactNamedPipe(_pipe.Fid, b, off, len); + if (_dcePipe) + { + req.MaxDataCount = 1024; + } + _pipe.Send(req, new TransTransactNamedPipeResponse(_pipe)); + } + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/WinError.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/WinError.cs new file mode 100644 index 000000000..daecc5407 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/WinError.cs @@ -0,0 +1,49 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Smb +{ + public static class WinError + { + public static int ErrorSuccess = 0; + + public static int ErrorAccessDenied = 5; + + public static int ErrorReqNotAccep = 71; + + public static int ErrorBadPipe = 230; + + public static int ErrorPipeBusy = 231; + + public static int ErrorNoData = 232; + + public static int ErrorPipeNotConnected = 233; + + public static int ErrorMoreData = 234; + + public static int ErrorNoBrowserServersFound = 6118; + + public static int[] WinerrCodes = { ErrorSuccess, ErrorAccessDenied, + ErrorReqNotAccep, ErrorBadPipe, ErrorPipeBusy, ErrorNoData, ErrorPipeNotConnected + , ErrorMoreData, ErrorNoBrowserServersFound }; + + public static string[] WinerrMessages = { "The operation completed successfully." + , "Access is denied.", "No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept." + , "The pipe state is invalid.", "All pipe instances are busy.", "The pipe is being closed." + , "No process is on the other end of the pipe.", "More data is available.", "The list of servers for this workgroup is not currently available." + }; + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/UniAddress.cs b/Emby.Server.Implementations/IO/SharpCifs/UniAddress.cs new file mode 100644 index 000000000..816fbe781 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/UniAddress.cs @@ -0,0 +1,591 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using System.Linq; +using System.Net; +using SharpCifs.Netbios; +using SharpCifs.Util; +using SharpCifs.Util.Sharpen; +using Extensions = SharpCifs.Util.Sharpen.Extensions; + +namespace SharpCifs +{ + /// <summary> + /// <p>Under normal conditions it is not necessary to use + /// this class to use jCIFS properly. + /// </summary> + /// <remarks> + /// <p>Under normal conditions it is not necessary to use + /// this class to use jCIFS properly. Name resolusion is + /// handled internally to the <code>jcifs.smb</code> package. + /// <p> + /// This class is a wrapper for both + /// <see cref="Jcifs.Netbios.NbtAddress">Jcifs.Netbios.NbtAddress</see> + /// and + /// <see cref="System.Net.IPAddress">System.Net.IPAddress</see> + /// . The name resolution mechanisms + /// used will systematically query all available configured resolution + /// services including WINS, broadcasts, DNS, and LMHOSTS. See + /// <a href="../../resolver.html">Setting Name Resolution Properties</a> + /// and the <code>jcifs.resolveOrder</code> property. Changing + /// jCIFS name resolution properties can greatly affect the behavior of + /// the client and may be necessary for proper operation. + /// <p> + /// This class should be used in favor of <tt>InetAddress</tt> to resolve + /// hostnames on LANs and WANs that support a mixture of NetBIOS/WINS and + /// DNS resolvable hosts. + /// </remarks> + public class UniAddress + { + private const int ResolverWins = 0; + + private const int ResolverBcast = 1; + + private const int ResolverDns = 2; + + private const int ResolverLmhosts = 3; + + private static int[] _resolveOrder; + + private static IPAddress _baddr; + + private static LogStream _log = LogStream.GetInstance(); + + static UniAddress() + { + string ro = Config.GetProperty("jcifs.resolveOrder"); + IPAddress nbns = NbtAddress.GetWinsAddress(); + try + { + _baddr = Config.GetInetAddress("jcifs.netbios.baddr", Extensions.GetAddressByName + ("255.255.255.255")); + } + catch (UnknownHostException) + { + } + if (string.IsNullOrEmpty(ro)) + { + if (nbns == null) + { + _resolveOrder = new int[3]; + _resolveOrder[0] = ResolverLmhosts; + _resolveOrder[1] = ResolverDns; + _resolveOrder[2] = ResolverBcast; + } + else + { + _resolveOrder = new int[4]; + _resolveOrder[0] = ResolverLmhosts; + _resolveOrder[1] = ResolverWins; + _resolveOrder[2] = ResolverDns; + _resolveOrder[3] = ResolverBcast; + } + } + else + { + int[] tmp = new int[4]; + StringTokenizer st = new StringTokenizer(ro, ","); + int i = 0; + while (st.HasMoreTokens()) + { + string s = st.NextToken().Trim(); + if (Runtime.EqualsIgnoreCase(s, "LMHOSTS")) + { + tmp[i++] = ResolverLmhosts; + } + else + { + if (Runtime.EqualsIgnoreCase(s, "WINS")) + { + if (nbns == null) + { + if (_log.Level > 1) + { + _log.WriteLine("UniAddress resolveOrder specifies WINS however the " + "jcifs.netbios.wins property has not been set" + ); + } + continue; + } + tmp[i++] = ResolverWins; + } + else + { + if (Runtime.EqualsIgnoreCase(s, "BCAST")) + { + tmp[i++] = ResolverBcast; + } + else + { + if (Runtime.EqualsIgnoreCase(s, "DNS")) + { + tmp[i++] = ResolverDns; + } + else + { + if (_log.Level > 1) + { + _log.WriteLine("unknown resolver method: " + s); + } + } + } + } + } + } + _resolveOrder = new int[i]; + Array.Copy(tmp, 0, _resolveOrder, 0, i); + } + } + + internal class Sem + { + internal Sem(int count) + { + this.Count = count; + } + + internal int Count; + } + + internal class QueryThread : Thread + { + internal Sem Sem; + + internal string Host; + + internal string Scope; + + internal int Type; + + internal NbtAddress[] Ans; + + internal IPAddress Svr; + + internal UnknownHostException Uhe; + + internal QueryThread(Sem sem, string host, int type, string scope, IPAddress + svr) : base("JCIFS-QueryThread: " + host) + { + this.Sem = sem; + this.Host = host; + this.Type = type; + this.Scope = scope; + this.Svr = svr; + } + + public override void Run() + { + try + { + //Ans = new [] { NbtAddress.GetByName(Host, Type, Scope, Svr) }; + Ans = NbtAddress.GetAllByName(Host, Type, Scope, Svr); + } + catch (UnknownHostException uhe) + { + this.Uhe = uhe; + } + catch (Exception ex) + { + Uhe = new UnknownHostException(ex.Message); + } + finally + { + lock (Sem) + { + Sem.Count--; + Runtime.Notify(Sem); + } + } + } + } + + /// <exception cref="UnknownHostException"></exception> + internal static NbtAddress[] LookupServerOrWorkgroup(string name, IPAddress svr) + { + Sem sem = new Sem(2); + int type = NbtAddress.IsWins(svr) ? unchecked(0x1b) : unchecked(0x1d); + QueryThread q1X = new QueryThread(sem, name, type, null, svr + ); + QueryThread q20 = new QueryThread(sem, name, unchecked(0x20), null, svr); + q1X.SetDaemon(true); + q20.SetDaemon(true); + try + { + lock (sem) + { + q1X.Start(); + q20.Start(); + while (sem.Count > 0 && q1X.Ans == null && q20.Ans == null) + { + Runtime.Wait(sem); + } + } + } + catch (Exception) + { + throw new UnknownHostException(name); + } + if (q1X.Ans != null) + { + return q1X.Ans; + } + if (q20.Ans != null) + { + return q20.Ans; + } + throw q1X.Uhe; + } + + /// <summary>Determines the address of a host given it's host name.</summary> + /// <remarks> + /// Determines the address of a host given it's host name. The name can be a + /// machine name like "jcifs.samba.org", or an IP address like "192.168.1.15". + /// </remarks> + /// <param name="hostname">NetBIOS or DNS hostname to resolve</param> + /// <exception cref="UnknownHostException">if there is an error resolving the name + /// </exception> + public static UniAddress GetByName(string hostname) + { + return GetByName(hostname, false); + } + + internal static bool IsDotQuadIp(string hostname) + { + if (char.IsDigit(hostname[0])) + { + int i; + int len; + int dots; + char[] data; + i = dots = 0; + len = hostname.Length; + data = hostname.ToCharArray(); + while (i < len && char.IsDigit(data[i++])) + { + if (i == len && dots == 3) + { + // probably an IP address + return true; + } + if (i < len && data[i] == '.') + { + dots++; + i++; + } + } + } + return false; + } + + internal static bool IsAllDigits(string hostname) + { + for (int i = 0; i < hostname.Length; i++) + { + if (char.IsDigit(hostname[i]) == false) + { + return false; + } + } + return true; + } + + /// <summary>Lookup <tt>hostname</tt> and return it's <tt>UniAddress</tt>.</summary> + /// <remarks> + /// Lookup <tt>hostname</tt> and return it's <tt>UniAddress</tt>. If the + /// <tt>possibleNTDomainOrWorkgroup</tt> parameter is <tt>true</tt> an + /// addtional name query will be performed to locate a master browser. + /// </remarks> + /// <exception cref="UnknownHostException"></exception> + public static UniAddress GetByName(string hostname, bool possibleNtDomainOrWorkgroup + ) + { + UniAddress[] addrs = GetAllByName(hostname, possibleNtDomainOrWorkgroup + ); + return addrs[0]; + } + + /// <exception cref="UnknownHostException"></exception> + public static UniAddress[] GetAllByName(string hostname, bool possibleNtDomainOrWorkgroup + ) + { + object addr; + int i; + if (string.IsNullOrEmpty(hostname)) + { + throw new UnknownHostException(); + } + if (IsDotQuadIp(hostname)) + { + UniAddress[] addrs = new UniAddress[1]; + addrs[0] = new UniAddress(NbtAddress.GetByName(hostname)); + return addrs; + } + for (i = 0; i < _resolveOrder.Length; i++) + { + try + { + switch (_resolveOrder[i]) + { + case ResolverLmhosts: + { + if ((addr = Lmhosts.GetByName(hostname)) == null) + { + continue; + } + break; + } + + case ResolverWins: + { + if (hostname == NbtAddress.MasterBrowserName || hostname.Length > 15) + { + // invalid netbios name + continue; + } + if (possibleNtDomainOrWorkgroup) + { + addr = LookupServerOrWorkgroup(hostname, NbtAddress.GetWinsAddress()); + } + else + { + addr = NbtAddress.GetByName(hostname, unchecked(0x20), null, NbtAddress.GetWinsAddress + ()); + } + break; + } + + case ResolverBcast: + { + if (hostname.Length > 15) + { + // invalid netbios name + continue; + } + + try + { + if (possibleNtDomainOrWorkgroup) + { + NbtAddress[] iaddrs = LookupServerOrWorkgroup(hostname, _baddr); + + UniAddress[] addrs = new UniAddress[iaddrs.Length]; + for (int ii = 0; ii < iaddrs.Length; ii++) + { + addrs[ii] = new UniAddress(iaddrs[ii]); + } + return addrs; + + } + else + { + addr = NbtAddress.GetByName(hostname, unchecked(0x20), null, _baddr); + } + + } + catch (Exception ex) + { + if (i == _resolveOrder.Length - 1) + { + throw ex; + } + else + { + continue; + } + } + break; + } + + case ResolverDns: + { + if (IsAllDigits(hostname)) + { + throw new UnknownHostException(hostname); + } + + IPAddress[] iaddrs = Extensions.GetAddressesByName(hostname); + + if (iaddrs == null || iaddrs.Length == 0) + { + continue; + } + + return iaddrs.Select(iaddr => new UniAddress(iaddr)).ToArray(); + } + + default: + { + // Success + throw new UnknownHostException(hostname); + } + } + UniAddress[] addrs1 = new UniAddress[1]; + addrs1[0] = new UniAddress(addr); + return addrs1; + } + catch (IOException) + { + } + } + // Success + // Failure + throw new UnknownHostException(hostname); + } + + internal object Addr; + + internal string CalledName; + + /// <summary> + /// Create a <tt>UniAddress</tt> by wrapping an <tt>InetAddress</tt> or + /// <tt>NbtAddress</tt>. + /// </summary> + /// <remarks> + /// Create a <tt>UniAddress</tt> by wrapping an <tt>InetAddress</tt> or + /// <tt>NbtAddress</tt>. + /// </remarks> + public UniAddress(object addr) + { + if (addr == null) + { + throw new ArgumentException(); + } + this.Addr = addr; + } + + /// <summary>Return the IP address of this address as a 32 bit integer.</summary> + /// <remarks>Return the IP address of this address as a 32 bit integer.</remarks> + public override int GetHashCode() + { + return Addr.GetHashCode(); + } + + /// <summary>Compare two addresses for equality.</summary> + /// <remarks> + /// Compare two addresses for equality. Two <tt>UniAddress</tt>s are equal + /// if they are both <tt>UniAddress</tt>' and refer to the same IP address. + /// </remarks> + public override bool Equals(object obj) + { + return obj is UniAddress && Addr.Equals(((UniAddress)obj).Addr); + } + + /// <summary>Guess first called name to try for session establishment.</summary> + /// <remarks> + /// Guess first called name to try for session establishment. This + /// method is used exclusively by the <tt>jcifs.smb</tt> package. + /// </remarks> + public virtual string FirstCalledName() + { + if (Addr is NbtAddress) + { + return ((NbtAddress)Addr).FirstCalledName(); + } + CalledName = ((IPAddress) Addr).GetHostAddress(); + if (IsDotQuadIp(CalledName)) + { + CalledName = NbtAddress.SmbserverName; + } + else + { + int i = CalledName.IndexOf('.'); + if (i > 1 && i < 15) + { + CalledName = Runtime.Substring(CalledName, 0, i).ToUpper(); + } + else + { + if (CalledName.Length > 15) + { + CalledName = NbtAddress.SmbserverName; + } + else + { + CalledName = CalledName.ToUpper(); + } + } + } + return CalledName; + } + + /// <summary>Guess next called name to try for session establishment.</summary> + /// <remarks> + /// Guess next called name to try for session establishment. This + /// method is used exclusively by the <tt>jcifs.smb</tt> package. + /// </remarks> + public virtual string NextCalledName() + { + if (Addr is NbtAddress) + { + return ((NbtAddress)Addr).NextCalledName(); + } + if (CalledName != NbtAddress.SmbserverName) + { + CalledName = NbtAddress.SmbserverName; + return CalledName; + } + return null; + } + + /// <summary>Return the underlying <tt>NbtAddress</tt> or <tt>InetAddress</tt>.</summary> + /// <remarks>Return the underlying <tt>NbtAddress</tt> or <tt>InetAddress</tt>.</remarks> + public virtual object GetAddress() + { + return Addr; + } + + /// <summary>Return the hostname of this address such as "MYCOMPUTER".</summary> + /// <remarks>Return the hostname of this address such as "MYCOMPUTER".</remarks> + public virtual string GetHostName() + { + if (Addr is NbtAddress) + { + return ((NbtAddress)Addr).GetHostName(); + } + return ((IPAddress) Addr).GetHostAddress(); + } + + /// <summary>Return the IP address as text such as "192.168.1.15".</summary> + /// <remarks>Return the IP address as text such as "192.168.1.15".</remarks> + public virtual string GetHostAddress() + { + if (Addr is NbtAddress) + { + return ((NbtAddress)Addr).GetHostAddress(); + } + return ((IPAddress)Addr).GetHostAddress(); + } + + public virtual IPAddress GetHostIpAddress() + { + return (IPAddress) Addr; + } + + /// <summary> + /// Return the a text representation of this address such as + /// <tt>MYCOMPUTER/192.168.1.15</tt>. + /// </summary> + /// <remarks> + /// Return the a text representation of this address such as + /// <tt>MYCOMPUTER/192.168.1.15</tt>. + /// </remarks> + public override string ToString() + { + return Addr.ToString(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Base64.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Base64.cs new file mode 100644 index 000000000..4770f1354 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Base64.cs @@ -0,0 +1,110 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Text; + +namespace SharpCifs.Util +{ + public class Base64 + { + private static readonly string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + /// <summary>Base-64 encodes the supplied block of data.</summary> + /// <remarks> + /// Base-64 encodes the supplied block of data. Line wrapping is not + /// applied on output. + /// </remarks> + /// <param name="bytes">The block of data that is to be Base-64 encoded.</param> + /// <returns>A <code>String</code> containing the encoded data.</returns> + public static string Encode(byte[] bytes) + { + int length = bytes.Length; + if (length == 0) + { + return string.Empty; + } + StringBuilder buffer = new StringBuilder((int)Math.Ceiling(length / 3d) * 4); + int remainder = length % 3; + length -= remainder; + int block; + int i = 0; + while (i < length) + { + block = ((bytes[i++] & unchecked(0xff)) << 16) | ((bytes[i++] & unchecked( + 0xff)) << 8) | (bytes[i++] & unchecked(0xff)); + buffer.Append(Alphabet[(int)(((uint)block) >> 18)]); + buffer.Append(Alphabet[((int)(((uint)block) >> 12)) & unchecked(0x3f)]); + buffer.Append(Alphabet[((int)(((uint)block) >> 6)) & unchecked(0x3f)]); + buffer.Append(Alphabet[block & unchecked(0x3f)]); + } + if (remainder == 0) + { + return buffer.ToString(); + } + if (remainder == 1) + { + block = (bytes[i] & unchecked(0xff)) << 4; + buffer.Append(Alphabet[(int)(((uint)block) >> 6)]); + buffer.Append(Alphabet[block & unchecked(0x3f)]); + buffer.Append("=="); + return buffer.ToString(); + } + block = (((bytes[i++] & unchecked(0xff)) << 8) | ((bytes[i]) & unchecked(0xff))) << 2; + buffer.Append(Alphabet[(int)(((uint)block) >> 12)]); + buffer.Append(Alphabet[((int)(((uint)block) >> 6)) & unchecked(0x3f)]); + buffer.Append(Alphabet[block & unchecked(0x3f)]); + buffer.Append("="); + return buffer.ToString(); + } + + /// <summary>Decodes the supplied Base-64 encoded string.</summary> + /// <remarks>Decodes the supplied Base-64 encoded string.</remarks> + /// <param name="string">The Base-64 encoded string that is to be decoded.</param> + /// <returns>A <code>byte[]</code> containing the decoded data block.</returns> + public static byte[] Decode(string @string) + { + int length = @string.Length; + if (length == 0) + { + return new byte[0]; + } + int pad = (@string[length - 2] == '=') ? 2 : (@string[length - 1] == '=') ? 1 : 0; + int size = length * 3 / 4 - pad; + byte[] buffer = new byte[size]; + int block; + int i = 0; + int index = 0; + while (i < length) + { + block = (Alphabet.IndexOf(@string[i++]) & unchecked(0xff)) << 18 | (Alphabet + .IndexOf(@string[i++]) & unchecked(0xff)) << 12 | (Alphabet.IndexOf(@string + [i++]) & unchecked(0xff)) << 6 | (Alphabet.IndexOf(@string[i++]) & unchecked( + 0xff)); + buffer[index++] = unchecked((byte)((int)(((uint)block) >> 16))); + if (index < size) + { + buffer[index++] = unchecked((byte)(((int)(((uint)block) >> 8)) & unchecked(0xff))); + } + if (index < size) + { + buffer[index++] = unchecked((byte)(block & unchecked(0xff))); + } + } + return buffer; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/DES.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/DES.cs new file mode 100644 index 000000000..c23b14cf8 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/DES.cs @@ -0,0 +1,568 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; + +namespace SharpCifs.Util +{ + /// <summary> + /// This code is derived from the above source + /// JCIFS API + /// Norbert Hranitzky + /// <p>and modified again by Michael B. + /// </summary> + /// <remarks> + /// This code is derived from the above source + /// JCIFS API + /// Norbert Hranitzky + /// <p>and modified again by Michael B. Allen + /// </remarks> + public class DES + { + private int[] _encryptKeys = new int[32]; + + private int[] _decryptKeys = new int[32]; + + private int[] _tempInts = new int[2]; + + public DES() + { + } + + public DES(byte[] key) + { + // DesCipher - the DES encryption method + // + // The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is: + // + // Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. + // + // Permission to use, copy, modify, and distribute this software + // and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and + // without fee is hereby granted, provided that this copyright notice is kept + // intact. + // + // WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY + // OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + // TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + // PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE + // FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + // DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + // + // THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE + // CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE + // PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT + // NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE + // SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE + // SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE + // PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP + // SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR + // HIGH RISK ACTIVITIES. + // + // + // The rest is: + // + // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved. + // + // Copyright (C) 1996 by Wolfgang Platzer + // email: wplatzer@iaik.tu-graz.ac.at + // + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions + // are met: + // 1. Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // 2. Redistributions in binary form must reproduce the above copyright + // notice, this list of conditions and the following disclaimer in the + // documentation and/or other materials provided with the distribution. + // + // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + // SUCH DAMAGE. + // + // Constructor, byte-array key. + if (key.Length == 7) + { + byte[] key8 = new byte[8]; + MakeSmbKey(key, key8); + SetKey(key8); + } + else + { + SetKey(key); + } + } + + public static void MakeSmbKey(byte[] key7, byte[] key8) + { + int i; + key8[0] = unchecked((byte)((key7[0] >> 1) & unchecked(0xff))); + key8[1] = unchecked((byte)((((key7[0] & unchecked(0x01)) << 6) | (((key7[1 + ] & unchecked(0xff)) >> 2) & unchecked(0xff))) & unchecked(0xff))); + key8[2] = unchecked((byte)((((key7[1] & unchecked(0x03)) << 5) | (((key7[2 + ] & unchecked(0xff)) >> 3) & unchecked(0xff))) & unchecked(0xff))); + key8[3] = unchecked((byte)((((key7[2] & unchecked(0x07)) << 4) | (((key7[3 + ] & unchecked(0xff)) >> 4) & unchecked(0xff))) & unchecked(0xff))); + key8[4] = unchecked((byte)((((key7[3] & unchecked(0x0F)) << 3) | (((key7[4 + ] & unchecked(0xff)) >> 5) & unchecked(0xff))) & unchecked(0xff))); + key8[5] = unchecked((byte)((((key7[4] & unchecked(0x1F)) << 2) | (((key7[5 + ] & unchecked(0xff)) >> 6) & unchecked(0xff))) & unchecked(0xff))); + key8[6] = unchecked((byte)((((key7[5] & unchecked(0x3F)) << 1) | (((key7[6 + ] & unchecked(0xff)) >> 7) & unchecked(0xff))) & unchecked(0xff))); + key8[7] = unchecked((byte)(key7[6] & unchecked(0x7F))); + for (i = 0; i < 8; i++) + { + key8[i] = unchecked((byte)(key8[i] << 1)); + } + } + + /// Set the key. + public virtual void SetKey(byte[] key) + { + // CHECK PAROTY TBD + Deskey(key, true, _encryptKeys); + Deskey(key, false, _decryptKeys); + } + + // Turn an 8-byte key into internal keys. + private void Deskey(byte[] keyBlock, bool encrypting, int[] knL) + { + int i; + int j; + int l; + int m; + int n; + int[] pc1M = new int[56]; + int[] pcr = new int[56]; + int[] kn = new int[32]; + for (j = 0; j < 56; ++j) + { + l = _pc1[j]; + m = l & 0x7; + pc1M[j] = ((keyBlock[(int)(((uint)l) >> 3)] & _bytebit[m]) != 0) ? 1 : 0; + } + for (i = 0; i < 16; ++i) + { + if (encrypting) + { + m = i << 1; + } + else + { + m = (15 - i) << 1; + } + n = m + 1; + kn[m] = kn[n] = 0; + for (j = 0; j < 28; ++j) + { + l = j + _totrot[i]; + if (l < 28) + { + pcr[j] = pc1M[l]; + } + else + { + pcr[j] = pc1M[l - 28]; + } + } + for (j = 28; j < 56; ++j) + { + l = j + _totrot[i]; + if (l < 56) + { + pcr[j] = pc1M[l]; + } + else + { + pcr[j] = pc1M[l - 28]; + } + } + for (j = 0; j < 24; ++j) + { + if (pcr[_pc2[j]] != 0) + { + kn[m] |= _bigbyte[j]; + } + if (pcr[_pc2[j + 24]] != 0) + { + kn[n] |= _bigbyte[j]; + } + } + } + Cookey(kn, knL); + } + + private void Cookey(int[] raw, int[] knL) + { + int raw0; + int raw1; + int rawi; + int knLi; + int i; + for (i = 0, rawi = 0, knLi = 0; i < 16; ++i) + { + raw0 = raw[rawi++]; + raw1 = raw[rawi++]; + knL[knLi] = (raw0 & unchecked(0x00fc0000)) << 6; + knL[knLi] |= (raw0 & unchecked(0x00000fc0)) << 10; + knL[knLi] |= (int)(((uint)(raw1 & unchecked(0x00fc0000))) >> 10); + knL[knLi] |= (int)(((uint)(raw1 & unchecked(0x00000fc0))) >> 6); + ++knLi; + knL[knLi] = (raw0 & unchecked(0x0003f000)) << 12; + knL[knLi] |= (raw0 & unchecked(0x0000003f)) << 16; + knL[knLi] |= (int)(((uint)(raw1 & unchecked(0x0003f000))) >> 4); + knL[knLi] |= (raw1 & unchecked(0x0000003f)); + ++knLi; + } + } + + /// Encrypt a block of eight bytes. + private void Encrypt(byte[] clearText, int clearOff, byte[] cipherText, int cipherOff + ) + { + SquashBytesToInts(clearText, clearOff, _tempInts, 0, 2); + Des(_tempInts, _tempInts, _encryptKeys); + SpreadIntsToBytes(_tempInts, 0, cipherText, cipherOff, 2); + } + + /// Decrypt a block of eight bytes. + private void Decrypt(byte[] cipherText, int cipherOff, byte[] clearText, int clearOff + ) + { + SquashBytesToInts(cipherText, cipherOff, _tempInts, 0, 2); + Des(_tempInts, _tempInts, _decryptKeys); + SpreadIntsToBytes(_tempInts, 0, clearText, clearOff, 2); + } + + // The DES function. + private void Des(int[] inInts, int[] outInts, int[] keys) + { + int fval; + int work; + int right; + int leftt; + int round; + int keysi = 0; + leftt = inInts[0]; + right = inInts[1]; + work = (((int)(((uint)leftt) >> 4)) ^ right) & unchecked(0x0f0f0f0f); + right ^= work; + leftt ^= (work << 4); + work = (((int)(((uint)leftt) >> 16)) ^ right) & unchecked(0x0000ffff); + right ^= work; + leftt ^= (work << 16); + work = (((int)(((uint)right) >> 2)) ^ leftt) & unchecked(0x33333333); + leftt ^= work; + right ^= (work << 2); + work = (((int)(((uint)right) >> 8)) ^ leftt) & unchecked(0x00ff00ff); + leftt ^= work; + right ^= (work << 8); + right = (right << 1) | (((int)(((uint)right) >> 31)) & 1); + work = (leftt ^ right) & unchecked((int)(0xaaaaaaaa)); + leftt ^= work; + right ^= work; + leftt = (leftt << 1) | (((int)(((uint)leftt) >> 31)) & 1); + for (round = 0; round < 8; ++round) + { + work = (right << 28) | ((int)(((uint)right) >> 4)); + work ^= keys[keysi++]; + fval = _sp7[work & unchecked(0x0000003f)]; + fval |= _sp5[((int)(((uint)work) >> 8)) & unchecked(0x0000003f)]; + fval |= _sp3[((int)(((uint)work) >> 16)) & unchecked(0x0000003f)]; + fval |= _sp1[((int)(((uint)work) >> 24)) & unchecked(0x0000003f)]; + work = right ^ keys[keysi++]; + fval |= _sp8[work & unchecked(0x0000003f)]; + fval |= _sp6[((int)(((uint)work) >> 8)) & unchecked(0x0000003f)]; + fval |= _sp4[((int)(((uint)work) >> 16)) & unchecked(0x0000003f)]; + fval |= _sp2[((int)(((uint)work) >> 24)) & unchecked(0x0000003f)]; + leftt ^= fval; + work = (leftt << 28) | ((int)(((uint)leftt) >> 4)); + work ^= keys[keysi++]; + fval = _sp7[work & unchecked(0x0000003f)]; + fval |= _sp5[((int)(((uint)work) >> 8)) & unchecked(0x0000003f)]; + fval |= _sp3[((int)(((uint)work) >> 16)) & unchecked(0x0000003f)]; + fval |= _sp1[((int)(((uint)work) >> 24)) & unchecked(0x0000003f)]; + work = leftt ^ keys[keysi++]; + fval |= _sp8[work & unchecked(0x0000003f)]; + fval |= _sp6[((int)(((uint)work) >> 8)) & unchecked(0x0000003f)]; + fval |= _sp4[((int)(((uint)work) >> 16)) & unchecked(0x0000003f)]; + fval |= _sp2[((int)(((uint)work) >> 24)) & unchecked(0x0000003f)]; + right ^= fval; + } + right = (right << 31) | ((int)(((uint)right) >> 1)); + work = (leftt ^ right) & unchecked((int)(0xaaaaaaaa)); + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | ((int)(((uint)leftt) >> 1)); + work = (((int)(((uint)leftt) >> 8)) ^ right) & unchecked(0x00ff00ff); + right ^= work; + leftt ^= (work << 8); + work = (((int)(((uint)leftt) >> 2)) ^ right) & unchecked(0x33333333); + right ^= work; + leftt ^= (work << 2); + work = (((int)(((uint)right) >> 16)) ^ leftt) & unchecked(0x0000ffff); + leftt ^= work; + right ^= (work << 16); + work = (((int)(((uint)right) >> 4)) ^ leftt) & unchecked(0x0f0f0f0f); + leftt ^= work; + right ^= (work << 4); + outInts[0] = right; + outInts[1] = leftt; + } + + /// Encrypt a block of bytes. + public virtual void Encrypt(byte[] clearText, byte[] cipherText) + { + Encrypt(clearText, 0, cipherText, 0); + } + + /// Decrypt a block of bytes. + public virtual void Decrypt(byte[] cipherText, byte[] clearText) + { + Decrypt(cipherText, 0, clearText, 0); + } + + /// <summary>encrypts an array where the length must be a multiple of 8</summary> + public virtual byte[] Encrypt(byte[] clearText) + { + int length = clearText.Length; + if (length % 8 != 0) + { + Console.Out.WriteLine("Array must be a multiple of 8"); + return null; + } + byte[] cipherText = new byte[length]; + int count = length / 8; + for (int i = 0; i < count; i++) + { + Encrypt(clearText, i * 8, cipherText, i * 8); + } + return cipherText; + } + + /// <summary>decrypts an array where the length must be a multiple of 8</summary> + public virtual byte[] Decrypt(byte[] cipherText) + { + int length = cipherText.Length; + if (length % 8 != 0) + { + Console.Out.WriteLine("Array must be a multiple of 8"); + return null; + } + byte[] clearText = new byte[length]; + int count = length / 8; + for (int i = 0; i < count; i++) + { + Encrypt(cipherText, i * 8, clearText, i * 8); + } + return clearText; + } + + private static byte[] _bytebit = { unchecked(unchecked(0x80)), unchecked(unchecked(0x40)), unchecked(unchecked(0x20)), unchecked(unchecked(0x10)), unchecked(unchecked(0x08)), unchecked(unchecked(0x04)), unchecked(unchecked(0x02)), unchecked(unchecked(0x01)) }; + + private static int[] _bigbyte = { unchecked(0x800000), unchecked( + 0x400000), unchecked(0x200000), unchecked(0x100000), unchecked( + 0x080000), unchecked(0x040000), unchecked(0x020000), unchecked( + 0x010000), unchecked(0x008000), unchecked(0x004000), unchecked( + 0x002000), unchecked(0x001000), unchecked(0x000800), unchecked( + 0x000400), unchecked(0x000200), unchecked(0x000100), unchecked( + 0x000080), unchecked(0x000040), unchecked(0x000020), unchecked( + 0x000010), unchecked(0x000008), unchecked(0x000004), unchecked( + 0x000002), unchecked(0x000001) }; + + private static byte[] _pc1 = { unchecked(56), unchecked(48) + , unchecked(40), unchecked(32), unchecked(24), unchecked(16), unchecked(8), unchecked(0), unchecked(57), unchecked(49), unchecked(41), unchecked(33), unchecked(25), unchecked(17), unchecked(9), unchecked(1), unchecked(58), unchecked( + 50), unchecked(42), unchecked(34), unchecked(26), unchecked( + 18), unchecked(10), unchecked(2), unchecked(59), unchecked( + 51), unchecked(43), unchecked(35), unchecked(62), unchecked( + 54), unchecked(46), unchecked(38), unchecked(30), unchecked( + 22), unchecked(14), unchecked(6), unchecked(61), unchecked( + 53), unchecked(45), unchecked(37), unchecked(29), unchecked( + 21), unchecked(13), unchecked(5), unchecked(60), unchecked( + 52), unchecked(44), unchecked(36), unchecked(28), unchecked( + 20), unchecked(12), unchecked(4), unchecked(27), unchecked( + 19), unchecked(11), unchecked(3) }; + + private static int[] _totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, + 21, 23, 25, 27, 28 }; + + private static byte[] _pc2 = { unchecked(13), unchecked(16) + , unchecked(10), unchecked(23), unchecked(0), unchecked(4), unchecked(2), unchecked(27), unchecked(14), unchecked(5), unchecked(20), unchecked(9), unchecked(22), unchecked(18), unchecked(11), unchecked(3), unchecked(25), unchecked(7), unchecked(15), unchecked(6), unchecked(26), unchecked(19), unchecked(12), unchecked(1), unchecked(40), unchecked(51), unchecked(30), unchecked(36), unchecked(46), unchecked(54), unchecked(29), unchecked(39), unchecked(50), unchecked( + 44), unchecked(32), unchecked(47), unchecked(43), unchecked( + 48), unchecked(38), unchecked(55), unchecked(33), unchecked( + 52), unchecked(45), unchecked(41), unchecked(49), unchecked( + 35), unchecked(28), unchecked(31) }; + + private static int[] _sp1 = { unchecked(0x01010400), unchecked(0x00000000), unchecked(0x00010000), unchecked(0x01010404), unchecked( + 0x01010004), unchecked(0x00010404), unchecked(0x00000004), + unchecked(0x00010000), unchecked(0x00000400), unchecked(0x01010400), unchecked(0x01010404), unchecked(0x00000400), unchecked(0x01000404), unchecked(0x01010004), unchecked(0x01000000), unchecked( + 0x00000004), unchecked(0x00000404), unchecked(0x01000400), + unchecked(0x01000400), unchecked(0x00010400), unchecked(0x00010400), unchecked(0x01010000), unchecked(0x01010000), unchecked(0x01000404), unchecked(0x00010004), unchecked(0x01000004), unchecked( + 0x01000004), unchecked(0x00010004), unchecked(0x00000000), + unchecked(0x00000404), unchecked(0x00010404), unchecked(0x01000000), unchecked(0x00010000), unchecked(0x01010404), unchecked(0x00000004), unchecked(0x01010000), unchecked(0x01010400), unchecked( + 0x01000000), unchecked(0x01000000), unchecked(0x00000400), + unchecked(0x01010004), unchecked(0x00010000), unchecked(0x00010400), unchecked(0x01000004), unchecked(0x00000400), unchecked(0x00000004), unchecked(0x01000404), unchecked(0x00010404), unchecked( + 0x01010404), unchecked(0x00010004), unchecked(0x01010000), + unchecked(0x01000404), unchecked(0x01000004), unchecked(0x00000404), unchecked(0x00010404), unchecked(0x01010400), unchecked(0x00000404), unchecked(0x01000400), unchecked(0x01000400), unchecked( + 0x00000000), unchecked(0x00010004), unchecked(0x00010400), + unchecked(0x00000000), unchecked(0x01010004) }; + + private static int[] _sp2 = { unchecked((int)(0x80108020)), unchecked((int + )(0x80008000)), unchecked(0x00008000), unchecked(0x00108020), unchecked( + 0x00100000), unchecked(0x00000020), unchecked((int)(0x80100020)), + unchecked((int)(0x80008020)), unchecked((int)(0x80000020)), unchecked((int)(0x80108020 + )), unchecked((int)(0x80108000)), unchecked((int)(0x80000000)), unchecked((int)( + 0x80008000)), unchecked(0x00100000), unchecked(0x00000020), unchecked( + (int)(0x80100020)), unchecked(0x00108000), unchecked(0x00100020), + unchecked((int)(0x80008020)), unchecked(0x00000000), unchecked((int)(0x80000000 + )), unchecked(0x00008000), unchecked(0x00108020), unchecked((int)( + 0x80100000)), unchecked(0x00100020), unchecked((int)(0x80000020)), unchecked( + 0x00000000), unchecked(0x00108000), unchecked(0x00008020), + unchecked((int)(0x80108000)), unchecked((int)(0x80100000)), unchecked(0x00008020), unchecked(0x00000000), unchecked(0x00108020), unchecked((int)( + 0x80100020)), unchecked(0x00100000), unchecked((int)(0x80008020)), unchecked( + (int)(0x80100000)), unchecked((int)(0x80108000)), unchecked(0x00008000), + unchecked((int)(0x80100000)), unchecked((int)(0x80008000)), unchecked(0x00000020), unchecked((int)(0x80108020)), unchecked(0x00108020), unchecked(0x00000020), unchecked(0x00008000), unchecked((int)(0x80000000)), unchecked( + 0x00008020), unchecked((int)(0x80108000)), unchecked(0x00100000), + unchecked((int)(0x80000020)), unchecked(0x00100020), unchecked((int)(0x80008020 + )), unchecked((int)(0x80000020)), unchecked(0x00100020), unchecked(0x00108000), unchecked(0x00000000), unchecked((int)(0x80008000)), unchecked( + 0x00008020), unchecked((int)(0x80000000)), unchecked((int)(0x80100020)), + unchecked((int)(0x80108020)), unchecked(0x00108000) }; + + private static int[] _sp3 = { unchecked(0x00000208), unchecked(0x08020200), unchecked(0x00000000), unchecked(0x08020008), unchecked( + 0x08000200), unchecked(0x00000000), unchecked(0x00020208), + unchecked(0x08000200), unchecked(0x00020008), unchecked(0x08000008), unchecked(0x08000008), unchecked(0x00020000), unchecked(0x08020208), unchecked(0x00020008), unchecked(0x08020000), unchecked( + 0x00000208), unchecked(0x08000000), unchecked(0x00000008), + unchecked(0x08020200), unchecked(0x00000200), unchecked(0x00020200), unchecked(0x08020000), unchecked(0x08020008), unchecked(0x00020208), unchecked(0x08000208), unchecked(0x00020200), unchecked( + 0x00020000), unchecked(0x08000208), unchecked(0x00000008), + unchecked(0x08020208), unchecked(0x00000200), unchecked(0x08000000), unchecked(0x08020200), unchecked(0x08000000), unchecked(0x00020008), unchecked(0x00000208), unchecked(0x00020000), unchecked( + 0x08020200), unchecked(0x08000200), unchecked(0x00000000), + unchecked(0x00000200), unchecked(0x00020008), unchecked(0x08020208), unchecked(0x08000200), unchecked(0x08000008), unchecked(0x00000200), unchecked(0x00000000), unchecked(0x08020008), unchecked( + 0x08000208), unchecked(0x00020000), unchecked(0x08000000), + unchecked(0x08020208), unchecked(0x00000008), unchecked(0x00020208), unchecked(0x00020200), unchecked(0x08000008), unchecked(0x08020000), unchecked(0x08000208), unchecked(0x00000208), unchecked( + 0x08020000), unchecked(0x00020208), unchecked(0x00000008), + unchecked(0x08020008), unchecked(0x00020200) }; + + private static int[] _sp4 = { unchecked(0x00802001), unchecked(0x00002081), unchecked(0x00002081), unchecked(0x00000080), unchecked( + 0x00802080), unchecked(0x00800081), unchecked(0x00800001), + unchecked(0x00002001), unchecked(0x00000000), unchecked(0x00802000), unchecked(0x00802000), unchecked(0x00802081), unchecked(0x00000081), unchecked(0x00000000), unchecked(0x00800080), unchecked( + 0x00800001), unchecked(0x00000001), unchecked(0x00002000), + unchecked(0x00800000), unchecked(0x00802001), unchecked(0x00000080), unchecked(0x00800000), unchecked(0x00002001), unchecked(0x00002080), unchecked(0x00800081), unchecked(0x00000001), unchecked( + 0x00002080), unchecked(0x00800080), unchecked(0x00002000), + unchecked(0x00802080), unchecked(0x00802081), unchecked(0x00000081), unchecked(0x00800080), unchecked(0x00800001), unchecked(0x00802000), unchecked(0x00802081), unchecked(0x00000081), unchecked( + 0x00000000), unchecked(0x00000000), unchecked(0x00802000), + unchecked(0x00002080), unchecked(0x00800080), unchecked(0x00800081), unchecked(0x00000001), unchecked(0x00802001), unchecked(0x00002081), unchecked(0x00002081), unchecked(0x00000080), unchecked( + 0x00802081), unchecked(0x00000081), unchecked(0x00000001), + unchecked(0x00002000), unchecked(0x00800001), unchecked(0x00002001), unchecked(0x00802080), unchecked(0x00800081), unchecked(0x00002001), unchecked(0x00002080), unchecked(0x00800000), unchecked( + 0x00802001), unchecked(0x00000080), unchecked(0x00800000), + unchecked(0x00002000), unchecked(0x00802080) }; + + private static int[] _sp5 = { unchecked(0x00000100), unchecked(0x02080100), unchecked(0x02080000), unchecked(0x42000100), unchecked( + 0x00080000), unchecked(0x00000100), unchecked(0x40000000), + unchecked(0x02080000), unchecked(0x40080100), unchecked(0x00080000), unchecked(0x02000100), unchecked(0x40080100), unchecked(0x42000100), unchecked(0x42080000), unchecked(0x00080100), unchecked( + 0x40000000), unchecked(0x02000000), unchecked(0x40080000), + unchecked(0x40080000), unchecked(0x00000000), unchecked(0x40000100), unchecked(0x42080100), unchecked(0x42080100), unchecked(0x02000100), unchecked(0x42080000), unchecked(0x40000100), unchecked( + 0x00000000), unchecked(0x42000000), unchecked(0x02080100), + unchecked(0x02000000), unchecked(0x42000000), unchecked(0x00080100), unchecked(0x00080000), unchecked(0x42000100), unchecked(0x00000100), unchecked(0x02000000), unchecked(0x40000000), unchecked( + 0x02080000), unchecked(0x42000100), unchecked(0x40080100), + unchecked(0x02000100), unchecked(0x40000000), unchecked(0x42080000), unchecked(0x02080100), unchecked(0x40080100), unchecked(0x00000100), unchecked(0x02000000), unchecked(0x42080000), unchecked( + 0x42080100), unchecked(0x00080100), unchecked(0x42000000), + unchecked(0x42080100), unchecked(0x02080000), unchecked(0x00000000), unchecked(0x40080000), unchecked(0x42000000), unchecked(0x00080100), unchecked(0x02000100), unchecked(0x40000100), unchecked( + 0x00080000), unchecked(0x00000000), unchecked(0x40080000), + unchecked(0x02080100), unchecked(0x40000100) }; + + private static int[] _sp6 = { unchecked(0x20000010), unchecked(0x20400000), unchecked(0x00004000), unchecked(0x20404010), unchecked( + 0x20400000), unchecked(0x00000010), unchecked(0x20404010), + unchecked(0x00400000), unchecked(0x20004000), unchecked(0x00404010), unchecked(0x00400000), unchecked(0x20000010), unchecked(0x00400010), unchecked(0x20004000), unchecked(0x20000000), unchecked( + 0x00004010), unchecked(0x00000000), unchecked(0x00400010), + unchecked(0x20004010), unchecked(0x00004000), unchecked(0x00404000), unchecked(0x20004010), unchecked(0x00000010), unchecked(0x20400010), unchecked(0x20400010), unchecked(0x00000000), unchecked( + 0x00404010), unchecked(0x20404000), unchecked(0x00004010), + unchecked(0x00404000), unchecked(0x20404000), unchecked(0x20000000), unchecked(0x20004000), unchecked(0x00000010), unchecked(0x20400010), unchecked(0x00404000), unchecked(0x20404010), unchecked( + 0x00400000), unchecked(0x00004010), unchecked(0x20000010), + unchecked(0x00400000), unchecked(0x20004000), unchecked(0x20000000), unchecked(0x00004010), unchecked(0x20000010), unchecked(0x20404010), unchecked(0x00404000), unchecked(0x20400000), unchecked( + 0x00404010), unchecked(0x20404000), unchecked(0x00000000), + unchecked(0x20400010), unchecked(0x00000010), unchecked(0x00004000), unchecked(0x20400000), unchecked(0x00404010), unchecked(0x00004000), unchecked(0x00400010), unchecked(0x20004010), unchecked( + 0x00000000), unchecked(0x20404000), unchecked(0x20000000), + unchecked(0x00400010), unchecked(0x20004010) }; + + private static int[] _sp7 = { unchecked(0x00200000), unchecked(0x04200002), unchecked(0x04000802), unchecked(0x00000000), unchecked( + 0x00000800), unchecked(0x04000802), unchecked(0x00200802), + unchecked(0x04200800), unchecked(0x04200802), unchecked(0x00200000), unchecked(0x00000000), unchecked(0x04000002), unchecked(0x00000002), unchecked(0x04000000), unchecked(0x04200002), unchecked( + 0x00000802), unchecked(0x04000800), unchecked(0x00200802), + unchecked(0x00200002), unchecked(0x04000800), unchecked(0x04000002), unchecked(0x04200000), unchecked(0x04200800), unchecked(0x00200002), unchecked(0x04200000), unchecked(0x00000800), unchecked( + 0x00000802), unchecked(0x04200802), unchecked(0x00200800), + unchecked(0x00000002), unchecked(0x04000000), unchecked(0x00200800), unchecked(0x04000000), unchecked(0x00200800), unchecked(0x00200000), unchecked(0x04000802), unchecked(0x04000802), unchecked( + 0x04200002), unchecked(0x04200002), unchecked(0x00000002), + unchecked(0x00200002), unchecked(0x04000000), unchecked(0x04000800), unchecked(0x00200000), unchecked(0x04200800), unchecked(0x00000802), unchecked(0x00200802), unchecked(0x04200800), unchecked( + 0x00000802), unchecked(0x04000002), unchecked(0x04200802), + unchecked(0x04200000), unchecked(0x00200800), unchecked(0x00000000), unchecked(0x00000002), unchecked(0x04200802), unchecked(0x00000000), unchecked(0x00200802), unchecked(0x04200000), unchecked( + 0x00000800), unchecked(0x04000002), unchecked(0x04000800), + unchecked(0x00000800), unchecked(0x00200002) }; + + private static int[] _sp8 = { unchecked(0x10001040), unchecked(0x00001000), unchecked(0x00040000), unchecked(0x10041040), unchecked( + 0x10000000), unchecked(0x10001040), unchecked(0x00000040), + unchecked(0x10000000), unchecked(0x00040040), unchecked(0x10040000), unchecked(0x10041040), unchecked(0x00041000), unchecked(0x10041000), unchecked(0x00041040), unchecked(0x00001000), unchecked( + 0x00000040), unchecked(0x10040000), unchecked(0x10000040), + unchecked(0x10001000), unchecked(0x00001040), unchecked(0x00041000), unchecked(0x00040040), unchecked(0x10040040), unchecked(0x10041000), unchecked(0x00001040), unchecked(0x00000000), unchecked( + 0x00000000), unchecked(0x10040040), unchecked(0x10000040), + unchecked(0x10001000), unchecked(0x00041040), unchecked(0x00040000), unchecked(0x00041040), unchecked(0x00040000), unchecked(0x10041000), unchecked(0x00001000), unchecked(0x00000040), unchecked( + 0x10040040), unchecked(0x00001000), unchecked(0x00041040), + unchecked(0x10001000), unchecked(0x00000040), unchecked(0x10000040), unchecked(0x10040000), unchecked(0x10040040), unchecked(0x10000000), unchecked(0x00040000), unchecked(0x10001040), unchecked( + 0x00000000), unchecked(0x10041040), unchecked(0x00040040), + unchecked(0x10000040), unchecked(0x10040000), unchecked(0x10001000), unchecked(0x10001040), unchecked(0x00000000), unchecked(0x10041040), unchecked(0x00041000), unchecked(0x00041000), unchecked( + 0x00001040), unchecked(0x00001040), unchecked(0x00040040), + unchecked(0x10000000), unchecked(0x10041000) }; + + // Tables, permutations, S-boxes, etc. + /// Squash bytes down to ints. + public static void SquashBytesToInts(byte[] inBytes, int inOff, int[] outInts, int + outOff, int intLen) + { + for (int i = 0; i < intLen; ++i) + { + outInts[outOff + i] = ((inBytes[inOff + i * 4] & unchecked(0xff)) << 24) | + ((inBytes[inOff + i * 4 + 1] & unchecked(0xff)) << 16) | ((inBytes[inOff + + i * 4 + 2] & unchecked(0xff)) << 8) | (inBytes[inOff + i * 4 + 3] & unchecked( + 0xff)); + } + } + + /// Spread ints into bytes. + public static void SpreadIntsToBytes(int[] inInts, int inOff, byte[] outBytes, int + outOff, int intLen) + { + for (int i = 0; i < intLen; ++i) + { + outBytes[outOff + i * 4] = unchecked((byte)((int)(((uint)inInts[inOff + i]) >> 24 + ))); + outBytes[outOff + i * 4 + 1] = unchecked((byte)((int)(((uint)inInts[inOff + i]) >> + 16))); + outBytes[outOff + i * 4 + 2] = unchecked((byte)((int)(((uint)inInts[inOff + i]) >> + 8))); + outBytes[outOff + i * 4 + 3] = unchecked((byte)inInts[inOff + i]); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Encdec.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Encdec.cs new file mode 100644 index 000000000..7e4d57705 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Encdec.cs @@ -0,0 +1,401 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Util +{ + public class Encdec + { + public const long MillisecondsBetween1970And1601 = 11644473600000L; + + public const long SecBetweeen1904And1970 = 2082844800L; + + public const int Time1970Sec32Be = 1; + + public const int Time1970Sec32Le = 2; + + public const int Time1904Sec32Be = 3; + + public const int Time1904Sec32Le = 4; + + public const int Time1601Nanos64Le = 5; + + public const int Time1601Nanos64Be = 6; + + public const int Time1970Millis64Be = 7; + + public const int Time1970Millis64Le = 8; + + public static int Enc_uint16be(short s, byte[] dst, int di) + { + dst[di++] = unchecked((byte)((s >> 8) & unchecked(0xFF))); + dst[di] = unchecked((byte)(s & unchecked(0xFF))); + return 2; + } + + public static int Enc_uint32be(int i, byte[] dst, int di) + { + dst[di++] = unchecked((byte)((i >> 24) & unchecked(0xFF))); + dst[di++] = unchecked((byte)((i >> 16) & unchecked(0xFF))); + dst[di++] = unchecked((byte)((i >> 8) & unchecked(0xFF))); + dst[di] = unchecked((byte)(i & unchecked(0xFF))); + return 4; + } + + public static int Enc_uint16le(short s, byte[] dst, int di) + { + dst[di++] = unchecked((byte)(s & unchecked(0xFF))); + dst[di] = unchecked((byte)((s >> 8) & unchecked(0xFF))); + return 2; + } + + public static int Enc_uint32le(int i, byte[] dst, int di) + { + dst[di++] = unchecked((byte)(i & unchecked(0xFF))); + dst[di++] = unchecked((byte)((i >> 8) & unchecked(0xFF))); + dst[di++] = unchecked((byte)((i >> 16) & unchecked(0xFF))); + dst[di] = unchecked((byte)((i >> 24) & unchecked(0xFF))); + return 4; + } + + public static short Dec_uint16be(byte[] src, int si) + { + return (short)(((src[si] & unchecked(0xFF)) << 8) | (src[si + 1] & unchecked( + 0xFF))); + } + + public static int Dec_uint32be(byte[] src, int si) + { + return ((src[si] & unchecked(0xFF)) << 24) | ((src[si + 1] & unchecked(0xFF)) << 16) | ((src[si + 2] & unchecked(0xFF)) << 8) | (src[si + 3] + & unchecked(0xFF)); + } + + public static short Dec_uint16le(byte[] src, int si) + { + return (short)((src[si] & unchecked(0xFF)) | ((src[si + 1] & unchecked(0xFF)) << 8)); + } + + public static int Dec_uint32le(byte[] src, int si) + { + return (src[si] & unchecked(0xFF)) | ((src[si + 1] & unchecked(0xFF + )) << 8) | ((src[si + 2] & unchecked(0xFF)) << 16) | ((src[si + 3] & unchecked( + 0xFF)) << 24); + } + + public static int Enc_uint64be(long l, byte[] dst, int di) + { + Enc_uint32be((int)(l & unchecked(0xFFFFFFFFL)), dst, di + 4); + Enc_uint32be((int)((l >> 32) & unchecked(0xFFFFFFFFL)), dst, di); + return 8; + } + + public static int Enc_uint64le(long l, byte[] dst, int di) + { + Enc_uint32le((int)(l & unchecked(0xFFFFFFFFL)), dst, di); + Enc_uint32le((int)((l >> 32) & unchecked(0xFFFFFFFFL)), dst, di + 4); + return 8; + } + + public static long Dec_uint64be(byte[] src, int si) + { + long l; + l = Dec_uint32be(src, si) & unchecked(0xFFFFFFFFL); + l <<= 32; + l |= Dec_uint32be(src, si + 4) & unchecked(0xFFFFFFFFL); + return l; + } + + public static long Dec_uint64le(byte[] src, int si) + { + long l; + l = Dec_uint32le(src, si + 4) & unchecked(0xFFFFFFFFL); + l <<= 32; + l |= Dec_uint32le(src, si) & unchecked(0xFFFFFFFFL); + return l; + } + + public static int Enc_floatle(float f, byte[] dst, int di) + { + return Enc_uint32le((int)BitConverter.DoubleToInt64Bits(f), dst, di); + } + + public static int Enc_floatbe(float f, byte[] dst, int di) + { + return Enc_uint32be((int)BitConverter.DoubleToInt64Bits(f), dst, di); + } + + public static float Dec_floatle(byte[] src, int si) + { + return (float)BitConverter.Int64BitsToDouble(Dec_uint32le(src, si)); + } + + public static float Dec_floatbe(byte[] src, int si) + { + return (float)BitConverter.Int64BitsToDouble(Dec_uint32be(src, si)); + } + + public static int Enc_doublele(double d, byte[] dst, int di) + { + return Enc_uint64le(BitConverter.DoubleToInt64Bits(d), dst, di); + } + + public static int Enc_doublebe(double d, byte[] dst, int di) + { + return Enc_uint64be(BitConverter.DoubleToInt64Bits(d), dst, di); + } + + public static double Dec_doublele(byte[] src, int si) + { + return BitConverter.Int64BitsToDouble(Dec_uint64le(src, si)); + } + + public static double Dec_doublebe(byte[] src, int si) + { + return BitConverter.Int64BitsToDouble(Dec_uint64be(src, si)); + } + + public static int Enc_time(DateTime date, byte[] dst, int di, int enc) + { + long t; + switch (enc) + { + case Time1970Sec32Be: + { + return Enc_uint32be((int)(date.GetTime() / 1000L), dst, di); + } + + case Time1970Sec32Le: + { + return Enc_uint32le((int)(date.GetTime() / 1000L), dst, di); + } + + case Time1904Sec32Be: + { + return Enc_uint32be((int)((date.GetTime() / 1000L + SecBetweeen1904And1970) & + unchecked((int)(0xFFFFFFFF))), dst, di); + } + + case Time1904Sec32Le: + { + return Enc_uint32le((int)((date.GetTime() / 1000L + SecBetweeen1904And1970) & + unchecked((int)(0xFFFFFFFF))), dst, di); + } + + case Time1601Nanos64Be: + { + t = (date.GetTime() + MillisecondsBetween1970And1601) * 10000L; + return Enc_uint64be(t, dst, di); + } + + case Time1601Nanos64Le: + { + t = (date.GetTime() + MillisecondsBetween1970And1601) * 10000L; + return Enc_uint64le(t, dst, di); + } + + case Time1970Millis64Be: + { + return Enc_uint64be(date.GetTime(), dst, di); + } + + case Time1970Millis64Le: + { + return Enc_uint64le(date.GetTime(), dst, di); + } + + default: + { + throw new ArgumentException("Unsupported time encoding"); + } + } + } + + public static DateTime Dec_time(byte[] src, int si, int enc) + { + long t; + switch (enc) + { + case Time1970Sec32Be: + { + return Sharpen.Extensions.CreateDate(Dec_uint32be(src, si) * 1000L); + } + + case Time1970Sec32Le: + { + return Sharpen.Extensions.CreateDate(Dec_uint32le(src, si) * 1000L); + } + + case Time1904Sec32Be: + { + return Sharpen.Extensions.CreateDate(((Dec_uint32be(src, si) & unchecked(0xFFFFFFFFL)) - SecBetweeen1904And1970) * 1000L); + } + + case Time1904Sec32Le: + { + return Sharpen.Extensions.CreateDate(((Dec_uint32le(src, si) & unchecked(0xFFFFFFFFL)) - SecBetweeen1904And1970) * 1000L); + } + + case Time1601Nanos64Be: + { + t = Dec_uint64be(src, si); + return Sharpen.Extensions.CreateDate(t / 10000L - MillisecondsBetween1970And1601 + ); + } + + case Time1601Nanos64Le: + { + t = Dec_uint64le(src, si); + return Sharpen.Extensions.CreateDate(t / 10000L - MillisecondsBetween1970And1601 + ); + } + + case Time1970Millis64Be: + { + return Sharpen.Extensions.CreateDate(Dec_uint64be(src, si)); + } + + case Time1970Millis64Le: + { + return Sharpen.Extensions.CreateDate(Dec_uint64le(src, si)); + } + + default: + { + throw new ArgumentException("Unsupported time encoding"); + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public static int Enc_utf8(string str, byte[] dst, int di, int dlim) + { + int start = di; + int ch; + int strlen = str.Length; + for (int i = 0; di < dlim && i < strlen; i++) + { + ch = str[i]; + if ((ch >= unchecked(0x0001)) && (ch <= unchecked(0x007F))) + { + dst[di++] = unchecked((byte)ch); + } + else + { + if (ch > unchecked(0x07FF)) + { + if ((dlim - di) < 3) + { + break; + } + dst[di++] = unchecked((byte)(unchecked(0xE0) | ((ch >> 12) & unchecked(0x0F)))); + dst[di++] = unchecked((byte)(unchecked(0x80) | ((ch >> 6) & unchecked(0x3F)))); + dst[di++] = unchecked((byte)(unchecked(0x80) | ((ch >> 0) & unchecked(0x3F)))); + } + else + { + if ((dlim - di) < 2) + { + break; + } + dst[di++] = unchecked((byte)(unchecked(0xC0) | ((ch >> 6) & unchecked(0x1F)))); + dst[di++] = unchecked((byte)(unchecked(0x80) | ((ch >> 0) & unchecked(0x3F)))); + } + } + } + return di - start; + } + + /// <exception cref="System.IO.IOException"></exception> + public static string Dec_utf8(byte[] src, int si, int slim) + { + char[] uni = new char[slim - si]; + int ui; + int ch; + for (ui = 0; si < slim && (ch = src[si++] & unchecked(0xFF)) != 0; ui++) + { + if (ch < unchecked(0x80)) + { + uni[ui] = (char)ch; + } + else + { + if ((ch & unchecked(0xE0)) == unchecked(0xC0)) + { + if ((slim - si) < 2) + { + break; + } + uni[ui] = (char)((ch & unchecked(0x1F)) << 6); + ch = src[si++] & unchecked(0xFF); + uni[ui] |= (char)((char)ch & unchecked(0x3F)); + if ((ch & unchecked(0xC0)) != unchecked(0x80) || uni[ui] < unchecked( + 0x80)) + { + throw new IOException("Invalid UTF-8 sequence"); + } + } + else + { + if ((ch & unchecked(0xF0)) == unchecked(0xE0)) + { + if ((slim - si) < 3) + { + break; + } + uni[ui] = (char)((ch & unchecked(0x0F)) << 12); + ch = src[si++] & unchecked(0xFF); + if ((ch & unchecked(0xC0)) != unchecked(0x80)) + { + throw new IOException("Invalid UTF-8 sequence"); + } + uni[ui] |= (char)((char)(ch & unchecked(0x3F)) << 6); + ch = src[si++] & unchecked(0xFF); + uni[ui] |= (char)((char)ch & unchecked(0x3F)); + if ((ch & unchecked(0xC0)) != unchecked(0x80) || uni[ui] < unchecked( + 0x800)) + { + throw new IOException("Invalid UTF-8 sequence"); + } + } + else + { + throw new IOException("Unsupported UTF-8 sequence"); + } + } + } + } + return new string(uni, 0, ui); + } + + /// <exception cref="System.IO.IOException"></exception> + public static string Dec_ucs2le(byte[] src, int si, int slim, char[] buf) + { + int bi; + for (bi = 0; (si + 1) < slim; bi++, si += 2) + { + buf[bi] = (char)Dec_uint16le(src, si); + if (buf[bi] == '\0') + { + break; + } + } + return new string(buf, 0, bi); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/HMACT64.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/HMACT64.cs new file mode 100644 index 000000000..9ab31d61b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/HMACT64.cs @@ -0,0 +1,146 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Util +{ + /// <summary>This is an implementation of the HMACT64 keyed hashing algorithm.</summary> + /// <remarks> + /// This is an implementation of the HMACT64 keyed hashing algorithm. + /// HMACT64 is defined by Luke Leighton as a modified HMAC-MD5 (RFC 2104) + /// in which the key is truncated at 64 bytes (rather than being hashed + /// via MD5). + /// </remarks> + public class Hmact64 : MessageDigest + { + private const int BlockLength = 64; + + private const byte Ipad = unchecked(unchecked(0x36)); + + private const byte Opad = unchecked(unchecked(0x5c)); + + private MessageDigest _md5; + + private byte[] _ipad = new byte[BlockLength]; + + private byte[] _opad = new byte[BlockLength]; + + /// <summary>Creates an HMACT64 instance which uses the given secret key material.</summary> + /// <remarks>Creates an HMACT64 instance which uses the given secret key material.</remarks> + /// <param name="key">The key material to use in hashing.</param> + public Hmact64(byte[] key) + { + int length = Math.Min(key.Length, BlockLength); + for (int i = 0; i < length; i++) + { + _ipad[i] = unchecked((byte)(key[i] ^ Ipad)); + _opad[i] = unchecked((byte)(key[i] ^ Opad)); + } + for (int i1 = length; i1 < BlockLength; i1++) + { + _ipad[i1] = Ipad; + _opad[i1] = Opad; + } + try + { + _md5 = GetInstance("MD5"); + } + catch (Exception ex) + { + throw new InvalidOperationException(ex.Message); + } + EngineReset(); + } + + + protected byte[] EngineDigest() + { + byte[] digest = _md5.Digest(); + _md5.Update(_opad); + return _md5.Digest(digest); + } + + protected int EngineDigest(byte[] buf, int offset, int len) + { + byte[] digest = _md5.Digest(); + _md5.Update(_opad); + _md5.Update(digest); + try + { + _md5.Digest(buf, offset, len); + + return len; + } + catch (Exception) + { + throw new InvalidOperationException(); + } + } + + protected int EngineGetDigestLength() + { + return _md5.GetDigestLength(); + } + + protected void EngineReset() + { + _md5.Reset(); + _md5.Update(_ipad); + } + + protected void EngineUpdate(byte b) + { + _md5.Update(b); + } + + protected void EngineUpdate(byte[] input, int offset, int len) + { + _md5.Update(input, offset, len); + } + + public override byte[] Digest() + { + return EngineDigest(); + } + + public override int GetDigestLength() + { + return EngineGetDigestLength(); + } + + public override void Reset() + { + EngineReset(); + } + + public override void Update(byte[] b) + { + EngineUpdate(b, 0, b.Length); + } + + public override void Update(byte b) + { + EngineUpdate(b); + } + + public override void Update(byte[] b, int offset, int len) + { + EngineUpdate(b, offset, len); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Hexdump.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Hexdump.cs new file mode 100644 index 000000000..7e53f76e3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Hexdump.cs @@ -0,0 +1,191 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; + +namespace SharpCifs.Util +{ + public class Hexdump + { + private static readonly string Nl = @"\r\n"; //Runtime.GetProperty("line.separator"); + + private static readonly int NlLength = Nl.Length; + + private static readonly char[] SpaceChars = { ' ', ' ', ' ', ' ', ' ' + , ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' + , ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' + , ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; + + public static readonly char[] HexDigits = { '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + + private static bool IsIsoControl(char c) + { + return (c >= '\u0000' && c <= '\u001F') || (c >= '\u007F' && c <= '\u009F'); + } + + /// <summary> + /// Generate "hexdump" output of the buffer at src like the following: + /// <p><blockquote><pre> + /// 00000: 04 d2 29 00 00 01 00 00 00 00 00 01 20 45 47 46 |..)......... + /// </summary> + /// <remarks> + /// Generate "hexdump" output of the buffer at src like the following: + /// <p><blockquote><pre> + /// 00000: 04 d2 29 00 00 01 00 00 00 00 00 01 20 45 47 46 |..)......... EGF| + /// 00010: 43 45 46 45 45 43 41 43 41 43 41 43 41 43 41 43 |CEFEECACACACACAC| + /// 00020: 41 43 41 43 41 43 41 43 41 43 41 41 44 00 00 20 |ACACACACACAAD.. | + /// 00030: 00 01 c0 0c 00 20 00 01 00 00 00 00 00 06 20 00 |..... ........ .| + /// 00040: ac 22 22 e1 |."". | + /// </blockquote></pre> + /// </remarks> + public static void ToHexdump(TextWriter ps, byte[] src, int srcIndex, int length) + { + if (length == 0) + { + return; + } + int s = length % 16; + int r = (s == 0) ? length / 16 : length / 16 + 1; + char[] c = new char[r * (74 + NlLength)]; + char[] d = new char[16]; + int i; + int si = 0; + int ci = 0; + do + { + ToHexChars(si, c, ci, 5); + ci += 5; + c[ci++] = ':'; + do + { + if (si == length) + { + int n = 16 - s; + Array.Copy(SpaceChars, 0, c, ci, n * 3); + ci += n * 3; + Array.Copy(SpaceChars, 0, d, s, n); + break; + } + c[ci++] = ' '; + i = src[srcIndex + si] & 0xFF; + ToHexChars(i, c, ci, 2); + ci += 2; + if (i < 0 || IsIsoControl((char)i)) + { + d[si % 16] = '.'; + } + else + { + d[si % 16] = (char)i; + } + } + while ((++si % 16) != 0); + c[ci++] = ' '; + c[ci++] = ' '; + c[ci++] = '|'; + Array.Copy(d, 0, c, ci, 16); + ci += 16; + c[ci++] = '|'; + //Sharpen.Runtime.GetCharsForString(NL, 0, NL_LENGTH, c, ci); + c = Nl.ToCharArray(0, NlLength); + ci += NlLength; + } + while (si < length); + ps.WriteLine(c); + } + + /// <summary> + /// This is an alternative to the <code>java.lang.Integer.toHexString</cod> + /// method. + /// </summary> + /// <remarks> + /// This is an alternative to the <code>java.lang.Integer.toHexString</cod> + /// method. It is an efficient relative that also will pad the left side so + /// that the result is <code>size</code> digits. + /// </remarks> + public static string ToHexString(int val, int size) + { + char[] c = new char[size]; + ToHexChars(val, c, 0, size); + return new string(c); + } + + public static string ToHexString(long val, int size) + { + char[] c = new char[size]; + ToHexChars(val, c, 0, size); + return new string(c); + } + + public static string ToHexString(byte[] src, int srcIndex, int size) + { + char[] c = new char[size]; + size = (size % 2 == 0) ? size / 2 : size / 2 + 1; + for (int i = 0, j = 0; i < size; i++) + { + c[j++] = HexDigits[(src[i] >> 4) & 0x0F]; + if (j == c.Length) + { + break; + } + c[j++] = HexDigits[src[i] & 0x0F]; + } + return new string(c); + } + + /// <summary> + /// This is the same as + /// <see cref="ToHexString(int, int)">ToHexString(int, int)</see> + /// but provides a more practical form when trying to avoid + /// <see cref="string">string</see> + /// concatenation and + /// <see cref="System.Text.StringBuilder">System.Text.StringBuilder</see> + /// . + /// </summary> + public static void ToHexChars(int val, char[] dst, int dstIndex, int size) + { + while (size > 0) + { + int i = dstIndex + size - 1; + if (i < dst.Length) + { + dst[i] = HexDigits[val & 0x000F]; + } + if (val != 0) + { + val = (int)(((uint)val) >> 4); + } + size--; + } + } + + public static void ToHexChars(long val, char[] dst, int dstIndex, int size) + { + while (size > 0) + { + dst[dstIndex + size - 1] = HexDigits[(int)(val & 0x000FL)]; + if (val != 0) + { + val = (long)(((ulong)val) >> 4); + } + size--; + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/LogStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/LogStream.cs new file mode 100644 index 000000000..9dd130b50 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/LogStream.cs @@ -0,0 +1,78 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +//using Windows.Storage; +//using Windows.UI.Notifications; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Util +{ + /// <summary> + /// 0 - nothing + /// 1 - critical [default] + /// 2 - basic info can be logged under load + /// 3 - almost everything + /// N - debugging + /// </summary> + public class LogStream: PrintWriter +{ + private static LogStream _inst = null; + + public int Level = 1; + + public void SetLevel(int level) + { + this.Level = level; + } + + public LogStream(TextWriter other) : base(other) + { + + } + + /// <summary> + /// This must be called before <tt>getInstance</tt> is called or + /// it will have no effect. + /// </summary> + /// <remarks> + /// This must be called before <tt>getInstance</tt> is called or + /// it will have no effect. + /// </remarks> + public static void SetInstance(TextWriter other) + { + //inst = new Jcifs.Util.LogStream(); + _inst = new LogStream(other); + } + + public static LogStream GetInstance() + { + if (_inst == null) + { + SetInstance(Console.Error); + } + return _inst; + } + + public override Encoding Encoding + { + get { throw new NotImplementedException(); } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/MD4.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/MD4.cs new file mode 100644 index 000000000..99eb6ade6 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/MD4.cs @@ -0,0 +1,347 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Util +{ + /// <summary>Implements the MD4 message digest algorithm in Java.</summary> + /// <remarks> + /// Implements the MD4 message digest algorithm in Java. + /// <p> + /// <b>References:</b> + /// <ol> + /// <li> Ronald L. Rivest, + /// "<a href="http://www.roxen.com/rfc/rfc1320.html"> + /// The MD4 Message-Digest Algorithm</a>", + /// IETF RFC-1320 (informational). + /// </ol> + /// <p><b>$Revision: 1.2 $</b> + /// </remarks> + /// <author>Raif S. Naffah</author> + public class Md4 : MessageDigest + { + /// <summary>The size in bytes of the input block to the tranformation algorithm.</summary> + /// <remarks>The size in bytes of the input block to the tranformation algorithm.</remarks> + private const int BlockLength = 64; + + /// <summary>4 32-bit words (interim result)</summary> + private int[] _context = new int[4]; + + /// <summary>Number of bytes processed so far mod.</summary> + /// <remarks>Number of bytes processed so far mod. 2 power of 64.</remarks> + private long _count; + + /// <summary>512 bits input buffer = 16 x 32-bit words holds until reaches 512 bits.</summary> + /// <remarks>512 bits input buffer = 16 x 32-bit words holds until reaches 512 bits.</remarks> + private byte[] _buffer = new byte[BlockLength]; + + /// <summary>512 bits work buffer = 16 x 32-bit words</summary> + private int[] _x = new int[16]; + + public Md4() + { + // This file is currently unlocked (change this line if you lock the file) + // + // $Log: MD4.java,v $ + // Revision 1.2 1998/01/05 03:41:19 iang + // Added references only. + // + // Revision 1.1.1.1 1997/11/03 22:36:56 hopwood + // + Imported to CVS (tagged as 'start'). + // + // Revision 0.1.0.0 1997/07/14 R. Naffah + // + original version + // + // $Endlog$ + // MD4 specific object variables + //........................................................................... + // = 512 / 8; + // Constructors + //........................................................................... + EngineReset(); + } + + /// <summary>This constructor is here to implement cloneability of this class.</summary> + /// <remarks>This constructor is here to implement cloneability of this class.</remarks> + private Md4(Md4 md) : this() + { + _context = (int[])md._context.Clone(); + _buffer = (byte[])md._buffer.Clone(); + _count = md._count; + } + + // Cloneable method implementation + //........................................................................... + /// <summary>Returns a copy of this MD object.</summary> + /// <remarks>Returns a copy of this MD object.</remarks> + public object Clone() + { + return new Md4(this); + } + + // JCE methods + //........................................................................... + /// <summary> + /// Resets this object disregarding any temporary data present at the + /// time of the invocation of this call. + /// </summary> + /// <remarks> + /// Resets this object disregarding any temporary data present at the + /// time of the invocation of this call. + /// </remarks> + protected void EngineReset() + { + // initial values of MD4 i.e. A, B, C, D + // as per rfc-1320; they are low-order byte first + _context[0] = unchecked(0x67452301); + _context[1] = unchecked((int)(0xEFCDAB89)); + _context[2] = unchecked((int)(0x98BADCFE)); + _context[3] = unchecked(0x10325476); + _count = 0L; + for (int i = 0; i < BlockLength; i++) + { + _buffer[i] = 0; + } + } + + /// <summary>Continues an MD4 message digest using the input byte.</summary> + /// <remarks>Continues an MD4 message digest using the input byte.</remarks> + protected void EngineUpdate(byte b) + { + // compute number of bytes still unhashed; ie. present in buffer + int i = (int)(_count % BlockLength); + _count++; + // update number of bytes + _buffer[i] = b; + if (i == BlockLength - 1) + { + Transform(_buffer, 0); + } + } + + /// <summary>MD4 block update operation.</summary> + /// <remarks> + /// MD4 block update operation. + /// <p> + /// Continues an MD4 message digest operation, by filling the buffer, + /// transform(ing) data in 512-bit message block(s), updating the variables + /// context and count, and leaving (buffering) the remaining bytes in buffer + /// for the next update or finish. + /// </remarks> + /// <param name="input">input block</param> + /// <param name="offset">start of meaningful bytes in input</param> + /// <param name="len">count of bytes in input block to consider</param> + protected void EngineUpdate(byte[] input, int offset, int len) + { + // make sure we don't exceed input's allocated size/length + if (offset < 0 || len < 0 || (long)offset + len > input.Length) + { + throw new IndexOutOfRangeException(); + } + // compute number of bytes still unhashed; ie. present in buffer + int bufferNdx = (int)(_count % BlockLength); + _count += len; + // update number of bytes + int partLen = BlockLength - bufferNdx; + int i = 0; + if (len >= partLen) + { + Array.Copy(input, offset, _buffer, bufferNdx, partLen); + Transform(_buffer, 0); + for (i = partLen; i + BlockLength - 1 < len; i += BlockLength) + { + Transform(input, offset + i); + } + bufferNdx = 0; + } + // buffer remaining input + if (i < len) + { + Array.Copy(input, offset + i, _buffer, bufferNdx, len - i); + } + } + + /// <summary> + /// Completes the hash computation by performing final operations such + /// as padding. + /// </summary> + /// <remarks> + /// Completes the hash computation by performing final operations such + /// as padding. At the return of this engineDigest, the MD engine is + /// reset. + /// </remarks> + /// <returns>the array of bytes for the resulting hash value.</returns> + protected byte[] EngineDigest() + { + // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512 + int bufferNdx = (int)(_count % BlockLength); + int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); + // padding is alwas binary 1 followed by binary 0s + byte[] tail = new byte[padLen + 8]; + tail[0] = unchecked(unchecked(0x80)); + // append length before final transform: + // save number of bits, casting the long to an array of 8 bytes + // save low-order byte first. + for (int i = 0; i < 8; i++) + { + tail[padLen + i] = unchecked((byte)((long)(((ulong)(_count * 8)) >> (8 * i)))); + } + EngineUpdate(tail, 0, tail.Length); + byte[] result = new byte[16]; + // cast this MD4's context (array of 4 ints) into an array of 16 bytes. + for (int i1 = 0; i1 < 4; i1++) + { + for (int j = 0; j < 4; j++) + { + result[i1 * 4 + j] = unchecked((byte)((int)(((uint)_context[i1]) >> (8 * j)))); + } + } + // reset the engine + EngineReset(); + return result; + } + + // own methods + //........................................................................... + /// <summary>MD4 basic transformation.</summary> + /// <remarks> + /// MD4 basic transformation. + /// <p> + /// Transforms context based on 512 bits from input block starting + /// from the offset'th byte. + /// </remarks> + /// <param name="block">input sub-array.</param> + /// <param name="offset">starting position of sub-array.</param> + private void Transform(byte[] block, int offset) + { + // encodes 64 bytes from input block into an array of 16 32-bit + // entities. Use A as a temp var. + for (int i = 0; i < 16; i++) + { + _x[i] = (block[offset++] & unchecked(0xFF)) | (block[offset++] & unchecked( + 0xFF)) << 8 | (block[offset++] & unchecked(0xFF)) << 16 | (block[offset + ++] & unchecked(0xFF)) << 24; + } + int a = _context[0]; + int b = _context[1]; + int c = _context[2]; + int d = _context[3]; + a = Ff(a, b, c, d, _x[0], 3); + d = Ff(d, a, b, c, _x[1], 7); + c = Ff(c, d, a, b, _x[2], 11); + b = Ff(b, c, d, a, _x[3], 19); + a = Ff(a, b, c, d, _x[4], 3); + d = Ff(d, a, b, c, _x[5], 7); + c = Ff(c, d, a, b, _x[6], 11); + b = Ff(b, c, d, a, _x[7], 19); + a = Ff(a, b, c, d, _x[8], 3); + d = Ff(d, a, b, c, _x[9], 7); + c = Ff(c, d, a, b, _x[10], 11); + b = Ff(b, c, d, a, _x[11], 19); + a = Ff(a, b, c, d, _x[12], 3); + d = Ff(d, a, b, c, _x[13], 7); + c = Ff(c, d, a, b, _x[14], 11); + b = Ff(b, c, d, a, _x[15], 19); + a = Gg(a, b, c, d, _x[0], 3); + d = Gg(d, a, b, c, _x[4], 5); + c = Gg(c, d, a, b, _x[8], 9); + b = Gg(b, c, d, a, _x[12], 13); + a = Gg(a, b, c, d, _x[1], 3); + d = Gg(d, a, b, c, _x[5], 5); + c = Gg(c, d, a, b, _x[9], 9); + b = Gg(b, c, d, a, _x[13], 13); + a = Gg(a, b, c, d, _x[2], 3); + d = Gg(d, a, b, c, _x[6], 5); + c = Gg(c, d, a, b, _x[10], 9); + b = Gg(b, c, d, a, _x[14], 13); + a = Gg(a, b, c, d, _x[3], 3); + d = Gg(d, a, b, c, _x[7], 5); + c = Gg(c, d, a, b, _x[11], 9); + b = Gg(b, c, d, a, _x[15], 13); + a = Hh(a, b, c, d, _x[0], 3); + d = Hh(d, a, b, c, _x[8], 9); + c = Hh(c, d, a, b, _x[4], 11); + b = Hh(b, c, d, a, _x[12], 15); + a = Hh(a, b, c, d, _x[2], 3); + d = Hh(d, a, b, c, _x[10], 9); + c = Hh(c, d, a, b, _x[6], 11); + b = Hh(b, c, d, a, _x[14], 15); + a = Hh(a, b, c, d, _x[1], 3); + d = Hh(d, a, b, c, _x[9], 9); + c = Hh(c, d, a, b, _x[5], 11); + b = Hh(b, c, d, a, _x[13], 15); + a = Hh(a, b, c, d, _x[3], 3); + d = Hh(d, a, b, c, _x[11], 9); + c = Hh(c, d, a, b, _x[7], 11); + b = Hh(b, c, d, a, _x[15], 15); + _context[0] += a; + _context[1] += b; + _context[2] += c; + _context[3] += d; + } + + // The basic MD4 atomic functions. + private int Ff(int a, int b, int c, int d, int x, int s) + { + int t = a + ((b & c) | (~b & d)) + x; + return t << s | (int)(((uint)t) >> (32 - s)); + } + + private int Gg(int a, int b, int c, int d, int x, int s) + { + int t = a + ((b & (c | d)) | (c & d)) + x + unchecked(0x5A827999); + return t << s | (int)(((uint)t) >> (32 - s)); + } + + private int Hh(int a, int b, int c, int d, int x, int s) + { + int t = a + (b ^ c ^ d) + x + unchecked(0x6ED9EBA1); + return t << s | (int)(((uint)t) >> (32 - s)); + } + + public override byte[] Digest() + { + return EngineDigest(); + } + + public override int GetDigestLength() + { + return EngineDigest().Length; + } + + public override void Reset() + { + EngineReset(); + } + + public override void Update(byte[] b) + { + EngineUpdate(b, 0, b.Length); + } + + public override void Update(byte b) + { + EngineUpdate(b); + } + + public override void Update(byte[] b, int offset, int len) + { + EngineUpdate(b, offset, len); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/RC4.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/RC4.cs new file mode 100644 index 000000000..b17e076e7 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/RC4.cs @@ -0,0 +1,68 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Util +{ + public class Rc4 + { + internal byte[] S; + + internal int I; + + internal int J; + + public Rc4() + { + } + + public Rc4(byte[] key) + { + Init(key, 0, key.Length); + } + + public virtual void Init(byte[] key, int ki, int klen) + { + S = new byte[256]; + for (I = 0; I < 256; I++) + { + S[I] = unchecked((byte)I); + } + for (I = J = 0; I < 256; I++) + { + J = (J + key[ki + I % klen] + S[I]) & unchecked(0xff); + byte t = S[I]; + S[I] = S[J]; + S[J] = t; + } + I = J = 0; + } + + public virtual void Update(byte[] src, int soff, int slen, byte[] dst, int doff) + { + int slim; + slim = soff + slen; + while (soff < slim) + { + I = (I + 1) & unchecked(0xff); + J = (J + S[I]) & unchecked(0xff); + byte t = S[I]; + S[I] = S[J]; + S[J] = t; + dst[doff++] = unchecked((byte)(src[soff++] ^ S[(S[I] + S[J]) & unchecked(0xff)])); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/AbstractMap.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/AbstractMap.cs new file mode 100644 index 000000000..2868a840a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/AbstractMap.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace SharpCifs.Util.Sharpen +{ + public abstract class AbstractMap<T, TU> : IDictionary<T, TU> + { + public virtual void Clear () + { + EntrySet ().Clear (); + } + + public virtual bool ContainsKey (object name) + { + return EntrySet ().Any (p => p.Key.Equals ((T)name)); + } + + public abstract ICollection<KeyValuePair<T, TU>> EntrySet (); + + public virtual TU Get (object key) + { + return EntrySet ().Where (p => p.Key.Equals (key)).Select (p => p.Value).FirstOrDefault (); + } + + protected virtual IEnumerator<KeyValuePair<T, TU>> InternalGetEnumerator () + { + return EntrySet ().GetEnumerator (); + } + + public virtual bool IsEmpty () + { + return !EntrySet ().Any (); + } + + public virtual TU Put (T key, TU value) + { + throw new NotSupportedException (); + } + + public virtual TU Remove (object key) + { + Iterator<TU> iterator = EntrySet () as Iterator<TU>; + if (iterator == null) { + throw new NotSupportedException (); + } + while (iterator.HasNext ()) { + TU local = iterator.Next (); + if (local.Equals ((T)key)) { + iterator.Remove (); + return local; + } + } + return default(TU); + } + + void ICollection<KeyValuePair<T, TU>>.Add (KeyValuePair<T, TU> item) + { + Put (item.Key, item.Value); + } + + bool ICollection<KeyValuePair<T, TU>>.Contains (KeyValuePair<T, TU> item) + { + throw new NotImplementedException (); + } + + void ICollection<KeyValuePair<T, TU>>.CopyTo (KeyValuePair<T, TU>[] array, int arrayIndex) + { + EntrySet ().CopyTo (array, arrayIndex); + } + + bool ICollection<KeyValuePair<T, TU>>.Remove (KeyValuePair<T, TU> item) + { + Remove (item.Key); + return true; + } + + void IDictionary<T, TU>.Add (T key, TU value) + { + Put (key, value); + } + + bool IDictionary<T, TU>.ContainsKey (T key) + { + return ContainsKey (key); + } + + bool IDictionary<T, TU>.Remove (T key) + { + if (ContainsKey (key)) { + Remove (key); + return true; + } + return false; + } + + bool IDictionary<T, TU>.TryGetValue (T key, out TU value) + { + if (ContainsKey (key)) { + value = Get (key); + return true; + } + value = default(TU); + return false; + } + + IEnumerator<KeyValuePair<T, TU>> IEnumerable<KeyValuePair<T, TU>>.GetEnumerator () + { + return InternalGetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return InternalGetEnumerator (); + } + + public virtual int Count { + get { return EntrySet ().Count; } + } + + public TU this[T key] { + get { return Get (key); } + set { Put (key, value); } + } + + public virtual IEnumerable<T> Keys { + get { return EntrySet ().Select (p => p.Key); } + } + + int ICollection<KeyValuePair<T, TU>>.Count { + get { return Count; } + } + + bool ICollection<KeyValuePair<T, TU>>.IsReadOnly { + get { return false; } + } + + ICollection<T> IDictionary<T, TU>.Keys { + get { return Keys.ToList (); } + } + + ICollection<TU> IDictionary<T, TU>.Values { + get { return Values.ToList (); } + } + + public virtual IEnumerable<TU> Values { + get { return EntrySet ().Select (p => p.Value); } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Arrays.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Arrays.cs new file mode 100644 index 000000000..b3a0a85fa --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Arrays.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SharpCifs.Util.Sharpen +{ + public class Arrays + { + public static List<T> AsList<T> (params T[] array) + { + return array.ToList (); + } + + public static bool Equals<T> (T[] a1, T[] a2) + { + if (a1.Length != a2.Length) { + return false; + } + return !a1.Where((t, i) => !t.Equals(a2[i])).Any(); + } + + public static void Fill<T> (T[] array, T val) + { + Fill (array, 0, array.Length, val); + } + + public static void Fill<T> (T[] array, int start, int end, T val) + { + for (int i = start; i < end; i++) { + array[i] = val; + } + } + + public static void Sort (string[] array) + { + Array.Sort (array, (s1,s2) => string.CompareOrdinal (s1,s2)); + } + + public static void Sort<T> (T[] array) + { + Array.Sort (array); + } + + public static void Sort<T> (T[] array, IComparer<T> c) + { + Array.Sort (array, c); + } + + public static void Sort<T> (T[] array, int start, int count) + { + Array.Sort (array, start, count); + } + + public static void Sort<T> (T[] array, int start, int count, IComparer<T> c) + { + Array.Sort (array, start, count, c); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/BufferedReader.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/BufferedReader.cs new file mode 100644 index 000000000..b3824b0d2 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/BufferedReader.cs @@ -0,0 +1,11 @@ +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class BufferedReader : StreamReader + { + public BufferedReader (InputStreamReader r) : base(r.BaseStream) + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/BufferedWriter.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/BufferedWriter.cs new file mode 100644 index 000000000..64a45915a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/BufferedWriter.cs @@ -0,0 +1,58 @@ +// +// BufferedWriter.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class BufferedWriter + { + StreamWriter _writer; + + public BufferedWriter (StreamWriter w) + { + _writer = w; + } + + public void Write (string s) + { + _writer.Write (s); + } + + public void NewLine () + { + _writer.WriteLine (); + } + + public void Close () + { + //Stream.`Close` method deleted + //_writer.Close (); + _writer.Dispose(); + } + } +} + diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/CharBuffer.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/CharBuffer.cs new file mode 100644 index 000000000..76ca2dc95 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/CharBuffer.cs @@ -0,0 +1,19 @@ +namespace SharpCifs.Util.Sharpen +{ + internal class CharBuffer : CharSequence + { + internal string Wrapped; + + public override string ToString () + { + return Wrapped; + } + + public static CharBuffer Wrap (string str) + { + CharBuffer buffer = new CharBuffer (); + buffer.Wrapped = str; + return buffer; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/CharSequence.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/CharSequence.cs new file mode 100644 index 000000000..fa2acf7bd --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/CharSequence.cs @@ -0,0 +1,32 @@ +using System.Text; + +namespace SharpCifs.Util.Sharpen +{ + public class CharSequence + { + public static implicit operator CharSequence (string str) + { + return new StringCharSequence (str); + } + + public static implicit operator CharSequence (StringBuilder str) + { + return new StringCharSequence (str.ToString ()); + } + } + + class StringCharSequence: CharSequence + { + string _str; + + public StringCharSequence (string str) + { + this._str = str; + } + + public override string ToString () + { + return _str; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Collections.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Collections.cs new file mode 100644 index 000000000..4432e62fb --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Collections.cs @@ -0,0 +1,146 @@ +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace SharpCifs.Util.Sharpen +{ + internal static class Collections<T> + { + static readonly IList<T> Empty = new T [0]; + public static IList<T> EmptySet { + get { return Empty; } + } + + } + + public static class Collections + { + public static bool AddAll<T> (ICollection<T> list, IEnumerable toAdd) + { + foreach (T t in toAdd) + list.Add (t); + return true; + } + + public static TV Remove<TK, TV> (IDictionary<TK, TV> map, TK toRemove) where TK : class + { + TV local; + if (map.TryGetValue (toRemove, out local)) { + map.Remove (toRemove); + return local; + } + return default(TV); + } + + + public static T[] ToArray<T> (ICollection<T> list) + { + T[] array = new T[list.Count]; + list.CopyTo (array, 0); + return array; + } + + public static T[] ToArray<T>(List<object> list) + { + T[] array = new T[list.Count]; + for(int c = 0; c < list.Count; c++) + { + array[c] = (T)list[c]; + } + + return array; + } + + + public static TU[] ToArray<T,TU> (ICollection<T> list, TU[] res) where T:TU + { + if (res.Length < list.Count) + res = new TU [list.Count]; + + int n = 0; + foreach (T t in list) + res [n++] = t; + + if (res.Length > list.Count) + res [list.Count] = default (T); + return res; + } + + public static IDictionary<TK,TV> EmptyMap<TK,TV> () + { + return new Dictionary<TK,TV> (); + } + + public static IList<T> EmptyList<T> () + { + return Collections<T>.EmptySet; + } + + public static ICollection<T> EmptySet<T> () + { + return Collections<T>.EmptySet; + } + + public static IList<T> NCopies<T> (int n, T elem) + { + List<T> list = new List<T> (n); + while (n-- > 0) { + list.Add (elem); + } + return list; + } + + public static void Reverse<T> (IList<T> list) + { + int end = list.Count - 1; + int index = 0; + while (index < end) { + T tmp = list [index]; + list [index] = list [end]; + list [end] = tmp; + ++index; + --end; + } + } + + public static ICollection<T> Singleton<T> (T item) + { + List<T> list = new List<T> (1); + list.Add (item); + return list; + } + + public static IList<T> SingletonList<T> (T item) + { + List<T> list = new List<T> (1); + list.Add (item); + return list; + } + + public static IList<T> SynchronizedList<T> (IList<T> list) + { + return new SynchronizedList<T> (list); + } + + public static ICollection<T> UnmodifiableCollection<T> (ICollection<T> list) + { + return list; + } + + public static IList<T> UnmodifiableList<T> (IList<T> list) + { + return new ReadOnlyCollection<T> (list); + } + + public static ICollection<T> UnmodifiableSet<T> (ICollection<T> list) + { + return list; + } + + public static IDictionary<TK,TV> UnmodifiableMap<TK,TV> (IDictionary<TK,TV> dict) + { + return dict; + } + + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ConcurrentHashMap.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ConcurrentHashMap.cs new file mode 100644 index 000000000..7f464ad36 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ConcurrentHashMap.cs @@ -0,0 +1,122 @@ +using System.Collections.Generic; + +namespace SharpCifs.Util.Sharpen +{ + internal class ConcurrentHashMap<T, TU> : AbstractMap<T, TU>, IConcurrentMap<T, TU> + { + private Dictionary<T, TU> _table; + + public ConcurrentHashMap () + { + _table = new Dictionary<T, TU> (); + } + + public ConcurrentHashMap (int initialCapacity, float loadFactor, int concurrencyLevel) + { + _table = new Dictionary<T, TU> (initialCapacity); + } + + public override void Clear () + { + lock (_table) { + _table = new Dictionary<T, TU> (); + } + } + + public override bool ContainsKey (object name) + { + return _table.ContainsKey ((T)name); + } + + public override ICollection<KeyValuePair<T, TU>> EntrySet () + { + return this; + } + + public override TU Get (object key) + { + TU local; + _table.TryGetValue ((T)key, out local); + return local; + } + + protected override IEnumerator<KeyValuePair<T, TU>> InternalGetEnumerator () + { + return _table.GetEnumerator (); + } + + public override bool IsEmpty () + { + return _table.Count == 0; + } + + public override TU Put (T key, TU value) + { + lock (_table) { + TU old = Get (key); + Dictionary<T, TU> newTable = new Dictionary<T, TU> (_table); + newTable[key] = value; + _table = newTable; + return old; + } + } + + public TU PutIfAbsent (T key, TU value) + { + lock (_table) { + if (!ContainsKey (key)) { + Dictionary<T, TU> newTable = new Dictionary<T, TU> (_table); + newTable[key] = value; + _table = newTable; + return value; + } + return Get (key); + } + } + + public override TU Remove (object key) + { + lock (_table) { + TU old = Get ((T)key); + Dictionary<T, TU> newTable = new Dictionary<T, TU> (_table); + newTable.Remove ((T)key); + _table = newTable; + return old; + } + } + + public bool Remove (object key, object value) + { + lock (_table) { + if (ContainsKey (key) && value.Equals (Get (key))) { + Dictionary<T, TU> newTable = new Dictionary<T, TU> (_table); + newTable.Remove ((T)key); + _table = newTable; + return true; + } + return false; + } + } + + public bool Replace (T key, TU oldValue, TU newValue) + { + lock (_table) { + if (ContainsKey (key) && oldValue.Equals (Get (key))) { + Dictionary<T, TU> newTable = new Dictionary<T, TU> (_table); + newTable[key] = newValue; + _table = newTable; + return true; + } + return false; + } + } + + public override IEnumerable<T> Keys { + get { return _table.Keys; } + } + + public override IEnumerable<TU> Values { + get { return _table.Values; } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/DateFormat.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/DateFormat.cs new file mode 100644 index 000000000..9a3b7ec4a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/DateFormat.cs @@ -0,0 +1,37 @@ +using System; +using System.Globalization; + +namespace SharpCifs.Util.Sharpen +{ + public abstract class DateFormat + { + public const int Default = 2; + + public static DateFormat GetDateTimeInstance (int dateStyle, int timeStyle) + { + return GetDateTimeInstance (dateStyle, timeStyle, CultureInfo.CurrentCulture); + } + + public static DateFormat GetDateTimeInstance (int dateStyle, int timeStyle, CultureInfo aLocale) + { + return new SimpleDateFormat (aLocale.DateTimeFormat.FullDateTimePattern, aLocale); + } + + TimeZoneInfo _timeZone; + + public abstract DateTime Parse (string value); + + public TimeZoneInfo GetTimeZone () + { + return _timeZone; + } + + public void SetTimeZone (TimeZoneInfo timeZone) + { + this._timeZone = timeZone; + } + + public abstract string Format (DateTime time); + } +} + diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/EnumeratorWrapper.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/EnumeratorWrapper.cs new file mode 100644 index 000000000..f8efdde2a --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/EnumeratorWrapper.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; + +namespace SharpCifs.Util.Sharpen +{ + internal class EnumeratorWrapper<T> : Iterator<T> + { + object _collection; + IEnumerator<T> _e; + T _lastVal; + bool _more; + bool _copied; + + public EnumeratorWrapper (object collection, IEnumerator<T> e) + { + this._e = e; + this._collection = collection; + _more = e.MoveNext (); + } + + public override bool HasNext () + { + return _more; + } + + public override T Next () + { + if (!_more) + throw new NoSuchElementException (); + _lastVal = _e.Current; + _more = _e.MoveNext (); + return _lastVal; + } + + public override void Remove () + { + ICollection<T> col = _collection as ICollection<T>; + if (col == null) { + throw new NotSupportedException (); + } + if (_more && !_copied) { + // Read the remaining elements, since the current enumerator + // will be invalid after removing the element + List<T> remaining = new List<T> (); + do { + remaining.Add (_e.Current); + } while (_e.MoveNext ()); + _e = remaining.GetEnumerator (); + _e.MoveNext (); + _copied = true; + } + col.Remove (_lastVal); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Exceptions.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Exceptions.cs new file mode 100644 index 000000000..ec88b2849 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Exceptions.cs @@ -0,0 +1,217 @@ +// +// Exceptions.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace SharpCifs.Util.Sharpen +{ + public class VirtualMachineError : Error + { + } + + public class StackOverflowError : VirtualMachineError + { + } + + public class BrokenBarrierException : Exception + { + } + + internal class BufferUnderflowException : Exception + { + } + + public class CharacterCodingException : Exception + { + } + + public class DataFormatException : Exception + { + } + + public class EofException : Exception + { + public EofException () + { + } + + public EofException (string msg) : base(msg) + { + } + } + + public class Error : Exception + { + public Error () + { + } + + public Error (Exception ex) : base("Runtime Exception", ex) + { + } + + public Error (string msg) : base(msg) + { + } + + public Error (string msg, Exception ex) : base(msg, ex) + { + } + } + + public class ExecutionException : Exception + { + public ExecutionException (Exception inner): base ("Execution failed", inner) + { + } + } + + public class InstantiationException : Exception + { + } + + public class InterruptedIoException : Exception + { + public InterruptedIoException (string msg) : base(msg) + { + } + } + + public class MissingResourceException : Exception + { + } + + public class NoSuchAlgorithmException : Exception + { + } + + public class NoSuchElementException : Exception + { + } + + internal class NoSuchMethodException : Exception + { + } + + internal class OverlappingFileLockException : Exception + { + } + + public class ParseException : Exception + { + public ParseException () + { + } + + public ParseException (string msg, int errorOffset) : base(string.Format ("Msg: {0}. Error Offset: {1}", msg, errorOffset)) + { + } + } + + public class RuntimeException : Exception + { + public RuntimeException () + { + } + + public RuntimeException (Exception ex) : base("Runtime Exception", ex) + { + } + + public RuntimeException (string msg) : base(msg) + { + } + + public RuntimeException (string msg, Exception ex) : base(msg, ex) + { + } + } + + internal class StringIndexOutOfBoundsException : Exception + { + } + + public class UnknownHostException : Exception + { + public UnknownHostException () + { + } + + public UnknownHostException(string message) : base(message) + { + + } + + public UnknownHostException (Exception ex): base ("Host not found", ex) + { + } + } + + public class UnsupportedEncodingException : Exception + { + } + + internal class UriSyntaxException : Exception + { + public UriSyntaxException (string s, string msg) : base(s + " " + msg) + { + } + } + + internal class ZipException : Exception + { + } + + public class GitException : Exception + { + } + + public class ConnectException: Exception + { + public ConnectException (string msg): base (msg) + { + } + } + + class KeyManagementException: Exception + { + } + + class IllegalCharsetNameException: Exception + { + public IllegalCharsetNameException (string msg): base (msg) + { + } + } + + class UnsupportedCharsetException: Exception + { + public UnsupportedCharsetException (string msg): base (msg) + { + } + } +} + diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Extensions.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Extensions.cs new file mode 100644 index 000000000..1716adef7 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Extensions.cs @@ -0,0 +1,696 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +//using Windows.Networking; +//using Windows.Networking.Sockets; + +namespace SharpCifs.Util.Sharpen +{ + + + public static class Extensions + { + private static readonly long EpochTicks; + + static Extensions() + { + DateTime time = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + EpochTicks = time.Ticks; + } + + public static void Add<T>(this IList<T> list, int index, T item) + { + list.Insert(index, item); + } + + public static void AddFirst<T>(this IList<T> list, T item) + { + list.Insert(0, item); + } + + public static void AddLast<T>(this IList<T> list, T item) + { + list.Add(item); + } + + public static void RemoveLast<T>(this IList<T> list) + { + if (list.Count > 0) + list.Remove(list.Count - 1); + } + + public static StringBuilder AppendRange(this StringBuilder sb, string str, int start, int end) + { + return sb.Append(str, start, end - start); + } + + public static StringBuilder Delete(this StringBuilder sb, int start, int end) + { + return sb.Remove(start, end - start); + } + + public static void SetCharAt(this StringBuilder sb, int index, char c) + { + sb[index] = c; + } + + public static int IndexOf(this StringBuilder sb, string str) + { + return sb.ToString().IndexOf(str); + } + + public static int BitCount(int val) + { + uint num = (uint)val; + int count = 0; + for (int i = 0; i < 32; i++) + { + if ((num & 1) != 0) + { + count++; + } + num >>= 1; + } + return count; + } + + public static IndexOutOfRangeException CreateIndexOutOfRangeException(int index) + { + return new IndexOutOfRangeException("Index: " + index); + } + + public static string Decode(this Encoding e, byte[] chars, int start, int len) + { + try + { + byte[] bom = e.GetPreamble(); + if (bom != null && bom.Length > 0) + { + if (len >= bom.Length) + { + int pos = start; + bool hasBom = true; + for (int n = 0; n < bom.Length && hasBom; n++) + { + if (bom[n] != chars[pos++]) + hasBom = false; + } + if (hasBom) + { + len -= pos - start; + start = pos; + } + } + } + return e.GetString(chars, start, len); + } + catch (DecoderFallbackException) + { + throw new CharacterCodingException(); + } + } + + + + public static Encoding GetEncoding(string name) + { + // Encoding e = Encoding.GetEncoding (name, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback); + try + { + + Encoding e = Encoding.GetEncoding(name.Replace('_', '-')); + if (e is UTF8Encoding) + return new UTF8Encoding(false, true); + + return e; + } + catch (ArgumentException) + { + throw new UnsupportedCharsetException(name); + } + } + + public static ICollection<KeyValuePair<T, TU>> EntrySet<T, TU>(this IDictionary<T, TU> s) + { + return s; + } + + + public static bool AddItem<T>(this IList<T> list, T item) + { + list.Add(item); + return true; + } + + public static bool AddItem<T>(this ICollection<T> list, T item) + { + list.Add(item); + return true; + } + + public static TU Get<T, TU>(this IDictionary<T, TU> d, T key) + { + TU val; + d.TryGetValue(key, out val); + return val; + } + + + public static TU Put<T, TU>(this IDictionary<T, TU> d, T key, TU value) + { + TU old; + d.TryGetValue(key, out old); + d[key] = value; + return old; + } + + public static void PutAll<T, TU>(this IDictionary<T, TU> d, IDictionary<T, TU> values) + { + foreach (KeyValuePair<T, TU> val in values) + d[val.Key] = val.Value; + } + + + public static CultureInfo GetEnglishCulture() + { + return new CultureInfo("en-US"); + } + + public static T GetFirst<T>(this IList<T> list) + { + return ((list.Count == 0) ? default(T) : list[0]); + } + + public static CultureInfo GetGermanCulture() + { + CultureInfo r = new CultureInfo("de-DE"); + return r; + } + + public static T GetLast<T>(this IList<T> list) + { + return ((list.Count == 0) ? default(T) : list[list.Count - 1]); + } + + public static int GetOffset(this TimeZoneInfo tzone, long date) + { + return (int)tzone.GetUtcOffset(MillisToDateTimeOffset(date, 0).DateTime).TotalMilliseconds; + } + + public static long GetTime(this DateTime dateTime) + { + return new DateTimeOffset(DateTime.SpecifyKind(dateTime, DateTimeKind.Utc), TimeSpan.Zero).ToMillisecondsSinceEpoch(); + } + + public static void InitCause(this Exception ex, Exception cause) + { + Console.WriteLine(cause); + } + + public static bool IsEmpty<T>(this ICollection<T> col) + { + return (col.Count == 0); + } + + public static bool IsEmpty<T>(this Stack<T> col) + { + return (col.Count == 0); + } + + public static bool IsLower(this char c) + { + return char.IsLower(c); + } + + public static bool IsUpper(this char c) + { + return char.IsUpper(c); + } + + public static Iterator<T> Iterator<T>(this ICollection<T> col) + { + return new EnumeratorWrapper<T>(col, col.GetEnumerator()); + } + + public static Iterator<T> Iterator<T>(this IEnumerable<T> col) + { + return new EnumeratorWrapper<T>(col, col.GetEnumerator()); + } + + public static T Last<T>(this ICollection<T> col) + { + IList<T> list = col as IList<T>; + if (list != null) + { + return list[list.Count - 1]; + } + return col.Last(); + } + + public static int LowestOneBit(int val) + { + return (1 << NumberOfTrailingZeros(val)); + } + + public static bool Matches(this string str, string regex) + { + Regex regex2 = new Regex(regex); + return regex2.IsMatch(str); + } + + public static DateTime CreateDate(long milliSecondsSinceEpoch) + { + long num = EpochTicks + (milliSecondsSinceEpoch * 10000); + return new DateTime(num); + } + + public static DateTime CreateDateFromUTC(long milliSecondsSinceEpoch) + { + long num = EpochTicks + (milliSecondsSinceEpoch * 10000); + return new DateTime(num, DateTimeKind.Utc); + } + + + public static DateTimeOffset MillisToDateTimeOffset(long milliSecondsSinceEpoch, long offsetMinutes) + { + TimeSpan offset = TimeSpan.FromMinutes(offsetMinutes); + long num = EpochTicks + (milliSecondsSinceEpoch * 10000); + return new DateTimeOffset(num + offset.Ticks, offset); + } + + public static int NumberOfLeadingZeros(int val) + { + uint num = (uint)val; + int count = 0; + while ((num & 0x80000000) == 0) + { + num = num << 1; + count++; + } + return count; + } + + public static int NumberOfTrailingZeros(int val) + { + uint num = (uint)val; + int count = 0; + while ((num & 1) == 0) + { + num = num >> 1; + count++; + } + return count; + } + + public static int Read(this StreamReader reader, char[] data) + { + return reader.Read(data, 0, data.Length); + } + + public static T Remove<T>(this IList<T> list, T item) + { + int index = list.IndexOf(item); + if (index == -1) + { + return default(T); + } + T local = list[index]; + list.RemoveAt(index); + return local; + } + + public static T Remove<T>(this IList<T> list, int i) + { + T old; + try + { + old = list[i]; + list.RemoveAt(i); + } + catch (IndexOutOfRangeException) + { + throw new NoSuchElementException(); + } + return old; + } + + public static T RemoveFirst<T>(this IList<T> list) + { + return list.Remove(0); + } + + public static string ReplaceAll(this string str, string regex, string replacement) + { + Regex rgx = new Regex(regex); + + if (replacement.IndexOfAny(new[] { '\\', '$' }) != -1) + { + // Back references not yet supported + StringBuilder sb = new StringBuilder(); + for (int n = 0; n < replacement.Length; n++) + { + char c = replacement[n]; + if (c == '$') + throw new NotSupportedException("Back references not supported"); + if (c == '\\') + c = replacement[++n]; + sb.Append(c); + } + replacement = sb.ToString(); + } + + return rgx.Replace(str, replacement); + } + + public static bool RegionMatches(this string str, bool ignoreCase, int toOffset, string other, int ooffset, int len) + { + if (toOffset < 0 || ooffset < 0 || toOffset + len > str.Length || ooffset + len > other.Length) + return false; + return string.Compare(str, toOffset, other, ooffset, len) == 0; + } + + public static T Set<T>(this IList<T> list, int index, T item) + { + T old = list[index]; + list[index] = item; + return old; + } + + public static int Signum(long val) + { + if (val < 0) + { + return -1; + } + if (val > 0) + { + return 1; + } + return 0; + } + + public static void RemoveAll<T, TU>(this ICollection<T> col, ICollection<TU> items) where TU : T + { + foreach (var u in items) + col.Remove(u); + } + + public static bool ContainsAll<T, TU>(this ICollection<T> col, ICollection<TU> items) where TU : T + { + foreach (var u in items) + if (!col.Any(n => (ReferenceEquals(n, u)) || n.Equals(u))) + return false; + return true; + } + + public static bool Contains<T>(this ICollection<T> col, object item) + { + if (!(item is T)) + return false; + return col.Any(n => (ReferenceEquals(n, item)) || n.Equals(item)); + } + + public static void Sort<T>(this IList<T> list) + { + List<T> sorted = new List<T>(list); + sorted.Sort(); + for (int i = 0; i < list.Count; i++) + { + list[i] = sorted[i]; + } + } + + public static void Sort<T>(this IList<T> list, IComparer<T> comparer) + { + List<T> sorted = new List<T>(list); + sorted.Sort(comparer); + for (int i = 0; i < list.Count; i++) + { + list[i] = sorted[i]; + } + } + + public static string[] Split(this string str, string regex) + { + return str.Split(regex, 0); + } + + public static string[] Split(this string str, string regex, int limit) + { + Regex rgx = new Regex(regex); + List<string> list = new List<string>(); + int startIndex = 0; + if (limit != 1) + { + int nm = 1; + foreach (Match match in rgx.Matches(str)) + { + list.Add(str.Substring(startIndex, match.Index - startIndex)); + startIndex = match.Index + match.Length; + if (limit > 0 && ++nm == limit) + break; + } + } + if (startIndex < str.Length) + { + list.Add(str.Substring(startIndex)); + } + if (limit >= 0) + { + int count = list.Count - 1; + while ((count >= 0) && (list[count].Length == 0)) + { + count--; + } + list.RemoveRange(count + 1, (list.Count - count) - 1); + } + return list.ToArray(); + } + + public static IList<T> SubList<T>(this IList<T> list, int start, int len) + { + List<T> sublist = new List<T>(len); + for (int i = start; i < (start + len); i++) + { + sublist.Add(list[i]); + } + return sublist; + } + + public static char[] ToCharArray(this string str) + { + char[] destination = new char[str.Length]; + str.CopyTo(0, destination, 0, str.Length); + return destination; + } + + public static long ToMillisecondsSinceEpoch(this DateTime dateTime) + { + if (dateTime.Kind != DateTimeKind.Utc) + { + throw new ArgumentException("dateTime is expected to be expressed as a UTC DateTime", "dateTime"); + } + return new DateTimeOffset(DateTime.SpecifyKind(dateTime, DateTimeKind.Utc), TimeSpan.Zero).ToMillisecondsSinceEpoch(); + } + + public static long ToMillisecondsSinceEpoch(this DateTimeOffset dateTimeOffset) + { + return (((dateTimeOffset.Ticks - dateTimeOffset.Offset.Ticks) - EpochTicks) / TimeSpan.TicksPerMillisecond); + } + + public static string ToOctalString(int val) + { + return Convert.ToString(val, 8); + } + + public static string ToHexString(int val) + { + return Convert.ToString(val, 16); + } + + public static string ToString(object val) + { + return val.ToString(); + } + + public static string ToString(int val, int bas) + { + return Convert.ToString(val, bas); + } + + public static IList<TU> UpcastTo<T, TU>(this IList<T> s) where T : TU + { + List<TU> list = new List<TU>(s.Count); + for (int i = 0; i < s.Count; i++) + { + list.Add(s[i]); + } + return list; + } + + public static ICollection<TU> UpcastTo<T, TU>(this ICollection<T> s) where T : TU + { + List<TU> list = new List<TU>(s.Count); + foreach (var v in s) + { + list.Add(v); + } + return list; + } + + public static T ValueOf<T>(T val) + { + return val; + } + + + //use? for NUnit-testing? + //public static string GetTestName(object obj) + //{ + // return GetTestName(); + //} + + //public static string GetTestName() + //{ + // MethodBase met; + // int n = 0; + // do + // { + // met = new StackFrame(n).GetMethod(); + // if (met != null) + // { + // foreach (Attribute at in met.GetCustomAttributes(true)) + // { + // if (at.GetType().FullName == "NUnit.Framework.TestAttribute") + // { + // // Convert back to camel case + // string name = met.Name; + // if (char.IsUpper(name[0])) + // name = char.ToLower(name[0]) + name.Substring(1); + // return name; + // } + // } + // } + // n++; + // } while (met != null); + // return ""; + //} + + public static string GetHostAddress(this IPAddress addr) + { + return addr.ToString(); + } + + + public static IPAddress GetAddressByName(string host) + { + if (host == "0.0.0.0") + { + return IPAddress.Any; + } + + try + { + return IPAddress.Parse(host); + } + catch (Exception ex) + { + return null; + } + } + + public static IPAddress[] GetAddressesByName(string host) + { + //IReadOnlyList<EndpointPair> data = null; + + //try + //{ + // Task.Run(async () => + // { + // data = await DatagramSocket.GetEndpointPairsAsync(new HostName(host), "0"); + // }).Wait(); + //} + //catch (Exception ex) + //{ + // return null; + //} + + //return data != null + // ? data.Where(i => i.RemoteHostName.Type == HostNameType.Ipv4) + // .GroupBy(i => i.RemoteHostName.DisplayName) + // .Select(i => IPAddress.Parse(i.First().RemoteHostName.DisplayName)) + // .ToArray() + // : null; + + //get v4-address only + var entry = Task.Run(() => System.Net.Dns.GetHostEntryAsync(host)) + .GetAwaiter() + .GetResult(); + return entry.AddressList + .Where(addr => addr.AddressFamily == AddressFamily.InterNetwork) + .ToArray(); + + } + + public static string GetImplementationVersion(this Assembly asm) + { + return asm.GetName().Version.ToString(); + } + + public static string GetHost(this Uri uri) + { + return string.IsNullOrEmpty(uri.Host) ? "" : uri.Host; + } + + public static string GetUserInfo(this Uri uri) + { + return string.IsNullOrEmpty(uri.UserInfo) ? null : uri.UserInfo; + } + + public static string GetQuery(this Uri uri) + { + return string.IsNullOrEmpty(uri.Query) ? null : uri.Query; + } + + public static int GetLocalPort(this Socket socket) + { + return ((IPEndPoint)socket.LocalEndPoint).Port; + } + + public static int GetPort(this Socket socket) + { + return ((IPEndPoint)socket.RemoteEndPoint).Port; + } + + public static IPAddress GetInetAddress(this Socket socket) + { + return ((IPEndPoint)socket.RemoteEndPoint).Address; + } + + + /*public static bool RemoveElement(this ArrayList list, object elem) + { + int i = list.IndexOf(elem); + if (i == -1) + return false; + list.RemoveAt(i); + return true; + }*/ + + public static Semaphore CreateSemaphore(int count) + { + return new Semaphore(count, int.MaxValue); + } + + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileInputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileInputStream.cs new file mode 100644 index 000000000..25c5e06e0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileInputStream.cs @@ -0,0 +1,20 @@ +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class FileInputStream : InputStream + { + public FileInputStream (FilePath file) : this(file.GetPath ()) + { + } + + public FileInputStream (string file) + { + if (!File.Exists (file)) { + throw new FileNotFoundException ("File not found", file); + } + Wrapped = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + } + + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileOutputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileOutputStream.cs new file mode 100644 index 000000000..bf8029488 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileOutputStream.cs @@ -0,0 +1,33 @@ +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + internal class FileOutputStream : OutputStream + { + public FileOutputStream (FilePath file): this (file.GetPath (), false) + { + } + + public FileOutputStream (string file): this (file, false) + { + } + + public FileOutputStream (FilePath file, bool append) : this(file.GetPath (), append) + { + } + + public FileOutputStream (string file, bool append) + { + try { + if (append) { + Wrapped = File.Open (file, FileMode.Append, FileAccess.Write); + } else { + Wrapped = File.Open (file, FileMode.Create, FileAccess.Write); + } + } catch (DirectoryNotFoundException) { + throw new FileNotFoundException ("File not found: " + file); + } + } + + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilePath.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilePath.cs new file mode 100644 index 000000000..1b2f5eddc --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilePath.cs @@ -0,0 +1,313 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; + +namespace SharpCifs.Util.Sharpen +{ + public class FilePath + { + private string _path; + private static long _tempCounter; + + public FilePath () + { + } + + public FilePath (string path) + : this ((string) null, path) + { + + } + + public FilePath (FilePath other, string child) + : this ((string) other, child) + { + + } + + public FilePath (string other, string child) + { + if (other == null) { + _path = child; + } else { + while (!string.IsNullOrEmpty(child) && (child[0] == Path.DirectorySeparatorChar || child[0] == Path.AltDirectorySeparatorChar)) + child = child.Substring (1); + + if (!string.IsNullOrEmpty(other) && other[other.Length - 1] == Path.VolumeSeparatorChar) + other += Path.DirectorySeparatorChar; + + _path = Path.Combine (other, child); + } + } + + public static implicit operator FilePath (string name) + { + return new FilePath (name); + } + + public static implicit operator string (FilePath filePath) + { + return filePath == null ? null : filePath._path; + } + + public override bool Equals (object obj) + { + FilePath other = obj as FilePath; + if (other == null) + return false; + return GetCanonicalPath () == other.GetCanonicalPath (); + } + + public override int GetHashCode () + { + return _path.GetHashCode (); + } + + public bool CreateNewFile () + { + try { + //Stream.`Close` method deleted + //File.Open (_path, FileMode.CreateNew).Close (); + File.Open(_path, FileMode.CreateNew).Dispose(); + return true; + } catch { + return false; + } + } + + public static FilePath CreateTempFile () + { + return new FilePath (Path.GetTempFileName ()); + } + + public static FilePath CreateTempFile (string prefix, string suffix) + { + return CreateTempFile (prefix, suffix, null); + } + + public static FilePath CreateTempFile (string prefix, string suffix, FilePath directory) + { + string file; + if (prefix == null) { + throw new ArgumentNullException ("prefix"); + } + if (prefix.Length < 3) { + throw new ArgumentException ("prefix must have at least 3 characters"); + } + string str = (directory == null) ? Path.GetTempPath () : directory.GetPath (); + do { + file = Path.Combine (str, prefix + Interlocked.Increment (ref _tempCounter) + suffix); + } while (File.Exists (file)); + + new FileOutputStream (file).Close (); + return new FilePath (file); + } + + + public void DeleteOnExit () + { + } + + + public FilePath GetAbsoluteFile () + { + return new FilePath (Path.GetFullPath (_path)); + } + + public string GetAbsolutePath () + { + return Path.GetFullPath (_path); + } + + public FilePath GetCanonicalFile () + { + return new FilePath (GetCanonicalPath ()); + } + + public string GetCanonicalPath () + { + string p = Path.GetFullPath (_path); + p.TrimEnd (Path.DirectorySeparatorChar); + return p; + } + + public string GetName () + { + return Path.GetFileName (_path); + } + + public FilePath GetParentFile () + { + return new FilePath (Path.GetDirectoryName (_path)); + } + + public string GetPath () + { + return _path; + } + + public bool IsAbsolute () + { + return Path.IsPathRooted (_path); + } + + public bool IsDirectory () + { + return false; // FileHelper.Instance.IsDirectory(this); + } + + public bool IsFile () + { + return false; //FileHelper.Instance.IsFile (this); + } + + public long LastModified () + { + return 0; // FileHelper.Instance.LastModified(this); + } + + public long Length () + { + return 0; // FileHelper.Instance.Length(this); + } + + public string[] List () + { + return List (null); + } + + public string[] List (IFilenameFilter filter) + { + try { + if (IsFile ()) + return null; + List<string> list = new List<string> (); + foreach (string filePth in Directory.GetFileSystemEntries (_path)) { + string fileName = Path.GetFileName (filePth); + if ((filter == null) || filter.Accept (this, fileName)) { + list.Add (fileName); + } + } + return list.ToArray (); + } catch { + return null; + } + } + + public FilePath[] ListFiles () + { + try { + if (IsFile ()) + return null; + List<FilePath> list = new List<FilePath> (); + foreach (string filePath in Directory.GetFileSystemEntries (_path)) { + list.Add (new FilePath (filePath)); + } + return list.ToArray (); + } catch { + return null; + } + } + + static void MakeDirWritable (string dir) + { + //FileHelper.Instance.MakeDirWritable (dir); + } + + static void MakeFileWritable (string file) + { + //FileHelper.Instance.MakeFileWritable (file); + } + + public bool Mkdir () + { + try { + if (Directory.Exists (_path)) + return false; + Directory.CreateDirectory (_path); + return true; + } catch (Exception) { + return false; + } + } + + public bool Mkdirs () + { + try { + if (Directory.Exists (_path)) + return false; + Directory.CreateDirectory (_path); + return true; + } catch { + return false; + } + } + + public bool RenameTo (FilePath file) + { + return RenameTo (file._path); + } + + public bool RenameTo (string name) + { + return false; // FileHelper.Instance.RenameTo(this, name); + } + + public bool SetLastModified (long milis) + { + return false; // FileHelper.Instance.SetLastModified(this, milis); + } + + public bool SetReadOnly () + { + return false; // FileHelper.Instance.SetReadOnly(this); + } + + public Uri ToUri () + { + return new Uri (_path); + } + + // Don't change the case of this method, since ngit does reflection on it + public bool CanExecute () + { + return false; // FileHelper.Instance.CanExecute(this); + } + + // Don't change the case of this method, since ngit does reflection on it + public bool SetExecutable (bool exec) + { + return false; // FileHelper.Instance.SetExecutable(this, exec); + } + + public string GetParent () + { + string p = Path.GetDirectoryName (_path); + if (string.IsNullOrEmpty(p) || p == _path) + return null; + return p; + } + + public override string ToString () + { + return _path; + } + + static internal string PathSeparator { + get { return Path.PathSeparator.ToString (); } + } + + static internal char PathSeparatorChar { + get { return Path.PathSeparator; } + } + + static internal char SeparatorChar { + get { return Path.DirectorySeparatorChar; } + } + + static internal string Separator { + get { return Path.DirectorySeparatorChar.ToString (); } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileReader.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileReader.cs new file mode 100644 index 000000000..7a0c1f90e --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileReader.cs @@ -0,0 +1,13 @@ +namespace SharpCifs.Util.Sharpen +{ + public class FileReader : InputStreamReader + { + //public FileReader (FilePath f) : base(f.GetPath ()) + //{ + //} + //path -> fileStream + public FileReader(InputStream s) : base(s) + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileWriter.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileWriter.cs new file mode 100644 index 000000000..0675c238b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FileWriter.cs @@ -0,0 +1,18 @@ +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + //resharper said, nobody using this. i believe it. + //internal class FileWriter : StreamWriter + //{ + // public FileWriter (FilePath path) : base(path.GetPath ()) + // { + // } + + // public FileWriter Append (string sequence) + // { + // Write (sequence); + // return this; + // } + //} +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilterInputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilterInputStream.cs new file mode 100644 index 000000000..dfc0ba264 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilterInputStream.cs @@ -0,0 +1,57 @@ +namespace SharpCifs.Util.Sharpen +{ + public class FilterInputStream : InputStream + { + protected InputStream In; + + public FilterInputStream (InputStream s) + { + In = s; + } + + public override int Available () + { + return In.Available (); + } + + public override void Close () + { + In.Close (); + } + + public override void Mark (int readlimit) + { + In.Mark (readlimit); + } + + public override bool MarkSupported () + { + return In.MarkSupported (); + } + + public override int Read () + { + return In.Read (); + } + + public override int Read (byte[] buf) + { + return In.Read (buf); + } + + public override int Read (byte[] b, int off, int len) + { + return In.Read (b, off, len); + } + + public override void Reset () + { + In.Reset (); + } + + public override long Skip (long cnt) + { + return In.Skip (cnt); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilterOutputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilterOutputStream.cs new file mode 100644 index 000000000..4863105ed --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/FilterOutputStream.cs @@ -0,0 +1,37 @@ +namespace SharpCifs.Util.Sharpen +{ + public class FilterOutputStream : OutputStream + { + protected OutputStream Out; + + public FilterOutputStream (OutputStream os) + { + Out = os; + } + + public override void Close () + { + Out.Close (); + } + + public override void Flush () + { + Out.Flush (); + } + + public override void Write (byte[] b) + { + Out.Write (b); + } + + public override void Write (int b) + { + Out.Write (b); + } + + public override void Write (byte[] b, int offset, int len) + { + Out.Write (b, offset, len); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Hashtable.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Hashtable.cs new file mode 100644 index 000000000..c2c53485d --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Hashtable.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; + +namespace SharpCifs.Util.Sharpen +{ + public class Hashtable : Dictionary<object, object> + { + public void Put(object key, object value) + { + Add(key, value); + } + + public object Get(object key) + { + var m_key = Keys.SingleOrDefault(k => k.Equals(key)); + + return m_key != null ? this[m_key] : null; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/HttpURLConnection.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/HttpURLConnection.cs new file mode 100644 index 000000000..ace314eee --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/HttpURLConnection.cs @@ -0,0 +1,37 @@ +// +// HttpURLConnection.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace SharpCifs.Util.Sharpen +{ + public class UrlConnection + { + protected Uri Url; + } + +} + diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ICallable.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ICallable.cs new file mode 100644 index 000000000..d847cb497 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ICallable.cs @@ -0,0 +1,7 @@ +namespace SharpCifs.Util.Sharpen +{ + internal interface ICallable<T> + { + T Call (); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IConcurrentMap.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IConcurrentMap.cs new file mode 100644 index 000000000..dead24244 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IConcurrentMap.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace SharpCifs.Util.Sharpen +{ + internal interface IConcurrentMap<T, TU> : IDictionary<T, TU> + { + TU PutIfAbsent (T key, TU value); + bool Remove (object key, object value); + bool Replace (T key, TU oldValue, TU newValue); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IExecutor.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IExecutor.cs new file mode 100644 index 000000000..5f76c2ed5 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IExecutor.cs @@ -0,0 +1,7 @@ +namespace SharpCifs.Util.Sharpen +{ + public interface IExecutor + { + void Execute (IRunnable runnable); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IFilenameFilter.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IFilenameFilter.cs new file mode 100644 index 000000000..fe2eb6a3d --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IFilenameFilter.cs @@ -0,0 +1,7 @@ +namespace SharpCifs.Util.Sharpen +{ + public interface IFilenameFilter + { + bool Accept (FilePath dir, string name); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IFuture.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IFuture.cs new file mode 100644 index 000000000..5215e4502 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IFuture.cs @@ -0,0 +1,8 @@ +namespace SharpCifs.Util.Sharpen +{ + internal interface IFuture<T> + { + bool Cancel (bool mayInterruptIfRunning); + T Get (); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IPrivilegedAction.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IPrivilegedAction.cs new file mode 100644 index 000000000..4a5e92f9b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IPrivilegedAction.cs @@ -0,0 +1,7 @@ +namespace SharpCifs.Util.Sharpen +{ + internal interface IPrivilegedAction<T> + { + T Run (); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IRunnable.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IRunnable.cs new file mode 100644 index 000000000..7f6ae5533 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/IRunnable.cs @@ -0,0 +1,7 @@ +namespace SharpCifs.Util.Sharpen +{ + public interface IRunnable + { + void Run (); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/InputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/InputStream.cs new file mode 100644 index 000000000..2f3f070b5 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/InputStream.cs @@ -0,0 +1,169 @@ +using System; +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class InputStream : IDisposable + { + private long _mark; + protected Stream Wrapped; + protected Stream BaseStream; + + public static implicit operator InputStream (Stream s) + { + return Wrap (s); + } + + public static implicit operator Stream (InputStream s) + { + return s.GetWrappedStream (); + } + + public virtual int Available () + { + if (Wrapped is WrappedSystemStream) + return ((WrappedSystemStream)Wrapped).InputStream.Available (); + return 0; + } + + public virtual void Close () + { + if (Wrapped != null) { + //Stream.`Close` method deleted + //Wrapped.Close (); + Wrapped.Dispose(); + } + } + + public void Dispose () + { + Close (); + } + + internal Stream GetWrappedStream () + { + // Always create a wrapper stream (not directly Wrapped) since the subclass + // may be overriding methods that need to be called when used through the Stream class + return new WrappedSystemStream (this); + } + + public virtual void Mark (int readlimit) + { + if (Wrapped is WrappedSystemStream) + ((WrappedSystemStream)Wrapped).InputStream.Mark (readlimit); + else { + if (BaseStream is WrappedSystemStream) + ((WrappedSystemStream)BaseStream).OnMark (readlimit); + if (Wrapped != null) + _mark = Wrapped.Position; + } + } + + public virtual bool MarkSupported () + { + if (Wrapped is WrappedSystemStream) + return ((WrappedSystemStream)Wrapped).InputStream.MarkSupported (); + return ((Wrapped != null) && Wrapped.CanSeek); + } + + public virtual int Read () + { + if (Wrapped == null) { + throw new NotImplementedException (); + } + return Wrapped.ReadByte (); + } + + public virtual int Read (byte[] buf) + { + return Read (buf, 0, buf.Length); + } + + public virtual int Read (byte[] b, int off, int len) + { + if (Wrapped is WrappedSystemStream) + return ((WrappedSystemStream)Wrapped).InputStream.Read (b, off, len); + + if (Wrapped != null) { + int num = Wrapped.Read (b, off, len); + return ((num <= 0) ? -1 : num); + } + int totalRead = 0; + while (totalRead < len) { + int nr = Read (); + if (nr == -1) + return -1; + b[off + totalRead] = (byte)nr; + totalRead++; + } + return totalRead; + } + + public virtual void Reset () + { + if (Wrapped is WrappedSystemStream) + ((WrappedSystemStream)Wrapped).InputStream.Reset (); + else { + if (Wrapped == null) + throw new IOException (); + Wrapped.Position = _mark; + } + } + + public virtual long Skip (long cnt) + { + if (Wrapped is WrappedSystemStream) + return ((WrappedSystemStream)Wrapped).InputStream.Skip (cnt); + + long n = cnt; + while (n > 0) { + if (Read () == -1) + return cnt - n; + n--; + } + return cnt - n; + } + + internal virtual bool CanSeek () + { + if (Wrapped != null) + return Wrapped.CanSeek; + return false; + } + + internal virtual long Position { + get + { + if (Wrapped != null) + return Wrapped.Position; + throw new NotSupportedException (); + } + set { + if (Wrapped != null) + Wrapped.Position = value; + else + throw new NotSupportedException (); + } + } + + public virtual long Length + { + get + { + if (Wrapped != null) + { + return Wrapped.Length; + } + + throw new NotSupportedException(); + } + } + + static internal InputStream Wrap (Stream s) + { + InputStream stream = new InputStream (); + stream.Wrapped = s; + return stream; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/InputStreamReader.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/InputStreamReader.cs new file mode 100644 index 000000000..f9f1983b8 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/InputStreamReader.cs @@ -0,0 +1,25 @@ +using System.IO; +using System.Text; + +namespace SharpCifs.Util.Sharpen +{ + public class InputStreamReader : StreamReader + { + //Stream(string path) constructor deleted + //protected InputStreamReader (string file) : base(file) + //{ + //} + + public InputStreamReader (InputStream s) : base(s.GetWrappedStream ()) + { + } + + public InputStreamReader (InputStream s, string encoding) : base(s.GetWrappedStream (), Encoding.GetEncoding (encoding)) + { + } + + public InputStreamReader (InputStream s, Encoding e) : base(s.GetWrappedStream (), e) + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Iterator.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Iterator.cs new file mode 100644 index 000000000..634c7b404 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Iterator.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace SharpCifs.Util.Sharpen +{ + public interface ITerator + { + bool HasNext (); + object Next (); + void Remove (); + } + + public abstract class Iterator<T> : IEnumerator<T>, ITerator + { + private T _lastValue; + + object ITerator.Next () + { + return Next (); + } + + public abstract bool HasNext (); + public abstract T Next (); + public abstract void Remove (); + + bool IEnumerator.MoveNext () + { + if (HasNext ()) { + _lastValue = Next (); + return true; + } + return false; + } + + void IEnumerator.Reset () + { + throw new NotImplementedException (); + } + + void IDisposable.Dispose () + { + } + + T IEnumerator<T>.Current { + get { return _lastValue; } + } + + object IEnumerator.Current { + get { return _lastValue; } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/LinkageError.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/LinkageError.cs new file mode 100644 index 000000000..9f4970bdd --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/LinkageError.cs @@ -0,0 +1,11 @@ +using System; + +namespace SharpCifs.Util.Sharpen +{ + internal class LinkageError : Exception + { + public LinkageError (string msg) : base(msg) + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MD5.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MD5.cs new file mode 100644 index 000000000..50f3fa43b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MD5.cs @@ -0,0 +1,275 @@ +//Copyright (c) Microsoft Corporation. All rights reserved. + +using System; +using System.Text; + +namespace SharpCifs.Util.Sharpen +{ // ************************************************************** +// * Raw implementation of the MD5 hash algorithm +// * from RFC 1321. +// * +// * Written By: Reid Borsuk and Jenny Zheng +// * Copyright (c) Microsoft Corporation. All rights reserved. +// ************************************************************** + +// Simple struct for the (a,b,c,d) which is used to compute the mesage digest. + struct AbcdStruct + { + public uint A; + public uint B; + public uint C; + public uint D; + } + + public sealed class Md5Core + { + //Prevent CSC from adding a default public constructor + private Md5Core() { } + + public static byte[] GetHash(string input, Encoding encoding) + { + if (null == input) + throw new ArgumentNullException("input", "Unable to calculate hash over null input data"); + if (null == encoding) + throw new ArgumentNullException("encoding", "Unable to calculate hash over a string without a default encoding. Consider using the GetHash(string) overload to use UTF8 Encoding"); + + byte[] target = encoding.GetBytes(input); + + return GetHash(target); + } + + public static byte[] GetHash(string input) + { + return GetHash(input, new UTF8Encoding()); + } + + public static string GetHashString(byte[] input) + { + if (null == input) + throw new ArgumentNullException("input", "Unable to calculate hash over null input data"); + + string retval = BitConverter.ToString(GetHash(input)); + retval = retval.Replace("-", ""); + + return retval; + } + + public static string GetHashString(string input, Encoding encoding) + { + if (null == input) + throw new ArgumentNullException("input", "Unable to calculate hash over null input data"); + if (null == encoding) + throw new ArgumentNullException("encoding", "Unable to calculate hash over a string without a default encoding. Consider using the GetHashString(string) overload to use UTF8 Encoding"); + + byte[] target = encoding.GetBytes(input); + + return GetHashString(target); + } + + public static string GetHashString(string input) + { + return GetHashString(input, new UTF8Encoding()); + } + + public static byte[] GetHash(byte[] input) + { + if (null == input) + throw new ArgumentNullException("input", "Unable to calculate hash over null input data"); + + //Intitial values defined in RFC 1321 + AbcdStruct abcd = new AbcdStruct(); + abcd.A = 0x67452301; + abcd.B = 0xefcdab89; + abcd.C = 0x98badcfe; + abcd.D = 0x10325476; + + //We pass in the input array by block, the final block of data must be handled specialy for padding & length embeding + int startIndex = 0; + while (startIndex <= input.Length - 64) + { + GetHashBlock(input, ref abcd, startIndex); + startIndex += 64; + } + // The final data block. + return GetHashFinalBlock(input, startIndex, input.Length - startIndex, abcd, (Int64)input.Length * 8); + } + + internal static byte[] GetHashFinalBlock(byte[] input, int ibStart, int cbSize, AbcdStruct abcd, Int64 len) + { + byte[] working = new byte[64]; + byte[] length = BitConverter.GetBytes(len); + + //Padding is a single bit 1, followed by the number of 0s required to make size congruent to 448 modulo 512. Step 1 of RFC 1321 + //The CLR ensures that our buffer is 0-assigned, we don't need to explicitly set it. This is why it ends up being quicker to just + //use a temporary array rather then doing in-place assignment (5% for small inputs) + Array.Copy(input, ibStart, working, 0, cbSize); + working[cbSize] = 0x80; + + //We have enough room to store the length in this chunk + if (cbSize < 56) + { + Array.Copy(length, 0, working, 56, 8); + GetHashBlock(working, ref abcd, 0); + } + else //We need an aditional chunk to store the length + { + GetHashBlock(working, ref abcd, 0); + //Create an entirely new chunk due to the 0-assigned trick mentioned above, to avoid an extra function call clearing the array + working = new byte[64]; + Array.Copy(length, 0, working, 56, 8); + GetHashBlock(working, ref abcd, 0); + } + byte[] output = new byte[16]; + Array.Copy(BitConverter.GetBytes(abcd.A), 0, output, 0, 4); + Array.Copy(BitConverter.GetBytes(abcd.B), 0, output, 4, 4); + Array.Copy(BitConverter.GetBytes(abcd.C), 0, output, 8, 4); + Array.Copy(BitConverter.GetBytes(abcd.D), 0, output, 12, 4); + return output; + } + + // Performs a single block transform of MD5 for a given set of ABCD inputs + /* If implementing your own hashing framework, be sure to set the initial ABCD correctly according to RFC 1321: + // A = 0x67452301; + // B = 0xefcdab89; + // C = 0x98badcfe; + // D = 0x10325476; + */ + internal static void GetHashBlock(byte[] input, ref AbcdStruct abcdValue, int ibStart) + { + uint[] temp = Converter(input, ibStart); + uint a = abcdValue.A; + uint b = abcdValue.B; + uint c = abcdValue.C; + uint d = abcdValue.D; + + a = R1(a, b, c, d, temp[0], 7, 0xd76aa478); + d = R1(d, a, b, c, temp[1], 12, 0xe8c7b756); + c = R1(c, d, a, b, temp[2], 17, 0x242070db); + b = R1(b, c, d, a, temp[3], 22, 0xc1bdceee); + a = R1(a, b, c, d, temp[4], 7, 0xf57c0faf); + d = R1(d, a, b, c, temp[5], 12, 0x4787c62a); + c = R1(c, d, a, b, temp[6], 17, 0xa8304613); + b = R1(b, c, d, a, temp[7], 22, 0xfd469501); + a = R1(a, b, c, d, temp[8], 7, 0x698098d8); + d = R1(d, a, b, c, temp[9], 12, 0x8b44f7af); + c = R1(c, d, a, b, temp[10], 17, 0xffff5bb1); + b = R1(b, c, d, a, temp[11], 22, 0x895cd7be); + a = R1(a, b, c, d, temp[12], 7, 0x6b901122); + d = R1(d, a, b, c, temp[13], 12, 0xfd987193); + c = R1(c, d, a, b, temp[14], 17, 0xa679438e); + b = R1(b, c, d, a, temp[15], 22, 0x49b40821); + + a = R2(a, b, c, d, temp[1], 5, 0xf61e2562); + d = R2(d, a, b, c, temp[6], 9, 0xc040b340); + c = R2(c, d, a, b, temp[11], 14, 0x265e5a51); + b = R2(b, c, d, a, temp[0], 20, 0xe9b6c7aa); + a = R2(a, b, c, d, temp[5], 5, 0xd62f105d); + d = R2(d, a, b, c, temp[10], 9, 0x02441453); + c = R2(c, d, a, b, temp[15], 14, 0xd8a1e681); + b = R2(b, c, d, a, temp[4], 20, 0xe7d3fbc8); + a = R2(a, b, c, d, temp[9], 5, 0x21e1cde6); + d = R2(d, a, b, c, temp[14], 9, 0xc33707d6); + c = R2(c, d, a, b, temp[3], 14, 0xf4d50d87); + b = R2(b, c, d, a, temp[8], 20, 0x455a14ed); + a = R2(a, b, c, d, temp[13], 5, 0xa9e3e905); + d = R2(d, a, b, c, temp[2], 9, 0xfcefa3f8); + c = R2(c, d, a, b, temp[7], 14, 0x676f02d9); + b = R2(b, c, d, a, temp[12], 20, 0x8d2a4c8a); + + a = R3(a, b, c, d, temp[5], 4, 0xfffa3942); + d = R3(d, a, b, c, temp[8], 11, 0x8771f681); + c = R3(c, d, a, b, temp[11], 16, 0x6d9d6122); + b = R3(b, c, d, a, temp[14], 23, 0xfde5380c); + a = R3(a, b, c, d, temp[1], 4, 0xa4beea44); + d = R3(d, a, b, c, temp[4], 11, 0x4bdecfa9); + c = R3(c, d, a, b, temp[7], 16, 0xf6bb4b60); + b = R3(b, c, d, a, temp[10], 23, 0xbebfbc70); + a = R3(a, b, c, d, temp[13], 4, 0x289b7ec6); + d = R3(d, a, b, c, temp[0], 11, 0xeaa127fa); + c = R3(c, d, a, b, temp[3], 16, 0xd4ef3085); + b = R3(b, c, d, a, temp[6], 23, 0x04881d05); + a = R3(a, b, c, d, temp[9], 4, 0xd9d4d039); + d = R3(d, a, b, c, temp[12], 11, 0xe6db99e5); + c = R3(c, d, a, b, temp[15], 16, 0x1fa27cf8); + b = R3(b, c, d, a, temp[2], 23, 0xc4ac5665); + + a = R4(a, b, c, d, temp[0], 6, 0xf4292244); + d = R4(d, a, b, c, temp[7], 10, 0x432aff97); + c = R4(c, d, a, b, temp[14], 15, 0xab9423a7); + b = R4(b, c, d, a, temp[5], 21, 0xfc93a039); + a = R4(a, b, c, d, temp[12], 6, 0x655b59c3); + d = R4(d, a, b, c, temp[3], 10, 0x8f0ccc92); + c = R4(c, d, a, b, temp[10], 15, 0xffeff47d); + b = R4(b, c, d, a, temp[1], 21, 0x85845dd1); + a = R4(a, b, c, d, temp[8], 6, 0x6fa87e4f); + d = R4(d, a, b, c, temp[15], 10, 0xfe2ce6e0); + c = R4(c, d, a, b, temp[6], 15, 0xa3014314); + b = R4(b, c, d, a, temp[13], 21, 0x4e0811a1); + a = R4(a, b, c, d, temp[4], 6, 0xf7537e82); + d = R4(d, a, b, c, temp[11], 10, 0xbd3af235); + c = R4(c, d, a, b, temp[2], 15, 0x2ad7d2bb); + b = R4(b, c, d, a, temp[9], 21, 0xeb86d391); + + abcdValue.A = unchecked(a + abcdValue.A); + abcdValue.B = unchecked(b + abcdValue.B); + abcdValue.C = unchecked(c + abcdValue.C); + abcdValue.D = unchecked(d + abcdValue.D); + } + + //Manually unrolling these equations nets us a 20% performance improvement + private static uint R1(uint a, uint b, uint c, uint d, uint x, int s, uint t) + { + // (b + LSR((a + F(b, c, d) + x + t), s)) + //F(x, y, z) ((x & y) | ((x ^ 0xFFFFFFFF) & z)) + return unchecked(b + Lsr((a + ((b & c) | ((b ^ 0xFFFFFFFF) & d)) + x + t), s)); + } + + private static uint R2(uint a, uint b, uint c, uint d, uint x, int s, uint t) + { + // (b + LSR((a + G(b, c, d) + x + t), s)) + //G(x, y, z) ((x & z) | (y & (z ^ 0xFFFFFFFF))) + return unchecked(b + Lsr((a + ((b & d) | (c & (d ^ 0xFFFFFFFF))) + x + t), s)); + } + + private static uint R3(uint a, uint b, uint c, uint d, uint x, int s, uint t) + { + // (b + LSR((a + H(b, c, d) + k + i), s)) + //H(x, y, z) (x ^ y ^ z) + return unchecked(b + Lsr((a + (b ^ c ^ d) + x + t), s)); + } + + private static uint R4(uint a, uint b, uint c, uint d, uint x, int s, uint t) + { + // (b + LSR((a + I(b, c, d) + k + i), s)) + //I(x, y, z) (y ^ (x | (z ^ 0xFFFFFFFF))) + return unchecked(b + Lsr((a + (c ^ (b | (d ^ 0xFFFFFFFF))) + x + t), s)); + } + + // Implementation of left rotate + // s is an int instead of a uint becuase the CLR requires the argument passed to >>/<< is of + // type int. Doing the demoting inside this function would add overhead. + private static uint Lsr(uint i, int s) + { + return ((i << s) | (i >> (32 - s))); + } + + //Convert input array into array of UInts + private static uint[] Converter(byte[] input, int ibStart) + { + if (null == input) + throw new ArgumentNullException("input", "Unable convert null array to array of uInts"); + + uint[] result = new uint[16]; + + for (int i = 0; i < 16; i++) + { + result[i] = input[ibStart + i * 4]; + result[i] += (uint)input[ibStart + i * 4 + 1] << 8; + result[i] += (uint)input[ibStart + i * 4 + 2] << 16; + result[i] += (uint)input[ibStart + i * 4 + 3] << 24; + } + + return result; + } + } +}
\ No newline at end of file diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MD5Managed.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MD5Managed.cs new file mode 100644 index 000000000..e74a05abf --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MD5Managed.cs @@ -0,0 +1,91 @@ +//Copyright (c) Microsoft Corporation. All rights reserved. + +using System; +using System.Security.Cryptography; + +// ************************************************************** +// * Raw implementation of the MD5 hash algorithm +// * from RFC 1321. +// * +// * Written By: Reid Borsuk and Jenny Zheng +// * Copyright (c) Microsoft Corporation. All rights reserved. +// ************************************************************** + + +#if SILVERLIGHT +#else +//public class MD5Managed : MD5 +#endif +namespace SharpCifs.Util.Sharpen +{ + public class Md5Managed : HashAlgorithm + + { + public static Md5Managed Create() + { + return new Md5Managed(); + } + + private byte[] _data; + private AbcdStruct _abcd; + private Int64 _totalLength; + private int _dataSize; + + public Md5Managed() + { + //field cannot access + //HashSizeValue = 0x80; + Initialize(); + } + + public override void Initialize() + { + _data = new byte[64]; + _dataSize = 0; + _totalLength = 0; + _abcd = new AbcdStruct(); + //Intitial values as defined in RFC 1321 + _abcd.A = 0x67452301; + _abcd.B = 0xefcdab89; + _abcd.C = 0x98badcfe; + _abcd.D = 0x10325476; + } + + protected override void HashCore(byte[] array, int ibStart, int cbSize) + { + int startIndex = ibStart; + int totalArrayLength = _dataSize + cbSize; + if (totalArrayLength >= 64) + { + Array.Copy(array, startIndex, _data, _dataSize, 64 - _dataSize); + // Process message of 64 bytes (512 bits) + Md5Core.GetHashBlock(_data, ref _abcd, 0); + startIndex += 64 - _dataSize; + totalArrayLength -= 64; + while (totalArrayLength >= 64) + { + Array.Copy(array, startIndex, _data, 0, 64); + Md5Core.GetHashBlock(array, ref _abcd, startIndex); + totalArrayLength -= 64; + startIndex += 64; + } + _dataSize = totalArrayLength; + Array.Copy(array, startIndex, _data, 0, totalArrayLength); + } + else + { + Array.Copy(array, startIndex, _data, _dataSize, cbSize); + _dataSize = totalArrayLength; + } + _totalLength += cbSize; + } + + protected override byte[] HashFinal() + { + //field cannot access + //HashValue = Md5Core.GetHashFinalBlock(_data, 0, _dataSize, _abcd, _totalLength * 8); + //return HashValue; + return Md5Core.GetHashFinalBlock(_data, 0, _dataSize, _abcd, _totalLength * 8); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Matcher.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Matcher.cs new file mode 100644 index 000000000..d0bd79aa2 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Matcher.cs @@ -0,0 +1,83 @@ +using System; +using System.Text.RegularExpressions; + +namespace SharpCifs.Util.Sharpen +{ + internal class Matcher + { + private int _current; + private MatchCollection _matches; + private Regex _regex; + private string _str; + + internal Matcher (Regex regex, string str) + { + this._regex = regex; + this._str = str; + } + + public int End () + { + if ((_matches == null) || (_current >= _matches.Count)) { + throw new InvalidOperationException (); + } + return (_matches[_current].Index + _matches[_current].Length); + } + + public bool Find () + { + if (_matches == null) { + _matches = _regex.Matches (_str); + _current = 0; + } + return (_current < _matches.Count); + } + + public bool Find (int index) + { + _matches = _regex.Matches (_str, index); + _current = 0; + return (_matches.Count > 0); + } + + public string Group (int n) + { + if ((_matches == null) || (_current >= _matches.Count)) { + throw new InvalidOperationException (); + } + Group grp = _matches[_current].Groups[n]; + return grp.Success ? grp.Value : null; + } + + public bool Matches () + { + _matches = null; + return Find (); + } + + public string ReplaceFirst (string txt) + { + return _regex.Replace (_str, txt, 1); + } + + public Matcher Reset (CharSequence str) + { + return Reset (str.ToString ()); + } + + public Matcher Reset (string str) + { + _matches = null; + this._str = str; + return this; + } + + public int Start () + { + if ((_matches == null) || (_current >= _matches.Count)) { + throw new InvalidOperationException (); + } + return _matches[_current].Index; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MessageDigest.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MessageDigest.cs new file mode 100644 index 000000000..5562f9d36 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/MessageDigest.cs @@ -0,0 +1,118 @@ +using System; +using System.IO; +using System.Reflection; +using System.Security.Cryptography; + +namespace SharpCifs.Util.Sharpen +{ + public abstract class MessageDigest + { + public void Digest (byte[] buffer, int o, int len) + { + byte[] d = Digest (); + d.CopyTo (buffer, o); + } + + public byte[] Digest (byte[] buffer) + { + Update (buffer); + return Digest (); + } + + public abstract byte[] Digest (); + public abstract int GetDigestLength (); + public static MessageDigest GetInstance (string algorithm) + { + switch (algorithm.ToLower ()) { + case "sha-1": + //System.Security.CryptographySHA1Managed not found + //return new MessageDigest<SHA1Managed> (); + return new MessageDigest<System.Security.Cryptography.SHA1>(); + case "md5": + return new MessageDigest<Md5Managed> (); + } + throw new NotSupportedException (string.Format ("The requested algorithm \"{0}\" is not supported.", algorithm)); + } + + public abstract void Reset (); + public abstract void Update (byte[] b); + public abstract void Update (byte b); + public abstract void Update (byte[] b, int offset, int len); + } + + + public class MessageDigest<TAlgorithm> : MessageDigest where TAlgorithm : HashAlgorithm //, new() //use static `Create` method + { + private TAlgorithm _hash; + //private CryptoStream _stream; //don't work .NET Core + private MemoryStream _stream; + + + public MessageDigest () + { + Init (); + } + + public override byte[] Digest () + { + //CryptoStream -> MemoryStream, needless method + //_stream.FlushFinalBlock (); + + //HashAlgorithm.`Hash` property deleted + //byte[] hash = _hash.Hash; + byte[] hash = _hash.ComputeHash(_stream.ToArray()); + + Reset (); + return hash; + } + + public void Dispose () + { + if (_stream != null) { + _stream.Dispose (); + } + _stream = null; + } + + public override int GetDigestLength () + { + return (_hash.HashSize / 8); + } + + private void Init () + { + //use static `Create` method + //_hash = Activator.CreateInstance<TAlgorithm> (); + var createMethod = typeof(TAlgorithm).GetRuntimeMethod("Create", new Type[0]); + _hash = (TAlgorithm)createMethod.Invoke(null, new object[] {}); + + //HashAlgorithm cannot cast `ICryptoTransform` on .NET Core, gave up using CryptoStream. + //_stream = new CryptoStream(Stream.Null, _hash, CryptoStreamMode.Write); + //_stream = new CryptoStream(_tmpStream, (ICryptoTransform)_hash, CryptoStreamMode.Write); + _stream = new MemoryStream(); + } + + public override void Reset () + { + Dispose (); + Init (); + } + + public override void Update (byte[] input) + { + _stream.Write (input, 0, input.Length); + } + + public override void Update (byte input) + { + _stream.WriteByte (input); + } + + public override void Update (byte[] input, int index, int count) + { + if (count < 0) + Console.WriteLine ("Argh!"); + _stream.Write (input, index, count); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/NetworkStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/NetworkStream.cs new file mode 100644 index 000000000..05599cea3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/NetworkStream.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class NetworkStream : Stream + { + SocketEx _socket; + + public NetworkStream(SocketEx socket) + { + _socket = socket; + } + + public override bool CanRead + { + get { throw new NotImplementedException(); } + } + + public override bool CanSeek + { + get { throw new NotImplementedException(); } + } + + public override bool CanWrite + { + get { throw new NotImplementedException(); } + } + + public override void Flush() + { + // throw new NotImplementedException(); + } + + public override long Length + { + get { throw new NotImplementedException(); } + } + + public override long Position + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + return _socket.Receive(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + _socket.Send(buffer, offset, count); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ObjectInputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ObjectInputStream.cs new file mode 100644 index 000000000..dc3d6ccc3 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ObjectInputStream.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + internal class ObjectInputStream : InputStream + { + private BinaryReader _reader; + + public ObjectInputStream (InputStream s) + { + _reader = new BinaryReader (s.GetWrappedStream ()); + } + + public int ReadInt () + { + return _reader.ReadInt32 (); + } + + public object ReadObject () + { + throw new NotImplementedException (); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ObjectOutputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ObjectOutputStream.cs new file mode 100644 index 000000000..97f3a2cfd --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ObjectOutputStream.cs @@ -0,0 +1,19 @@ +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + internal class ObjectOutputStream : OutputStream + { + private BinaryWriter _bw; + + public ObjectOutputStream (OutputStream os) + { + _bw = new BinaryWriter (os.GetWrappedStream ()); + } + + public virtual void WriteInt (int i) + { + _bw.Write (i); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/OutputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/OutputStream.cs new file mode 100644 index 000000000..0e6189f0c --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/OutputStream.cs @@ -0,0 +1,86 @@ +using System; +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class OutputStream : IDisposable + { + protected Stream Wrapped; + + public static implicit operator OutputStream (Stream s) + { + return Wrap (s); + } + + public static implicit operator Stream (OutputStream s) + { + return s.GetWrappedStream (); + } + + public virtual void Close () + { + if (Wrapped != null) { + //Stream.`Close` method deleted + //Wrapped.Close (); + Wrapped.Dispose(); + } + } + + public void Dispose () + { + Close (); + } + + public virtual void Flush () + { + if (Wrapped != null) { + Wrapped.Flush (); + } + } + + internal Stream GetWrappedStream () + { + // Always create a wrapper stream (not directly Wrapped) since the subclass + // may be overriding methods that need to be called when used through the Stream class + return new WrappedSystemStream (this); + } + + static internal OutputStream Wrap (Stream s) + { + OutputStream stream = new OutputStream (); + stream.Wrapped = s; + return stream; + } + + public virtual void Write (int b) + { + if (Wrapped is WrappedSystemStream) + ((WrappedSystemStream)Wrapped).OutputStream.Write (b); + else { + if (Wrapped == null) + throw new NotImplementedException (); + Wrapped.WriteByte ((byte)b); + } + } + + public virtual void Write (byte[] b) + { + Write (b, 0, b.Length); + } + + public virtual void Write (byte[] b, int offset, int len) + { + if (Wrapped is WrappedSystemStream) + ((WrappedSystemStream)Wrapped).OutputStream.Write (b, offset, len); + else { + if (Wrapped != null) { + Wrapped.Write (b, offset, len); + } else { + for (int i = 0; i < len; i++) { + Write (b[i + offset]); + } + } + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/OutputStreamWriter.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/OutputStreamWriter.cs new file mode 100644 index 000000000..6313b7c79 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/OutputStreamWriter.cs @@ -0,0 +1,20 @@ +using System.IO; +using System.Text; + +namespace SharpCifs.Util.Sharpen +{ + internal class OutputStreamWriter : StreamWriter + { + public OutputStreamWriter (OutputStream stream) : base(stream.GetWrappedStream ()) + { + } + + public OutputStreamWriter (OutputStream stream, string encoding) : base(stream.GetWrappedStream (), Extensions.GetEncoding (encoding)) + { + } + + public OutputStreamWriter (OutputStream stream, Encoding encoding) : base(stream.GetWrappedStream (), encoding) + { + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs new file mode 100644 index 000000000..d5004c988 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs @@ -0,0 +1,172 @@ +using System; +using System.Threading; + +namespace SharpCifs.Util.Sharpen +{ + internal class PipedInputStream : InputStream + { + private byte[] _oneBuffer; + public const int PipeSize = 1024; + + protected byte[] Buffer; + private bool _closed; + private ManualResetEvent _dataEvent; + private int _end; + private int _start; + private object _thisLock; + private bool _allowGrow = false; + + public int In { + get { return _start; } + set { _start = value; } + } + + public int Out { + get { return _end; } + set { _end = value; } + } + + public PipedInputStream () + { + _thisLock = new object (); + _dataEvent = new ManualResetEvent (false); + Buffer = new byte[PipeSize + 1]; + } + + public PipedInputStream (PipedOutputStream os): this () + { + os.Attach (this); + } + + public override void Close () + { + lock (_thisLock) { + _closed = true; + _dataEvent.Set (); + } + } + + public override int Available () + { + lock (_thisLock) { + if (_start <= _end) { + return (_end - _start); + } + return ((Buffer.Length - _start) + _end); + } + } + + public override int Read () + { + if (_oneBuffer == null) + _oneBuffer = new byte[1]; + if (Read (_oneBuffer, 0, 1) == -1) + return -1; + return _oneBuffer[0]; + } + + public override int Read (byte[] b, int offset, int len) + { + int length = 0; + do { + _dataEvent.WaitOne (); + lock (_thisLock) { + if (_closed && Available () == 0) { + return -1; + } + if (_start < _end) { + length = Math.Min (len, _end - _start); + Array.Copy (Buffer, _start, b, offset, length); + _start += length; + } else if (_start > _end) { + length = Math.Min (len, Buffer.Length - _start); + Array.Copy (Buffer, _start, b, offset, length); + len -= length; + _start = (_start + length) % Buffer.Length; + if (len > 0) { + int i = Math.Min (len, _end); + Array.Copy (Buffer, 0, b, offset + length, i); + _start += i; + length += i; + } + } + if (_start == _end && !_closed) { + _dataEvent.Reset (); + } + Monitor.PulseAll (_thisLock); + } + } while (length == 0); + return length; + } + + private int Allocate (int len) + { + int alen; + while ((alen = TryAllocate (len)) == 0) { + // Wait until somebody reads data + try { + Monitor.Wait (_thisLock); + } catch { + _closed = true; + _dataEvent.Set (); + throw; + } + } + return alen; + } + + int TryAllocate (int len) + { + int free; + if (_start <= _end) { + free = (Buffer.Length - _end) + _start; + } else { + free = _start - _end; + } + if (free <= len) { + if (!_allowGrow) + return free > 0 ? free - 1 : 0; + int sizeInc = (len - free) + 1; + byte[] destinationArray = new byte[Buffer.Length + sizeInc]; + if (_start <= _end) { + Array.Copy (Buffer, _start, destinationArray, _start, _end - _start); + } else { + Array.Copy (Buffer, 0, destinationArray, 0, _end); + Array.Copy (Buffer, _start, destinationArray, _start + sizeInc, Buffer.Length - _start); + _start += sizeInc; + } + Buffer = destinationArray; + } + return len; + } + + internal void Write (int b) + { + lock (_thisLock) { + Allocate (1); + Buffer[_end] = (byte)b; + _end = (_end + 1) % Buffer.Length; + _dataEvent.Set (); + } + } + + internal void Write (byte[] b, int offset, int len) + { + do { + lock (_thisLock) { + int alen = Allocate (len); + int length = Math.Min (Buffer.Length - _end, alen); + Array.Copy (b, offset, Buffer, _end, length); + _end = (_end + length) % Buffer.Length; + if (length < alen) { + Array.Copy (b, offset + length, Buffer, 0, alen - length); + _end += alen - length; + } + _dataEvent.Set (); + len -= alen; + offset += alen; + } + } while (len > 0); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PipedOutputStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PipedOutputStream.cs new file mode 100644 index 000000000..4c46f1ec0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PipedOutputStream.cs @@ -0,0 +1,37 @@ +namespace SharpCifs.Util.Sharpen +{ + internal class PipedOutputStream : OutputStream + { + PipedInputStream _ips; + + public PipedOutputStream () + { + } + + public PipedOutputStream (PipedInputStream iss) : this() + { + Attach (iss); + } + + public override void Close () + { + _ips.Close (); + base.Close (); + } + + internal void Attach (PipedInputStream iss) + { + _ips = iss; + } + + public override void Write (int b) + { + _ips.Write (b); + } + + public override void Write (byte[] b, int offset, int len) + { + _ips.Write (b, offset, len); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PrintWriter.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PrintWriter.cs new file mode 100644 index 000000000..c366aa665 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/PrintWriter.cs @@ -0,0 +1,231 @@ +using System; +using System.IO; +using System.Text; + +namespace SharpCifs.Util.Sharpen +{ + public class PrintWriter : TextWriter + { + TextWriter _writer; + private FileStream _stream; + + public PrintWriter (FilePath path) + { + //Stream(string path) constructor deleted + _stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite); + _writer = new StreamWriter (_stream); + } + + public PrintWriter (TextWriter other) + { + _writer = other; + } + + public override Encoding Encoding { + get { return _writer.Encoding; } + } + + public void Close() // remove `override` + { + //Stream.`Close` method deleted + //_writer.Close (); + _writer.Dispose(); + _stream.Dispose(); + } + + public override void Flush () + { + _writer.Flush (); + } + + public override IFormatProvider FormatProvider { + get { + return _writer.FormatProvider; + } + } + + public override string NewLine { + get { + return _writer.NewLine; + } + set { + _writer.NewLine = value; + } + } + + public override void Write (char[] buffer, int index, int count) + { + _writer.Write (buffer, index, count); + } + + public override void Write (char[] buffer) + { + _writer.Write (buffer); + } + + public void Write (string format, object arg0, object arg1, object arg2) + { + _writer.Write (format, arg0, arg1, arg2); + } + + public override void Write (string format, object arg0, object arg1) + { + _writer.Write (format, arg0, arg1); + } + + public override void Write (string format, object arg0) + { + _writer.Write (format, arg0); + } + + public override void Write (string format, params object[] arg) + { + _writer.Write (format, arg); + } + + public override void WriteLine (char[] buffer, int index, int count) + { + _writer.WriteLine (buffer, index, count); + } + + public override void WriteLine (char[] buffer) + { + _writer.WriteLine (buffer); + } + + public void WriteLine (string format, object arg0, object arg1, object arg2) + { + _writer.WriteLine (format, arg0, arg1, arg2); + } + + public override void WriteLine (string format, object arg0, object arg1) + { + _writer.WriteLine (format, arg0, arg1); + } + + public override void WriteLine (string format, object arg0) + { + _writer.WriteLine (format, arg0); + } + + public override void WriteLine (string format, params object[] arg) + { + _writer.WriteLine (format, arg); + } + + public override void WriteLine (ulong value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (uint value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (string value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (float value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (object value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (long value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (int value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (double value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (decimal value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (char value) + { + _writer.WriteLine (value); + } + + public override void WriteLine (bool value) + { + _writer.WriteLine (value); + } + + public override void WriteLine () + { + _writer.WriteLine (); + } + + public override void Write (bool value) + { + _writer.Write (value); + } + + public override void Write (char value) + { + _writer.Write (value); + } + + public override void Write (decimal value) + { + _writer.Write (value); + } + + public override void Write (double value) + { + _writer.Write (value); + } + + public override void Write (int value) + { + _writer.Write (value); + } + + public override void Write (long value) + { + _writer.Write (value); + } + + public override void Write (object value) + { + _writer.Write (value); + } + + public override void Write (float value) + { + _writer.Write (value); + } + + public override void Write (string value) + { + _writer.Write (value); + } + + public override void Write (uint value) + { + _writer.Write (value); + } + + public override void Write (ulong value) + { + _writer.Write (value); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Properties.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Properties.cs new file mode 100644 index 000000000..3d886ea87 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Properties.cs @@ -0,0 +1,86 @@ +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class Properties + { + protected Hashtable _properties; + + public Properties() + { + _properties = new Hashtable(); + } + + public Properties(Properties defaultProp): this() + { + PutAll(defaultProp._properties); + } + + public void PutAll(Hashtable properties) + { + foreach (var key in properties.Keys) + { + //_properties.Add(key, properties[key]); + _properties.Put(key, properties[key]); + } + } + + public void SetProperty(object key, object value) + { + //_properties.Add(key, value); + _properties.Put(key, value); + } + + public object GetProperty(object key) + { + return _properties.Keys.Contains(key) ? _properties[key] : null; + } + + public object GetProperty(object key, object def) + { + /*if (_properties.ContainsKey(key)) + { + return _properties[key]; + } + return def;*/ + object value = _properties.Get(key); + + return value ?? def; + } + + public void Load(InputStream input) + { + StreamReader sr = new StreamReader(input); + while (!sr.EndOfStream) + { + string line = sr.ReadLine(); + + if (!string.IsNullOrEmpty(line)) + { + string[] tokens = line.Split('='); + //_properties.Add(tokens[0], tokens[1]); + _properties.Put(tokens[0], tokens[1]); + } + } + } + + public void Store(OutputStream output) + { + StreamWriter sw = new StreamWriter(output); + foreach (var key in _properties.Keys) + { + string line = string.Format("{0}={1}", key, _properties[key]); + sw.WriteLine(line); + } + } + + public void Store(TextWriter output) + { + foreach (var key in _properties.Keys) + { + string line = string.Format("{0}={1}", key, _properties[key]); + output.WriteLine(line); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/RandomAccessFile.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/RandomAccessFile.cs new file mode 100644 index 000000000..bf3596212 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/RandomAccessFile.cs @@ -0,0 +1,87 @@ +using System; +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + public class RandomAccessFile + { + private FileStream _stream; + + public RandomAccessFile (FilePath file, string mode) : this(file.GetPath (), mode) + { + } + + public RandomAccessFile (string file, string mode) + { + if (mode.IndexOf ('w') != -1) + _stream = new FileStream (file, FileMode.OpenOrCreate, FileAccess.ReadWrite); + else + _stream = new FileStream (file, FileMode.Open, FileAccess.Read); + } + + public void Close () + { + //Stream.`Close` method deleted + //_stream.Close (); + _stream.Dispose(); + } + + public long GetFilePointer () + { + return _stream.Position; + } + + public long Length () + { + return _stream.Length; + } + + public int Read (byte[] buffer) + { + int r = _stream.Read (buffer, 0, buffer.Length); + return r > 0 ? r : -1; + } + + public int Read (byte[] buffer, int start, int size) + { + return _stream.Read (buffer, start, size); + } + + public void ReadFully (byte[] buffer, int start, int size) + { + while (size > 0) { + int num = _stream.Read (buffer, start, size); + if (num == 0) { + throw new EofException (); + } + size -= num; + start += num; + } + } + + public void Seek (long pos) + { + _stream.Position = pos; + } + + public void SetLength (long len) + { + _stream.SetLength (len); + } + + public void Write (int value) + { + _stream.Write (BitConverter.GetBytes (value), 0, 4); + } + + public void Write (byte[] buffer) + { + _stream.Write (buffer, 0, buffer.Length); + } + + public void Write (byte[] buffer, int start, int size) + { + _stream.Write (buffer, start, size); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ReentrantLock.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ReentrantLock.cs new file mode 100644 index 000000000..aa34db9d0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ReentrantLock.cs @@ -0,0 +1,22 @@ +using System.Threading; + +namespace SharpCifs.Util.Sharpen +{ + internal class ReentrantLock + { + public void Lock () + { + Monitor.Enter (this); + } + + public bool TryLock () + { + return Monitor.TryEnter (this); + } + + public void Unlock () + { + Monitor.Exit (this); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Reference.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Reference.cs new file mode 100644 index 000000000..c7fbe9a48 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Reference.cs @@ -0,0 +1,7 @@ +namespace SharpCifs.Util.Sharpen +{ + internal abstract class Reference<T> + { + public abstract T Get (); + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Runtime.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Runtime.cs new file mode 100644 index 000000000..74ff16b1b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Runtime.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; + +namespace SharpCifs.Util.Sharpen +{ + public class Runtime + { + private static Runtime _instance; + private List<ShutdownHook> _shutdownHooks = new List<ShutdownHook> (); + + internal void AddShutdownHook (IRunnable r) + { + ShutdownHook item = new ShutdownHook (); + item.Runnable = r; + _shutdownHooks.Add (item); + } + + internal int AvailableProcessors () + { + return Environment.ProcessorCount; + } + + public static long CurrentTimeMillis () + { + return DateTime.UtcNow.ToMillisecondsSinceEpoch (); + } + + static Hashtable _properties; + + public static Hashtable GetProperties () + { + if (_properties == null) { + _properties = new Hashtable (); + _properties ["jgit.fs.debug"] = "false"; + _properties["file.encoding"] = "UTF-8"; + if (Path.DirectorySeparatorChar != '\\') + _properties ["os.name"] = "Unix"; + else + _properties ["os.name"] = "Windows"; + } + return _properties; + } + + public static string GetProperty (string key) + { + if (GetProperties().Keys.Contains(key)) + { + return ((string)GetProperties()[key]); + } + return null; + } + + public static void SetProperty (string key, string value) + { + GetProperties () [key] = value; + } + + public static Runtime GetRuntime () + { + if (_instance == null) { + _instance = new Runtime (); + } + return _instance; + } + + public static int IdentityHashCode (object ob) + { + return RuntimeHelpers.GetHashCode (ob); + } + + internal long MaxMemory () + { + return int.MaxValue; + } + + private class ShutdownHook + { + public IRunnable Runnable; + + ~ShutdownHook () + { + Runnable.Run (); + } + } + + public static void DeleteCharAt (StringBuilder sb, int index) + { + sb.Remove (index, 1); + } + + public static byte[] GetBytesForString (string str) + { + return Encoding.UTF8.GetBytes (str); + } + + public static byte[] GetBytesForString (string str, string encoding) + { + return Encoding.GetEncoding (encoding).GetBytes (str); + } + + public static FieldInfo[] GetDeclaredFields (Type t) + { + throw new NotImplementedException("Type.GetFields not found on .NetStandard"); + //return t.GetFields (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + } + + public static void NotifyAll (object ob) + { + Monitor.PulseAll (ob); + } + + public static void Notify(object obj) + { + Monitor.Pulse(obj); + } + + public static void PrintStackTrace (Exception ex) + { + Console.WriteLine (ex); + } + + public static void PrintStackTrace (Exception ex, TextWriter tw) + { + tw.WriteLine (ex); + } + + public static string Substring (string str, int index) + { + return str.Substring (index); + } + + public static string Substring (string str, int index, int endIndex) + { + return str.Substring (index, endIndex - index); + } + + public static void Wait (object ob) + { + Monitor.Wait (ob); + } + + public static bool Wait (object ob, long milis) + { + return Monitor.Wait (ob, (int)milis); + } + + public static Type GetType (string name) + { + throw new NotImplementedException("AppDomain.CurrentDomain.GetAssemblies not found on .NetStandard"); + //foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies ()) { + // Type t = a.GetType (name); + // if (t != null) + // return t; + //} + //never used + //throw new InvalidOperationException ("Type not found: " + name); + } + + public static void SetCharAt (StringBuilder sb, int index, char c) + { + sb [index] = c; + } + + public static bool EqualsIgnoreCase (string s1, string s2) + { + return s1.Equals (s2, StringComparison.CurrentCultureIgnoreCase); + } + + internal static long NanoTime () + { + return Environment.TickCount * 1000 * 1000; + } + + internal static int CompareOrdinal (string s1, string s2) + { + return string.CompareOrdinal (s1, s2); + } + + public static string GetStringForBytes (byte[] chars) + { + return Encoding.UTF8.GetString (chars, 0, chars.Length); + } + + public static string GetStringForBytes (byte[] chars, string encoding) + { + return GetEncoding (encoding).GetString (chars, 0, chars.Length); + } + + public static string GetStringForBytes (byte[] chars, int start, int len) + { + return Encoding.UTF8.GetString (chars, start, len); + } + + public static string GetStringForBytes (byte[] chars, int start, int len, string encoding) + { + return GetEncoding (encoding).Decode (chars, start, len); + } + + public static Encoding GetEncoding (string name) + { + Encoding e = Encoding.GetEncoding (name.Replace ('_','-')); + if (e is UTF8Encoding) + return new UTF8Encoding (false, true); + return e; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SimpleDateFormat.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SimpleDateFormat.cs new file mode 100644 index 000000000..35334b4f2 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SimpleDateFormat.cs @@ -0,0 +1,62 @@ +using System; +using System.Globalization; + +namespace SharpCifs.Util.Sharpen +{ + public class SimpleDateFormat : DateFormat + { + string _format; + + CultureInfo Culture { + get; set; + } + + bool Lenient { + get; set; + } + + public SimpleDateFormat (): this ("g") + { + } + + public SimpleDateFormat (string format): this (format, CultureInfo.CurrentCulture) + { + } + + public SimpleDateFormat (string format, CultureInfo c) + { + Culture = c; + this._format = format.Replace ("EEE", "ddd"); + this._format = this._format.Replace ("Z", "zzz"); + SetTimeZone (TimeZoneInfo.Local); + } + + public bool IsLenient () + { + return Lenient; + } + + public void SetLenient (bool lenient) + { + Lenient = lenient; + } + + public override DateTime Parse (string value) + { + if (IsLenient ()) + return DateTime.Parse (value); + return DateTime.ParseExact (value, _format, Culture); + } + + public override string Format (DateTime date) + { + date += GetTimeZone().BaseUtcOffset; + return date.ToString (_format); + } + + public string Format (long date) + { + return Extensions.MillisToDateTimeOffset (date, (int)GetTimeZone ().BaseUtcOffset.TotalMinutes).DateTime.ToString (_format); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SocketEx.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SocketEx.cs new file mode 100644 index 000000000..4d0651949 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SocketEx.cs @@ -0,0 +1,161 @@ +// SocketEx.cs implementation by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +using System; +using System.Net; +using System.Net.Sockets; +using System.Threading; + +namespace SharpCifs.Util.Sharpen +{ + public class SocketEx : Socket + { + private int _soTimeOut = -1; + + public int SoTimeOut + { + get + { + return _soTimeOut; + } + + set + { + if (value > 0) + { + _soTimeOut = value; + } + else + { + _soTimeOut = -1; + } + + } + } + + public SocketEx(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) + : base(addressFamily, socketType, protocolType) + { + + } + + public void Connect(IPEndPoint endPoint, int timeOut) + { + using (var evt = new ManualResetEventSlim(false)) + { + using (var args = new SocketAsyncEventArgs + { + RemoteEndPoint = endPoint + }) + { + args.Completed += delegate + { + evt.Set(); + }; + + ConnectAsync(args); + + if (!evt.Wait(timeOut)) + { + CancelConnectAsync(args); + throw new ConnectException("Can't connect to end point."); + } + if (args.SocketError != SocketError.Success) + { + throw new ConnectException("Can't connect to end point."); + } + } + } + } + + public void Bind2(EndPoint ep) + { + if (ep == null) + Bind(new IPEndPoint(IPAddress.Any, 0)); + else + Bind(ep); + } + + + public int Receive(byte[] buffer, int offset, int count) + { + using (var evt = new ManualResetEventSlim(false)) + { + using (var args = new SocketAsyncEventArgs + { + UserToken = this + }) + { + args.SetBuffer(buffer, offset, count); + + args.Completed += delegate + { + evt.Set(); + }; + + if (ReceiveAsync(args)) + { + if (!evt.Wait(_soTimeOut)) + { + throw new TimeoutException("No data received."); + } + } + + return args.BytesTransferred; + } + } + } + + public void Send(byte[] buffer, int offset, int length, EndPoint destination = null) + { + using (var evt = new ManualResetEventSlim(false)) + { + using (SocketAsyncEventArgs args = new SocketAsyncEventArgs + { + UserToken = this + }) + { + args.SetBuffer(buffer, offset, length); + + args.Completed += delegate + { + evt.Set(); + }; + + args.RemoteEndPoint = destination ?? RemoteEndPoint; + + + SendToAsync(args); + if (!evt.Wait(_soTimeOut)) + { + throw new TimeoutException("No data sent."); + } + } + } + } + + public InputStream GetInputStream() + { + return new NetworkStream(this); + } + + public OutputStream GetOutputStream() + { + return new NetworkStream(this); + } + + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/StringTokenizer.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/StringTokenizer.cs new file mode 100644 index 000000000..74c14cff6 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/StringTokenizer.cs @@ -0,0 +1,32 @@ +namespace SharpCifs.Util.Sharpen +{ + public class StringTokenizer + { + private string[] _tokens; + private int _pos; + + public StringTokenizer(string text, string delim) + { + _tokens = text.Split(delim); + } + + public int CountTokens() + { + return _tokens.Length; + } + + public string NextToken() + { + string value = _tokens[_pos]; + + _pos++; + + return value; + } + + public bool HasMoreTokens() + { + return _pos < _tokens.Length; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SynchronizedList.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SynchronizedList.cs new file mode 100644 index 000000000..c105a8bab --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/SynchronizedList.cs @@ -0,0 +1,106 @@ +using System.Collections; +using System.Collections.Generic; + +namespace SharpCifs.Util.Sharpen +{ + internal class SynchronizedList<T> : IList<T> + { + private IList<T> _list; + + public SynchronizedList (IList<T> list) + { + this._list = list; + } + + public int IndexOf (T item) + { + lock (_list) { + return _list.IndexOf (item); + } + } + + public void Insert (int index, T item) + { + lock (_list) { + _list.Insert (index, item); + } + } + + public void RemoveAt (int index) + { + lock (_list) { + _list.RemoveAt (index); + } + } + + void ICollection<T>.Add (T item) + { + lock (_list) { + _list.Add (item); + } + } + + void ICollection<T>.Clear () + { + lock (_list) { + _list.Clear (); + } + } + + bool ICollection<T>.Contains (T item) + { + lock (_list) { + return _list.Contains (item); + } + } + + void ICollection<T>.CopyTo (T[] array, int arrayIndex) + { + lock (_list) { + _list.CopyTo (array, arrayIndex); + } + } + + bool ICollection<T>.Remove (T item) + { + lock (_list) { + return _list.Remove (item); + } + } + + IEnumerator<T> IEnumerable<T>.GetEnumerator () + { + return _list.GetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return _list.GetEnumerator (); + } + + public T this[int index] { + get { + lock (_list) { + return _list[index]; + } + } + set { + lock (_list) { + _list[index] = value; + } + } + } + + int ICollection<T>.Count { + get { + lock (_list) { + return _list.Count; + } + } + } + + bool ICollection<T>.IsReadOnly { + get { return _list.IsReadOnly; } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Thread.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Thread.cs new file mode 100644 index 000000000..59f3df469 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/Thread.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Generic; + +namespace SharpCifs.Util.Sharpen +{ + public class Thread : IRunnable + { + private static ThreadGroup _defaultGroup = new ThreadGroup (); + private bool _interrupted; + private IRunnable _runnable; + private ThreadGroup _tgroup; + private System.Threading.Thread _thread; + + [ThreadStatic] + private static Thread _wrapperThread; + + public Thread () : this(null, null, null) + { + } + + public Thread (string name) : this (null, null, name) + { + } + + public Thread (ThreadGroup grp, string name) : this (null, grp, name) + { + } + + public Thread (IRunnable runnable): this (runnable, null, null) + { + } + + Thread (IRunnable runnable, ThreadGroup grp, string name) + { + _thread = new System.Threading.Thread (InternalRun); + + this._runnable = runnable ?? this; + _tgroup = grp ?? _defaultGroup; + _tgroup.Add (this); + if (name != null) + _thread.Name = name; + } + + private Thread (System.Threading.Thread t) + { + _thread = t; + _tgroup = _defaultGroup; + _tgroup.Add (this); + } + + public static Thread CurrentThread () + { + if (_wrapperThread == null) { + _wrapperThread = new Thread (System.Threading.Thread.CurrentThread); + } + return _wrapperThread; + } + + public string GetName () + { + return _thread.Name; + } + + public ThreadGroup GetThreadGroup () + { + return _tgroup; + } + + private void InternalRun () + { + _wrapperThread = this; + try { + _runnable.Run (); + } catch (Exception exception) { + Console.WriteLine (exception); + } finally { + _tgroup.Remove (this); + } + } + + public static void Yield () + { + } + + public void Interrupt () + { + lock (_thread) { + _interrupted = true; + //thread.Interrupt (); + + //TODO: implement CancellationToken + //_thread.Abort(); + throw new NotImplementedException("implement CancellationToken for thread"); + } + } + + public static bool Interrupted () + { + if (Thread._wrapperThread == null) { + return false; + } + Thread wrapperThread = Thread._wrapperThread; + lock (wrapperThread) { + bool interrupted = Thread._wrapperThread._interrupted; + Thread._wrapperThread._interrupted = false; + return interrupted; + } + } + + public bool IsAlive () + { + return _thread.IsAlive; + } + + public void Join () + { + _thread.Join (); + } + + public void Join (long timeout) + { + _thread.Join ((int)timeout); + } + + public virtual void Run () + { + } + + public void SetDaemon (bool daemon) + { + _thread.IsBackground = daemon; + } + + public void SetName (string name) + { + _thread.Name = name; + } + + public static void Sleep (long milis) + { + System.Threading.Thread.Sleep ((int)milis); + } + + public void Start () + { + _thread.Start (); + } + + public void Abort () + { + //TODO: implement CancellationToken + //_thread.Abort (); + throw new NotImplementedException("implement CancellationToken for thread"); + } + + } + + public class ThreadGroup + { + private List<Thread> _threads = new List<Thread> (); + + public ThreadGroup() + { + } + + public ThreadGroup (string name) + { + } + + internal void Add (Thread t) + { + lock (_threads) { + _threads.Add (t); + } + } + + internal void Remove (Thread t) + { + lock (_threads) { + _threads.Remove (t); + } + } + + public int Enumerate (Thread[] array) + { + lock (_threads) { + int count = Math.Min (array.Length, _threads.Count); + _threads.CopyTo (0, array, 0, count); + return count; + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ThreadFactory.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ThreadFactory.cs new file mode 100644 index 000000000..7276c06a2 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ThreadFactory.cs @@ -0,0 +1,13 @@ +namespace SharpCifs.Util.Sharpen +{ + internal class ThreadFactory + { + public Thread NewThread (IRunnable r) + { + Thread t = new Thread (r); + t.SetDaemon (true); + t.Start (); + return t; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ThreadPoolExecutor.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ThreadPoolExecutor.cs new file mode 100644 index 000000000..ef19b8bff --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/ThreadPoolExecutor.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using ST = System.Threading; + +namespace SharpCifs.Util.Sharpen +{ + class ThreadPoolExecutor + { + ThreadFactory _tf; + int _corePoolSize; + int _maxPoolSize; + List<Thread> _pool = new List<Thread> (); + int _runningThreads; + int _freeThreads; + bool _shutdown; + Queue<IRunnable> _pendingTasks = new Queue<IRunnable> (); + + public ThreadPoolExecutor (int corePoolSize, ThreadFactory factory) + { + this._corePoolSize = corePoolSize; + _maxPoolSize = corePoolSize; + _tf = factory; + } + + public void SetMaximumPoolSize (int size) + { + _maxPoolSize = size; + } + + public bool IsShutdown () + { + return _shutdown; + } + + public virtual bool IsTerminated () + { + lock (_pendingTasks) { + return _shutdown && _pendingTasks.Count == 0; + } + } + + public virtual bool IsTerminating () + { + lock (_pendingTasks) { + return _shutdown && !IsTerminated (); + } + } + + public int GetCorePoolSize () + { + return _corePoolSize; + } + + public void PrestartAllCoreThreads () + { + lock (_pendingTasks) { + while (_runningThreads < _corePoolSize) + StartPoolThread (); + } + } + + public void SetThreadFactory (ThreadFactory f) + { + _tf = f; + } + + public void Execute (IRunnable r) + { + InternalExecute (r, true); + } + + internal void InternalExecute (IRunnable r, bool checkShutdown) + { + lock (_pendingTasks) { + if (_shutdown && checkShutdown) + throw new InvalidOperationException (); + if (_runningThreads < _corePoolSize) { + StartPoolThread (); + } + else if (_freeThreads > 0) { + _freeThreads--; + } + else if (_runningThreads < _maxPoolSize) { + StartPoolThread (); + } + _pendingTasks.Enqueue (r); + ST.Monitor.PulseAll (_pendingTasks); + } + } + + void StartPoolThread () + { + _runningThreads++; + _pool.Add (_tf.NewThread (new RunnableAction (RunPoolThread))); + } + + public void RunPoolThread () + { + while (!IsTerminated ()) { + try { + IRunnable r = null; + lock (_pendingTasks) { + _freeThreads++; + while (!IsTerminated () && _pendingTasks.Count == 0) + ST.Monitor.Wait (_pendingTasks); + if (IsTerminated ()) + break; + r = _pendingTasks.Dequeue (); + } + if (r != null) + r.Run (); + } + //supress all errors, anyway + //catch (ST.ThreadAbortException) { + // // Do not catch a thread abort. If we've been aborted just let the thread die. + // // Currently reseting an abort which was issued because the appdomain is being + // // torn down results in the process living forever and consuming 100% cpu time. + // return; + //} + catch { + } + } + } + + public virtual void Shutdown () + { + lock (_pendingTasks) { + _shutdown = true; + ST.Monitor.PulseAll (_pendingTasks); + } + } + + public virtual List<IRunnable> ShutdownNow () + { + lock (_pendingTasks) { + _shutdown = true; + foreach (var t in _pool) { + try { + t.Abort (); + } catch {} + } + _pool.Clear (); + _freeThreads = 0; + _runningThreads = 0; + var res = new List<IRunnable> (_pendingTasks); + _pendingTasks.Clear (); + return res; + } + } + } + + class RunnableAction: IRunnable + { + Action _action; + + public RunnableAction (Action a) + { + _action = a; + } + + public void Run () + { + _action (); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/WrappedSystemStream.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/WrappedSystemStream.cs new file mode 100644 index 000000000..ef2993fa6 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Sharpen/WrappedSystemStream.cs @@ -0,0 +1,139 @@ +using System; +using System.IO; + +namespace SharpCifs.Util.Sharpen +{ + internal class WrappedSystemStream : Stream + { + private InputStream _ist; + private OutputStream _ost; + int _position; + int _markedPosition; + + public WrappedSystemStream (InputStream ist) + { + this._ist = ist; + } + + public WrappedSystemStream (OutputStream ost) + { + this._ost = ost; + } + + public InputStream InputStream { + get { return _ist; } + } + + public OutputStream OutputStream { + get { return _ost; } + } + + public void Close() //remove `override` + { + if (_ist != null) { + //Stream.`Close` method deleted + //_ist.Close (); + _ist.Dispose(); + } + if (_ost != null) { + //Stream.`Close` method deleted + //_ost.Close (); + _ost.Dispose(); + } + } + + public override void Flush () + { + _ost.Flush (); + } + + public override int Read (byte[] buffer, int offset, int count) + { + int res = _ist.Read (buffer, offset, count); + if (res != -1) { + _position += res; + return res; + } + return 0; + } + + public override int ReadByte () + { + int res = _ist.Read (); + if (res != -1) + _position++; + return res; + } + + public override long Seek (long offset, SeekOrigin origin) + { + if (origin == SeekOrigin.Begin) + Position = offset; + else if (origin == SeekOrigin.Current) + Position = Position + offset; + else if (origin == SeekOrigin.End) + Position = Length + offset; + return Position; + } + + public override void SetLength (long value) + { + throw new NotSupportedException (); + } + + public override void Write (byte[] buffer, int offset, int count) + { + _ost.Write (buffer, offset, count); + _position += count; + } + + public override void WriteByte (byte value) + { + _ost.Write (value); + _position++; + } + + public override bool CanRead { + get { return (_ist != null); } + } + + public override bool CanSeek { + get { return true; } + } + + public override bool CanWrite { + get { return (_ost != null); } + } + + public override long Length { + get { return _ist.Length; } + } + + internal void OnMark (int nb) + { + _markedPosition = _position; + _ist.Mark (nb); + } + + public override long Position { + get + { + if (_ist != null && _ist.CanSeek ()) + return _ist.Position; + return _position; + } + set + { + if (value == _position) + return; + if (value == _markedPosition) + _ist.Reset (); + else if (_ist != null && _ist.CanSeek ()) { + _ist.Position = value; + } + else + throw new NotSupportedException (); + } + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Request.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Request.cs new file mode 100644 index 000000000..6e0c3fc7b --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Request.cs @@ -0,0 +1,22 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Util.Transport +{ + public interface IRequest + { + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Response.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Response.cs new file mode 100644 index 000000000..702fea918 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Response.cs @@ -0,0 +1,25 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +namespace SharpCifs.Util.Transport +{ + public abstract class Response + { + public long Expiration; + + public bool IsReceived; + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Transport.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Transport.cs new file mode 100644 index 000000000..b02936ca6 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/Transport.cs @@ -0,0 +1,454 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Smb; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Util.Transport +{ + /// <summary> + /// This class simplifies communication for protocols that support + /// multiplexing requests. + /// </summary> + /// <remarks> + /// This class simplifies communication for protocols that support + /// multiplexing requests. It encapsulates a stream and some protocol + /// knowledge (provided by a concrete subclass) so that connecting, + /// disconnecting, sending, and receiving can be syncronized + /// properly. Apparatus is provided to send and receive requests + /// concurrently. + /// </remarks> + public abstract class Transport : IRunnable + { + internal static int Id; + + //internal static LogStream log = LogStream.GetInstance(); + + public LogStream Log + { + get + { + return LogStream.GetInstance(); + } + } + + /// <exception cref="System.IO.IOException"></exception> + public static int Readn(InputStream @in, byte[] b, int off, int len) + { + int i = 0; + int n = -5; + while (i < len) + { + n = @in.Read(b, off + i, len - i); + if (n <= 0) + { + break; + } + i += n; + } + return i; + } + + internal int State; + + internal string Name = "Transport" + Id++; + + internal Thread Thread; + + internal TransportException Te; + + protected internal Hashtable ResponseMap = new Hashtable(); + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract void MakeKey(ServerMessageBlock request); + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract ServerMessageBlock PeekKey(); + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract void DoSend(ServerMessageBlock request); + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract void DoRecv(Response response); + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract void DoSkip(); + + /// <exception cref="System.IO.IOException"></exception> + public virtual void Sendrecv(ServerMessageBlock request, Response response, long timeout) + { + lock (this) + { + MakeKey(request); + response.IsReceived = false; + try + { + ResponseMap.Put(request, response); + DoSend(request); + response.Expiration = Runtime.CurrentTimeMillis() + timeout; + while (!response.IsReceived) + { + Runtime.Wait(this, timeout); + timeout = response.Expiration - Runtime.CurrentTimeMillis(); + if (timeout <= 0) + { + throw new TransportException(Name + " timedout waiting for response to " + request + ); + } + } + } + catch (IOException ioe) + { + if (Log.Level > 2) + { + Runtime.PrintStackTrace(ioe, Log); + } + try + { + Disconnect(true); + } + catch (IOException ioe2) + { + Runtime.PrintStackTrace(ioe2, Log); + } + throw; + } + catch (Exception ie) + { + throw new TransportException(ie); + } + finally + { + //Sharpen.Collections.Remove(response_map, request); + ResponseMap.Remove(request); + } + } + } + + private void Loop() + { + while (Thread == Thread.CurrentThread()) + { + try + { + ServerMessageBlock key = PeekKey(); + if (key == null) + { + throw new IOException("end of stream"); + } + + + lock (this) + { + Response response = (Response)ResponseMap.Get(key); + if (response == null) + { + if (Log.Level >= 4) + { + Log.WriteLine("Invalid key, skipping message"); + } + DoSkip(); + } + else + { + DoRecv(response); + response.IsReceived = true; + Runtime.NotifyAll(this); + } + } + } + catch (Exception ex) + { + string msg = ex.Message; + bool timeout = msg != null && msg.Equals("Read timed out"); + bool hard = timeout == false; + if (!timeout && Log.Level >= 3) + { + Runtime.PrintStackTrace(ex, Log); + } + try + { + Disconnect(hard); + } + catch (IOException ioe) + { + Runtime.PrintStackTrace(ioe, Log); + } + } + } + } + + /// <exception cref="System.Exception"></exception> + protected internal abstract void DoConnect(); + + /// <exception cref="System.IO.IOException"></exception> + protected internal abstract void DoDisconnect(bool hard); + + /// <exception cref="SharpCifs.Util.Transport.TransportException"></exception> + public virtual void Connect(long timeout) + { + lock (this) + { + try + { + switch (State) + { + case 0: + { + break; + } + + case 3: + { + return; + } + + case 4: + { + // already connected + State = 0; + throw new TransportException("Connection in error", Te); + } + + default: + { + //TransportException te = new TransportException("Invalid state: " + state); + State = 0; + throw new TransportException("Invalid state: " + State); + } + } + State = 1; + Te = null; + Thread = new Thread(this); + Thread.SetDaemon(true); + lock (Thread) + { + Thread.Start(); + Runtime.Wait(Thread, timeout); + switch (State) + { + case 1: + { + State = 0; + Thread = null; + throw new TransportException("Connection timeout"); + } + + case 2: + { + if (Te != null) + { + State = 4; + Thread = null; + throw Te; + } + State = 3; + return; + } + } + } + } + catch (Exception ie) + { + State = 0; + Thread = null; + throw new TransportException(ie); + } + finally + { + if (State != 0 && State != 3 && State != 4) + { + if (Log.Level >= 1) + { + Log.WriteLine("Invalid state: " + State); + } + State = 0; + Thread = null; + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual void Disconnect(bool hard) + { + + if (hard) + { + IOException ioe = null; + switch (State) + { + case 0: + { + return; + } + + case 2: + { + hard = true; + goto case 3; + } + + case 3: + { + if (ResponseMap.Count != 0 && !hard) + { + break; + } + try + { + DoDisconnect(hard); + } + catch (IOException ioe0) + { + ioe = ioe0; + } + goto case 4; + } + + case 4: + { + Thread = null; + State = 0; + break; + } + + default: + { + if (Log.Level >= 1) + { + Log.WriteLine("Invalid state: " + State); + } + Thread = null; + State = 0; + break; + } + } + if (ioe != null) + { + throw ioe; + } + + return; + } + + lock (this) + { + IOException ioe = null; + switch (State) + { + case 0: + { + return; + } + + case 2: + { + hard = true; + goto case 3; + } + + case 3: + { + if (ResponseMap.Count != 0 && !hard) + { + break; + } + try + { + DoDisconnect(hard); + } + catch (IOException ioe0) + { + ioe = ioe0; + } + goto case 4; + } + + case 4: + { + Thread = null; + State = 0; + break; + } + + default: + { + if (Log.Level >= 1) + { + Log.WriteLine("Invalid state: " + State); + } + Thread = null; + State = 0; + break; + } + } + if (ioe != null) + { + throw ioe; + } + } + } + + public virtual void Run() + { + Thread runThread = Thread.CurrentThread(); + Exception ex0 = null; + try + { + DoConnect(); + } + catch (Exception ex) + { + ex0 = ex; + // Defer to below where we're locked + return; + } + finally + { + lock (runThread) + { + if (runThread != Thread) + { + if (ex0 != null) + { + if (Log.Level >= 2) + { + Runtime.PrintStackTrace(ex0, Log); + } + } + //return; + } + if (ex0 != null) + { + Te = new TransportException(ex0); + } + State = 2; + // run connected + Runtime.Notify(runThread); + } + } + Loop(); + } + + public override string ToString() + { + return Name; + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/TransportException.cs b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/TransportException.cs new file mode 100644 index 000000000..bd0455197 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Util/Transport/TransportException.cs @@ -0,0 +1,63 @@ +// This code is derived from jcifs smb client library <jcifs at samba dot org> +// Ported by J. Arturo <webmaster at komodosoft dot net> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +using System; +using System.IO; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Util.Transport +{ + + public class TransportException : IOException + { + private Exception _rootCause; + + public TransportException() + { + } + + public TransportException(string msg) : base(msg) + { + } + + public TransportException(Exception rootCause) + { + this._rootCause = rootCause; + } + + public TransportException(string msg, Exception rootCause) : base(msg) + { + this._rootCause = rootCause; + } + + public virtual Exception GetRootCause() + { + return _rootCause; + } + + public override string ToString() + { + if (_rootCause != null) + { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Runtime.PrintStackTrace(_rootCause, pw); + return base.ToString() + "\n" + sw; + } + return base.ToString(); + } + } +} diff --git a/Emby.Server.Implementations/IO/SharpCifsFileSystem.cs b/Emby.Server.Implementations/IO/SharpCifsFileSystem.cs new file mode 100644 index 000000000..1d21796b1 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifsFileSystem.cs @@ -0,0 +1,604 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using MediaBrowser.Model.IO; +using SharpCifs.Smb; + +namespace Emby.Server.Implementations.IO +{ + public class SharpCifsFileSystem + { + private readonly MediaBrowser.Model.System.OperatingSystem _operatingSystem; + + public SharpCifsFileSystem(MediaBrowser.Model.System.OperatingSystem operatingSystem) + { + _operatingSystem = operatingSystem; + } + + public bool IsEnabledForPath(string path) + { + if (_operatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + { + return false; + } + + return path.StartsWith("smb://", StringComparison.OrdinalIgnoreCase) || IsUncPath(path); + } + + public string NormalizePath(string path) + { + if (path.StartsWith("smb://", StringComparison.OrdinalIgnoreCase)) + { + return path; + } + + if (IsUncPath(path)) + { + return ConvertUncToSmb(path); + } + + return path; + } + + public string GetDirectoryName(string path) + { + var separator = GetDirectorySeparatorChar(path); + var result = Path.GetDirectoryName(path); + + if (separator == '/') + { + result = result.Replace('\\', '/'); + + if (result.StartsWith("smb:/", StringComparison.OrdinalIgnoreCase) && !result.StartsWith("smb://", StringComparison.OrdinalIgnoreCase)) + { + result = result.Replace("smb:/", "smb://"); + } + } + + return result; + } + + public char GetDirectorySeparatorChar(string path) + { + if (path.IndexOf('/') != -1) + { + return '/'; + } + + return '\\'; + } + + public FileSystemMetadata GetFileSystemInfo(string path) + { + var file = CreateSmbFile(path); + return ToMetadata(file); + } + + public FileSystemMetadata GetFileInfo(string path) + { + var file = CreateSmbFile(path); + return ToMetadata(file, false); + } + + public FileSystemMetadata GetDirectoryInfo(string path) + { + var file = CreateSmbFile(path); + return ToMetadata(file, true); + } + + private bool IsUncPath(string path) + { + return path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase); + } + + private string GetReturnPath(SmbFile file) + { + return file.GetCanonicalPath().TrimEnd('/'); + //return file.GetPath(); + } + + private string ConvertUncToSmb(string path) + { + if (IsUncPath(path)) + { + path = path.Replace('\\', '/'); + path = "smb:" + path; + } + return path; + } + + private string AddAuthentication(string path) + { + return path; + } + + private SmbFile CreateSmbFile(string path) + { + path = ConvertUncToSmb(path); + path = AddAuthentication(path); + + return new SmbFile(path); + } + + DateTime baseDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + private FileSystemMetadata ToMetadata(SmbFile info, bool? isDirectory = null) + { + var result = new FileSystemMetadata(); + + result.Exists = info.Exists(); + result.FullName = GetReturnPath(info); + result.Extension = Path.GetExtension(result.FullName); + result.Name = info.GetName(); + + if (result.Exists) + { + result.IsDirectory = info.IsDirectory(); + result.IsHidden = info.IsHidden(); + + result.IsReadOnly = !info.CanWrite(); + + if (info.IsFile()) + { + result.Length = info.Length(); + result.DirectoryName = info.GetParent(); + } + + result.CreationTimeUtc = baseDate.AddMilliseconds(info.CreateTime()); + result.LastWriteTimeUtc = baseDate.AddMilliseconds(info.GetLastModified()); + } + else + { + if (isDirectory.HasValue) + { + result.IsDirectory = isDirectory.Value; + } + } + + return result; + } + + public void SetHidden(string path, bool isHidden) + { + var file = CreateSmbFile(path); + SetHidden(file, isHidden); + } + + public void SetReadOnly(string path, bool isReadOnly) + { + var file = CreateSmbFile(path); + SetReadOnly(file, isReadOnly); + } + + public void SetAttributes(string path, bool isHidden, bool isReadOnly) + { + var file = CreateSmbFile(path); + SetHidden(file, isHidden); + SetReadOnly(file, isReadOnly); + } + + private void SetHidden(SmbFile file, bool isHidden) + { + var isCurrentlyHidden = file.IsHidden(); + + if (isCurrentlyHidden && !isHidden) + { + file.SetAttributes(file.GetAttributes() & ~SmbFile.AttrHidden); + } + else if (!isCurrentlyHidden && isHidden) + { + file.SetAttributes(file.GetAttributes() | SmbFile.AttrHidden); + } + } + + private void SetReadOnly(SmbFile file, bool isReadOnly) + { + var isCurrentlyReadOnly = !file.CanWrite(); + + if (isCurrentlyReadOnly && !isReadOnly) + { + file.SetReadWrite(); + } + else if (!isCurrentlyReadOnly && isReadOnly) + { + file.SetReadOnly(); + } + } + + public void DeleteFile(string path) + { + var file = CreateSmbFile(path); + + AssertFileExists(file, path); + + file.Delete(); + } + + public void DeleteDirectory(string path, bool recursive) + { + var file = CreateSmbFile(path); + + AssertDirectoryExists(file, path); + + file.Delete(); + } + + public void CreateDirectory(string path) + { + } + + public string[] ReadAllLines(string path) + { + var lines = new List<string>(); + + using (var stream = OpenRead(path)) + { + using (var reader = new StreamReader(stream)) + { + while (!reader.EndOfStream) + { + lines.Add(reader.ReadLine()); + } + } + } + + return lines.ToArray(); + } + + public void WriteAllLines(string path, IEnumerable<string> lines) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + using (var writer = new StreamWriter(stream)) + { + foreach (var line in lines) + { + writer.WriteLine(line); + } + } + } + } + + private void AssertFileExists(SmbFile file, string path) + { + if (!file.Exists()) + { + throw new FileNotFoundException("File not found.", path); + } + } + + private void AssertDirectoryExists(SmbFile file, string path) + { + if (!file.Exists()) + { + throw new FileNotFoundException("File not found.", path); + } + } + + public Stream OpenRead(string path) + { + var file = CreateSmbFile(path); + + AssertFileExists(file, path); + + return file.GetInputStream(); + } + + private Stream OpenWrite(string path) + { + var file = CreateSmbFile(path); + + AssertFileExists(file, path); + + return file.GetInputStream(); + } + + public void CopyFile(string source, string target, bool overwrite) + { + if (string.Equals(source, target, StringComparison.Ordinal)) + { + throw new ArgumentException("Cannot CopyFile when source and target are the same"); + } + + using (var input = OpenRead(source)) + { + using (var output = GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + input.CopyTo(output); + } + } + } + + public void MoveFile(string source, string target) + { + if (string.Equals(source, target, StringComparison.Ordinal)) + { + throw new ArgumentException("Cannot MoveFile when source and target are the same"); + } + + using (var input = OpenRead(source)) + { + using (var output = GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + input.CopyTo(output); + } + } + + DeleteFile(source); + } + + public void MoveDirectory(string source, string target) + { + throw new NotImplementedException(); + } + + public bool DirectoryExists(string path) + { + var dir = CreateSmbFile(path); + + return dir.Exists() && dir.IsDirectory(); + } + + public bool FileExists(string path) + { + var file = CreateSmbFile(path); + return file.Exists(); + } + + public string ReadAllText(string path, Encoding encoding) + { + using (var stream = OpenRead(path)) + { + using (var reader = new StreamReader(stream, encoding)) + { + return reader.ReadToEnd(); + } + } + } + + public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share) + { + if (mode == FileOpenMode.OpenOrCreate) + { + var file = CreateSmbFile(path); + if (!file.Exists()) + { + file.CreateNewFile(); + } + + mode = FileOpenMode.Open; + } + + if (mode == FileOpenMode.CreateNew) + { + var file = CreateSmbFile(path); + if (file.Exists()) + { + throw new IOException("File already exists"); + } + + file.CreateNewFile(); + + mode = FileOpenMode.Open; + } + + if (mode == FileOpenMode.Create) + { + var file = CreateSmbFile(path); + if (file.Exists()) + { + if (file.IsHidden()) + { + throw new UnauthorizedAccessException(string.Format("File {0} already exists and is hidden", path)); + } + + file.Delete(); + file.CreateNewFile(); + } + else + { + file.CreateNewFile(); + } + + mode = FileOpenMode.Open; + } + + if (mode == FileOpenMode.Open) + { + if (access == FileAccessMode.Read) + { + return OpenRead(path); + } + if (access == FileAccessMode.Write) + { + return OpenWrite(path); + } + throw new NotImplementedException(); + } + throw new NotImplementedException(); + } + + public void WriteAllBytes(string path, byte[] bytes) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + stream.Write(bytes, 0, bytes.Length); + } + } + + public void WriteAllText(string path, string text) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + using (var writer = new StreamWriter(stream)) + { + writer.Write(text); + } + } + } + + public void WriteAllText(string path, string text, Encoding encoding) + { + using (var stream = GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None)) + { + using (var writer = new StreamWriter(stream, encoding)) + { + writer.Write(text); + } + } + } + + public string ReadAllText(string path) + { + using (var stream = OpenRead(path)) + { + using (var reader = new StreamReader(stream)) + { + return reader.ReadToEnd(); + } + } + } + + public byte[] ReadAllBytes(string path) + { + using (var stream = OpenRead(path)) + { + using (var ms = new MemoryStream()) + { + stream.CopyTo(ms); + ms.Position = 0; + return ms.ToArray(); + } + } + } + + private SmbFile CreateSmbDirectoryForListFiles(string path) + { + // In order to call ListFiles, it has to end with the separator + + return CreateSmbFile(path.TrimEnd('/') + '/'); + } + + public IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false) + { + var dir = CreateSmbDirectoryForListFiles(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsDirectory()) + { + yield return ToMetadata(file); + } + } + } + + public IEnumerable<FileSystemMetadata> GetFiles(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + var dir = CreateSmbDirectoryForListFiles(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsFile()) + { + var filePath = GetReturnPath(file); + var extension = Path.GetExtension(filePath); + + if (extensions == null || extensions.Length == 0 || extensions.Contains(extension ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + yield return ToMetadata(file); + } + } + } + } + + public IEnumerable<FileSystemMetadata> GetFileSystemEntries(string path, bool recursive = false) + { + var dir = CreateSmbDirectoryForListFiles(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + yield return ToMetadata(file); + } + } + + public IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false) + { + var dir = CreateSmbDirectoryForListFiles(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + yield return GetReturnPath(file); + } + } + + public IEnumerable<string> GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + var dir = CreateSmbDirectoryForListFiles(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsFile()) + { + var filePath = GetReturnPath(file); + var extension = Path.GetExtension(filePath); + + if (extensions == null || extensions.Length == 0 || extensions.Contains(extension ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + yield return filePath; + } + } + } + } + + public IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false) + { + var dir = CreateSmbDirectoryForListFiles(path); + AssertDirectoryExists(dir, path); + + var list = ListFiles(dir, recursive); + + foreach (var file in list) + { + if (file.IsDirectory()) + { + yield return GetReturnPath(file); + } + } + } + + private IEnumerable<SmbFile> ListFiles(SmbFile dir, bool recursive) + { + var list = dir.ListFiles(); + + foreach (var file in list) + { + yield return file; + + if (recursive && file.IsDirectory()) + { + foreach (var subFile in ListFiles(file, recursive)) + { + yield return subFile; + } + } + } + } + } +} diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index b8ce23a42..3f9ea79c6 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -37,12 +37,12 @@ namespace Emby.Server.Implementations.Images ImageProcessor = imageProcessor; } - protected virtual bool Supports(IHasImages item) + protected virtual bool Supports(IHasMetadata item) { return true; } - public virtual IEnumerable<ImageType> GetSupportedImages(IHasImages item) + public virtual IEnumerable<ImageType> GetSupportedImages(IHasMetadata item) { return new List<ImageType> { @@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.Images }; } - private IEnumerable<ImageType> GetEnabledImages(IHasImages item) + private IEnumerable<ImageType> GetEnabledImages(IHasMetadata item) { //var options = ProviderManager.GetMetadataOptions(item); @@ -84,7 +84,7 @@ namespace Emby.Server.Implementations.Images return updateType; } - protected async Task<ItemUpdateType> FetchAsync(IHasImages item, ImageType imageType, MetadataRefreshOptions options, CancellationToken cancellationToken) + protected async Task<ItemUpdateType> FetchAsync(IHasMetadata item, ImageType imageType, MetadataRefreshOptions options, CancellationToken cancellationToken) { var image = item.GetImageInfo(imageType, 0); @@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.Images return await FetchToFileInternal(item, items, imageType, cancellationToken).ConfigureAwait(false); } - protected async Task<ItemUpdateType> FetchToFileInternal(IHasImages item, + protected async Task<ItemUpdateType> FetchToFileInternal(IHasMetadata item, List<BaseItem> itemsWithImages, ImageType imageType, CancellationToken cancellationToken) @@ -132,14 +132,14 @@ namespace Emby.Server.Implementations.Images return ItemUpdateType.ImageUpdate; } - protected abstract List<BaseItem> GetItemsWithImages(IHasImages item); + protected abstract List<BaseItem> GetItemsWithImages(IHasMetadata item); - protected string CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath) + protected string CreateThumbCollage(IHasMetadata primaryItem, List<BaseItem> items, string outputPath) { return CreateCollage(primaryItem, items, outputPath, 640, 360); } - protected virtual IEnumerable<string> GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable<BaseItem> items) + protected virtual IEnumerable<string> GetStripCollageImagePaths(IHasMetadata primaryItem, IEnumerable<BaseItem> items) { return items .Select(i => @@ -161,22 +161,22 @@ namespace Emby.Server.Implementations.Images .Where(i => !string.IsNullOrWhiteSpace(i)); } - protected string CreatePosterCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath) + protected string CreatePosterCollage(IHasMetadata primaryItem, List<BaseItem> items, string outputPath) { return CreateCollage(primaryItem, items, outputPath, 400, 600); } - protected string CreateSquareCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath) + protected string CreateSquareCollage(IHasMetadata primaryItem, List<BaseItem> items, string outputPath) { return CreateCollage(primaryItem, items, outputPath, 600, 600); } - protected string CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height) + protected string CreateThumbCollage(IHasMetadata primaryItem, List<BaseItem> items, string outputPath, int width, int height) { return CreateCollage(primaryItem, items, outputPath, width, height); } - private string CreateCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height) + private string CreateCollage(IHasMetadata primaryItem, List<BaseItem> items, string outputPath, int width, int height) { FileSystem.CreateDirectory(FileSystem.GetDirectoryName(outputPath)); @@ -207,7 +207,7 @@ namespace Emby.Server.Implementations.Images get { return "Dynamic Image Provider"; } } - protected virtual string CreateImage(IHasImages item, + protected virtual string CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, @@ -267,7 +267,7 @@ namespace Emby.Server.Implementations.Images return false; } - protected bool HasChanged(IHasImages item, ImageType type) + protected bool HasChanged(IHasMetadata item, ImageType type) { var image = item.GetImageInfo(type, 0); @@ -293,20 +293,16 @@ namespace Emby.Server.Implementations.Images return true; } - protected List<BaseItem> GetFinalItems(List<BaseItem> items) + protected List<BaseItem> GetFinalItems(IEnumerable<BaseItem> items) { return GetFinalItems(items, 4); } - protected virtual List<BaseItem> GetFinalItems(List<BaseItem> items, int limit) + protected virtual List<BaseItem> GetFinalItems(IEnumerable<BaseItem> items, int limit) { - // Rotate the images once every x days - var random = DateTime.Now.DayOfYear % MaxImageAgeDays; - return items - .OrderBy(i => (random + string.Empty + items.IndexOf(i)).GetMD5()) + .OrderBy(i => Guid.NewGuid()) .Take(limit) - .OrderBy(i => i.Name) .ToList(); } diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 4846a5768..8c5ecf782 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -136,14 +136,6 @@ namespace Emby.Server.Implementations.Library /// <value>The configuration manager.</value> private IServerConfigurationManager ConfigurationManager { get; set; } - /// <summary> - /// A collection of items that may be referenced from multiple physical places in the library - /// (typically, multiple user roots). We store them here and be sure they all reference a - /// single instance. - /// </summary> - /// <value>The by reference items.</value> - private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; } - private readonly Func<ILibraryMonitor> _libraryMonitorFactory; private readonly Func<IProviderManager> _providerManagerFactory; private readonly Func<IUserViewManager> _userviewManager; @@ -186,7 +178,6 @@ namespace Emby.Server.Implementations.Library _fileSystem = fileSystem; _providerManagerFactory = providerManagerFactory; _userviewManager = userviewManager; - ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>(); _libraryItemsCache = new ConcurrentDictionary<Guid, BaseItem>(); ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated; @@ -362,7 +353,7 @@ namespace Emby.Server.Implementations.Library } else { - if (item is Photo) + if (!(item is Video)) { return; } @@ -470,10 +461,10 @@ namespace Emby.Server.Implementations.Library parent.RemoveChild(item); } - await ItemRepository.DeleteItem(item.Id, CancellationToken.None).ConfigureAwait(false); + ItemRepository.DeleteItem(item.Id, CancellationToken.None); foreach (var child in children) { - await ItemRepository.DeleteItem(child.Id, CancellationToken.None).ConfigureAwait(false); + ItemRepository.DeleteItem(child.Id, CancellationToken.None); } BaseItem removed; @@ -560,22 +551,6 @@ namespace Emby.Server.Implementations.Library return key.GetMD5(); } - /// <summary> - /// Ensure supplied item has only one instance throughout - /// </summary> - /// <param name="item">The item.</param> - /// <returns>The proper instance to the item</returns> - public BaseItem GetOrAddByReferenceItem(BaseItem item) - { - // Add this item to our list if not there already - if (!ByReferenceItems.TryAdd(item.Id, item)) - { - // Already there - return the existing reference - item = ByReferenceItems[item.Id]; - } - return item; - } - public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null) { @@ -624,18 +599,16 @@ namespace Emby.Server.Implementations.Library // When resolving the root, we need it's grandchildren (children of user views) var flattenFolderDepth = isPhysicalRoot ? 2 : 0; - var fileSystemDictionary = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); + var files = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); // Need to remove subpaths that may have been resolved from shortcuts // Example: if \\server\movies exists, then strip out \\server\movies\action if (isPhysicalRoot) { - var paths = NormalizeRootPathList(fileSystemDictionary.Values); - - fileSystemDictionary = paths.ToDictionary(i => i.FullName); + files = NormalizeRootPathList(files).ToArray(); } - args.FileSystemDictionary = fileSystemDictionary; + args.FileSystemChildren = files; } // Check to see if we should resolve based on our contents @@ -681,7 +654,7 @@ namespace Emby.Server.Implementations.Library return false; } - public IEnumerable<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths) + public List<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths) { var originalList = paths.ToList(); @@ -873,8 +846,7 @@ namespace Emby.Server.Implementations.Library { Path = path, IsFolder = isFolder, - SortBy = new[] { ItemSortBy.DateCreated }, - SortOrder = SortOrder.Descending, + OrderBy = new[] { ItemSortBy.DateCreated }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(), Limit = 1, DtoOptions = new DtoOptions(true) }; @@ -1024,8 +996,7 @@ namespace Emby.Server.Implementations.Library Path = path }; - var task = CreateItem(item, CancellationToken.None); - Task.WaitAll(task); + CreateItem(item, CancellationToken.None); } return item; @@ -1197,6 +1168,8 @@ namespace Emby.Server.Implementations.Library progress.Report(percent * 100); } + ItemRepository.UpdateInheritedValues(cancellationToken); + progress.Report(100); } @@ -1231,7 +1204,7 @@ namespace Emby.Server.Implementations.Library .Where(i => string.Equals(ShortcutFileExtension, Path.GetExtension(i), StringComparison.OrdinalIgnoreCase)) .Select(_fileSystem.ResolveShortcut) .OrderBy(i => i) - .ToList(), + .ToArray(), CollectionType = GetCollectionType(dir) }; @@ -1298,7 +1271,7 @@ namespace Emby.Server.Implementations.Library return item; } - public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent) + public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent) { if (query.Recursive && query.ParentId.HasValue) { @@ -1317,7 +1290,7 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetItemList(query); } - public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query) + public List<BaseItem> GetItemList(InternalItemsQuery query) { return GetItemList(query, true); } @@ -1341,7 +1314,7 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetCount(query); } - public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents) + public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents) { SetTopParentIdsOrAncestors(query, parents); @@ -1515,9 +1488,11 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetItems(query); } + var list = ItemRepository.GetItemList(query); + return new QueryResult<BaseItem> { - Items = ItemRepository.GetItemList(query).ToArray() + Items = list.ToArray(list.Count) }; } @@ -1575,7 +1550,7 @@ namespace Emby.Server.Implementations.Library IncludeHidden = true, IncludeExternalContent = allowExternalContent - }, CancellationToken.None).Result.ToList(); + }, CancellationToken.None).Result; query.TopParentIds = userViews.SelectMany(i => GetTopParentIdsForQuery(i, user)).Select(i => i.ToString("N")).ToArray(); } @@ -1801,6 +1776,37 @@ namespace Emby.Server.Implementations.Library return orderedItems ?? items; } + public IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<Tuple<string, SortOrder>> orderByList) + { + var isFirst = true; + + IOrderedEnumerable<BaseItem> orderedItems = null; + + foreach (var orderBy in orderByList) + { + var comparer = GetComparer(orderBy.Item1, user); + if (comparer == null) + { + continue; + } + + var sortOrder = orderBy.Item2; + + if (isFirst) + { + orderedItems = sortOrder == SortOrder.Descending ? items.OrderByDescending(i => i, comparer) : items.OrderBy(i => i, comparer); + } + else + { + orderedItems = sortOrder == SortOrder.Descending ? orderedItems.ThenByDescending(i => i, comparer) : orderedItems.ThenBy(i => i, comparer); + } + + isFirst = false; + } + + return orderedItems ?? items; + } + /// <summary> /// Gets the comparer. /// </summary> @@ -1835,9 +1841,9 @@ namespace Emby.Server.Implementations.Library /// <param name="item">The item.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public Task CreateItem(BaseItem item, CancellationToken cancellationToken) + public void CreateItem(BaseItem item, CancellationToken cancellationToken) { - return CreateItems(new[] { item }, cancellationToken); + CreateItems(new[] { item }, cancellationToken); } /// <summary> @@ -1846,11 +1852,11 @@ namespace Emby.Server.Implementations.Library /// <param name="items">The items.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public async Task CreateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken) + public void CreateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken) { var list = items.ToList(); - await ItemRepository.SaveItems(list, cancellationToken).ConfigureAwait(false); + ItemRepository.SaveItems(list, cancellationToken); foreach (var item in list) { @@ -1893,7 +1899,7 @@ namespace Emby.Server.Implementations.Library var logName = item.LocationType == LocationType.Remote ? item.Name ?? item.Path : item.Path ?? item.Name; _logger.Debug("Saving {0} to database.", logName); - await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false); + ItemRepository.SaveItem(item, cancellationToken); RegisterItem(item); @@ -2090,7 +2096,7 @@ namespace Emby.Server.Implementations.Library private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24); //private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromMinutes(1); - public Task<UserView> GetNamedView(User user, + public UserView GetNamedView(User user, string name, string viewType, string sortName, @@ -2128,7 +2134,7 @@ namespace Emby.Server.Implementations.Library ForcedSortName = sortName }; - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); refresh = true; } @@ -2159,7 +2165,7 @@ namespace Emby.Server.Implementations.Library return item; } - public async Task<UserView> GetNamedView(User user, + public UserView GetNamedView(User user, string name, string parentId, string viewType, @@ -2196,7 +2202,7 @@ namespace Emby.Server.Implementations.Library item.DisplayParentId = new Guid(parentId); } - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); isNew = true; } @@ -2222,7 +2228,7 @@ namespace Emby.Server.Implementations.Library return item; } - public async Task<UserView> GetShadowView(BaseItem parent, + public UserView GetShadowView(BaseItem parent, string viewType, string sortName, CancellationToken cancellationToken) @@ -2261,7 +2267,7 @@ namespace Emby.Server.Implementations.Library item.DisplayParentId = parentId; - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); isNew = true; } @@ -2332,7 +2338,7 @@ namespace Emby.Server.Implementations.Library item.DisplayParentId = new Guid(parentId); } - await CreateItem(item, cancellationToken).ConfigureAwait(false); + CreateItem(item, cancellationToken); isNew = true; } @@ -2395,8 +2401,7 @@ namespace Emby.Server.Implementations.Library var resolver = new EpisodeResolver(GetNamingOptions(), new NullLogger()); - var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd || - episode.VideoType == VideoType.HdDvd; + var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd; var locationType = episode.LocationType; @@ -2593,7 +2598,7 @@ namespace Emby.Server.Implementations.Library { var namingOptions = GetNamingOptions(); - var files = owner.DetectIsInMixedFolder() ? new List<FileSystemMetadata>() : fileSystemChildren.Where(i => i.IsDirectory) + var files = owner.IsInMixedFolder ? new List<FileSystemMetadata>() : fileSystemChildren.Where(i => i.IsDirectory) .Where(i => string.Equals(i.Name, BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase)) .SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false)) .ToList(); @@ -2611,7 +2616,7 @@ namespace Emby.Server.Implementations.Library var resolvers = new IItemResolver[] { - new GenericVideoResolver<Trailer>(this) + new GenericVideoResolver<Trailer>(this, _fileSystem) }; return ResolvePaths(files, directoryService, null, new LibraryOptions(), null, resolvers) @@ -2632,7 +2637,7 @@ namespace Emby.Server.Implementations.Library return video; // Sort them so that the list can be easily compared for changes - }).OrderBy(i => i.Path).ToList(); + }).OrderBy(i => i.Path); } private static readonly string[] ExtrasSubfolderNames = new[] { "extras", "specials", "shorts", "scenes", "featurettes", "behind the scenes", "deleted scenes", "interviews" }; @@ -2674,7 +2679,7 @@ namespace Emby.Server.Implementations.Library return video; // Sort them so that the list can be easily compared for changes - }).OrderBy(i => i.Path).ToList(); + }).OrderBy(i => i.Path); } public string GetPathAfterNetworkSubstitution(string path, BaseItem ownerItem) @@ -2847,17 +2852,17 @@ namespace Emby.Server.Implementations.Library return ItemRepository.GetPeopleNames(query); } - public Task UpdatePeople(BaseItem item, List<PersonInfo> people) + public void UpdatePeople(BaseItem item, List<PersonInfo> people) { if (!item.SupportsPeople) { - return Task.FromResult(true); + return; } - return ItemRepository.UpdatePeople(item.Id, people); + ItemRepository.UpdatePeople(item.Id, people); } - public async Task<ItemImageInfo> ConvertImageToLocal(IHasImages item, ItemImageInfo image, int imageIndex) + public async Task<ItemImageInfo> ConvertImageToLocal(IHasMetadata item, ItemImageInfo image, int imageIndex) { foreach (var url in image.Path.Split('|')) { @@ -3083,7 +3088,7 @@ namespace Emby.Server.Implementations.Library var topLibraryFolders = GetUserRootFolder().Children.ToList(); var info = GetVirtualFolderInfo(virtualFolderPath, topLibraryFolders, null); - if (info.Locations.Count > 0 && info.Locations.Count != options.PathInfos.Length) + if (info.Locations.Length > 0 && info.Locations.Length != options.PathInfos.Length) { var list = options.PathInfos.ToList(); diff --git a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs index e64980dff..757e67eb4 100644 --- a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs +++ b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -45,7 +46,7 @@ namespace Emby.Server.Implementations.Library Recursive = true, DtoOptions = new DtoOptions(false) - }).ToArray(); + }); var numComplete = 0; @@ -64,7 +65,7 @@ namespace Emby.Server.Implementations.Library progress.Report(100); } - private async Task AssignTrailers(IHasTrailers item, BaseItem[] channelTrailers) + private async Task AssignTrailers(IHasTrailers item, IEnumerable<BaseItem> channelTrailers) { if (item is Game) { @@ -90,7 +91,7 @@ namespace Emby.Server.Implementations.Library }); var trailerIds = trailers.Select(i => i.Id) - .ToList(); + .ToArray(); if (!trailerIds.SequenceEqual(item.RemoteTrailerIds)) { diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index c1360c887..d60a04353 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -49,10 +49,9 @@ namespace Emby.Server.Implementations.Library _providers = providers.ToArray(); } - public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query) + public List<MediaStream> GetMediaStreams(MediaStreamQuery query) { - var list = _itemRepo.GetMediaStreams(query) - .ToList(); + var list = _itemRepo.GetMediaStreams(query); foreach (var stream in list) { @@ -77,7 +76,7 @@ namespace Emby.Server.Implementations.Library return false; } - public IEnumerable<MediaStream> GetMediaStreams(string mediaSourceId) + public List<MediaStream> GetMediaStreams(string mediaSourceId) { var list = GetMediaStreams(new MediaStreamQuery { @@ -87,7 +86,7 @@ namespace Emby.Server.Implementations.Library return GetMediaStreamsForItem(list); } - public IEnumerable<MediaStream> GetMediaStreams(Guid itemId) + public List<MediaStream> GetMediaStreams(Guid itemId) { var list = GetMediaStreams(new MediaStreamQuery { @@ -97,7 +96,7 @@ namespace Emby.Server.Implementations.Library return GetMediaStreamsForItem(list); } - private IEnumerable<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams) + private List<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams) { var list = streams.ToList(); @@ -253,7 +252,7 @@ namespace Emby.Server.Implementations.Library return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); } - public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null) + public List<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null) { if (item == null) { @@ -265,7 +264,7 @@ namespace Emby.Server.Implementations.Library return item.GetMediaSources(enablePathSubstitution); } - var sources = item.GetMediaSources(enablePathSubstitution).ToList(); + var sources = item.GetMediaSources(enablePathSubstitution); if (user != null) { @@ -525,6 +524,7 @@ namespace Emby.Server.Implementations.Library public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } private readonly object _disposeLock = new object(); diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs index f0d07cc3c..1cbf4235a 100644 --- a/Emby.Server.Implementations/Library/MusicManager.cs +++ b/Emby.Server.Implementations/Library/MusicManager.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; using MediaBrowser.Controller.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; namespace Emby.Server.Implementations.Library @@ -19,27 +20,27 @@ namespace Emby.Server.Implementations.Library _libraryManager = libraryManager; } - public IEnumerable<Audio> GetInstantMixFromSong(Audio item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromSong(Audio item, User user, DtoOptions dtoOptions) { var list = new List<Audio> { item }; - return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions)); + return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions)).ToList(); } - public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromArtist(MusicArtist item, User user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromFolder(Folder item, User user, DtoOptions dtoOptions) { var genres = item .GetRecursiveChildren(user, new InternalItemsQuery(user) @@ -55,12 +56,12 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromGenres(genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromPlaylist(Playlist item, User user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions) { var genreIds = genres.DistinctNames().Select(i => { @@ -78,7 +79,7 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromGenreIds(genreIds, user, dtoOptions); } - public IEnumerable<Audio> GetInstantMixFromGenreIds(IEnumerable<string> genreIds, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromGenreIds(IEnumerable<string> genreIds, User user, DtoOptions dtoOptions) { return _libraryManager.GetItemList(new InternalItemsQuery(user) { @@ -88,14 +89,14 @@ namespace Emby.Server.Implementations.Library Limit = 200, - SortBy = new[] { ItemSortBy.Random }, + OrderBy = new [] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, DtoOptions = dtoOptions - }).Cast<Audio>(); + }); } - public IEnumerable<Audio> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions) + public List<BaseItem> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions) { var genre = item as MusicGenre; if (genre != null) @@ -133,7 +134,7 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromFolder(folder, user, dtoOptions); } - return new Audio[] { }; + return new List<BaseItem>(); } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index 9a5d6b105..fa4f026f4 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -6,6 +6,7 @@ using System; using System.IO; using System.Linq; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; namespace Emby.Server.Implementations.Library.Resolvers @@ -18,9 +19,11 @@ namespace Emby.Server.Implementations.Library.Resolvers where T : Video, new() { protected readonly ILibraryManager LibraryManager; + protected readonly IFileSystem FileSystem; - protected BaseVideoResolver(ILibraryManager libraryManager) + protected BaseVideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) { + FileSystem = fileSystem; LibraryManager = libraryManager; } @@ -178,11 +181,6 @@ namespace Emby.Server.Implementations.Library.Resolvers { video.VideoType = VideoType.Dvd; } - else if (string.Equals(videoInfo.StubType, "hddvd", StringComparison.OrdinalIgnoreCase)) - { - video.VideoType = VideoType.HdDvd; - video.IsHD = true; - } else if (string.Equals(videoInfo.StubType, "bluray", StringComparison.OrdinalIgnoreCase)) { video.VideoType = VideoType.BluRay; @@ -276,7 +274,7 @@ namespace Emby.Server.Implementations.Library.Resolvers return false; } - return directoryService.GetFilePaths(fullPath).Any(i => string.Equals(Path.GetExtension(i), ".vob", StringComparison.OrdinalIgnoreCase)); + return FileSystem.GetFilePaths(fullPath).Any(i => string.Equals(Path.GetExtension(i), ".vob", StringComparison.OrdinalIgnoreCase)); } /// <summary> diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 69563e5a0..1e5c0beed 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -23,11 +23,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies /// </summary> public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver { - public MovieResolver(ILibraryManager libraryManager) - : base(libraryManager) - { - } - /// <summary> /// Gets the priority. /// </summary> @@ -74,7 +69,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) { - return ResolveVideos<MusicVideo>(parent, files, directoryService, false, collectionType); + return ResolveVideos<MusicVideo>(parent, files, directoryService, true, collectionType); } if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) || @@ -164,8 +159,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies IsInMixedFolder = isInMixedFolder, ProductionYear = video.Year, Name = video.Name, - AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToList(), - LocalAlternateVersions = video.AlternateVersions.Select(i => i.Path).ToList() + AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToArray(), + LocalAlternateVersions = video.AlternateVersions.Select(i => i.Path).ToArray() }; SetVideoType(videoItem, firstVideo); @@ -452,8 +447,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies var folderPaths = multiDiscFolders.Select(i => i.FullName).Where(i => { - var subFileEntries = directoryService.GetFileSystemEntries(i) - .ToList(); + var subFileEntries = directoryService.GetFileSystemEntries(i); var subfolders = subFileEntries .Where(e => e.IsDirectory) @@ -509,7 +503,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies { Path = folderPaths[0], - AdditionalParts = folderPaths.Skip(1).ToList(), + AdditionalParts = folderPaths.Skip(1).ToArray(), VideoType = videoTypes[0], @@ -547,5 +541,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies return !validCollectionTypes.Contains(collectionType, StringComparer.OrdinalIgnoreCase); } + + public MovieResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) + { + } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 8bbda3b62..04312f277 100644 --- a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -44,7 +44,7 @@ namespace Emby.Server.Implementations.Library.Resolvers var filename = Path.GetFileNameWithoutExtension(args.Path); // Make sure the image doesn't belong to a video file - if (args.DirectoryService.GetFilePaths(_fileSystem.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename))) + if (_fileSystem.GetFilePaths(_fileSystem.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename))) { return null; } diff --git a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs index 6c7c1f052..6a1f8ec6f 100644 --- a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs @@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Library.Resolvers return new CollectionFolder { CollectionType = GetCollectionType(args), - PhysicalLocationsList = args.PhysicalLocations.ToList() + PhysicalLocationsList = args.PhysicalLocations }; } } diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index bdab8552a..7d1c4d65a 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using System.Linq; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; namespace Emby.Server.Implementations.Library.Resolvers.TV { @@ -11,10 +12,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV /// </summary> public class EpisodeResolver : BaseVideoResolver<Episode> { - public EpisodeResolver(ILibraryManager libraryManager) : base(libraryManager) - { - } - /// <summary> /// Resolves the specified args. /// </summary> @@ -76,5 +73,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV return null; } + + public EpisodeResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) + { + } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index 84ceac65e..830bd9d85 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -1,6 +1,8 @@ -using MediaBrowser.Controller.Configuration; +using System.Globalization; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Globalization; using MediaBrowser.Naming.Common; using MediaBrowser.Naming.TV; @@ -17,15 +19,18 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; + private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + private readonly ILocalizationManager _localization; /// <summary> /// Initializes a new instance of the <see cref="SeasonResolver"/> class. /// </summary> /// <param name="config">The config.</param> - public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager) + public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization) { _config = config; _libraryManager = libraryManager; + _localization = localization; } /// <summary> @@ -47,9 +52,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV SeriesName = series.Name }; - if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0) + if (season.IndexNumber.HasValue) { - season.Name = _config.Configuration.SeasonZeroDisplayName; + var seasonNumber = season.IndexNumber.Value; + + season.Name = seasonNumber == 0 ? + _config.Configuration.SeasonZeroDisplayName : + string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.ToString(UsCulture)); } return season; diff --git a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs index b5e1bf5f7..5c7a528f5 100644 --- a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; +using MediaBrowser.Model.IO; namespace Emby.Server.Implementations.Library.Resolvers { @@ -9,11 +10,6 @@ namespace Emby.Server.Implementations.Library.Resolvers /// </summary> public class VideoResolver : BaseVideoResolver<Video> { - public VideoResolver(ILibraryManager libraryManager) - : base(libraryManager) - { - } - protected override Video Resolve(ItemResolveArgs args) { if (args.Parent != null) @@ -33,12 +29,16 @@ namespace Emby.Server.Implementations.Library.Resolvers { get { return ResolverPriority.Last; } } + + public VideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) + { + } } public class GenericVideoResolver<T> : BaseVideoResolver<T> where T : Video, new () { - public GenericVideoResolver(ILibraryManager libraryManager) : base(libraryManager) + public GenericVideoResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager, fileSystem) { } } diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index 6f63322c8..b1ed034ca 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -10,6 +10,8 @@ using System.Linq; using System.Threading.Tasks; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Library { @@ -163,12 +165,12 @@ namespace Emby.Server.Implementations.Library var mediaItems = _libraryManager.GetItemList(new InternalItemsQuery(user) { NameContains = searchTerm, - ExcludeItemTypes = excludeItemTypes.ToArray(), - IncludeItemTypes = includeItemTypes.ToArray(), + ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count), + IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count), Limit = query.Limit, IncludeItemsByName = string.IsNullOrWhiteSpace(query.ParentId), ParentId = string.IsNullOrWhiteSpace(query.ParentId) ? (Guid?)null : new Guid(query.ParentId), - SortBy = new[] { ItemSortBy.SortName }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }, Recursive = true, IsKids = query.IsKids, @@ -180,7 +182,7 @@ namespace Emby.Server.Implementations.Library DtoOptions = new DtoOptions { - Fields = new List<ItemFields> + Fields = new ItemFields[] { ItemFields.AirTime, ItemFields.DateCreated, diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index e066ab61b..7ef5ca35e 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -41,7 +41,7 @@ namespace Emby.Server.Implementations.Library /// <value>The repository.</value> public IUserDataRepository Repository { get; set; } - public async Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) + public void SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) { if (userData == null) { @@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.Library foreach (var key in keys) { - await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false); + Repository.SaveUserData(userId, key, userData, cancellationToken); } var cacheKey = GetCacheKey(userId, item.Id); @@ -86,7 +86,7 @@ namespace Emby.Server.Implementations.Library /// <param name="userData"></param> /// <param name="cancellationToken"></param> /// <returns></returns> - public async Task SaveAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken) + public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken) { if (userData == null) { @@ -99,7 +99,7 @@ namespace Emby.Server.Implementations.Library cancellationToken.ThrowIfCancellationRequested(); - await Repository.SaveAllUserData(userId, userData, cancellationToken).ConfigureAwait(false); + Repository.SaveAllUserData(userId, userData, cancellationToken); } /// <summary> @@ -107,7 +107,7 @@ namespace Emby.Server.Implementations.Library /// </summary> /// <param name="userId"></param> /// <returns></returns> - public IEnumerable<UserItemData> GetAllUserData(Guid userId) + public List<UserItemData> GetAllUserData(Guid userId) { if (userId == Guid.Empty) { @@ -187,11 +187,11 @@ namespace Emby.Server.Implementations.Library var userData = GetUserData(user.Id, item); var dto = GetUserItemDataDto(userData); - item.FillUserDataDtoValues(dto, userData, null, user, new List<ItemFields>()); + item.FillUserDataDtoValues(dto, userData, null, user, new ItemFields[] { }); return dto; } - public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields) + public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, ItemFields[] fields) { var userData = GetUserData(user.Id, item); var dto = GetUserItemDataDto(userData); diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 8e8f8c4dc..e5fe2969f 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -71,9 +71,8 @@ namespace Emby.Server.Implementations.Library private readonly IServerApplicationHost _appHost; private readonly IFileSystem _fileSystem; private readonly ICryptoProvider _cryptographyProvider; - private readonly string _defaultUserName; - public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, string defaultUserName) + public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) { _logger = logger; UserRepository = userRepository; @@ -86,7 +85,6 @@ namespace Emby.Server.Implementations.Library _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; _cryptographyProvider = cryptographyProvider; - _defaultUserName = defaultUserName; ConfigurationManager = configurationManager; Users = new List<User>(); @@ -122,7 +120,7 @@ namespace Emby.Server.Implementations.Library /// <param name="user">The user.</param> private void OnUserDeleted(User user) { - EventHelper.QueueEventIfNotNull(UserDeleted, this, new GenericEventArgs<User> { Argument = user }, _logger); + EventHelper.FireEventIfNotNull(UserDeleted, this, new GenericEventArgs<User> { Argument = user }, _logger); } #endregion @@ -162,9 +160,9 @@ namespace Emby.Server.Implementations.Library return Users.FirstOrDefault(u => string.Equals(u.Name, name, StringComparison.OrdinalIgnoreCase)); } - public async Task Initialize() + public void Initialize() { - Users = await LoadUsers().ConfigureAwait(false); + Users = LoadUsers(); var users = Users.ToList(); @@ -176,7 +174,7 @@ namespace Emby.Server.Implementations.Library if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value == UserLinkType.LinkedUser) { user.Policy.IsAdministrator = true; - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, false); } } } @@ -296,12 +294,12 @@ namespace Emby.Server.Implementations.Library if (success) { user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow; - await UpdateUser(user).ConfigureAwait(false); - await UpdateInvalidLoginAttemptCount(user, 0).ConfigureAwait(false); + UpdateUser(user); + UpdateInvalidLoginAttemptCount(user, 0); } else { - await UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1).ConfigureAwait(false); + UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1); } _logger.Info("Authentication request for {0} {1}.", user.Name, success ? "has succeeded" : "has been denied"); @@ -309,7 +307,7 @@ namespace Emby.Server.Implementations.Library return success ? user : null; } - private async Task UpdateInvalidLoginAttemptCount(User user, int newValue) + private void UpdateInvalidLoginAttemptCount(User user, int newValue) { if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0) { @@ -329,7 +327,7 @@ namespace Emby.Server.Implementations.Library //fireLockout = true; } - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, false); if (fireLockout) { @@ -374,27 +372,27 @@ namespace Emby.Server.Implementations.Library /// Loads the users from the repository /// </summary> /// <returns>IEnumerable{User}.</returns> - private async Task<IEnumerable<User>> LoadUsers() + private List<User> LoadUsers() { var users = UserRepository.RetrieveAllUsers().ToList(); // There always has to be at least one user. if (users.Count == 0) { - var name = MakeValidUsername(_defaultUserName); + var name = MakeValidUsername(Environment.UserName); var user = InstantiateNewUser(name); user.DateLastSaved = DateTime.UtcNow; - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.SaveUser(user, CancellationToken.None); users.Add(user); user.Policy.IsAdministrator = true; user.Policy.EnableContentDeletion = true; user.Policy.EnableRemoteControlOfOtherUsers = true; - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, false); } return users; @@ -541,7 +539,7 @@ namespace Emby.Server.Implementations.Library /// <param name="user">The user.</param> /// <exception cref="System.ArgumentNullException">user</exception> /// <exception cref="System.ArgumentException"></exception> - public async Task UpdateUser(User user) + public void UpdateUser(User user) { if (user == null) { @@ -556,7 +554,7 @@ namespace Emby.Server.Implementations.Library user.DateModified = DateTime.UtcNow; user.DateLastSaved = DateTime.UtcNow; - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.SaveUser(user, CancellationToken.None); OnUserUpdated(user); } @@ -601,7 +599,7 @@ namespace Emby.Server.Implementations.Library user.DateLastSaved = DateTime.UtcNow; - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.SaveUser(user, CancellationToken.None); EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger); @@ -655,7 +653,7 @@ namespace Emby.Server.Implementations.Library { var configPath = GetConfigurationFilePath(user); - await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false); + UserRepository.DeleteUser(user, CancellationToken.None); try { @@ -669,7 +667,7 @@ namespace Emby.Server.Implementations.Library DeleteUserPolicy(user); // Force this to be lazy loaded again - Users = await LoadUsers().ConfigureAwait(false); + Users = LoadUsers(); OnUserDeleted(user); } @@ -683,17 +681,17 @@ namespace Emby.Server.Implementations.Library /// Resets the password by clearing it. /// </summary> /// <returns>Task.</returns> - public Task ResetPassword(User user) + public void ResetPassword(User user) { - return ChangePassword(user, GetSha1String(string.Empty)); + ChangePassword(user, GetSha1String(string.Empty)); } - public Task ResetEasyPassword(User user) + public void ResetEasyPassword(User user) { - return ChangeEasyPassword(user, GetSha1String(string.Empty)); + ChangeEasyPassword(user, GetSha1String(string.Empty)); } - public async Task ChangePassword(User user, string newPasswordSha1) + public void ChangePassword(User user, string newPasswordSha1) { if (user == null) { @@ -711,12 +709,12 @@ namespace Emby.Server.Implementations.Library user.Password = newPasswordSha1; - await UpdateUser(user).ConfigureAwait(false); + UpdateUser(user); EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger); } - public async Task ChangeEasyPassword(User user, string newPasswordSha1) + public void ChangeEasyPassword(User user, string newPasswordSha1) { if (user == null) { @@ -729,7 +727,7 @@ namespace Emby.Server.Implementations.Library user.EasyPassword = newPasswordSha1; - await UpdateUser(user).ConfigureAwait(false); + UpdateUser(user); EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger); } @@ -844,7 +842,7 @@ namespace Emby.Server.Implementations.Library }; } - public async Task<PinRedeemResult> RedeemPasswordResetPin(string pin) + public PinRedeemResult RedeemPasswordResetPin(string pin) { DeletePinFile(); @@ -865,12 +863,12 @@ namespace Emby.Server.Implementations.Library foreach (var user in users) { - await ResetPassword(user).ConfigureAwait(false); + ResetPassword(user); if (user.Policy.IsDisabled) { user.Policy.IsDisabled = false; - await UpdateUserPolicy(user, user.Policy, true).ConfigureAwait(false); + UpdateUserPolicy(user, user.Policy, true); } usersReset.Add(user.Name); } @@ -947,13 +945,13 @@ namespace Emby.Server.Implementations.Library } private readonly object _policySyncLock = new object(); - public Task UpdateUserPolicy(string userId, UserPolicy userPolicy) + public void UpdateUserPolicy(string userId, UserPolicy userPolicy) { var user = GetUserById(userId); - return UpdateUserPolicy(user, userPolicy, true); + UpdateUserPolicy(user, userPolicy, true); } - private async Task UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent) + private void UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent) { // The xml serializer will output differently if the type is not exact if (userPolicy.GetType() != typeof(UserPolicy)) @@ -972,7 +970,7 @@ namespace Emby.Server.Implementations.Library user.Policy = userPolicy; } - await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false); + UpdateConfiguration(user, user.Configuration, true); } private void DeleteUserPolicy(User user) @@ -1034,13 +1032,13 @@ namespace Emby.Server.Implementations.Library } private readonly object _configSyncLock = new object(); - public Task UpdateConfiguration(string userId, UserConfiguration config) + public void UpdateConfiguration(string userId, UserConfiguration config) { var user = GetUserById(userId); - return UpdateConfiguration(user, config, true); + UpdateConfiguration(user, config, true); } - private async Task UpdateConfiguration(User user, UserConfiguration config, bool fireEvent) + private void UpdateConfiguration(User user, UserConfiguration config, bool fireEvent) { var path = GetConfigurationFilePath(user); diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index a6ed84f29..8c9377291 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Library { @@ -38,7 +39,7 @@ namespace Emby.Server.Implementations.Library _config = config; } - public async Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken) + public async Task<Folder[]> GetUserViews(UserViewQuery query, CancellationToken cancellationToken) { var user = _userManager.GetUserById(query.UserId); @@ -67,7 +68,7 @@ namespace Emby.Server.Implementations.Library if (UserView.IsUserSpecific(folder)) { - list.Add(await _libraryManager.GetNamedView(user, folder.Name, folder.Id.ToString("N"), folderViewType, null, cancellationToken).ConfigureAwait(false)); + list.Add(_libraryManager.GetNamedView(user, folder.Name, folder.Id.ToString("N"), folderViewType, null, cancellationToken)); continue; } @@ -79,7 +80,7 @@ namespace Emby.Server.Implementations.Library if (query.PresetViews.Contains(folderViewType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { - list.Add(await GetUserView(folder, folderViewType, string.Empty, cancellationToken).ConfigureAwait(false)); + list.Add(GetUserView(folder, folderViewType, string.Empty, cancellationToken)); } else { @@ -94,7 +95,7 @@ namespace Emby.Server.Implementations.Library if (parents.Count > 0) { - list.Add(await GetUserView(parents, viewType, string.Empty, user, query.PresetViews, cancellationToken).ConfigureAwait(false)); + list.Add(GetUserView(parents, viewType, string.Empty, user, query.PresetViews, cancellationToken)); } } @@ -113,7 +114,7 @@ namespace Emby.Server.Implementations.Library }, cancellationToken).ConfigureAwait(false); var channels = channelResult.Items; - + if (_config.Configuration.EnableChannelView && channels.Length > 0) { list.Add(await _channelManager.GetInternalChannelFolder(cancellationToken).ConfigureAwait(false)); @@ -153,7 +154,8 @@ namespace Emby.Server.Implementations.Library return index == -1 ? int.MaxValue : index; }) .ThenBy(sorted.IndexOf) - .ThenBy(i => i.SortName); + .ThenBy(i => i.SortName) + .ToArray(); } public Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken) @@ -170,7 +172,7 @@ namespace Emby.Server.Implementations.Library return GetUserSubView(name, parentId, type, sortName, cancellationToken); } - private async Task<Folder> GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, string[] presetViews, CancellationToken cancellationToken) + private Folder GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, string[] presetViews, CancellationToken cancellationToken) { if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase))) { @@ -179,14 +181,14 @@ namespace Emby.Server.Implementations.Library return (Folder)parents[0]; } - return await GetUserView((Folder)parents[0], viewType, string.Empty, cancellationToken).ConfigureAwait(false); + return GetUserView((Folder)parents[0], viewType, string.Empty, cancellationToken); } var name = _localizationManager.GetLocalizedString("ViewType" + viewType); - return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); + return _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken); } - public Task<UserView> GetUserView(Folder parent, string viewType, string sortName, CancellationToken cancellationToken) + public UserView GetUserView(Folder parent, string viewType, string sortName, CancellationToken cancellationToken) { return _libraryManager.GetShadowView(parent, viewType, sortName, cancellationToken); } @@ -231,7 +233,7 @@ namespace Emby.Server.Implementations.Library return list; } - private IEnumerable<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options) + private List<BaseItem> GetItemsForLatestItems(User user, LatestItemsQuery request, DtoOptions options) { var parentId = request.ParentId; @@ -269,7 +271,41 @@ namespace Emby.Server.Implementations.Library return new List<BaseItem>(); } - var excludeItemTypes = includeItemTypes.Length == 0 ? new[] + var mediaTypes = new List<string>(); + + if (includeItemTypes.Length == 0) + { + foreach (var parent in parents.OfType<ICollectionFolder>()) + { + switch (parent.CollectionType) + { + case CollectionType.Books: + mediaTypes.Add(MediaType.Book); + break; + case CollectionType.Games: + mediaTypes.Add(MediaType.Game); + break; + case CollectionType.Music: + mediaTypes.Add(MediaType.Audio); + break; + case CollectionType.Photos: + mediaTypes.Add(MediaType.Photo); + mediaTypes.Add(MediaType.Video); + break; + case CollectionType.HomeVideos: + mediaTypes.Add(MediaType.Photo); + mediaTypes.Add(MediaType.Video); + break; + default: + mediaTypes.Add(MediaType.Video); + break; + } + } + + mediaTypes = mediaTypes.Distinct().ToList(); + } + + var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Count == 0 ? new[] { typeof(Person).Name, typeof(Studio).Name, @@ -283,14 +319,14 @@ namespace Emby.Server.Implementations.Library var query = new InternalItemsQuery(user) { IncludeItemTypes = includeItemTypes, - SortOrder = SortOrder.Descending, - SortBy = new[] { ItemSortBy.DateCreated }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) }, IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null, ExcludeItemTypes = excludeItemTypes, IsVirtualItem = false, Limit = limit * 5, IsPlayed = isPlayed, - DtoOptions = options + DtoOptions = options, + MediaTypes = mediaTypes.ToArray(mediaTypes.Count) }; if (parents.Count == 0) diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs index c2eb30ee4..39630cf96 100644 --- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -55,28 +55,21 @@ namespace Emby.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress) { - var people = _libraryManager.GetPeople(new InternalPeopleQuery()); - - var dict = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase); - - foreach (var person in people) - { - dict[person.Name] = true; - } + var people = _libraryManager.GetPeopleNames(new InternalPeopleQuery()); var numComplete = 0; - _logger.Debug("Will refresh {0} people", dict.Count); + var numPeople = people.Count; - var numPeople = dict.Count; + _logger.Debug("Will refresh {0} people", numPeople); - foreach (var person in dict) + foreach (var person in people) { cancellationToken.ThrowIfCancellationRequested(); try { - var item = _libraryManager.GetPerson(person.Key); + var item = _libraryManager.GetPerson(person); var options = new MetadataRefreshOptions(_fileSystem) { diff --git a/Emby.Server.Implementations/LiveTv/ChannelImageProvider.cs b/Emby.Server.Implementations/LiveTv/ChannelImageProvider.cs index 95cefd999..0c8049d8b 100644 --- a/Emby.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/Emby.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -28,12 +28,12 @@ namespace Emby.Server.Implementations.LiveTv _appHost = appHost; } - public IEnumerable<ImageType> GetSupportedImages(IHasImages item) + public IEnumerable<ImageType> GetSupportedImages(IHasMetadata item) { return new[] { ImageType.Primary }; } - public async Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken) + public async Task<DynamicImageResponse> GetImage(IHasMetadata item, ImageType type, CancellationToken cancellationToken) { var liveTvItem = (LiveTvChannel)item; @@ -67,7 +67,7 @@ namespace Emby.Server.Implementations.LiveTv get { return "Live TV Service Provider"; } } - public bool Supports(IHasImages item) + public bool Supports(IHasMetadata item) { return item is LiveTvChannel; } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 9ac599846..92a47bddc 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -208,7 +208,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV continue; } - if (virtualFolder.Locations.Count == 1) + if (virtualFolder.Locations.Length == 1) { // remove entire virtual folder try @@ -458,7 +458,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return GetEpgChannelFromTunerChannel(info, tunerChannel, epgChannels); } - private string GetMappedChannel(string channelId, List<NameValuePair> mappings) + private string GetMappedChannel(string channelId, NameValuePair[] mappings) { foreach (NameValuePair mapping in mappings) { @@ -472,10 +472,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private ChannelInfo GetEpgChannelFromTunerChannel(ListingsProviderInfo info, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels) { - return GetEpgChannelFromTunerChannel(info.ChannelMappings.ToList(), tunerChannel, epgChannels); + return GetEpgChannelFromTunerChannel(info.ChannelMappings, tunerChannel, epgChannels); } - public ChannelInfo GetEpgChannelFromTunerChannel(List<NameValuePair> mappings, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels) + public ChannelInfo GetEpgChannelFromTunerChannel(NameValuePair[] mappings, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels) { if (!string.IsNullOrWhiteSpace(tunerChannel.Id)) { @@ -607,20 +607,22 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var timer = _timerProvider.GetTimer(timerId); if (timer != null) { + timer.Status = RecordingStatus.Cancelled; + if (string.IsNullOrWhiteSpace(timer.SeriesTimerId) || isSeriesCancelled) { _timerProvider.Delete(timer); } else { - timer.Status = RecordingStatus.Cancelled; _timerProvider.AddOrUpdate(timer, false); } } ActiveRecordingInfo activeRecordingInfo; if (_activeRecordings.TryGetValue(timerId, out activeRecordingInfo)) - { + { + activeRecordingInfo.Timer = timer; activeRecordingInfo.CancellationTokenSource.Cancel(); } } @@ -830,6 +832,9 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV existingTimer.IsKids = updatedTimer.IsKids; existingTimer.IsNews = updatedTimer.IsNews; existingTimer.IsMovie = updatedTimer.IsMovie; + existingTimer.IsSeries = updatedTimer.IsSeries; + existingTimer.IsLive = updatedTimer.IsLive; + existingTimer.IsPremiere = updatedTimer.IsPremiere; existingTimer.IsProgramSeries = updatedTimer.IsProgramSeries; existingTimer.IsRepeat = updatedTimer.IsRepeat; existingTimer.IsSports = updatedTimer.IsSports; @@ -861,7 +866,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken) { - return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList(); + return new List<RecordingInfo>(); } public string GetActiveRecordingPath(string id) @@ -875,49 +880,31 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return null; } - private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info) - { - var timer = info.Timer; - var program = info.Program; - - var result = new RecordingInfo - { - ChannelId = timer.ChannelId, - CommunityRating = timer.CommunityRating, - DateLastUpdated = DateTime.UtcNow, - EndDate = timer.EndDate, - EpisodeTitle = timer.EpisodeTitle, - Genres = timer.Genres, - Id = "recording" + timer.Id, - IsKids = timer.IsKids, - IsMovie = timer.IsMovie, - IsNews = timer.IsNews, - IsRepeat = timer.IsRepeat, - IsSeries = timer.IsProgramSeries, - IsSports = timer.IsSports, - Name = timer.Name, - OfficialRating = timer.OfficialRating, - OriginalAirDate = timer.OriginalAirDate, - Overview = timer.Overview, - ProgramId = timer.ProgramId, - SeriesTimerId = timer.SeriesTimerId, - StartDate = timer.StartDate, - Status = RecordingStatus.InProgress, - TimerId = timer.Id - }; + public IEnumerable<ActiveRecordingInfo> GetAllActiveRecordings() + { + return _activeRecordings.Values.Where(i => i.Timer.Status == RecordingStatus.InProgress && !i.CancellationTokenSource.IsCancellationRequested); + } - if (program != null) + public ActiveRecordingInfo GetActiveRecordingInfo(string path) + { + if (string.IsNullOrWhiteSpace(path)) { - result.Audio = program.Audio; - result.ImagePath = program.ImagePath; - result.ImageUrl = program.ImageUrl; - result.IsHD = program.IsHD; - result.IsLive = program.IsLive; - result.IsPremiere = program.IsPremiere; - result.ShowId = program.ShowId; + return null; } - return result; + foreach (var recording in _activeRecordings.Values) + { + if (string.Equals(recording.Path, path, StringComparison.Ordinal) && !recording.CancellationTokenSource.IsCancellationRequested) + { + var timer = recording.Timer; + if (timer.Status != RecordingStatus.InProgress) + { + return null; + } + return recording; + } + } + return null; } public Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken) @@ -1245,6 +1232,33 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV throw new FileNotFoundException(); } + public async Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken) + { + var stream = new MediaSourceInfo + { + Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveRecordings/" + info.Id + "/stream", + Id = info.Id, + SupportsDirectPlay = false, + SupportsDirectStream = true, + SupportsTranscoding = true, + IsInfiniteStream = true, + RequiresOpening = false, + RequiresClosing = false, + Protocol = MediaBrowser.Model.MediaInfo.MediaProtocol.Http, + BufferMs = 0, + IgnoreDts = true, + IgnoreIndex = true + }; + + var isAudio = false; + await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false); + + return new List<MediaSourceInfo> + { + stream + }; + } + public async Task CloseLiveStream(string id, CancellationToken cancellationToken) { // Ignore the consumer id @@ -1327,7 +1341,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var activeRecordingInfo = new ActiveRecordingInfo { CancellationTokenSource = new CancellationTokenSource(), - Timer = timer + Timer = timer, + Id = timer.Id }; if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo)) @@ -1493,7 +1508,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath); recordPath = EnsureFileUnique(recordPath, timer.Id); - _libraryManager.RegisterIgnoredPath(recordPath); _libraryMonitor.ReportFileSystemChangeBeginning(recordPath); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(recordPath)); activeRecordingInfo.Path = recordPath; @@ -1512,6 +1526,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV _timerProvider.AddOrUpdate(timer, false); SaveRecordingMetadata(timer, recordPath, seriesPath); + TriggerRefresh(recordPath); EnforceKeepUpTo(timer, seriesPath); }; @@ -1543,7 +1558,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } - _libraryManager.UnRegisterIgnoredPath(recordPath); + TriggerRefresh(recordPath); _libraryMonitor.ReportFileSystemChangeComplete(recordPath, true); ActiveRecordingInfo removed; @@ -1574,6 +1589,44 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV OnRecordingStatusChanged(); } + private void TriggerRefresh(string path) + { + var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path)); + + if (item != null) + { + item.ChangedExternally(); + } + } + + private BaseItem GetAffectedBaseItem(string path) + { + BaseItem item = null; + + while (item == null && !string.IsNullOrEmpty(path)) + { + item = _libraryManager.FindByPath(path, null); + + path = _fileSystem.GetDirectoryName(path); + } + + if (item != null) + { + // If the item has been deleted find the first valid parent that still exists + while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path)) + { + item = item.GetParent(); + + if (item == null) + { + break; + } + } + } + + return item; + } + private void OnRecordingStatusChanged() { EventHelper.FireEventIfNotNull(RecordingStatusChanged, this, new RecordingStatusChangedEventArgs @@ -1632,17 +1685,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return; } - var episodesToDelete = (librarySeries.GetItems(new InternalItemsQuery + var episodesToDelete = (librarySeries.GetItemList(new InternalItemsQuery { - SortBy = new[] { ItemSortBy.DateCreated }, - SortOrder = SortOrder.Descending, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) }, IsVirtualItem = false, IsFolder = false, Recursive = true, DtoOptions = new DtoOptions(true) })) - .Items .Where(i => i.LocationType == LocationType.FileSystem && _fileSystem.FileExists(i.Path)) .Skip(seriesTimer.KeepUpTo - 1) .ToList(); @@ -1758,7 +1809,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { var config = GetConfiguration(); - var regInfo = await _liveTvManager.GetRegistrationInfo("embytvrecordingconversion").ConfigureAwait(false); + var regInfo = await _liveTvManager.GetRegistrationInfo("dvr").ConfigureAwait(false); if (regInfo.IsValid) { @@ -2579,6 +2630,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { pair.Value.CancellationTokenSource.Cancel(); } + GC.SuppressFinalize(this); } public List<VirtualFolderInfo> GetRecordingFolders() @@ -2592,7 +2644,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { list.Add(new VirtualFolderInfo { - Locations = new List<string> { defaultFolder }, + Locations = new string[] { defaultFolder }, Name = defaultName }); } @@ -2602,7 +2654,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { list.Add(new VirtualFolderInfo { - Locations = new List<string> { customPath }, + Locations = new string[] { customPath }, Name = "Recorded Movies", CollectionType = CollectionType.Movies }); @@ -2613,7 +2665,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { list.Add(new VirtualFolderInfo { - Locations = new List<string> { customPath }, + Locations = new string[] { customPath }, Name = "Recorded Shows", CollectionType = CollectionType.TvShows }); @@ -2622,14 +2674,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return list; } - class ActiveRecordingInfo - { - public string Path { get; set; } - public TimerInfo Timer { get; set; } - public ProgramInfo Program { get; set; } - public CancellationTokenSource CancellationTokenSource { get; set; } - } - private const int TunerDiscoveryDurationMs = 3000; public async Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 6173068cc..48eba4117 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -70,7 +70,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return "ts"; } - return "mp4"; + return "mkv"; } } @@ -207,9 +207,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV inputModifier += " -fflags " + string.Join("", flags.ToArray()); } - if (!string.IsNullOrWhiteSpace(GetEncodingOptions().HardwareAccelerationType)) + var videoStream = mediaSource.VideoStream; + var videoDecoder = videoStream == null ? null : new EncodingHelper(_mediaEncoder, _fileSystem, null).GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions()); + + if (!string.IsNullOrWhiteSpace(videoDecoder)) { - inputModifier += " -hwaccel auto"; + inputModifier += " " + videoDecoder; } if (mediaSource.ReadAtNativeFramerate) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs index 139cf570e..7c5f630a7 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Plugins; +using System; +using MediaBrowser.Controller.Plugins; namespace Emby.Server.Implementations.LiveTv.EmbyTV { @@ -11,6 +12,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public void Dispose() { + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 94be4a02e..b5de6ef01 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -58,6 +58,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV timerInfo.OriginalAirDate = programInfo.OriginalAirDate; timerInfo.IsProgramSeries = programInfo.IsSeries; + timerInfo.IsSeries = programInfo.IsSeries; + timerInfo.IsLive = programInfo.IsLive; + timerInfo.IsPremiere = programInfo.IsPremiere; + timerInfo.HomePageUrl = programInfo.HomePageUrl; timerInfo.CommunityRating = programInfo.CommunityRating; timerInfo.Overview = programInfo.Overview; diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index e12acf140..b7cfdea1b 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -247,7 +247,10 @@ namespace Emby.Server.Implementations.LiveTv.Listings ProgramAudio audioType = ProgramAudio.Stereo; bool repeat = programInfo.@new == null; - string newID = programInfo.programID + "T" + startAt.Ticks + "C" + channelId; + + var programId = programInfo.programID ?? string.Empty; + + string newID = programId + "T" + startAt.Ticks + "C" + channelId; if (programInfo.audioProperties != null) { @@ -300,7 +303,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings Etag = programInfo.md5 }; - var showId = programInfo.programID ?? string.Empty; + var showId = programId; if (!info.IsSeries) { @@ -339,11 +342,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings if (details.descriptions != null) { - if (details.descriptions.description1000 != null) + if (details.descriptions.description1000 != null && details.descriptions.description1000.Count > 0) { info.Overview = details.descriptions.description1000[0].description; } - else if (details.descriptions.description100 != null) + else if (details.descriptions.description100 != null && details.descriptions.description100.Count > 0) { info.Overview = details.descriptions.description100[0].description; } @@ -351,16 +354,24 @@ namespace Emby.Server.Implementations.LiveTv.Listings if (info.IsSeries) { - info.SeriesId = programInfo.programID.Substring(0, 10); + info.SeriesId = programId.Substring(0, 10); if (details.metadata != null) { - var gracenote = details.metadata.Find(x => x.Gracenote != null).Gracenote; - info.SeasonNumber = gracenote.season; - - if (gracenote.episode > 0) + foreach (var metadataProgram in details.metadata) { - info.EpisodeNumber = gracenote.episode; + var gracenote = metadataProgram.Gracenote; + if (gracenote != null) + { + info.SeasonNumber = gracenote.season; + + if (gracenote.episode > 0) + { + info.EpisodeNumber = gracenote.episode; + } + + break; + } } } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs index 5c5072192..eff2909fd 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -15,6 +15,8 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Querying; namespace Emby.Server.Implementations.LiveTv { @@ -110,7 +112,7 @@ namespace Emby.Server.Implementations.LiveTv PostPaddingSeconds = info.PostPaddingSeconds, IsPostPaddingRequired = info.IsPostPaddingRequired, IsPrePaddingRequired = info.IsPrePaddingRequired, - Days = info.Days, + Days = info.Days.ToArray(), Priority = info.Priority, RecordAnyChannel = info.RecordAnyChannel, RecordAnyTime = info.RecordAnyTime, @@ -135,7 +137,7 @@ namespace Emby.Server.Implementations.LiveTv dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); } - dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days); + dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days.ToArray(info.Days.Count)); FillImages(dto, info.Name, info.SeriesId); @@ -150,10 +152,7 @@ namespace Emby.Server.Implementations.LiveTv Name = seriesName, Limit = 1, ImageTypes = new ImageType[] { ImageType.Thumb }, - DtoOptions = new DtoOptions - { - Fields = new List<MediaBrowser.Model.Querying.ItemFields>() - } + DtoOptions = new DtoOptions(false) }).FirstOrDefault(); @@ -176,7 +175,7 @@ namespace Emby.Server.Implementations.LiveTv { try { - dto.ParentBackdropImageTags = new List<string> + dto.ParentBackdropImageTags = new string[] { _imageProcessor.GetImageCacheTag(librarySeries, image) }; @@ -196,10 +195,7 @@ namespace Emby.Server.Implementations.LiveTv ExternalSeriesId = programSeriesId, Limit = 1, ImageTypes = new ImageType[] { ImageType.Primary }, - DtoOptions = new DtoOptions - { - Fields = new List<MediaBrowser.Model.Querying.ItemFields>() - } + DtoOptions = new DtoOptions(false) }).FirstOrDefault(); @@ -218,14 +214,14 @@ namespace Emby.Server.Implementations.LiveTv } } - if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Count == 0) + if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Length == 0) { image = program.GetImageInfo(ImageType.Backdrop, 0); if (image != null) { try { - dto.ParentBackdropImageTags = new List<string> + dto.ParentBackdropImageTags = new string[] { _imageProcessor.GetImageCacheTag(program, image) }; @@ -248,10 +244,7 @@ namespace Emby.Server.Implementations.LiveTv Name = seriesName, Limit = 1, ImageTypes = new ImageType[] { ImageType.Thumb }, - DtoOptions = new DtoOptions - { - Fields = new List<MediaBrowser.Model.Querying.ItemFields>() - } + DtoOptions = new DtoOptions(false) }).FirstOrDefault(); @@ -274,7 +267,7 @@ namespace Emby.Server.Implementations.LiveTv { try { - dto.ParentBackdropImageTags = new List<string> + dto.ParentBackdropImageTags = new string[] { _imageProcessor.GetImageCacheTag(librarySeries, image) }; @@ -294,10 +287,7 @@ namespace Emby.Server.Implementations.LiveTv Name = seriesName, Limit = 1, ImageTypes = new ImageType[] { ImageType.Primary }, - DtoOptions = new DtoOptions - { - Fields = new List<MediaBrowser.Model.Querying.ItemFields>() - } + DtoOptions = new DtoOptions(false) }).FirstOrDefault() ?? _libraryManager.GetItemList(new InternalItemsQuery { @@ -305,10 +295,7 @@ namespace Emby.Server.Implementations.LiveTv ExternalSeriesId = programSeriesId, Limit = 1, ImageTypes = new ImageType[] { ImageType.Primary }, - DtoOptions = new DtoOptions - { - Fields = new List<MediaBrowser.Model.Querying.ItemFields>() - } + DtoOptions = new DtoOptions(false) }).FirstOrDefault(); @@ -327,14 +314,14 @@ namespace Emby.Server.Implementations.LiveTv } } - if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Count == 0) + if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Length == 0) { image = program.GetImageInfo(ImageType.Backdrop, 0); if (image != null) { try { - dto.ParentBackdropImageTags = new List<string> + dto.ParentBackdropImageTags = new string[] { _imageProcessor.GetImageCacheTag(program, image) }; @@ -349,24 +336,24 @@ namespace Emby.Server.Implementations.LiveTv } } - public DayPattern? GetDayPattern(List<DayOfWeek> days) + public DayPattern? GetDayPattern(DayOfWeek[] days) { DayPattern? pattern = null; - if (days.Count > 0) + if (days.Length > 0) { - if (days.Count == 7) + if (days.Length == 7) { pattern = DayPattern.Daily; } - else if (days.Count == 2) + else if (days.Length == 2) { if (days.Contains(DayOfWeek.Saturday) && days.Contains(DayOfWeek.Sunday)) { pattern = DayPattern.Weekends; } } - else if (days.Count == 5) + else if (days.Length == 5) { if (days.Contains(DayOfWeek.Monday) && days.Contains(DayOfWeek.Tuesday) && days.Contains(DayOfWeek.Wednesday) && days.Contains(DayOfWeek.Thursday) && days.Contains(DayOfWeek.Friday)) { @@ -384,7 +371,7 @@ namespace Emby.Server.Implementations.LiveTv { Name = info.Name, Id = info.Id, - Clients = info.Clients, + Clients = info.Clients.ToArray(), ProgramName = info.ProgramName, SourceType = info.SourceType, Status = info.Status, @@ -406,7 +393,7 @@ namespace Emby.Server.Implementations.LiveTv return dto; } - internal string GetImageTag(IHasImages info) + internal string GetImageTag(IHasMetadata info) { try { @@ -543,7 +530,7 @@ namespace Emby.Server.Implementations.LiveTv PostPaddingSeconds = dto.PostPaddingSeconds, IsPostPaddingRequired = dto.IsPostPaddingRequired, IsPrePaddingRequired = dto.IsPrePaddingRequired, - Days = dto.Days, + Days = dto.Days.ToList(), Priority = dto.Priority, RecordAnyChannel = dto.RecordAnyChannel, RecordAnyTime = dto.RecordAnyTime, diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index bf11b7d3a..b243c6599 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -60,7 +60,7 @@ namespace Emby.Server.Implementations.LiveTv private readonly LiveTvDtoService _tvDtoService; - private readonly List<ILiveTvService> _services = new List<ILiveTvService>(); + private ILiveTvService[] _services = new ILiveTvService[] { }; private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1); @@ -124,7 +124,7 @@ namespace Emby.Server.Implementations.LiveTv /// <param name="listingProviders">The listing providers.</param> public void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders) { - _services.AddRange(services); + _services = services.ToArray(); _tunerHosts.AddRange(tunerHosts); _listingProviders.AddRange(listingProviders); @@ -173,7 +173,7 @@ namespace Emby.Server.Implementations.LiveTv } } - public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken) + public async Task<QueryResult<BaseItem>> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken) { var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -187,7 +187,6 @@ namespace Emby.Server.Implementations.LiveTv IsSports = query.IsSports, IsSeries = query.IsSeries, IncludeItemTypes = new[] { typeof(LiveTvChannel).Name }, - SortOrder = query.SortOrder ?? SortOrder.Ascending, TopParentIds = new[] { topFolder.Id.ToString("N") }, IsFavorite = query.IsFavorite, IsLiked = query.IsLiked, @@ -196,27 +195,23 @@ namespace Emby.Server.Implementations.LiveTv DtoOptions = dtoOptions }; - internalQuery.OrderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder ?? SortOrder.Ascending))); + var orderBy = internalQuery.OrderBy.ToList(); + + orderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder ?? SortOrder.Ascending))); if (query.EnableFavoriteSorting) { - internalQuery.OrderBy.Insert(0, new Tuple<string, SortOrder>(ItemSortBy.IsFavoriteOrLiked, SortOrder.Descending)); + orderBy.Insert(0, new Tuple<string, SortOrder>(ItemSortBy.IsFavoriteOrLiked, SortOrder.Descending)); } if (!internalQuery.OrderBy.Any(i => string.Equals(i.Item1, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase))) { - internalQuery.OrderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending)); + orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending)); } - var channelResult = _libraryManager.GetItemsResult(internalQuery); - - var result = new QueryResult<LiveTvChannel> - { - Items = channelResult.Items.Cast<LiveTvChannel>().ToArray(), - TotalRecordCount = channelResult.TotalRecordCount - }; + internalQuery.OrderBy = orderBy.ToArray(); - return result; + return _libraryManager.GetItemsResult(internalQuery); } public LiveTvChannel GetInternalChannel(string id) @@ -566,7 +561,7 @@ namespace Emby.Server.Implementations.LiveTv if (isNew) { - await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); + _libraryManager.CreateItem(item, cancellationToken); } else if (forceUpdate) { @@ -883,7 +878,7 @@ namespace Emby.Server.Implementations.LiveTv if (isNew) { - await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); + _libraryManager.CreateItem(item, cancellationToken); } else if (dataChanged || info.DateLastUpdated > recording.DateLastSaved || statusChanged) { @@ -926,10 +921,10 @@ namespace Emby.Server.Implementations.LiveTv var topFolder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); - if (query.SortBy.Length == 0) + if (query.OrderBy.Length == 0) { // Unless something else was specified, order by start date to take advantage of a specialized index - query.SortBy = new[] { ItemSortBy.StartDate }; + query.OrderBy = new Tuple<string, SortOrder>[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) }; } RemoveFields(options); @@ -950,8 +945,7 @@ namespace Emby.Server.Implementations.LiveTv Genres = query.Genres, StartIndex = query.StartIndex, Limit = query.Limit, - SortBy = query.SortBy, - SortOrder = query.SortOrder ?? SortOrder.Ascending, + OrderBy = query.OrderBy, EnableTotalRecordCount = query.EnableTotalRecordCount, TopParentIds = new[] { topFolder.Id.ToString("N") }, Name = query.Name, @@ -993,7 +987,7 @@ namespace Emby.Server.Implementations.LiveTv var queryResult = _libraryManager.QueryItems(internalQuery); - var returnArray = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user).ConfigureAwait(false)).ToArray(); + var returnArray = _dtoService.GetBaseItemDtos(queryResult.Items, options, user); var result = new QueryResult<BaseItemDto> { @@ -1004,7 +998,7 @@ namespace Emby.Server.Implementations.LiveTv return result; } - public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken) + public async Task<QueryResult<BaseItem>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken) { var user = _userManager.GetUserById(query.UserId); @@ -1020,7 +1014,7 @@ namespace Emby.Server.Implementations.LiveTv IsSports = query.IsSports, IsKids = query.IsKids, EnableTotalRecordCount = query.EnableTotalRecordCount, - SortBy = new[] { ItemSortBy.StartDate }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) }, TopParentIds = new[] { topFolder.Id.ToString("N") }, DtoOptions = options }; @@ -1042,10 +1036,10 @@ namespace Emby.Server.Implementations.LiveTv } } - var programList = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>().ToList(); - var totalCount = programList.Count; + var programList = _libraryManager.QueryItems(internalQuery).Items; + var totalCount = programList.Length; - IOrderedEnumerable<LiveTvProgram> orderedPrograms = programList.OrderBy(i => i.StartDate.Date); + IOrderedEnumerable<LiveTvProgram> orderedPrograms = programList.Cast<LiveTvProgram>().OrderBy(i => i.StartDate.Date); if (query.IsAiring ?? false) { @@ -1053,14 +1047,14 @@ namespace Emby.Server.Implementations.LiveTv .ThenByDescending(i => GetRecommendationScore(i, user.Id, true)); } - IEnumerable<LiveTvProgram> programs = orderedPrograms; + IEnumerable<BaseItem> programs = orderedPrograms; if (query.Limit.HasValue) { programs = programs.Take(query.Limit.Value); } - var result = new QueryResult<LiveTvProgram> + var result = new QueryResult<BaseItem> { Items = programs.ToArray(), TotalRecordCount = totalCount @@ -1077,7 +1071,7 @@ namespace Emby.Server.Implementations.LiveTv var user = _userManager.GetUserById(query.UserId); - var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray(); + var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user); var result = new QueryResult<BaseItemDto> { @@ -1227,9 +1221,9 @@ namespace Emby.Server.Implementations.LiveTv await EmbyTV.EmbyTV.Current.ScanForTunerDeviceChanges(cancellationToken).ConfigureAwait(false); var numComplete = 0; - double progressPerService = _services.Count == 0 + double progressPerService = _services.Length == 0 ? 0 - : 1 / _services.Count; + : 1 / _services.Length; var newChannelIdList = new List<Guid>(); var newProgramIdList = new List<Guid>(); @@ -1261,13 +1255,13 @@ namespace Emby.Server.Implementations.LiveTv numComplete++; double percent = numComplete; - percent /= _services.Count; + percent /= _services.Length; progress.Report(100 * percent); } - await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false); - await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false); + await CleanDatabaseInternal(newChannelIdList.ToArray(), new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false); + await CleanDatabaseInternal(newProgramIdList.ToArray(), new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false); var coreService = _services.OfType<EmbyTV.EmbyTV>().FirstOrDefault(); @@ -1279,8 +1273,11 @@ namespace Emby.Server.Implementations.LiveTv // Load these now which will prefetch metadata var dtoOptions = new DtoOptions(); - dtoOptions.Fields.Remove(ItemFields.SyncInfo); - dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo); + var fields = dtoOptions.Fields.ToList(); + fields.Remove(ItemFields.SyncInfo); + fields.Remove(ItemFields.BasicSyncInfo); + dtoOptions.Fields = fields.ToArray(fields.Count); + await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false); progress.Report(100); @@ -1413,7 +1410,7 @@ namespace Emby.Server.Implementations.LiveTv if (newPrograms.Count > 0) { - await _libraryManager.CreateItems(newPrograms, cancellationToken).ConfigureAwait(false); + _libraryManager.CreateItems(newPrograms, cancellationToken); } // TODO: Do this in bulk @@ -1450,14 +1447,14 @@ namespace Emby.Server.Implementations.LiveTv return new Tuple<List<Guid>, List<Guid>>(channels, programs); } - private async Task CleanDatabaseInternal(List<Guid> currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken) + private async Task CleanDatabaseInternal(Guid[] currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken) { var list = _itemRepo.GetItemIdsList(new InternalItemsQuery { IncludeItemTypes = validTypes, DtoOptions = new DtoOptions(false) - }).ToList(); + }); var numComplete = 0; @@ -1547,7 +1544,7 @@ namespace Emby.Server.Implementations.LiveTv var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false); - await CleanDatabaseInternal(idList.ToList(), new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false); + await CleanDatabaseInternal(idList, new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.UtcNow; } @@ -1564,11 +1561,6 @@ namespace Emby.Server.Implementations.LiveTv return new QueryResult<BaseItem>(); } - if ((query.IsInProgress ?? false)) - { - return new QueryResult<BaseItem>(); - } - var folderIds = EmbyTV.EmbyTV.Current.GetRecordingFolders() .SelectMany(i => i.Locations) .Distinct(StringComparer.OrdinalIgnoreCase) @@ -1580,13 +1572,10 @@ namespace Emby.Server.Implementations.LiveTv var excludeItemTypes = new List<string>(); - if (!query.IsInProgress.HasValue) - { - folderIds.Add(internalLiveTvFolderId); + folderIds.Add(internalLiveTvFolderId); - excludeItemTypes.Add(typeof(LiveTvChannel).Name); - excludeItemTypes.Add(typeof(LiveTvProgram).Name); - } + excludeItemTypes.Add(typeof(LiveTvChannel).Name); + excludeItemTypes.Add(typeof(LiveTvProgram).Name); if (folderIds.Count == 0) { @@ -1635,26 +1624,38 @@ namespace Emby.Server.Implementations.LiveTv } } + if ((query.IsInProgress ?? false)) + { + // TODO: filter + var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray(); + var items = allActivePaths.Select(i => _libraryManager.FindByPath(i, false)).Where(i => i != null).ToArray(); + + return new QueryResult<BaseItem> + { + Items = items, + TotalRecordCount = items.Length + }; + } + return _libraryManager.GetItemsResult(new InternalItemsQuery(user) { MediaTypes = new[] { MediaType.Video }, Recursive = true, - AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(), + AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(folderIds.Count), IsFolder = false, IsVirtualItem = false, Limit = query.Limit, StartIndex = query.StartIndex, - SortBy = new[] { ItemSortBy.DateCreated }, - SortOrder = SortOrder.Descending, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) }, EnableTotalRecordCount = query.EnableTotalRecordCount, - IncludeItemTypes = includeItemTypes.ToArray(), - ExcludeItemTypes = excludeItemTypes.ToArray(), - Genres = genres.ToArray(), + IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count), + ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count), + Genres = genres.ToArray(genres.Count), DtoOptions = dtoOptions }); } - public async Task<QueryResult<BaseItemDto>> GetRecordingSeries(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken) + public QueryResult<BaseItemDto> GetRecordingSeries(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken) { var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); if (user != null && !IsLiveTvEnabled(user)) @@ -1662,11 +1663,6 @@ namespace Emby.Server.Implementations.LiveTv return new QueryResult<BaseItemDto>(); } - if (_services.Count > 1) - { - return new QueryResult<BaseItemDto>(); - } - if (user == null || (query.IsInProgress ?? false)) { return new QueryResult<BaseItemDto>(); @@ -1695,17 +1691,16 @@ namespace Emby.Server.Implementations.LiveTv var internalResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user) { Recursive = true, - AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(), + AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(folders.Count), Limit = query.Limit, - SortBy = new[] { ItemSortBy.DateCreated }, - SortOrder = SortOrder.Descending, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) }, EnableTotalRecordCount = query.EnableTotalRecordCount, - IncludeItemTypes = includeItemTypes.ToArray(), - ExcludeItemTypes = excludeItemTypes.ToArray(), + IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count), + ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count), DtoOptions = options }); - var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray(); + var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user); return new QueryResult<BaseItemDto> { @@ -1724,13 +1719,9 @@ namespace Emby.Server.Implementations.LiveTv var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); - if (_services.Count == 1 && (!query.IsInProgress.HasValue || !query.IsInProgress.Value) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value)) + // TODO: Figure out how to merge emby recordings + service recordings + if (_services.Length == 1) { - if (!query.IsInProgress.HasValue) - { - await RefreshRecordings(folder.Id, cancellationToken).ConfigureAwait(false); - } - return GetEmbyRecordings(query, options, folder.Id, user); } @@ -1842,9 +1833,12 @@ namespace Emby.Server.Implementations.LiveTv }; } - public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, List<ItemFields> fields, User user = null) + public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, ItemFields[] fields, User user = null) { var programTuples = new List<Tuple<BaseItemDto, string, string, string>>(); + var hasChannelImage = fields.Contains(ItemFields.ChannelImage); + var hasChannelInfo = fields.Contains(ItemFields.ChannelInfo); + var hasServiceName = fields.Contains(ItemFields.ServiceName); foreach (var tuple in tuples) { @@ -1887,7 +1881,7 @@ namespace Emby.Server.Implementations.LiveTv dto.IsPremiere = program.IsPremiere; } - if (fields.Contains(ItemFields.ChannelInfo)) + if (hasChannelInfo || hasChannelImage) { var channel = GetInternalChannel(program.ChannelId); @@ -1897,7 +1891,7 @@ namespace Emby.Server.Implementations.LiveTv dto.MediaType = channel.MediaType; dto.ChannelNumber = channel.Number; - if (channel.HasImage(ImageType.Primary)) + if (hasChannelImage && channel.HasImage(ImageType.Primary)) { dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel); } @@ -1906,7 +1900,7 @@ namespace Emby.Server.Implementations.LiveTv var serviceName = program.ServiceName; - if (fields.Contains(ItemFields.ServiceName)) + if (hasServiceName) { dto.ServiceName = serviceName; } @@ -1919,6 +1913,11 @@ namespace Emby.Server.Implementations.LiveTv await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false); } + public ActiveRecordingInfo GetActiveRecordingInfo(string path) + { + return EmbyTV.EmbyTV.Current.GetActiveRecordingInfo(path); + } + public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null) { var recording = (ILiveTvRecording)item; @@ -1928,11 +1927,11 @@ namespace Emby.Server.Implementations.LiveTv var info = recording; - dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) + dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) || service == null ? null : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); - dto.TimerId = string.IsNullOrEmpty(info.TimerId) + dto.TimerId = string.IsNullOrEmpty(info.TimerId) || service == null ? null : _tvDtoService.GetInternalTimerId(service.Name, info.TimerId).ToString("N"); @@ -1948,27 +1947,72 @@ namespace Emby.Server.Implementations.LiveTv dto.IsKids = info.IsKids; dto.IsPremiere = info.IsPremiere; - dto.CanDelete = user == null - ? recording.CanDelete() - : recording.CanDelete(user); - - if (dto.MediaSources == null) + if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue) { - dto.MediaSources = recording.GetMediaSources(true).ToList(); + var now = DateTime.UtcNow.Ticks; + var start = info.StartDate.Ticks; + var end = info.EndDate.Value.Ticks; + + var pct = now - start; + pct /= end; + pct *= 100; + dto.CompletionPercentage = pct; } - if (dto.MediaStreams == null) + if (channel != null) { - dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); + dto.ChannelName = channel.Name; + + if (channel.HasImage(ImageType.Primary)) + { + dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel); + } } + } - if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue) + public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, ActiveRecordingInfo activeRecordingInfo, User user = null) + { + var service = EmbyTV.EmbyTV.Current; + + var info = activeRecordingInfo.Timer; + + var channel = string.IsNullOrWhiteSpace(info.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, info.ChannelId)); + + dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) + ? null + : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); + + dto.TimerId = string.IsNullOrEmpty(info.Id) + ? null + : _tvDtoService.GetInternalTimerId(service.Name, info.Id).ToString("N"); + + var startDate = info.StartDate; + var endDate = info.EndDate; + + dto.StartDate = startDate; + dto.EndDate = endDate; + dto.Status = info.Status.ToString(); + dto.IsRepeat = info.IsRepeat; + dto.EpisodeTitle = info.EpisodeTitle; + dto.IsMovie = info.IsMovie; + dto.IsSeries = info.IsSeries; + dto.IsSports = info.IsSports; + dto.IsLive = info.IsLive; + dto.IsNews = info.IsNews; + dto.IsKids = info.IsKids; + dto.IsPremiere = info.IsPremiere; + + if (info.Status == RecordingStatus.InProgress) { + startDate = info.StartDate.AddSeconds(0 - info.PrePaddingSeconds); + endDate = info.EndDate.AddSeconds(info.PostPaddingSeconds); + var now = DateTime.UtcNow.Ticks; - var start = info.StartDate.Ticks; - var end = info.EndDate.Value.Ticks; + var start = startDate.Ticks; + var end = endDate.Ticks; var pct = now - start; + pct /= end; pct *= 100; dto.CompletionPercentage = pct; @@ -1993,7 +2037,7 @@ namespace Emby.Server.Implementations.LiveTv var internalResult = await GetInternalRecordings(query, options, cancellationToken).ConfigureAwait(false); - var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray(); + var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user); return new QueryResult<BaseItemDto> { @@ -2081,7 +2125,7 @@ namespace Emby.Server.Implementations.LiveTv var returnArray = returnList .OrderBy(i => i.StartDate) - .ToArray(); + .ToArray(returnList.Count); return new QueryResult<TimerInfoDto> { @@ -2096,7 +2140,6 @@ namespace Emby.Server.Implementations.LiveTv if (service is EmbyTV.EmbyTV) { - // We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says return service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None); } @@ -2154,7 +2197,7 @@ namespace Emby.Server.Implementations.LiveTv await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; - EventHelper.QueueEventIfNotNull(TimerCancelled, this, new GenericEventArgs<TimerEventInfo> + EventHelper.FireEventIfNotNull(TimerCancelled, this, new GenericEventArgs<TimerEventInfo> { Argument = new TimerEventInfo { @@ -2177,7 +2220,7 @@ namespace Emby.Server.Implementations.LiveTv await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; - EventHelper.QueueEventIfNotNull(SeriesTimerCancelled, this, new GenericEventArgs<TimerEventInfo> + EventHelper.FireEventIfNotNull(SeriesTimerCancelled, this, new GenericEventArgs<TimerEventInfo> { Argument = new TimerEventInfo { @@ -2321,7 +2364,7 @@ namespace Emby.Server.Implementations.LiveTv }; } - public async Task AddChannelInfo(List<Tuple<BaseItemDto, LiveTvChannel>> tuples, DtoOptions options, User user) + public void AddChannelInfo(List<Tuple<BaseItemDto, LiveTvChannel>> tuples, DtoOptions options, User user) { var now = DateTime.UtcNow; @@ -2334,11 +2377,11 @@ namespace Emby.Server.Implementations.LiveTv MaxStartDate = now, MinEndDate = now, Limit = channelIds.Length, - SortBy = new[] { "StartDate" }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) }, TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Result.Id.ToString("N") }, DtoOptions = options - }).ToList() : new List<BaseItem>(); + }) : new List<BaseItem>(); RemoveFields(options); @@ -2346,7 +2389,7 @@ namespace Emby.Server.Implementations.LiveTv var currentChannelsDict = new Dictionary<string, BaseItemDto>(); var addCurrentProgram = options.AddCurrentProgram; - var addMediaSources = options.Fields.Contains(ItemFields.MediaSources); + var addServiceName = options.Fields.Contains(ItemFields.ServiceName); foreach (var tuple in tuples) { @@ -2356,15 +2399,14 @@ namespace Emby.Server.Implementations.LiveTv dto.Number = channel.Number; dto.ChannelNumber = channel.Number; dto.ChannelType = channel.ChannelType; - dto.ServiceName = channel.ServiceName; - currentChannelsDict[dto.Id] = dto; - - if (addMediaSources) + if (addServiceName) { - dto.MediaSources = channel.GetMediaSources(true).ToList(); + dto.ServiceName = channel.ServiceName; } + currentChannelsDict[dto.Id] = dto; + if (addCurrentProgram) { var channelIdString = channel.Id.ToString("N"); @@ -2379,7 +2421,7 @@ namespace Emby.Server.Implementations.LiveTv if (addCurrentProgram) { - var currentProgramDtos = await _dtoService.GetBaseItemDtos(currentProgramsList, options, user).ConfigureAwait(false); + var currentProgramDtos = _dtoService.GetBaseItemDtos(currentProgramsList, options, user); foreach (var programDto in currentProgramDtos) { @@ -2470,7 +2512,7 @@ namespace Emby.Server.Implementations.LiveTv var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false); var info = _tvDtoService.GetSeriesTimerInfoDto(defaults.Item1, defaults.Item2, null); - info.Days = defaults.Item1.Days; + info.Days = defaults.Item1.Days.ToArray(); info.DayPattern = _tvDtoService.GetDayPattern(info.Days); @@ -2516,7 +2558,7 @@ namespace Emby.Server.Implementations.LiveTv _lastRecordingRefreshTime = DateTime.MinValue; _logger.Info("New recording scheduled"); - EventHelper.QueueEventIfNotNull(TimerCreated, this, new GenericEventArgs<TimerEventInfo> + EventHelper.FireEventIfNotNull(TimerCreated, this, new GenericEventArgs<TimerEventInfo> { Argument = new TimerEventInfo { @@ -2558,7 +2600,7 @@ namespace Emby.Server.Implementations.LiveTv _lastRecordingRefreshTime = DateTime.MinValue; - EventHelper.QueueEventIfNotNull(SeriesTimerCreated, this, new GenericEventArgs<TimerEventInfo> + EventHelper.FireEventIfNotNull(SeriesTimerCreated, this, new GenericEventArgs<TimerEventInfo> { Argument = new TimerEventInfo { @@ -2647,8 +2689,7 @@ namespace Emby.Server.Implementations.LiveTv var series = recordings .Where(i => i.IsSeries) - .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase) - .ToList(); + .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase); groups.AddRange(series.OrderByString(i => i.Key).Select(i => new BaseItemDto { @@ -2697,7 +2738,7 @@ namespace Emby.Server.Implementations.LiveTv return new QueryResult<BaseItemDto> { - Items = groups.ToArray(), + Items = groups.ToArray(groups.Count), TotalRecordCount = groups.Count }; } @@ -2738,6 +2779,7 @@ namespace Emby.Server.Implementations.LiveTv public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } private bool _isDisposed = false; @@ -2753,7 +2795,7 @@ namespace Emby.Server.Implementations.LiveTv } } - private async Task<IEnumerable<LiveTvServiceInfo>> GetServiceInfos(CancellationToken cancellationToken) + private async Task<LiveTvServiceInfo[]> GetServiceInfos(CancellationToken cancellationToken) { var tasks = Services.Select(i => GetServiceInfo(i, cancellationToken)); @@ -2797,7 +2839,7 @@ namespace Emby.Server.Implementations.LiveTv return dto; - }).ToList(); + }).ToArray(); } catch (Exception ex) { @@ -2813,25 +2855,24 @@ namespace Emby.Server.Implementations.LiveTv public async Task<LiveTvInfo> GetLiveTvInfo(CancellationToken cancellationToken) { var services = await GetServiceInfos(CancellationToken.None).ConfigureAwait(false); - var servicesList = services.ToList(); var info = new LiveTvInfo { - Services = servicesList.ToList(), - IsEnabled = servicesList.Count > 0 + Services = services, + IsEnabled = services.Length > 0 }; info.EnabledUsers = _userManager.Users .Where(IsLiveTvEnabled) .Select(i => i.Id.ToString("N")) - .ToList(); + .ToArray(); return info; } private bool IsLiveTvEnabled(User user) { - return user.Policy.EnableLiveTvAccess && (Services.Count > 1 || GetConfiguration().TunerHosts.Count > 0); + return user.Policy.EnableLiveTvAccess && (Services.Count > 1 || GetConfiguration().TunerHosts.Length > 0); } public IEnumerable<User> GetEnabledUsers() @@ -2871,10 +2912,13 @@ namespace Emby.Server.Implementations.LiveTv private void RemoveFields(DtoOptions options) { - options.Fields.Remove(ItemFields.CanDelete); - options.Fields.Remove(ItemFields.CanDownload); - options.Fields.Remove(ItemFields.DisplayPreferencesId); - options.Fields.Remove(ItemFields.Etag); + var fields = options.Fields.ToList(); + + fields.Remove(ItemFields.CanDelete); + fields.Remove(ItemFields.CanDownload); + fields.Remove(ItemFields.DisplayPreferencesId); + fields.Remove(ItemFields.Etag); + options.Fields = fields.ToArray(fields.Count); } public async Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken) @@ -2902,12 +2946,14 @@ namespace Emby.Server.Implementations.LiveTv var config = GetConfiguration(); - var index = config.TunerHosts.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); + var list = config.TunerHosts.ToList(); + var index = list.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); if (index == -1 || string.IsNullOrWhiteSpace(info.Id)) { info.Id = Guid.NewGuid().ToString("N"); - config.TunerHosts.Add(info); + list.Add(info); + config.TunerHosts = list.ToArray(list.Count); } else { @@ -2939,12 +2985,14 @@ namespace Emby.Server.Implementations.LiveTv var config = GetConfiguration(); - var index = config.ListingProviders.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); + var list = config.ListingProviders.ToList(); + var index = list.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); if (index == -1 || string.IsNullOrWhiteSpace(info.Id)) { info.Id = Guid.NewGuid().ToString("N"); - config.ListingProviders.Add(info); + list.Add(info); + config.ListingProviders = list.ToArray(list.Count); info.EnableNewProgramIds = true; } else @@ -2963,7 +3011,7 @@ namespace Emby.Server.Implementations.LiveTv { var config = GetConfiguration(); - config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList(); + config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToArray(); _config.SaveConfiguration("livetv", config); _taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>(); @@ -2984,7 +3032,7 @@ namespace Emby.Server.Implementations.LiveTv Name = tunerChannelId, Value = providerChannelId }); - listingsProviderInfo.ChannelMappings = list.ToArray(); + listingsProviderInfo.ChannelMappings = list.ToArray(list.Count); } _config.SaveConfiguration("livetv", config); @@ -2995,7 +3043,7 @@ namespace Emby.Server.Implementations.LiveTv var providerChannels = await GetChannelsFromListingsProviderData(providerId, CancellationToken.None) .ConfigureAwait(false); - var mappings = listingsProviderInfo.ChannelMappings.ToList(); + var mappings = listingsProviderInfo.ChannelMappings; var tunerChannelMappings = tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(); @@ -3005,7 +3053,7 @@ namespace Emby.Server.Implementations.LiveTv return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelId, StringComparison.OrdinalIgnoreCase)); } - public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, List<NameValuePair> mappings, List<ChannelInfo> epgChannels) + public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, NameValuePair[] mappings, List<ChannelInfo> epgChannels) { var result = new TunerChannelMapping { @@ -3069,7 +3117,7 @@ namespace Emby.Server.Implementations.LiveTv if (string.Equals(feature, "dvr-l", StringComparison.OrdinalIgnoreCase)) { var config = GetConfiguration(); - if (config.TunerHosts.Count > 0 && + if (config.TunerHosts.Length > 0 && config.ListingProviders.Count(i => (i.EnableAllTuners || i.EnabledTuners.Length > 0) && string.Equals(i.Type, SchedulesDirect.TypeName, StringComparison.OrdinalIgnoreCase)) > 0) { return Task.FromResult(new MBRegistrationRecord diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index 919c0f10d..0e52f874d 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.LiveTv { @@ -42,9 +43,11 @@ namespace Emby.Server.Implementations.LiveTv if (baseItem.SourceType == SourceType.LiveTV) { - if (string.IsNullOrWhiteSpace(baseItem.Path)) + var activeRecordingInfo = _liveTvManager.GetActiveRecordingInfo(item.Path); + + if (string.IsNullOrWhiteSpace(baseItem.Path) || activeRecordingInfo != null) { - return GetMediaSourcesInternal(item, cancellationToken); + return GetMediaSourcesInternal(item, activeRecordingInfo, cancellationToken); } } @@ -55,7 +58,7 @@ namespace Emby.Server.Implementations.LiveTv private const char StreamIdDelimeter = '_'; private const string StreamIdDelimeterString = "_"; - private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(IHasMediaSources item, CancellationToken cancellationToken) + private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(IHasMediaSources item, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken) { IEnumerable<MediaSourceInfo> sources; @@ -66,20 +69,27 @@ namespace Emby.Server.Implementations.LiveTv if (item is ILiveTvRecording) { sources = await _liveTvManager.GetRecordingMediaSources(item, cancellationToken) - .ConfigureAwait(false); + .ConfigureAwait(false); } else { - sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken) - .ConfigureAwait(false); + if (activeRecordingInfo != null) + { + sources = await EmbyTV.EmbyTV.Current.GetRecordingStreamMediaSources(activeRecordingInfo, cancellationToken) + .ConfigureAwait(false); + } + else + { + sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken) + .ConfigureAwait(false); + } } } catch (NotImplementedException) { var hasMediaSources = (IHasMediaSources)item; - sources = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false) - .ToList(); + sources = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false); forceRequireOpening = true; } @@ -103,7 +113,7 @@ namespace Emby.Server.Implementations.LiveTv openKeys.Add(item.GetType().Name); openKeys.Add(item.Id.ToString("N")); openKeys.Add(source.Id ?? string.Empty); - source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray()); + source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray(openKeys.Count)); } // Dummy this up so that direct play checks can still run diff --git a/Emby.Server.Implementations/LiveTv/RecordingImageProvider.cs b/Emby.Server.Implementations/LiveTv/RecordingImageProvider.cs index 47663bdbc..992badbb5 100644 --- a/Emby.Server.Implementations/LiveTv/RecordingImageProvider.cs +++ b/Emby.Server.Implementations/LiveTv/RecordingImageProvider.cs @@ -19,12 +19,12 @@ namespace Emby.Server.Implementations.LiveTv _liveTvManager = liveTvManager; } - public IEnumerable<ImageType> GetSupportedImages(IHasImages item) + public IEnumerable<ImageType> GetSupportedImages(IHasMetadata item) { return new[] { ImageType.Primary }; } - public async Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken) + public async Task<DynamicImageResponse> GetImage(IHasMetadata item, ImageType type, CancellationToken cancellationToken) { var liveTvItem = (ILiveTvRecording)item; @@ -58,7 +58,7 @@ namespace Emby.Server.Implementations.LiveTv get { return "Live TV Service Provider"; } } - public bool Supports(IHasImages item) + public bool Supports(IHasMetadata item) { return item is ILiveTvRecording; } diff --git a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs index 5582d8f35..cad28c809 100644 --- a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs +++ b/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs @@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.LiveTv public bool IsHidden { - get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Count == 0; } + get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Length == 0; } } public bool IsEnabled diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index b6ba8b45c..f974b5c2c 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -68,7 +68,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var id = ChannelIdPrefix + i.GuideNumber; - id += '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"); + if (!info.EnableNewHdhrChannelIds) + { + id += '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"); + } return id; } @@ -419,7 +422,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun SupportsTranscoding = true, IsInfiniteStream = true, IgnoreDts = true, - //SupportsProbing = false, + SupportsProbing = false, //AnalyzeDurationMs = 2000000 //IgnoreIndex = true, //ReadAtNativeFramerate = true diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs index 41b058baf..c737c4cba 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs @@ -99,6 +99,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun var task = StopStreaming(); Task.WaitAll(task); + GC.SuppressFinalize(this); } public async Task<bool> CheckTunerAvailability(IpAddressInfo remoteIp, int tuner, CancellationToken cancellationToken) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 113cb33f4..eac845579 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -11,12 +10,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; - using MediaBrowser.Model.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; @@ -28,12 +25,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts private readonly IHttpClient _httpClient; private readonly IServerApplicationHost _appHost; private readonly IEnvironmentInfo _environment; + private readonly INetworkManager _networkManager; - public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, IEnvironmentInfo environment) : base(config, logger, jsonSerializer, mediaEncoder, fileSystem) + public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, IEnvironmentInfo environment, INetworkManager networkManager) : base(config, logger, jsonSerializer, mediaEncoder, fileSystem) { _httpClient = httpClient; _appHost = appHost; _environment = environment; + _networkManager = networkManager; } public override string Type @@ -41,14 +40,21 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts get { return "m3u"; } } - public string Name + public virtual string Name { get { return "M3U Tuner"; } } + private string GetFullChannelIdPrefix(TunerHostInfo info) + { + return ChannelIdPrefix + info.Url.GetMD5().ToString("N"); + } + protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { - var result = await new M3uParser(Logger, FileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, !info.EnableTvgId, cancellationToken).ConfigureAwait(false); + var channelIdPrefix = GetFullChannelIdPrefix(info); + + var result = await new M3uParser(Logger, FileSystem, _httpClient, _appHost).Parse(info.Url, channelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false); return result.Cast<ChannelInfo>().ToList(); } @@ -87,80 +93,92 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { - var urlHash = info.Url.GetMD5().ToString("N"); - var prefix = ChannelIdPrefix + urlHash; - if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + var channelIdPrefix = GetFullChannelIdPrefix(info); + + if (!channelId.StartsWith(channelIdPrefix, StringComparison.OrdinalIgnoreCase)) { return null; } var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false); - var m3uchannels = channels.Cast<M3UChannel>(); - var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase)); + var channel = channels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase)); if (channel != null) { - var path = channel.Path; - MediaProtocol protocol = MediaProtocol.File; - if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Http; - } - else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Rtmp; - } - else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Rtsp; - } - else if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Udp; - } - else if (path.StartsWith("rtp", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Rtmp; - } + return new List<MediaSourceInfo> { CreateMediaSourceInfo(info, channel) }; + } + return new List<MediaSourceInfo>(); + } + + protected virtual MediaSourceInfo CreateMediaSourceInfo(TunerHostInfo info, ChannelInfo channel) + { + var path = channel.Path; + MediaProtocol protocol = MediaProtocol.File; + if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Http; + } + else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Rtmp; + } + else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Rtsp; + } + else if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Udp; + } + else if (path.StartsWith("rtp", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Rtmp; + } - var mediaSource = new MediaSourceInfo + Uri uri; + var isRemote = true; + if (Uri.TryCreate(path, UriKind.Absolute, out uri)) + { + isRemote = !_networkManager.IsInLocalNetwork(uri.Host); + } + + var mediaSource = new MediaSourceInfo + { + Path = path, + Protocol = protocol, + MediaStreams = new List<MediaStream> { - Path = channel.Path, - Protocol = protocol, - MediaStreams = new List<MediaStream> + new MediaStream { - new MediaStream - { - Type = MediaStreamType.Video, - // Set the index to -1 because we don't know the exact index of the video stream within the container - Index = -1, - IsInterlaced = true - }, - new MediaStream - { - Type = MediaStreamType.Audio, - // Set the index to -1 because we don't know the exact index of the audio stream within the container - Index = -1 - - } + Type = MediaStreamType.Video, + // Set the index to -1 because we don't know the exact index of the video stream within the container + Index = -1, + IsInterlaced = true }, - RequiresOpening = true, - RequiresClosing = true, - RequiresLooping = info.EnableStreamLooping, + new MediaStream + { + Type = MediaStreamType.Audio, + // Set the index to -1 because we don't know the exact index of the audio stream within the container + Index = -1 - ReadAtNativeFramerate = false, + } + }, + RequiresOpening = true, + RequiresClosing = true, + RequiresLooping = info.EnableStreamLooping, + EnableMpDecimate = info.EnableMpDecimate, - Id = channel.Path.GetMD5().ToString("N"), - IsInfiniteStream = true, - IsRemote = true, + ReadAtNativeFramerate = false, - IgnoreDts = true - }; + Id = channel.Path.GetMD5().ToString("N"), + IsInfiniteStream = true, + IsRemote = isRemote, - mediaSource.InferTotalBitrate(); + IgnoreDts = true + }; - return new List<MediaSourceInfo> { mediaSource }; - } - return new List<MediaSourceInfo>(); + mediaSource.InferTotalBitrate(); + + return mediaSource; } protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 8d73c7e2b..ca744b615 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -32,25 +32,21 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts _appHost = appHost; } - public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, bool enableStreamUrlAsIdentifier, CancellationToken cancellationToken) + public async Task<List<ChannelInfo>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken) { - var urlHash = url.GetMD5().ToString("N"); - // Read the file and display it line by line. using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false))) { - return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId, enableStreamUrlAsIdentifier); + return GetChannels(reader, channelIdPrefix, tunerHostId); } } - public List<M3UChannel> ParseString(string text, string channelIdPrefix, string tunerHostId) + public List<ChannelInfo> ParseString(string text, string channelIdPrefix, string tunerHostId) { - var urlHash = "text".GetMD5().ToString("N"); - // Read the file and display it line by line. using (var reader = new StringReader(text)) { - return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId, false); + return GetChannels(reader, channelIdPrefix, tunerHostId); } } @@ -70,9 +66,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts } const string ExtInfPrefix = "#EXTINF:"; - private List<M3UChannel> GetChannels(TextReader reader, string urlHash, string channelIdPrefix, string tunerHostId, bool enableStreamUrlAsIdentifier) + private List<ChannelInfo> GetChannels(TextReader reader, string channelIdPrefix, string tunerHostId) { - var channels = new List<M3UChannel>(); + var channels = new List<ChannelInfo>(); string line; string extInf = ""; @@ -97,13 +93,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts else if (!string.IsNullOrWhiteSpace(extInf) && !line.StartsWith("#", StringComparison.OrdinalIgnoreCase)) { var channel = GetChannelnfo(extInf, tunerHostId, line); - if (string.IsNullOrWhiteSpace(channel.Id) || enableStreamUrlAsIdentifier) + if (string.IsNullOrWhiteSpace(channel.Id)) { - channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"); + channel.Id = channelIdPrefix + line.GetMD5().ToString("N"); } else { - channel.Id = channelIdPrefix + urlHash + channel.Id.GetMD5().ToString("N"); + channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N"); } channel.Path = line; @@ -115,9 +111,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return channels; } - private M3UChannel GetChannelnfo(string extInf, string tunerHostId, string mediaUrl) + private ChannelInfo GetChannelnfo(string extInf, string tunerHostId, string mediaUrl) { - var channel = new M3UChannel(); + var channel = new ChannelInfo(); channel.TunerHostId = tunerHostId; extInf = extInf.Trim(); @@ -339,10 +335,4 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return dict; } } - - - public class M3UChannel : ChannelInfo - { - public string Path { get; set; } - } }
\ No newline at end of file diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs index cf50e6092..45a0c348e 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs @@ -24,8 +24,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public async Task CopyUntilCancelled(Stream source, Action onStarted, CancellationToken cancellationToken) { - byte[] buffer = new byte[BufferSize]; - if (source == null) { throw new ArgumentNullException("source"); @@ -35,25 +33,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { cancellationToken.ThrowIfCancellationRequested(); + byte[] buffer = new byte[BufferSize]; + var bytesRead = source.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { - var allStreams = _outputStreams.ToList(); - - //if (allStreams.Count == 1) - //{ - // allStreams[0].Value.Write(buffer, 0, bytesRead); - //} - //else + foreach (var stream in _outputStreams) { - byte[] copy = new byte[bytesRead]; - Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead); - - foreach (var stream in allStreams) - { - stream.Value.Queue(copy, 0, copy.Length); - } + stream.Value.Queue(buffer, 0, bytesRead); } if (onStarted != null) @@ -73,27 +61,21 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) { - var result = new QueueStream(stream, _logger) - { - OnFinished = OnFinished - }; - - _outputStreams.TryAdd(result.Id, result); + var queueStream = new QueueStream(stream, _logger); - result.Start(cancellationToken); - - return result.TaskCompletion.Task; - } + _outputStreams.TryAdd(queueStream.Id, queueStream); - public void RemoveOutputStream(QueueStream stream) - { - QueueStream removed; - _outputStreams.TryRemove(stream.Id, out removed); - } + try + { + queueStream.Start(cancellationToken); + } + finally + { + _outputStreams.TryRemove(queueStream.Id, out queueStream); + GC.Collect(); + } - private void OnFinished(QueueStream queueStream) - { - RemoveOutputStream(queueStream); + return Task.FromResult(true); } } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs index 61bc390b4..07a4daa87 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs @@ -13,10 +13,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public class QueueStream { private readonly Stream _outputStream; - private readonly ConcurrentQueue<Tuple<byte[], int, int>> _queue = new ConcurrentQueue<Tuple<byte[], int, int>>(); - public TaskCompletionSource<bool> TaskCompletion { get; private set; } + private readonly BlockingCollection<Tuple<byte[], int, int>> _queue = new BlockingCollection<Tuple<byte[], int, int>>(); - public Action<QueueStream> OnFinished { get; set; } private readonly ILogger _logger; public Guid Id = Guid.NewGuid(); @@ -24,94 +22,24 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { _outputStream = outputStream; _logger = logger; - TaskCompletion = new TaskCompletionSource<bool>(); } public void Queue(byte[] bytes, int offset, int count) { - _queue.Enqueue(new Tuple<byte[], int, int>(bytes, offset, count)); + _queue.Add(new Tuple<byte[], int, int>(bytes, offset, count)); } public void Start(CancellationToken cancellationToken) { - Task.Run(() => StartInternal(cancellationToken)); - } - - private Tuple<byte[], int, int> Dequeue() - { - Tuple<byte[], int, int> result; - if (_queue.TryDequeue(out result)) - { - return result; - } - - return null; - } - - private void OnClosed() - { - GC.Collect(); - if (OnFinished != null) - { - OnFinished(this); - } - } - - public void Write(byte[] bytes, int offset, int count) - { - //return _outputStream.WriteAsync(bytes, offset, count, cancellationToken); - - try + while (true) { - _outputStream.Write(bytes, offset, count); - } - catch (OperationCanceledException) - { - _logger.Debug("QueueStream cancelled"); - TaskCompletion.TrySetCanceled(); - OnClosed(); - } - catch (Exception ex) - { - _logger.ErrorException("Error in QueueStream", ex); - TaskCompletion.TrySetException(ex); - OnClosed(); - } - } - - private async Task StartInternal(CancellationToken cancellationToken) - { - try - { - while (true) + foreach (var result in _queue.GetConsumingEnumerable()) { cancellationToken.ThrowIfCancellationRequested(); - var result = Dequeue(); - if (result != null) - { - _outputStream.Write(result.Item1, result.Item2, result.Item3); - } - else - { - await Task.Delay(50, cancellationToken).ConfigureAwait(false); - } + _outputStream.Write(result.Item1, result.Item2, result.Item3); } } - catch (OperationCanceledException) - { - _logger.Debug("QueueStream cancelled"); - TaskCompletion.TrySetCanceled(); - } - catch (Exception ex) - { - _logger.ErrorException("Error in QueueStream", ex); - TaskCompletion.TrySetException(ex); - } - finally - { - OnClosed(); - } } } } diff --git a/Emby.Server.Implementations/Localization/Core/core.json b/Emby.Server.Implementations/Localization/Core/core.json deleted file mode 100644 index 976faa8cb..000000000 --- a/Emby.Server.Implementations/Localization/Core/core.json +++ /dev/null @@ -1,179 +0,0 @@ -{ - "AppDeviceValues": "App: {0}, Device: {1}", - "UserDownloadingItemWithValues": "{0} is downloading {1}", - "FolderTypeMixed": "Mixed content", - "FolderTypeMovies": "Movies", - "FolderTypeMusic": "Music", - "FolderTypeAdultVideos": "Adult videos", - "FolderTypePhotos": "Photos", - "FolderTypeMusicVideos": "Music videos", - "FolderTypeHomeVideos": "Home videos", - "FolderTypeGames": "Games", - "FolderTypeBooks": "Books", - "FolderTypeTvShows": "TV", - "FolderTypeInherit": "Inherit", - "HeaderCastCrew": "Cast & Crew", - "HeaderPeople": "People", - "ValueSpecialEpisodeName": "Special - {0}", - "LabelChapterName": "Chapter {0}", - "NameSeasonNumber": "Season {0}", - "LabelExit": "Exit", - "LabelVisitCommunity": "Visit Community", - "LabelGithub": "Github", - "LabelApiDocumentation": "Api Documentation", - "LabelDeveloperResources": "Developer Resources", - "LabelBrowseLibrary": "Browse Library", - "LabelConfigureServer": "Configure Emby", - "LabelRestartServer": "Restart Server", - "CategorySync": "Sync", - "CategoryUser": "User", - "CategorySystem": "System", - "CategoryApplication": "Application", - "CategoryPlugin": "Plugin", - "NotificationOptionPluginError": "Plugin failure", - "NotificationOptionApplicationUpdateAvailable": "Application update available", - "NotificationOptionApplicationUpdateInstalled": "Application update installed", - "NotificationOptionPluginUpdateInstalled": "Plugin update installed", - "NotificationOptionPluginInstalled": "Plugin installed", - "NotificationOptionPluginUninstalled": "Plugin uninstalled", - "NotificationOptionVideoPlayback": "Video playback started", - "NotificationOptionAudioPlayback": "Audio playback started", - "NotificationOptionGamePlayback": "Game playback started", - "NotificationOptionVideoPlaybackStopped": "Video playback stopped", - "NotificationOptionAudioPlaybackStopped": "Audio playback stopped", - "NotificationOptionGamePlaybackStopped": "Game playback stopped", - "NotificationOptionTaskFailed": "Scheduled task failure", - "NotificationOptionInstallationFailed": "Installation failure", - "NotificationOptionNewLibraryContent": "New content added", - "NotificationOptionNewLibraryContentMultiple": "New content added (multiple)", - "NotificationOptionCameraImageUploaded": "Camera image uploaded", - "NotificationOptionUserLockedOut": "User locked out", - "NotificationOptionServerRestartRequired": "Server restart required", - "ViewTypePlaylists": "Playlists", - "ViewTypeMovies": "Movies", - "ViewTypeTvShows": "TV", - "ViewTypeGames": "Games", - "ViewTypeMusic": "Music", - "ViewTypeMusicGenres": "Genres", - "ViewTypeMusicArtists": "Artists", - "ViewTypeBoxSets": "Collections", - "ViewTypeChannels": "Channels", - "ViewTypeLiveTV": "Live TV", - "ViewTypeLiveTvNowPlaying": "Now Airing", - "ViewTypeLatestGames": "Latest Games", - "ViewTypeRecentlyPlayedGames": "Recently Played", - "ViewTypeGameFavorites": "Favorites", - "ViewTypeGameSystems": "Game Systems", - "ViewTypeGameGenres": "Genres", - "ViewTypeTvResume": "Resume", - "ViewTypeTvNextUp": "Next Up", - "ViewTypeTvLatest": "Latest", - "ViewTypeTvShowSeries": "Series", - "ViewTypeTvGenres": "Genres", - "ViewTypeTvFavoriteSeries": "Favorite Series", - "ViewTypeTvFavoriteEpisodes": "Favorite Episodes", - "ViewTypeMovieResume": "Resume", - "ViewTypeMovieLatest": "Latest", - "ViewTypeMovieMovies": "Movies", - "ViewTypeMovieCollections": "Collections", - "ViewTypeMovieFavorites": "Favorites", - "ViewTypeMovieGenres": "Genres", - "ViewTypeMusicLatest": "Latest", - "ViewTypeMusicPlaylists": "Playlists", - "ViewTypeMusicAlbums": "Albums", - "ViewTypeMusicAlbumArtists": "Album Artists", - "HeaderOtherDisplaySettings": "Display Settings", - "ViewTypeMusicSongs": "Songs", - "ViewTypeMusicFavorites": "Favorites", - "ViewTypeMusicFavoriteAlbums": "Favorite Albums", - "ViewTypeMusicFavoriteArtists": "Favorite Artists", - "ViewTypeMusicFavoriteSongs": "Favorite Songs", - "ViewTypeFolders": "Folders", - "ViewTypeLiveTvRecordingGroups": "Recordings", - "ViewTypeLiveTvChannels": "Channels", - "ScheduledTaskFailedWithName": "{0} failed", - "LabelRunningTimeValue": "Running time: {0}", - "ScheduledTaskStartedWithName": "{0} started", - "VersionNumber": "Version {0}", - "PluginInstalledWithName": "{0} was installed", - "PluginUpdatedWithName": "{0} was updated", - "PluginUninstalledWithName": "{0} was uninstalled", - "ItemAddedWithName": "{0} was added to the library", - "ItemRemovedWithName": "{0} was removed from the library", - "LabelIpAddressValue": "Ip address: {0}", - "DeviceOnlineWithName": "{0} is connected", - "UserOnlineFromDevice": "{0} is online from {1}", - "ProviderValue": "Provider: {0}", - "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", - "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}", - "UserCreatedWithName": "User {0} has been created", - "UserPasswordChangedWithName": "Password has been changed for user {0}", - "UserDeletedWithName": "User {0} has been deleted", - "MessageServerConfigurationUpdated": "Server configuration has been updated", - "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", - "MessageApplicationUpdated": "Emby Server has been updated", - "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", - "AuthenticationSucceededWithUserName": "{0} successfully authenticated", - "DeviceOfflineWithName": "{0} has disconnected", - "UserLockedOutWithName": "User {0} has been locked out", - "UserOfflineFromDevice": "{0} has disconnected from {1}", - "UserStartedPlayingItemWithValues": "{0} has started playing {1}", - "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}", - "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", - "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", - "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image", - "HeaderOverview": "Overview", - "HeaderShortOverview": "Short Overview", - "HeaderType": "Type", - "HeaderSeverity": "Severity", - "HeaderUser": "User", - "HeaderName": "Name", - "HeaderDate": "Date", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", - "HeaderReleaseDate": "Release date", - "HeaderRuntime": "Runtime", - "HeaderPlayCount": "Play Count", - "HeaderSeason": "Season", - "HeaderSeasonNumber": "Season number", - "HeaderSeries": "Series:", - "HeaderNetwork": "Network", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", - "HeaderCommunityRating": "Community rating", - "HeaderTrailers": "Trailers", - "HeaderSpecials": "Specials", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", - "HeaderAlbums": "Albums", - "HeaderDisc": "Disc", - "HeaderTrack": "Track", - "HeaderAudio": "Audio", - "HeaderVideo": "Video", - "HeaderEmbeddedImage": "Embedded image", - "HeaderResolution": "Resolution", - "HeaderSubtitles": "Subtitles", - "HeaderGenres": "Genres", - "HeaderCountries": "Countries", - "HeaderStatus": "Status", - "HeaderTracks": "Tracks", - "HeaderMusicArtist": "Music artist", - "HeaderLocked": "Locked", - "HeaderStudios": "Studios", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", - "HeaderParentalRatings": "Parental Ratings", - "HeaderCommunityRatings": "Community ratings", - "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.", - "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete." -} diff --git a/Emby.Server.Implementations/Localization/Core/en-US.json b/Emby.Server.Implementations/Localization/Core/en-US.json index bc0dc236d..c7f865233 100644 --- a/Emby.Server.Implementations/Localization/Core/en-US.json +++ b/Emby.Server.Implementations/Localization/Core/en-US.json @@ -1,5 +1,4 @@ { - "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete.", "AppDeviceValues": "App: {0}, Device: {1}", "UserDownloadingItemWithValues": "{0} is downloading {1}", "FolderTypeMixed": "Mixed content", @@ -13,15 +12,12 @@ "FolderTypeBooks": "Books", "FolderTypeTvShows": "TV", "FolderTypeInherit": "Inherit", - "HeaderCastCrew": "Cast & Crew", - "HeaderPeople": "People", "ValueSpecialEpisodeName": "Special - {0}", "LabelChapterName": "Chapter {0}", "NameSeasonUnknown": "Season Unknown", "NameSeasonNumber": "Season {0}", "LabelExit": "Exit", "LabelVisitCommunity": "Visit Community", - "LabelGithub": "Github", "LabelApiDocumentation": "Api Documentation", "LabelDeveloperResources": "Developer Resources", "LabelBrowseLibrary": "Browse Library", @@ -69,7 +65,7 @@ "ViewTypeTvResume": "Resume", "ViewTypeTvNextUp": "Next Up", "ViewTypeTvLatest": "Latest", - "ViewTypeTvShowSeries": "Series", + "ViewTypeTvShowSeries": "Shows", "ViewTypeTvGenres": "Genres", "ViewTypeTvFavoriteSeries": "Favorite Series", "ViewTypeTvFavoriteEpisodes": "Favorite Episodes", @@ -164,15 +160,5 @@ "HeaderStatus": "Status", "HeaderTracks": "Tracks", "HeaderMusicArtist": "Music artist", - "HeaderLocked": "Locked", - "HeaderStudios": "Studios", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", - "HeaderParentalRatings": "Parental Ratings", - "HeaderCommunityRatings": "Community ratings", "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly." }
\ No newline at end of file diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 64a41acef..278a39cd1 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.Localization /// Gets the cultures. /// </summary> /// <returns>IEnumerable{CultureDto}.</returns> - public IEnumerable<CultureDto> GetCultures() + public CultureDto[] GetCultures() { var type = GetType(); var path = type.Namespace + ".iso6392.txt"; @@ -169,21 +169,21 @@ namespace Emby.Server.Implementations.Localization return list.Where(i => !string.IsNullOrWhiteSpace(i.Name) && !string.IsNullOrWhiteSpace(i.DisplayName) && !string.IsNullOrWhiteSpace(i.ThreeLetterISOLanguageName) && - !string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)); + !string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)).ToArray(); } /// <summary> /// Gets the countries. /// </summary> /// <returns>IEnumerable{CountryInfo}.</returns> - public IEnumerable<CountryInfo> GetCountries() + public CountryInfo[] GetCountries() { var type = GetType(); var path = type.Namespace + ".countries.json"; using (var stream = _assemblyInfo.GetManifestResourceStream(type, path)) { - return _jsonSerializer.DeserializeFromStream<List<CountryInfo>>(stream); + return _jsonSerializer.DeserializeFromStream<CountryInfo[]>(stream); } } @@ -191,9 +191,9 @@ namespace Emby.Server.Implementations.Localization /// Gets the parental ratings. /// </summary> /// <returns>IEnumerable{ParentalRating}.</returns> - public IEnumerable<ParentalRating> GetParentalRatings() + public ParentalRating[] GetParentalRatings() { - return GetParentalRatingsDictionary().Values.ToList(); + return GetParentalRatingsDictionary().Values.ToArray(); } /// <summary> @@ -335,7 +335,7 @@ namespace Emby.Server.Implementations.Localization const string prefix = "Core"; var key = prefix + culture; - return _dictionaries.GetOrAdd(key, k => GetDictionary(prefix, culture, "core.json")); + return _dictionaries.GetOrAdd(key, k => GetDictionary(prefix, culture, "en-US.json")); } private Dictionary<string, string> GetDictionary(string prefix, string culture, string baseFilename) @@ -382,9 +382,9 @@ namespace Emby.Server.Implementations.Localization return culture + ".json"; } - public IEnumerable<LocalizatonOption> GetLocalizationOptions() + public LocalizatonOption[] GetLocalizationOptions() { - return new List<LocalizatonOption> + return new LocalizatonOption[] { new LocalizatonOption{ Name="Arabic", Value="ar"}, new LocalizatonOption{ Name="Bulgarian (Bulgaria)", Value="bg-BG"}, @@ -421,7 +421,7 @@ namespace Emby.Server.Implementations.Localization new LocalizatonOption{ Name="Ukrainian", Value="uk"}, new LocalizatonOption{ Name="Vietnamese", Value="vi"} - }.OrderBy(i => i.Name); + }; } } diff --git a/Emby.Server.Implementations/Localization/Ratings/es.txt b/Emby.Server.Implementations/Localization/Ratings/es.txt index 1ba24fb99..32a1e6438 100644 --- a/Emby.Server.Implementations/Localization/Ratings/es.txt +++ b/Emby.Server.Implementations/Localization/Ratings/es.txt @@ -1,4 +1,5 @@ ES-A,1 +ES-APTA,1 ES-7,3 ES-12,6 ES-16,8 diff --git a/Emby.Server.Implementations/Localization/Ratings/ro.txt b/Emby.Server.Implementations/Localization/Ratings/ro.txt new file mode 100644 index 000000000..3fdaed9cc --- /dev/null +++ b/Emby.Server.Implementations/Localization/Ratings/ro.txt @@ -0,0 +1 @@ +RO-AG,1
\ No newline at end of file diff --git a/Emby.Server.Implementations/Localization/Ratings/us.txt b/Emby.Server.Implementations/Localization/Ratings/us.txt index 3f5311e0e..9bd78c72b 100644 --- a/Emby.Server.Implementations/Localization/Ratings/us.txt +++ b/Emby.Server.Implementations/Localization/Ratings/us.txt @@ -1,3 +1,4 @@ +APPROVED,1 G,1 E,1 EC,1 diff --git a/Emby.Server.Implementations/Localization/TextLocalizer.cs b/Emby.Server.Implementations/Localization/TextLocalizer.cs new file mode 100644 index 000000000..5188a959e --- /dev/null +++ b/Emby.Server.Implementations/Localization/TextLocalizer.cs @@ -0,0 +1,63 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace Emby.Server.Implementations.Localization +{ + public class TextLocalizer : ITextLocalizer + { + public string RemoveDiacritics(string text) + { + if (text == null) + { + throw new ArgumentNullException("text"); + } + + var chars = Normalize(text, NormalizationForm.FormD) + .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != UnicodeCategory.NonSpacingMark); + + return Normalize(String.Concat(chars), NormalizationForm.FormC); + } + + private static string Normalize(string text, NormalizationForm form, bool stripStringOnFailure = true) + { + if (stripStringOnFailure) + { + try + { + return text.Normalize(form); + } + catch (ArgumentException) + { + // will throw if input contains invalid unicode chars + // https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/ + text = StripInvalidUnicodeCharacters(text); + return Normalize(text, form, false); + } + } + + try + { + return text.Normalize(form); + } + catch (ArgumentException) + { + // if it still fails, return the original text + return text; + } + } + + private static string StripInvalidUnicodeCharacters(string str) + { + var invalidCharactersRegex = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])"); + return invalidCharactersRegex.Replace(str, ""); + } + + public string NormalizeFormKD(string text) + { + return text.Normalize(NormalizationForm.FormKD); + } + } +} diff --git a/Emby.Server.Implementations/Logging/ConsoleLogger.cs b/Emby.Server.Implementations/Logging/ConsoleLogger.cs new file mode 100644 index 000000000..51199f08a --- /dev/null +++ b/Emby.Server.Implementations/Logging/ConsoleLogger.cs @@ -0,0 +1,13 @@ +using System; +using MediaBrowser.Model.Logging; + +namespace Emby.Server.Implementations.Logging +{ + public class ConsoleLogger : IConsoleLogger + { + public void WriteLine(string message) + { + Console.WriteLine(message); + } + } +} diff --git a/Emby.Server.Implementations/Logging/SimpleLogManager.cs b/Emby.Server.Implementations/Logging/SimpleLogManager.cs new file mode 100644 index 000000000..6129f38c4 --- /dev/null +++ b/Emby.Server.Implementations/Logging/SimpleLogManager.cs @@ -0,0 +1,301 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; + +namespace Emby.Server.Implementations.Logging +{ + public class SimpleLogManager : ILogManager, IDisposable + { + public LogSeverity LogSeverity { get; set; } + public string ExceptionMessagePrefix { get; set; } + private FileLogger _fileLogger; + + private readonly string LogDirectory; + private readonly string LogFilePrefix; + public string DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; + + public SimpleLogManager(string logDirectory, string logFileNamePrefix) + { + LogDirectory = logDirectory; + LogFilePrefix = logFileNamePrefix; + } + + public ILogger GetLogger(string name) + { + return new NamedLogger(name, this); + } + + public void ReloadLogger(LogSeverity severity) + { + LogSeverity = severity; + + var logger = _fileLogger; + if (logger != null) + { + logger.Dispose(); + } + + var path = Path.Combine(LogDirectory, LogFilePrefix + "-" + decimal.Floor(DateTime.Now.Ticks / 10000000) + ".txt"); + + _fileLogger = new FileLogger(path); + + if (LoggerLoaded != null) + { + try + { + + LoggerLoaded(this, EventArgs.Empty); + + } + catch (Exception ex) + { + GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex); + } + } + } + + public event EventHandler LoggerLoaded; + + public void Flush() + { + var logger = _fileLogger; + if (logger != null) + { + logger.Flush(); + } + } + + private bool _console = true; + public void AddConsoleOutput() + { + _console = true; + } + + public void RemoveConsoleOutput() + { + _console = false; + } + + public void Log(string message) + { + if (_console) + { + Console.WriteLine(message); + } + + var logger = _fileLogger; + if (logger != null) + { + message = DateTime.Now.ToString(DateTimeFormat) + " " + message; + + logger.Log(message); + } + } + + public void Dispose() + { + var logger = _fileLogger; + if (logger != null) + { + logger.Dispose(); + } + + _fileLogger = null; + GC.SuppressFinalize(this); + } + } + + public class FileLogger : IDisposable + { + private readonly FileStream _fileStream; + + private bool _disposed; + private readonly CancellationTokenSource _cancellationTokenSource; + private readonly BlockingCollection<string> _queue = new BlockingCollection<string>(); + + public FileLogger(string path) + { + Directory.CreateDirectory(Path.GetDirectoryName(path)); + + _fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, 32768); + _cancellationTokenSource = new CancellationTokenSource(); + + Task.Factory.StartNew(LogInternal, _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); + } + + private void LogInternal() + { + while (!_cancellationTokenSource.IsCancellationRequested && !_disposed) + { + try + { + foreach (var message in _queue.GetConsumingEnumerable()) + { + var bytes = Encoding.UTF8.GetBytes(message + Environment.NewLine); + if (_disposed) + { + return; + } + + _fileStream.Write(bytes, 0, bytes.Length); + + _fileStream.Flush(true); + } + } + catch + { + + } + } + } + + public void Log(string message) + { + if (_disposed) + { + return; + } + + _queue.Add(message); + } + + public void Flush() + { + if (_disposed) + { + return; + } + + _fileStream.Flush(true); + } + + public void Dispose() + { + _cancellationTokenSource.Cancel(); + + Flush(); + + _disposed = true; + _fileStream.Dispose(); + GC.SuppressFinalize(this); + } + } + + public class NamedLogger : ILogger + { + public string Name { get; private set; } + private readonly SimpleLogManager _logManager; + + public NamedLogger(string name, SimpleLogManager logManager) + { + Name = name; + _logManager = logManager; + } + + public void Info(string message, params object[] paramList) + { + Log(LogSeverity.Info, message, paramList); + } + + public void Error(string message, params object[] paramList) + { + Log(LogSeverity.Error, message, paramList); + } + + public void Warn(string message, params object[] paramList) + { + Log(LogSeverity.Warn, message, paramList); + } + + public void Debug(string message, params object[] paramList) + { + if (_logManager.LogSeverity == LogSeverity.Info) + { + return; + } + Log(LogSeverity.Debug, message, paramList); + } + + public void Fatal(string message, params object[] paramList) + { + Log(LogSeverity.Fatal, message, paramList); + } + + public void FatalException(string message, Exception exception, params object[] paramList) + { + ErrorException(message, exception, paramList); + } + + public void ErrorException(string message, Exception exception, params object[] paramList) + { + LogException(LogSeverity.Error, message, exception, paramList); + } + + private void LogException(LogSeverity level, string message, Exception exception, params object[] paramList) + { + message = FormatMessage(message, paramList).Replace(Environment.NewLine, ". "); + + var messageText = LogHelper.GetLogMessage(exception); + + var prefix = _logManager.ExceptionMessagePrefix; + + if (!string.IsNullOrWhiteSpace(prefix)) + { + messageText.Insert(0, prefix); + } + + LogMultiline(message, level, messageText); + } + + private static string FormatMessage(string message, params object[] paramList) + { + if (paramList != null) + { + for (var i = 0; i < paramList.Length; i++) + { + var obj = paramList[i]; + + message = message.Replace("{" + i + "}", (obj == null ? "null" : obj.ToString())); + } + } + + return message; + } + + public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent) + { + if (severity == LogSeverity.Debug && _logManager.LogSeverity == LogSeverity.Info) + { + return; + } + + additionalContent.Insert(0, message + Environment.NewLine); + + const char tabChar = '\t'; + + var text = additionalContent.ToString() + .Replace(Environment.NewLine, Environment.NewLine + tabChar) + .TrimEnd(tabChar); + + if (text.EndsWith(Environment.NewLine)) + { + text = text.Substring(0, text.LastIndexOf(Environment.NewLine, StringComparison.OrdinalIgnoreCase)); + } + + Log(severity, text); + } + + public void Log(LogSeverity severity, string message, params object[] paramList) + { + message = severity + " " + Name + ": " + FormatMessage(message, paramList); + + _logManager.Log(message); + } + } +} diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs index 1d74e8788..9a9e619a6 100644 --- a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -29,9 +29,9 @@ namespace Emby.Server.Implementations.MediaEncoder private readonly IChapterManager _chapterManager; private readonly ILibraryManager _libraryManager; - public EncodingManager(IFileSystem fileSystem, - ILogger logger, - IMediaEncoder encoder, + public EncodingManager(IFileSystem fileSystem, + ILogger logger, + IMediaEncoder encoder, IChapterManager chapterManager, ILibraryManager libraryManager) { _fileSystem = fileSystem; @@ -45,7 +45,7 @@ namespace Emby.Server.Implementations.MediaEncoder /// Gets the chapter images data path. /// </summary> /// <value>The chapter images data path.</value> - private string GetChapterImagesPath(IHasImages item) + private string GetChapterImagesPath(IHasMetadata item) { return Path.Combine(item.GetInternalMetadataPath(), "chapters"); } @@ -75,6 +75,11 @@ namespace Emby.Server.Implementations.MediaEncoder return false; } + if (!video.IsCompleteMedia) + { + return false; + } + // Can't extract images if there are no video streams return video.DefaultVideoStreamIndex.HasValue; } @@ -84,13 +89,8 @@ namespace Emby.Server.Implementations.MediaEncoder /// </summary> private static readonly long FirstChapterTicks = TimeSpan.FromSeconds(15).Ticks; - public async Task<bool> RefreshChapterImages(ChapterImageRefreshOptions options, CancellationToken cancellationToken) + public async Task<bool> RefreshChapterImages(Video video, List<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken) { - var extractImages = options.ExtractImages; - var video = options.Video; - var chapters = options.Chapters; - var saveChapters = options.SaveChapters; - if (!IsEligibleForChapterImageExtraction(video)) { extractImages = false; @@ -117,16 +117,14 @@ namespace Emby.Server.Implementations.MediaEncoder { if (extractImages) { - if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso) + if (video.VideoType == VideoType.Iso) { continue; } + if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd) { - if (video.PlayableStreamFileNames.Count != 1) - { - continue; - } + continue; } try @@ -136,13 +134,13 @@ namespace Emby.Server.Implementations.MediaEncoder var protocol = MediaProtocol.File; - var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames); + var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, new string[] { }); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); var container = video.Container; - var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false); + var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.GetDefaultVideoStream(), video.Video3DFormat, time, cancellationToken).ConfigureAwait(false); _fileSystem.CopyFile(tempFile, path, true); try @@ -151,7 +149,7 @@ namespace Emby.Server.Implementations.MediaEncoder } catch { - + } chapter.ImagePath = path; @@ -181,7 +179,7 @@ namespace Emby.Server.Implementations.MediaEncoder if (saveChapters && changesMade) { - await _chapterManager.SaveChapters(video.Id.ToString(), chapters, cancellationToken).ConfigureAwait(false); + _chapterManager.SaveChapters(video.Id.ToString(), chapters); } DeleteDeadImages(currentImages, chapters); diff --git a/Emby.Server.Implementations/Net/DisposableManagedObjectBase.cs b/Emby.Server.Implementations/Net/DisposableManagedObjectBase.cs new file mode 100644 index 000000000..b18335da7 --- /dev/null +++ b/Emby.Server.Implementations/Net/DisposableManagedObjectBase.cs @@ -0,0 +1,71 @@ +using System; + +namespace Emby.Server.Implementations.Net +{ + /// <summary> + /// Correclty implements the <see cref="IDisposable"/> interface and pattern for an object containing only managed resources, and adds a few common niceities not on the interface such as an <see cref="IsDisposed"/> property. + /// </summary> + public abstract class DisposableManagedObjectBase : IDisposable + { + + #region Public Methods + + /// <summary> + /// Override this method and dispose any objects you own the lifetime of if disposing is true; + /// </summary> + /// <param name="disposing">True if managed objects should be disposed, if false, only unmanaged resources should be released.</param> + protected abstract void Dispose(bool disposing); + + /// <summary> + /// Throws and <see cref="System.ObjectDisposedException"/> if the <see cref="IsDisposed"/> property is true. + /// </summary> + /// <seealso cref="IsDisposed"/> + /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="IsDisposed"/> property is true.</exception> + /// <seealso cref="Dispose()"/> + protected virtual void ThrowIfDisposed() + { + if (this.IsDisposed) throw new ObjectDisposedException(this.GetType().FullName); + } + + #endregion + + #region Public Properties + + /// <summary> + /// Sets or returns a boolean indicating whether or not this instance has been disposed. + /// </summary> + /// <seealso cref="Dispose()"/> + public bool IsDisposed + { + get; + private set; + } + + #endregion + + #region IDisposable Members + + /// <summary> + /// Disposes this object instance and all internally managed resources. + /// </summary> + /// <remarks> + /// <para>Sets the <see cref="IsDisposed"/> property to true. Does not explicitly throw an exception if called multiple times, but makes no promises about behaviour of derived classes.</para> + /// </remarks> + /// <seealso cref="IsDisposed"/> + public void Dispose() + { + try + { + IsDisposed = true; + + Dispose(true); + } + finally + { + GC.SuppressFinalize(this); + } + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/Net/NetAcceptSocket.cs b/Emby.Server.Implementations/Net/NetAcceptSocket.cs new file mode 100644 index 000000000..d80341a07 --- /dev/null +++ b/Emby.Server.Implementations/Net/NetAcceptSocket.cs @@ -0,0 +1,98 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; +using Emby.Server.Implementations.Networking; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; + +namespace Emby.Server.Implementations.Net +{ + public class NetAcceptSocket : IAcceptSocket + { + public Socket Socket { get; private set; } + private readonly ILogger _logger; + + public bool DualMode { get; private set; } + + public NetAcceptSocket(Socket socket, ILogger logger, bool isDualMode) + { + if (socket == null) + { + throw new ArgumentNullException("socket"); + } + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + Socket = socket; + _logger = logger; + DualMode = isDualMode; + } + + public IpEndPointInfo LocalEndPoint + { + get + { + return NetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.LocalEndPoint); + } + } + + public IpEndPointInfo RemoteEndPoint + { + get + { + return NetworkManager.ToIpEndPointInfo((IPEndPoint)Socket.RemoteEndPoint); + } + } + + public void Connect(IpEndPointInfo endPoint) + { + var nativeEndpoint = NetworkManager.ToIPEndPoint(endPoint); + + Socket.Connect(nativeEndpoint); + } + + public void Close() + { +#if NET46 + Socket.Close(); +#else + Socket.Dispose(); +#endif + } + + public void Shutdown(bool both) + { + if (both) + { + Socket.Shutdown(SocketShutdown.Both); + } + else + { + // Change interface if ever needed + throw new NotImplementedException(); + } + } + + public void Listen(int backlog) + { + Socket.Listen(backlog); + } + + public void Bind(IpEndPointInfo endpoint) + { + var nativeEndpoint = NetworkManager.ToIPEndPoint(endpoint); + + Socket.Bind(nativeEndpoint); + } + + public void Dispose() + { + Socket.Dispose(); + GC.SuppressFinalize(this); + } + } +} diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs new file mode 100644 index 000000000..f78fbdfd7 --- /dev/null +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -0,0 +1,303 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using Emby.Server.Implementations.Networking; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; + +namespace Emby.Server.Implementations.Net +{ + public class SocketFactory : ISocketFactory + { + // THIS IS A LINKED FILE - SHARED AMONGST MULTIPLE PLATFORMS + // Be careful to check any changes compile and work for all platform projects it is shared in. + + // Not entirely happy with this. Would have liked to have done something more generic/reusable, + // but that wasn't really the point so kept to YAGNI principal for now, even if the + // interfaces are a bit ugly, specific and make assumptions. + + private readonly ILogger _logger; + + public SocketFactory(ILogger logger) + { + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + _logger = logger; + } + + public IAcceptSocket CreateSocket(IpAddressFamily family, MediaBrowser.Model.Net.SocketType socketType, MediaBrowser.Model.Net.ProtocolType protocolType, bool dualMode) + { + try + { + var addressFamily = family == IpAddressFamily.InterNetwork + ? AddressFamily.InterNetwork + : AddressFamily.InterNetworkV6; + + var socket = new Socket(addressFamily, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp); + + if (dualMode) + { + socket.DualMode = true; + } + + return new NetAcceptSocket(socket, _logger, dualMode); + } + catch (SocketException ex) + { + throw new SocketCreateException(ex.SocketErrorCode.ToString(), ex); + } + catch (ArgumentException ex) + { + if (dualMode) + { + // Mono for BSD incorrectly throws ArgumentException instead of SocketException + throw new SocketCreateException("AddressFamilyNotSupported", ex); + } + else + { + throw; + } + } + } + + public ISocket CreateTcpSocket(IpAddressInfo remoteAddress, int remotePort) + { + if (remotePort < 0) throw new ArgumentException("remotePort cannot be less than zero.", "remotePort"); + + var addressFamily = remoteAddress.AddressFamily == IpAddressFamily.InterNetwork + ? AddressFamily.InterNetwork + : AddressFamily.InterNetworkV6; + + var retVal = new Socket(addressFamily, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp); + + try + { + retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + } + catch (SocketException) + { + // This is not supported on all operating systems (qnap) + } + + try + { + return new UdpSocket(retVal, new IpEndPointInfo(remoteAddress, remotePort)); + } + catch + { + if (retVal != null) + retVal.Dispose(); + + throw; + } + } + + /// <summary> + /// Creates a new UDP acceptSocket and binds it to the specified local port. + /// </summary> + /// <param name="localPort">An integer specifying the local port to bind the acceptSocket to.</param> + public ISocket CreateUdpSocket(int localPort) + { + if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); + + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); + try + { + retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + return new UdpSocket(retVal, localPort, IPAddress.Any); + } + catch + { + if (retVal != null) + retVal.Dispose(); + + throw; + } + } + + public ISocket CreateUdpBroadcastSocket(int localPort) + { + if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); + + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); + try + { + retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); + + return new UdpSocket(retVal, localPort, IPAddress.Any); + } + catch + { + if (retVal != null) + retVal.Dispose(); + + throw; + } + } + + /// <summary> + /// Creates a new UDP acceptSocket that is a member of the SSDP multicast local admin group and binds it to the specified local port. + /// </summary> + /// <returns>An implementation of the <see cref="ISocket"/> interface used by RSSDP components to perform acceptSocket operations.</returns> + public ISocket CreateSsdpUdpSocket(IpAddressInfo localIpAddress, int localPort) + { + if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); + + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); + try + { + retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); + + var localIp = NetworkManager.ToIPAddress(localIpAddress); + + retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIp)); + return new UdpSocket(retVal, localPort, localIp); + } + catch + { + if (retVal != null) + retVal.Dispose(); + + throw; + } + } + + /// <summary> + /// Creates a new UDP acceptSocket that is a member of the specified multicast IP address, and binds it to the specified local port. + /// </summary> + /// <param name="ipAddress">The multicast IP address to make the acceptSocket a member of.</param> + /// <param name="multicastTimeToLive">The multicast time to live value for the acceptSocket.</param> + /// <param name="localPort">The number of the local port to bind to.</param> + /// <returns></returns> + public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) + { + if (ipAddress == null) throw new ArgumentNullException("ipAddress"); + if (ipAddress.Length == 0) throw new ArgumentException("ipAddress cannot be an empty string.", "ipAddress"); + if (multicastTimeToLive <= 0) throw new ArgumentException("multicastTimeToLive cannot be zero or less.", "multicastTimeToLive"); + if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort"); + + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); + + try + { + // not supported on all platforms. throws on ubuntu with .net core 2.0 + retVal.ExclusiveAddressUse = false; + } + catch (SocketException) + { + + } + + try + { + //retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); + retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); + + var localIp = IPAddress.Any; + + retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); + retVal.MulticastLoopback = true; + + return new UdpSocket(retVal, localPort, localIp); + } + catch + { + if (retVal != null) + retVal.Dispose(); + + throw; + } + } + + public Stream CreateNetworkStream(ISocket socket, bool ownsSocket) + { + var netSocket = (UdpSocket)socket; + + return new SocketStream(netSocket.Socket, ownsSocket); + } + } + + public class SocketStream : Stream + { + private readonly Socket _socket; + + public SocketStream(Socket socket, bool ownsSocket) + { + _socket = socket; + } + + public override void Flush() + { + } + + public override bool CanRead + { + get { return true; } + } + public override bool CanSeek + { + get { return false; } + } + public override bool CanWrite + { + get { return true; } + } + public override long Length + { + get { throw new NotImplementedException(); } + } + public override long Position + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public override void Write(byte[] buffer, int offset, int count) + { + _socket.Send(buffer, offset, count, SocketFlags.None); + } + + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + return _socket.BeginSend(buffer, offset, count, SocketFlags.None, callback, state); + } + + public override void EndWrite(IAsyncResult asyncResult) + { + _socket.EndSend(asyncResult); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + return _socket.Receive(buffer, offset, count, SocketFlags.None); + } + + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + return _socket.BeginReceive(buffer, offset, count, SocketFlags.None, callback, state); + } + + public override int EndRead(IAsyncResult asyncResult) + { + return _socket.EndReceive(asyncResult); + } + } + +} diff --git a/Emby.Server.Implementations/Net/UdpSocket.cs b/Emby.Server.Implementations/Net/UdpSocket.cs new file mode 100644 index 000000000..58e4d6f89 --- /dev/null +++ b/Emby.Server.Implementations/Net/UdpSocket.cs @@ -0,0 +1,255 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; +using Emby.Server.Implementations.Networking; +using MediaBrowser.Model.Net; + +namespace Emby.Server.Implementations.Net +{ + // THIS IS A LINKED FILE - SHARED AMONGST MULTIPLE PLATFORMS + // Be careful to check any changes compile and work for all platform projects it is shared in. + + public sealed class UdpSocket : DisposableManagedObjectBase, ISocket + { + private Socket _Socket; + private int _LocalPort; + + public Socket Socket + { + get { return _Socket; } + } + + private readonly SocketAsyncEventArgs _receiveSocketAsyncEventArgs = new SocketAsyncEventArgs() + { + SocketFlags = SocketFlags.None + }; + + private readonly SocketAsyncEventArgs _sendSocketAsyncEventArgs = new SocketAsyncEventArgs() + { + SocketFlags = SocketFlags.None + }; + + private TaskCompletionSource<SocketReceiveResult> _currentReceiveTaskCompletionSource; + private TaskCompletionSource<int> _currentSendTaskCompletionSource; + + public UdpSocket(Socket socket, int localPort, IPAddress ip) + { + if (socket == null) throw new ArgumentNullException("socket"); + + _Socket = socket; + _LocalPort = localPort; + LocalIPAddress = NetworkManager.ToIpAddressInfo(ip); + + _Socket.Bind(new IPEndPoint(ip, _LocalPort)); + + InitReceiveSocketAsyncEventArgs(); + } + + private void InitReceiveSocketAsyncEventArgs() + { + var receiveBuffer = new byte[8192]; + _receiveSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length); + _receiveSocketAsyncEventArgs.Completed += _receiveSocketAsyncEventArgs_Completed; + + var sendBuffer = new byte[8192]; + _sendSocketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length); + _sendSocketAsyncEventArgs.Completed += _sendSocketAsyncEventArgs_Completed; + } + + private void _receiveSocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e) + { + var tcs = _currentReceiveTaskCompletionSource; + if (tcs != null) + { + _currentReceiveTaskCompletionSource = null; + + if (e.SocketError == SocketError.Success) + { + tcs.TrySetResult(new SocketReceiveResult + { + Buffer = e.Buffer, + ReceivedBytes = e.BytesTransferred, + RemoteEndPoint = ToIpEndPointInfo(e.RemoteEndPoint as IPEndPoint), + LocalIPAddress = LocalIPAddress + }); + } + else + { + tcs.TrySetException(new Exception("SocketError: " + e.SocketError)); + } + } + } + + private void _sendSocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e) + { + var tcs = _currentSendTaskCompletionSource; + if (tcs != null) + { + _currentSendTaskCompletionSource = null; + + if (e.SocketError == SocketError.Success) + { + tcs.TrySetResult(e.BytesTransferred); + } + else + { + tcs.TrySetException(new Exception("SocketError: " + e.SocketError)); + } + } + } + + public UdpSocket(Socket socket, IpEndPointInfo endPoint) + { + if (socket == null) throw new ArgumentNullException("socket"); + + _Socket = socket; + _Socket.Connect(NetworkManager.ToIPEndPoint(endPoint)); + + InitReceiveSocketAsyncEventArgs(); + } + + public IpAddressInfo LocalIPAddress + { + get; + private set; + } + + public IAsyncResult BeginReceive(byte[] buffer, int offset, int count, AsyncCallback callback) + { + EndPoint receivedFromEndPoint = new IPEndPoint(IPAddress.Any, 0); + + return _Socket.BeginReceiveFrom(buffer, offset, count, SocketFlags.None, ref receivedFromEndPoint, callback, buffer); + } + + public int Receive(byte[] buffer, int offset, int count) + { + return _Socket.Receive(buffer, 0, buffer.Length, SocketFlags.None); + } + + public SocketReceiveResult EndReceive(IAsyncResult result) + { + IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); + EndPoint remoteEndPoint = (EndPoint)sender; + + var receivedBytes = _Socket.EndReceiveFrom(result, ref remoteEndPoint); + + var buffer = (byte[]) result.AsyncState; + + return new SocketReceiveResult + { + ReceivedBytes = receivedBytes, + RemoteEndPoint = ToIpEndPointInfo((IPEndPoint)remoteEndPoint), + Buffer = buffer, + LocalIPAddress = LocalIPAddress + }; + } + + public Task<SocketReceiveResult> ReceiveAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + var taskCompletion = new TaskCompletionSource<SocketReceiveResult>(); + + Action<IAsyncResult> callback = callbackResult => + { + try + { + taskCompletion.TrySetResult(EndReceive(callbackResult)); + } + catch (Exception ex) + { + taskCompletion.TrySetException(ex); + } + }; + + var result = BeginReceive(buffer, offset, count, new AsyncCallback(callback)); + + if (result.CompletedSynchronously) + { + callback(result); + } + + cancellationToken.Register(() => taskCompletion.TrySetCanceled()); + + return taskCompletion.Task; + } + + public Task<SocketReceiveResult> ReceiveAsync(CancellationToken cancellationToken) + { + var buffer = new byte[8192]; + + return ReceiveAsync(buffer, 0, buffer.Length, cancellationToken); + } + + public Task SendToAsync(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken) + { + var taskCompletion = new TaskCompletionSource<int>(); + + Action<IAsyncResult> callback = callbackResult => + { + try + { + taskCompletion.TrySetResult(EndSendTo(callbackResult)); + } + catch (Exception ex) + { + taskCompletion.TrySetException(ex); + } + }; + + var result = BeginSendTo(buffer, offset, size, endPoint, new AsyncCallback(callback), null); + + if (result.CompletedSynchronously) + { + callback(result); + } + + cancellationToken.Register(() => taskCompletion.TrySetCanceled()); + + return taskCompletion.Task; + } + + public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, AsyncCallback callback, object state) + { + var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint); + + return _Socket.BeginSendTo(buffer, offset, size, SocketFlags.None, ipEndPoint, callback, state); + } + + public int EndSendTo(IAsyncResult result) + { + return _Socket.EndSendTo(result); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + var socket = _Socket; + if (socket != null) + socket.Dispose(); + + var tcs = _currentReceiveTaskCompletionSource; + if (tcs != null) + { + tcs.TrySetCanceled(); + } + var sendTcs = _currentSendTaskCompletionSource; + if (sendTcs != null) + { + sendTcs.TrySetCanceled(); + } + } + } + + private static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint) + { + if (endpoint == null) + { + return null; + } + + return NetworkManager.ToIpEndPointInfo(endpoint); + } + } +} diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs new file mode 100644 index 000000000..b47c058df --- /dev/null +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -0,0 +1,531 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Threading.Tasks; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; + +namespace Emby.Server.Implementations.Networking +{ + public class NetworkManager : INetworkManager + { + protected ILogger Logger { get; private set; } + private DateTime _lastRefresh; + + public NetworkManager(ILogger logger) + { + Logger = logger; + } + + private List<IpAddressInfo> _localIpAddresses; + private readonly object _localIpAddressSyncLock = new object(); + + public List<IpAddressInfo> GetLocalIpAddresses() + { + const int cacheMinutes = 5; + + lock (_localIpAddressSyncLock) + { + var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; + + if (_localIpAddresses == null || forceRefresh) + { + var addresses = GetLocalIpAddressesInternal().Select(ToIpAddressInfo).ToList(); + + _localIpAddresses = addresses; + _lastRefresh = DateTime.UtcNow; + + return addresses; + } + } + + return _localIpAddresses; + } + + private IEnumerable<IPAddress> GetLocalIpAddressesInternal() + { + var list = GetIPsDefault() + .ToList(); + + if (list.Count == 0) + { + list.AddRange(GetLocalIpAddressesFallback().Result); + } + + 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).Result.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; + } + + private Task<IPAddress[]> GetIpAddresses(string hostName) + { + return Dns.GetHostAddressesAsync(hostName); + } + + private readonly List<NetworkInterfaceType> _validNetworkInterfaceTypes = new List<NetworkInterfaceType> + { + NetworkInterfaceType.Ethernet, + NetworkInterfaceType.Wireless80211 + }; + + private List<IPAddress> GetIPsDefault() + { + NetworkInterface[] interfaces; + + try + { + var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown }; + + interfaces = NetworkInterface.GetAllNetworkInterfaces() + .Where(i => validStatuses.Contains(i.OperationalStatus)) + .ToArray(); + } + catch (Exception ex) + { + Logger.ErrorException("Error in GetAllNetworkInterfaces", ex); + return new List<IPAddress>(); + } + + return interfaces.SelectMany(network => + { + + try + { + Logger.Debug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus); + + var ipProperties = network.GetIPProperties(); + + // Try to exclude virtual adapters + // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms + var addr = ipProperties.GatewayAddresses.FirstOrDefault(); + if (addr == null || string.Equals(addr.Address.ToString(), "0.0.0.0", StringComparison.OrdinalIgnoreCase)) + { + return new List<IPAddress>(); + } + + //if (!_validNetworkInterfaceTypes.Contains(network.NetworkInterfaceType)) + //{ + // return new List<IPAddress>(); + //} + + return ipProperties.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<IPAddress>(); + } + + }).DistinctBy(i => i.ToString()) + .ToList(); + } + + private async Task<IEnumerable<IPAddress>> GetLocalIpAddressesFallback() + { + var host = await Dns.GetHostEntryAsync(Dns.GetHostName()).ConfigureAwait(false); + + // 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(); + } + + /// <summary> + /// Gets a random port number that is currently available + /// </summary> + /// <returns>System.Int32.</returns> + public int GetRandomUnusedTcpPort() + { + var listener = new TcpListener(IPAddress.Any, 0); + listener.Start(); + var port = ((IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + return port; + } + + public int GetRandomUnusedUdpPort() + { + IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 0); + using (var udpClient = new UdpClient(localEndPoint)) + { + var port = ((IPEndPoint)(udpClient.Client.LocalEndPoint)).Port; + return port; + } + } + + /// <summary> + /// Returns MAC Address from first Network Card in Computer + /// </summary> + /// <returns>[string] MAC Address</returns> + public string GetMacAddress() + { + return NetworkInterface.GetAllNetworkInterfaces() + .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback) + .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes())) + .FirstOrDefault(); + } + + /// <summary> + /// Parses the specified endpointstring. + /// </summary> + /// <param name="endpointstring">The endpointstring.</param> + /// <returns>IPEndPoint.</returns> + public IPEndPoint Parse(string endpointstring) + { + return Parse(endpointstring, -1).Result; + } + + /// <summary> + /// Parses the specified endpointstring. + /// </summary> + /// <param name="endpointstring">The endpointstring.</param> + /// <param name="defaultport">The defaultport.</param> + /// <returns>IPEndPoint.</returns> + /// <exception cref="System.ArgumentException">Endpoint descriptor may not be empty.</exception> + /// <exception cref="System.FormatException"></exception> + private static async Task<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 = await GetIPfromHost(values[0]).ConfigureAwait(false); + } + 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"); + + /// <summary> + /// Gets the port. + /// </summary> + /// <param name="p">The p.</param> + /// <returns>System.Int32.</returns> + /// <exception cref="System.FormatException"></exception> + 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; + } + + /// <summary> + /// Gets the I pfrom host. + /// </summary> + /// <param name="p">The p.</param> + /// <returns>IPAddress.</returns> + /// <exception cref="System.ArgumentException"></exception> + private static async Task<IPAddress> GetIPfromHost(string p) + { + var hosts = await Dns.GetHostAddressesAsync(p).ConfigureAwait(false); + + if (hosts == null || hosts.Length == 0) + throw new ArgumentException(String.Format("Host not found: {0}", p)); + + return hosts[0]; + } + + public IpAddressInfo ParseIpAddress(string ipAddress) + { + IpAddressInfo info; + if (TryParseIpAddress(ipAddress, out info)) + { + return info; + } + + throw new ArgumentException("Invalid ip address: " + ipAddress); + } + + public bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo) + { + IPAddress address; + if (IPAddress.TryParse(ipAddress, out address)) + { + ipAddressInfo = ToIpAddressInfo(address); + return true; + } + + ipAddressInfo = null; + return false; + } + + public static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint) + { + if (endpoint == null) + { + return null; + } + + return new IpEndPointInfo(ToIpAddressInfo(endpoint.Address), endpoint.Port); + } + + public static IPEndPoint ToIPEndPoint(IpEndPointInfo endpoint) + { + if (endpoint == null) + { + return null; + } + + return new IPEndPoint(ToIPAddress(endpoint.IpAddress), endpoint.Port); + } + + public static IPAddress ToIPAddress(IpAddressInfo address) + { + if (address.Equals(IpAddressInfo.Any)) + { + return IPAddress.Any; + } + if (address.Equals(IpAddressInfo.IPv6Any)) + { + return IPAddress.IPv6Any; + } + if (address.Equals(IpAddressInfo.Loopback)) + { + return IPAddress.Loopback; + } + if (address.Equals(IpAddressInfo.IPv6Loopback)) + { + return IPAddress.IPv6Loopback; + } + + return IPAddress.Parse(address.Address); + } + + public static IpAddressInfo ToIpAddressInfo(IPAddress address) + { + if (address.Equals(IPAddress.Any)) + { + return IpAddressInfo.Any; + } + if (address.Equals(IPAddress.IPv6Any)) + { + return IpAddressInfo.IPv6Any; + } + if (address.Equals(IPAddress.Loopback)) + { + return IpAddressInfo.Loopback; + } + if (address.Equals(IPAddress.IPv6Loopback)) + { + return IpAddressInfo.IPv6Loopback; + } + return new IpAddressInfo(address.ToString(), address.AddressFamily == AddressFamily.InterNetworkV6 ? IpAddressFamily.InterNetworkV6 : IpAddressFamily.InterNetwork); + } + + public async Task<IpAddressInfo[]> GetHostAddressesAsync(string host) + { + var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); + return addresses.Select(ToIpAddressInfo).ToArray(addresses.Length); + } + + /// <summary> + /// Gets the network shares. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>IEnumerable{NetworkShare}.</returns> + public virtual IEnumerable<NetworkShare> GetNetworkShares(string path) + { + return new List<NetworkShare>(); + } + + /// <summary> + /// Gets available devices within the domain + /// </summary> + /// <returns>PC's in the Domain</returns> + public virtual IEnumerable<FileSystemEntryInfo> GetNetworkDevices() + { + return new List<FileSystemEntryInfo>(); + } + } +} diff --git a/Emby.Server.Implementations/News/NewsEntryPoint.cs b/Emby.Server.Implementations/News/NewsEntryPoint.cs index 3c9a3bbf1..03c79c2c1 100644 --- a/Emby.Server.Implementations/News/NewsEntryPoint.cs +++ b/Emby.Server.Implementations/News/NewsEntryPoint.cs @@ -271,6 +271,7 @@ namespace Emby.Server.Implementations.News _timer.Dispose(); _timer = null; } + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs b/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs index f9fb98f85..849e02d81 100644 --- a/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs +++ b/Emby.Server.Implementations/Notifications/CoreNotificationTypes.cs @@ -28,21 +28,21 @@ namespace Emby.Server.Implementations.Notifications Type = NotificationType.ApplicationUpdateInstalled.ToString(), DefaultDescription = "{ReleaseNotes}", DefaultTitle = "A new version of Emby Server has been installed.", - Variables = new List<string>{"Version"} + Variables = new string[]{"Version"} }, new NotificationTypeInfo { Type = NotificationType.InstallationFailed.ToString(), DefaultTitle = "{Name} installation failed.", - Variables = new List<string>{"Name", "Version"} + Variables = new string[]{"Name", "Version"} }, new NotificationTypeInfo { Type = NotificationType.PluginInstalled.ToString(), DefaultTitle = "{Name} was installed.", - Variables = new List<string>{"Name", "Version"} + Variables = new string[]{"Name", "Version"} }, new NotificationTypeInfo @@ -50,14 +50,14 @@ namespace Emby.Server.Implementations.Notifications Type = NotificationType.PluginError.ToString(), DefaultTitle = "{Name} has encountered an error.", DefaultDescription = "{ErrorMessage}", - Variables = new List<string>{"Name", "ErrorMessage"} + Variables = new string[]{"Name", "ErrorMessage"} }, new NotificationTypeInfo { Type = NotificationType.PluginUninstalled.ToString(), DefaultTitle = "{Name} was uninstalled.", - Variables = new List<string>{"Name", "Version"} + Variables = new string[]{"Name", "Version"} }, new NotificationTypeInfo @@ -65,7 +65,7 @@ namespace Emby.Server.Implementations.Notifications Type = NotificationType.PluginUpdateInstalled.ToString(), DefaultTitle = "{Name} was updated.", DefaultDescription = "{ReleaseNotes}", - Variables = new List<string>{"Name", "ReleaseNotes", "Version"} + Variables = new string[]{"Name", "ReleaseNotes", "Version"} }, new NotificationTypeInfo @@ -79,70 +79,70 @@ namespace Emby.Server.Implementations.Notifications Type = NotificationType.TaskFailed.ToString(), DefaultTitle = "{Name} failed.", DefaultDescription = "{ErrorMessage}", - Variables = new List<string>{"Name", "ErrorMessage"} + Variables = new string[]{"Name", "ErrorMessage"} }, new NotificationTypeInfo { Type = NotificationType.NewLibraryContent.ToString(), DefaultTitle = "{Name} has been added to your media library.", - Variables = new List<string>{"Name"} + Variables = new string[]{"Name"} }, new NotificationTypeInfo { Type = NotificationType.AudioPlayback.ToString(), DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.", - Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} + Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"} }, new NotificationTypeInfo { Type = NotificationType.GamePlayback.ToString(), DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.", - Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} + Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"} }, new NotificationTypeInfo { Type = NotificationType.VideoPlayback.ToString(), DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.", - Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} + Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"} }, new NotificationTypeInfo { Type = NotificationType.AudioPlaybackStopped.ToString(), DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.", - Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} + Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"} }, new NotificationTypeInfo { Type = NotificationType.GamePlaybackStopped.ToString(), DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.", - Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} + Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"} }, new NotificationTypeInfo { Type = NotificationType.VideoPlaybackStopped.ToString(), DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.", - Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} + Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"} }, new NotificationTypeInfo { Type = NotificationType.CameraImageUploaded.ToString(), DefaultTitle = "A new camera image has been uploaded from {DeviceName}.", - Variables = new List<string>{"DeviceName"} + Variables = new string[]{"DeviceName"} }, new NotificationTypeInfo { Type = NotificationType.UserLockedOut.ToString(), DefaultTitle = "{UserName} has been locked out.", - Variables = new List<string>{"UserName"} + Variables = new string[]{"UserName"} } }; diff --git a/Emby.Server.Implementations/Notifications/NotificationManager.cs b/Emby.Server.Implementations/Notifications/NotificationManager.cs index db7980497..f49d5a1d1 100644 --- a/Emby.Server.Implementations/Notifications/NotificationManager.cs +++ b/Emby.Server.Implementations/Notifications/NotificationManager.cs @@ -251,7 +251,7 @@ namespace Emby.Server.Implementations.Notifications _typeFactories = notificationTypeFactories.ToArray(); } - public IEnumerable<NotificationTypeInfo> GetNotificationTypes() + public List<NotificationTypeInfo> GetNotificationTypes() { var list = _typeFactories.Select(i => { diff --git a/Emby.Server.Implementations/Notifications/Notifications.cs b/Emby.Server.Implementations/Notifications/Notifications.cs index f95b3f701..09c1f07e0 100644 --- a/Emby.Server.Implementations/Notifications/Notifications.cs +++ b/Emby.Server.Implementations/Notifications/Notifications.cs @@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.Notifications { var artists = hasArtist.AllArtists; - if (artists.Count > 0) + if (artists.Length > 0) { name = hasArtist.AllArtists[0] + " - " + name; } @@ -440,7 +440,7 @@ namespace Emby.Server.Implementations.Notifications name = item.SeriesName + " - " + name; } - if (item.Artists != null && item.Artists.Count > 0) + if (item.Artists != null && item.Artists.Length > 0) { name = item.Artists[0] + " - " + name; } @@ -551,6 +551,7 @@ namespace Emby.Server.Implementations.Notifications _deviceManager.CameraImageUploaded -= _deviceManager_CameraImageUploaded; _userManager.UserLockedOut -= _userManager_UserLockedOut; + GC.SuppressFinalize(this); } private void DisposeLibraryUpdateTimer() diff --git a/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index 40752db80..ff152c9e9 100644 --- a/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -12,6 +12,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Notifications; using SQLitePCL.pretty; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Notifications { @@ -83,13 +84,13 @@ namespace Emby.Server.Implementations.Notifications clauses.Add("UserId=?"); paramList.Add(query.UserId.ToGuidBlob()); - var whereClause = " where " + string.Join(" And ", clauses.ToArray()); + var whereClause = " where " + string.Join(" And ", clauses.ToArray(clauses.Count)); using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { - result.TotalRecordCount = connection.Query("select count(Id) from Notifications" + whereClause, paramList.ToArray()).SelectScalarInt().First(); + result.TotalRecordCount = connection.Query("select count(Id) from Notifications" + whereClause, paramList.ToArray(paramList.Count)).SelectScalarInt().First(); var commandText = string.Format("select Id,UserId,Date,Name,Description,Url,Level,IsRead,Category,RelatedId from Notifications{0} order by IsRead asc, Date desc", whereClause); @@ -110,12 +111,12 @@ namespace Emby.Server.Implementations.Notifications var resultList = new List<Notification>(); - foreach (var row in connection.Query(commandText, paramList.ToArray())) + foreach (var row in connection.Query(commandText, paramList.ToArray(paramList.Count))) { resultList.Add(GetNotification(row)); } - result.Notifications = resultList.ToArray(); + result.Notifications = resultList.ToArray(resultList.Count); } } @@ -280,7 +281,7 @@ namespace Emby.Server.Implementations.Notifications public async Task MarkRead(IEnumerable<string> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken) { var list = notificationIdList.ToList(); - var idArray = list.Select(i => new Guid(i)).ToArray(); + var idArray = list.Select(i => new Guid(i)).ToArray(list.Count); await MarkReadInternal(idArray, userId, isRead, cancellationToken).ConfigureAwait(false); @@ -290,7 +291,7 @@ namespace Emby.Server.Implementations.Notifications { NotificationsMarkedRead(this, new NotificationReadEventArgs { - IdList = list.ToArray(), + IdList = list.ToArray(list.Count), IsRead = isRead, UserId = userId }); diff --git a/Emby.Server.Implementations/Notifications/WebSocketNotifier.cs b/Emby.Server.Implementations/Notifications/WebSocketNotifier.cs index 0239ee336..6e57e7f81 100644 --- a/Emby.Server.Implementations/Notifications/WebSocketNotifier.cs +++ b/Emby.Server.Implementations/Notifications/WebSocketNotifier.cs @@ -1,7 +1,9 @@ -using MediaBrowser.Controller.Net; +using System; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Notifications; using MediaBrowser.Controller.Plugins; using System.Linq; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Notifications { @@ -33,7 +35,7 @@ namespace Emby.Server.Implementations.Notifications list.Add(e.UserId); list.Add(e.IsRead.ToString().ToLower()); - var msg = string.Join("|", list.ToArray()); + var msg = string.Join("|", list.ToArray(list.Count)); _serverManager.SendWebSocketMessage("NotificationsMarkedRead", msg); } @@ -48,6 +50,7 @@ namespace Emby.Server.Implementations.Notifications public void Dispose() { _notificationsRepo.NotificationAdded -= _notificationsRepo_NotificationAdded; + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs b/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs index 17f9b491d..f7c65f63d 100644 --- a/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs +++ b/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs @@ -18,15 +18,15 @@ namespace Emby.Server.Implementations.Photos { } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var photoAlbum = (PhotoAlbum)item; - var items = GetFinalItems(photoAlbum.Children.ToList()); + var items = GetFinalItems(photoAlbum.Children); return items; } - protected override string CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); } diff --git a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs new file mode 100644 index 000000000..2a178895c --- /dev/null +++ b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Linq; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Model.Querying; +using MediaBrowser.Model.Serialization; + +namespace Emby.Server.Implementations.Playlists +{ + public class PlaylistsFolder : BasePluginFolder + { + public PlaylistsFolder() + { + Name = "Playlists"; + } + + public override bool IsVisible(User user) + { + return base.IsVisible(user) && GetChildren(user, true).Any(); + } + + protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) + { + return base.GetEligibleChildrenForRecursiveChildren(user).OfType<Playlist>(); + } + + [IgnoreDataMember] + public override bool IsHidden + { + get + { + return true; + } + } + + [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get + { + return false; + } + } + + [IgnoreDataMember] + public override string CollectionType + { + get { return MediaBrowser.Model.Entities.CollectionType.Playlists; } + } + + protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query) + { + query.Recursive = false; + return base.GetItemsInternal(query); + } + } +} + diff --git a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs index 127ce24ae..525df0350 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Configuration; +using System; +using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -27,7 +28,7 @@ namespace Emby.Server.Implementations.Playlists { } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var playlist = (Playlist)item; @@ -65,8 +66,7 @@ namespace Emby.Server.Implementations.Playlists return null; }) .Where(i => i != null) - .DistinctBy(i => i.Id) - .ToList(); + .DistinctBy(i => i.Id); return GetFinalItems(items); } @@ -81,24 +81,24 @@ namespace Emby.Server.Implementations.Playlists _libraryManager = libraryManager; } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var items = _libraryManager.GetItemList(new InternalItemsQuery { Genres = new[] { item.Name }, IncludeItemTypes = new[] { typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Audio).Name }, - SortBy = new[] { ItemSortBy.Random }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, Limit = 4, Recursive = true, ImageTypes = new[] { ImageType.Primary }, DtoOptions = new DtoOptions(false) - }).ToList(); + }); return GetFinalItems(items); } - //protected override Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + //protected override Task<string> CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) //{ // return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); //} @@ -113,24 +113,24 @@ namespace Emby.Server.Implementations.Playlists _libraryManager = libraryManager; } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var items = _libraryManager.GetItemList(new InternalItemsQuery { Genres = new[] { item.Name }, IncludeItemTypes = new[] { typeof(Series).Name, typeof(Movie).Name }, - SortBy = new[] { ItemSortBy.Random }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, Limit = 4, Recursive = true, ImageTypes = new[] { ImageType.Primary }, DtoOptions = new DtoOptions(false) - }).ToList(); + }); return GetFinalItems(items); } - //protected override Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + //protected override Task<string> CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) //{ // return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); //} diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index e0e133e38..87832e7dd 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -12,10 +12,9 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; - using MediaBrowser.Controller.Dto; -using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Playlists { @@ -129,12 +128,12 @@ namespace Emby.Server.Implementations.Playlists playlist.SetMediaType(options.MediaType); - await parentFolder.AddChild(playlist, CancellationToken.None).ConfigureAwait(false); + parentFolder.AddChild(playlist, CancellationToken.None); await playlist.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { ForceSave = true }, CancellationToken.None) .ConfigureAwait(false); - if (options.ItemIdList.Count > 0) + if (options.ItemIdList.Length > 0) { await AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user, new DtoOptions(false) { @@ -164,7 +163,7 @@ namespace Emby.Server.Implementations.Playlists return path; } - private IEnumerable<BaseItem> GetPlaylistItems(IEnumerable<string> itemIds, string playlistMediaType, User user, DtoOptions options) + private List<BaseItem> GetPlaylistItems(IEnumerable<string> itemIds, string playlistMediaType, User user, DtoOptions options) { var items = itemIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null); @@ -206,7 +205,9 @@ namespace Emby.Server.Implementations.Playlists list.Add(LinkedChild.Create(item)); } - playlist.LinkedChildren.AddRange(list); + var newList = playlist.LinkedChildren.ToList(); + newList.AddRange(list); + playlist.LinkedChildren = newList.ToArray(newList.Count); await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); @@ -234,7 +235,7 @@ namespace Emby.Server.Implementations.Playlists playlist.LinkedChildren = children.Except(removals) .Select(i => i.Item1) - .ToList(); + .ToArray(); await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); @@ -265,17 +266,21 @@ namespace Emby.Server.Implementations.Playlists var item = playlist.LinkedChildren[oldIndex]; - playlist.LinkedChildren.Remove(item); + var newList = playlist.LinkedChildren.ToList(); - if (newIndex >= playlist.LinkedChildren.Count) + newList.Remove(item); + + if (newIndex >= newList.Count) { - playlist.LinkedChildren.Add(item); + newList.Add(item); } else { - playlist.LinkedChildren.Insert(newIndex, item); + newList.Insert(newIndex, item); } + playlist.LinkedChildren = newList.ToArray(newList.Count); + await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); } diff --git a/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs b/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs index dacc937e1..2ce835576 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs @@ -2,7 +2,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.IO; -using MediaBrowser.Server.Implementations.Playlists; namespace Emby.Server.Implementations.Playlists { diff --git a/Emby.Server.Implementations/Reflection/AssemblyInfo.cs b/Emby.Server.Implementations/Reflection/AssemblyInfo.cs new file mode 100644 index 000000000..c3ce97d40 --- /dev/null +++ b/Emby.Server.Implementations/Reflection/AssemblyInfo.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Reflection; +using MediaBrowser.Model.Reflection; + +namespace Emby.Server.Implementations.Reflection +{ + public class AssemblyInfo : IAssemblyInfo + { + public Stream GetManifestResourceStream(Type type, string resource) + { + return type.Assembly.GetManifestResourceStream(resource); + } + + public string[] GetManifestResourceNames(Type type) + { + return type.Assembly.GetManifestResourceNames(); + } + + public Assembly[] GetCurrentAssemblies() + { + return AppDomain.CurrentDomain.GetAssemblies(); + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs index 967e7ddd8..ec371c741 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs @@ -15,6 +15,7 @@ using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.ScheduledTasks { @@ -123,16 +124,9 @@ namespace Emby.Server.Implementations.ScheduledTasks try { - var chapters = _itemRepo.GetChapters(video.Id).ToList(); + var chapters = _itemRepo.GetChapters(video.Id); - var success = await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions - { - SaveChapters = true, - ExtractImages = extract, - Video = video, - Chapters = chapters - - }, CancellationToken.None); + var success = await _encodingManager.RefreshChapterImages(video, chapters, extract, true, CancellationToken.None); if (!success) { @@ -142,7 +136,7 @@ namespace Emby.Server.Implementations.ScheduledTasks _fileSystem.CreateDirectory(parentPath); - _fileSystem.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray())); + _fileSystem.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray(previouslyFailedImages.Count))); } numComplete++; diff --git a/Emby.Server.Implementations/ScheduledTasks/DailyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/DailyTrigger.cs new file mode 100644 index 000000000..1ba5d4329 --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks +{ + /// <summary> + /// Represents a task trigger that fires everyday + /// </summary> + public class DailyTrigger : ITaskTrigger + { + /// <summary> + /// Get the time of day to trigger the task to run + /// </summary> + /// <value>The time of day.</value> + public TimeSpan TimeOfDay { get; set; } + + /// <summary> + /// Gets or sets the timer. + /// </summary> + /// <value>The timer.</value> + private Timer Timer { get; set; } + + /// <summary> + /// Gets the execution properties of this task. + /// </summary> + /// <value> + /// The execution properties of this task. + /// </value> + public TaskExecutionOptions TaskOptions { get; set; } + + /// <summary> + /// Stars waiting for the trigger action + /// </summary> + /// <param name="lastResult">The last result.</param> + /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param> + 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)); + } + + /// <summary> + /// Stops waiting for the trigger action + /// </summary> + public void Stop() + { + DisposeTimer(); + } + + /// <summary> + /// Disposes the timer. + /// </summary> + private void DisposeTimer() + { + if (Timer != null) + { + Timer.Dispose(); + } + } + + /// <summary> + /// Occurs when [triggered]. + /// </summary> + public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered; + + /// <summary> + /// Called when [triggered]. + /// </summary> + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions)); + } + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/IntervalTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/IntervalTrigger.cs new file mode 100644 index 000000000..d09765e34 --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks +{ + /// <summary> + /// Represents a task trigger that runs repeatedly on an interval + /// </summary> + public class IntervalTrigger : ITaskTrigger + { + /// <summary> + /// Gets or sets the interval. + /// </summary> + /// <value>The interval.</value> + public TimeSpan Interval { get; set; } + + /// <summary> + /// Gets or sets the timer. + /// </summary> + /// <value>The timer.</value> + private Timer Timer { get; set; } + + /// <summary> + /// Gets the execution properties of this task. + /// </summary> + /// <value> + /// The execution properties of this task. + /// </value> + public TaskExecutionOptions TaskOptions { get; set; } + + private DateTime _lastStartDate; + + /// <summary> + /// Stars waiting for the trigger action + /// </summary> + /// <param name="lastResult">The last result.</param> + /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param> + 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)); + } + + /// <summary> + /// Stops waiting for the trigger action + /// </summary> + public void Stop() + { + DisposeTimer(); + } + + /// <summary> + /// Disposes the timer. + /// </summary> + private void DisposeTimer() + { + if (Timer != null) + { + Timer.Dispose(); + } + } + + /// <summary> + /// Occurs when [triggered]. + /// </summary> + public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered; + + /// <summary> + /// Called when [triggered]. + /// </summary> + private void OnTriggered() + { + DisposeTimer(); + + if (Triggered != null) + { + _lastStartDate = DateTime.UtcNow; + Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions)); + } + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs new file mode 100644 index 000000000..d7d048110 --- /dev/null +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -0,0 +1,794 @@ +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.Common.Progress; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.System; +using MediaBrowser.Model.Tasks; + +namespace Emby.Server.Implementations.ScheduledTasks +{ + /// <summary> + /// Class ScheduledTaskWorker + /// </summary> + public class ScheduledTaskWorker : IScheduledTaskWorker + { + public event EventHandler<GenericEventArgs<double>> TaskProgress; + + /// <summary> + /// Gets or sets the scheduled task. + /// </summary> + /// <value>The scheduled task.</value> + public IScheduledTask ScheduledTask { get; private set; } + + /// <summary> + /// Gets or sets the json serializer. + /// </summary> + /// <value>The json serializer.</value> + private IJsonSerializer JsonSerializer { get; set; } + + /// <summary> + /// Gets or sets the application paths. + /// </summary> + /// <value>The application paths.</value> + private IApplicationPaths ApplicationPaths { get; set; } + + /// <summary> + /// Gets the logger. + /// </summary> + /// <value>The logger.</value> + private ILogger Logger { get; set; } + + /// <summary> + /// Gets the task manager. + /// </summary> + /// <value>The task manager.</value> + private ITaskManager TaskManager { get; set; } + private readonly IFileSystem _fileSystem; + private readonly ISystemEvents _systemEvents; + + /// <summary> + /// Initializes a new instance of the <see cref="ScheduledTaskWorker" /> class. + /// </summary> + /// <param name="scheduledTask">The scheduled task.</param> + /// <param name="applicationPaths">The application paths.</param> + /// <param name="taskManager">The task manager.</param> + /// <param name="jsonSerializer">The json serializer.</param> + /// <param name="logger">The logger.</param> + /// <exception cref="System.ArgumentNullException"> + /// scheduledTask + /// or + /// applicationPaths + /// or + /// taskManager + /// or + /// jsonSerializer + /// or + /// logger + /// </exception> + 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; + /// <summary> + /// The _last execution result + /// </summary> + private TaskResult _lastExecutionResult; + /// <summary> + /// The _last execution result sync lock + /// </summary> + private readonly object _lastExecutionResultSyncLock = new object(); + /// <summary> + /// Gets the last execution result. + /// </summary> + /// <value>The last execution result.</value> + public TaskResult LastExecutionResult + { + get + { + var path = GetHistoryFilePath(); + + lock (_lastExecutionResultSyncLock) + { + if (_lastExecutionResult == null && !_readFromFile) + { + try + { + _lastExecutionResult = JsonSerializer.DeserializeFromFile<TaskResult>(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(_fileSystem.GetDirectoryName(path)); + + lock (_lastExecutionResultSyncLock) + { + JsonSerializer.SerializeToFile(value, path); + } + } + } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name + { + get { return ScheduledTask.Name; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public string Description + { + get { return ScheduledTask.Description; } + } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public string Category + { + get { return ScheduledTask.Category; } + } + + /// <summary> + /// Gets the current cancellation token + /// </summary> + /// <value>The current cancellation token source.</value> + private CancellationTokenSource CurrentCancellationTokenSource { get; set; } + + /// <summary> + /// Gets or sets the current execution start time. + /// </summary> + /// <value>The current execution start time.</value> + private DateTime CurrentExecutionStartTime { get; set; } + + /// <summary> + /// Gets the state. + /// </summary> + /// <value>The state.</value> + public TaskState State + { + get + { + if (CurrentCancellationTokenSource != null) + { + return CurrentCancellationTokenSource.IsCancellationRequested + ? TaskState.Cancelling + : TaskState.Running; + } + + return TaskState.Idle; + } + } + + /// <summary> + /// Gets the current progress. + /// </summary> + /// <value>The current progress.</value> + public double? CurrentProgress { get; private set; } + + /// <summary> + /// The _triggers + /// </summary> + private Tuple<TaskTriggerInfo,ITaskTrigger>[] _triggers; + /// <summary> + /// Gets the triggers that define when the task will run + /// </summary> + /// <value>The triggers.</value> + private Tuple<TaskTriggerInfo, ITaskTrigger>[] InternalTriggers + { + get + { + return _triggers; + } + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + // Cleanup current triggers + if (_triggers != null) + { + DisposeTriggers(); + } + + _triggers = value.ToArray(); + + ReloadTriggerEvents(false); + } + } + + /// <summary> + /// Gets the triggers that define when the task will run + /// </summary> + /// <value>The triggers.</value> + /// <exception cref="System.ArgumentNullException">value</exception> + public TaskTriggerInfo[] Triggers + { + get + { + var triggers = InternalTriggers; + return triggers.Select(i => i.Item1).ToArray(triggers.Length); + } + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + // This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly + var triggerList = value.Where(i => i != null).ToArray(); + + SaveTriggers(triggerList); + + InternalTriggers = triggerList.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray(triggerList.Length); + } + } + + /// <summary> + /// The _id + /// </summary> + private string _id; + + /// <summary> + /// Gets the unique id. + /// </summary> + /// <value>The unique id.</value> + 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); + } + + /// <summary> + /// Reloads the trigger events. + /// </summary> + /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param> + 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); + } + } + + /// <summary> + /// Handles the Triggered event of the trigger control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> + async void trigger_Triggered(object sender, GenericEventArgs<TaskExecutionOptions> 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; + + /// <summary> + /// Executes the task + /// </summary> + /// <param name="options">Task options.</param> + /// <returns>Task.</returns> + /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception> + public async Task Execute(TaskExecutionOptions options) + { + var task = Task.Run(async () => await ExecuteInternal(options).ConfigureAwait(false)); + + _currentTask = task; + + try + { + await task.ConfigureAwait(false); + } + finally + { + _currentTask = null; + GC.Collect(); + } + } + + 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 SimpleProgress<double>(); + + 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); + } + + /// <summary> + /// Progress_s the progress changed. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The e.</param> + void progress_ProgressChanged(object sender, double e) + { + CurrentProgress = e; + + EventHelper.FireEventIfNotNull(TaskProgress, this, new GenericEventArgs<double> + { + Argument = e + + }, Logger); + } + + /// <summary> + /// Stops the task if it is currently executing + /// </summary> + /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception> + public void Cancel() + { + if (State != TaskState.Running) + { + throw new InvalidOperationException("Cannot cancel a Task unless it is in the Running state."); + } + + CancelIfRunning(); + } + + /// <summary> + /// Cancels if running. + /// </summary> + public void CancelIfRunning() + { + if (State == TaskState.Running) + { + Logger.Info("Attempting to cancel Scheduled Task {0}", Name); + CurrentCancellationTokenSource.Cancel(); + } + } + + /// <summary> + /// Gets the scheduled tasks configuration directory. + /// </summary> + /// <returns>System.String.</returns> + private string GetScheduledTasksConfigurationDirectory() + { + return Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks"); + } + + /// <summary> + /// Gets the scheduled tasks data directory. + /// </summary> + /// <returns>System.String.</returns> + private string GetScheduledTasksDataDirectory() + { + return Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks"); + } + + /// <summary> + /// Gets the history file path. + /// </summary> + /// <value>The history file path.</value> + private string GetHistoryFilePath() + { + return Path.Combine(GetScheduledTasksDataDirectory(), new Guid(Id) + ".js"); + } + + /// <summary> + /// Gets the configuration file path. + /// </summary> + /// <returns>System.String.</returns> + private string GetConfigurationFilePath() + { + return Path.Combine(GetScheduledTasksConfigurationDirectory(), new Guid(Id) + ".js"); + } + + /// <summary> + /// Loads the triggers. + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + private Tuple<TaskTriggerInfo, ITaskTrigger>[] LoadTriggers() + { + // This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly + var settings = LoadTriggerSettings().Where(i => i != null).ToArray(); + + return settings.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray(); + } + + private TaskTriggerInfo[] LoadTriggerSettings() + { + try + { + var list = JsonSerializer.DeserializeFromFile<IEnumerable<TaskTriggerInfo>>(GetConfigurationFilePath()); + + if (list != null) + { + return list.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(); + } + + /// <summary> + /// Saves the triggers. + /// </summary> + /// <param name="triggers">The triggers.</param> + private void SaveTriggers(TaskTriggerInfo[] triggers) + { + var path = GetConfigurationFilePath(); + + _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); + + JsonSerializer.SerializeToFile(triggers, path); + } + + /// <summary> + /// Called when [task completed]. + /// </summary> + /// <param name="startTime">The start time.</param> + /// <param name="endTime">The end time.</param> + /// <param name="status">The status.</param> + 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); + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + 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); + } + } + } + + /// <summary> + /// Converts a TaskTriggerInfo into a concrete BaseTaskTrigger + /// </summary> + /// <param name="info">The info.</param> + /// <returns>BaseTaskTrigger.</returns> + /// <exception cref="System.ArgumentNullException"></exception> + /// <exception cref="System.ArgumentException">Invalid trigger type: + info.Type</exception> + 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); + } + + /// <summary> + /// Disposes each trigger + /// </summary> + private void DisposeTriggers() + { + foreach (var triggerInfo in InternalTriggers) + { + var trigger = triggerInfo.Item2; + trigger.Triggered -= trigger_Triggered; + trigger.Stop(); + } + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/StartupTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/StartupTrigger.cs new file mode 100644 index 000000000..d708c905d --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks +{ + /// <summary> + /// Class StartupTaskTrigger + /// </summary> + public class StartupTrigger : ITaskTrigger + { + public int DelayMs { get; set; } + + /// <summary> + /// Gets the execution properties of this task. + /// </summary> + /// <value> + /// The execution properties of this task. + /// </value> + public TaskExecutionOptions TaskOptions { get; set; } + + public StartupTrigger() + { + DelayMs = 3000; + } + + /// <summary> + /// Stars waiting for the trigger action + /// </summary> + /// <param name="lastResult">The last result.</param> + /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param> + public async void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup) + { + if (isApplicationStartup) + { + await Task.Delay(DelayMs).ConfigureAwait(false); + + OnTriggered(); + } + } + + /// <summary> + /// Stops waiting for the trigger action + /// </summary> + public void Stop() + { + } + + /// <summary> + /// Occurs when [triggered]. + /// </summary> + public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered; + + /// <summary> + /// Called when [triggered]. + /// </summary> + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions)); + } + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/SystemEventTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/SystemEventTrigger.cs new file mode 100644 index 000000000..976754a40 --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks +{ + /// <summary> + /// Class SystemEventTrigger + /// </summary> + public class SystemEventTrigger : ITaskTrigger + { + /// <summary> + /// Gets or sets the system event. + /// </summary> + /// <value>The system event.</value> + public SystemEvent SystemEvent { get; set; } + + /// <summary> + /// Gets the execution properties of this task. + /// </summary> + /// <value> + /// The execution properties of this task. + /// </value> + public TaskExecutionOptions TaskOptions { get; set; } + + private readonly ISystemEvents _systemEvents; + + public SystemEventTrigger(ISystemEvents systemEvents) + { + _systemEvents = systemEvents; + } + + /// <summary> + /// Stars waiting for the trigger action + /// </summary> + /// <param name="lastResult">The last result.</param> + /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param> + 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(); + } + } + + /// <summary> + /// Stops waiting for the trigger action + /// </summary> + public void Stop() + { + _systemEvents.Resume -= _systemEvents_Resume; + } + + /// <summary> + /// Occurs when [triggered]. + /// </summary> + public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered; + + /// <summary> + /// Called when [triggered]. + /// </summary> + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions)); + } + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs new file mode 100644 index 000000000..5f9bf3731 --- /dev/null +++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs @@ -0,0 +1,334 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Events; +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.Server.Implementations.ScheduledTasks +{ + /// <summary> + /// Class TaskManager + /// </summary> + public class TaskManager : ITaskManager + { + public event EventHandler<GenericEventArgs<IScheduledTaskWorker>> TaskExecuting; + public event EventHandler<TaskCompletionEventArgs> TaskCompleted; + + /// <summary> + /// Gets the list of Scheduled Tasks + /// </summary> + /// <value>The scheduled tasks.</value> + public IScheduledTaskWorker[] ScheduledTasks { get; private set; } + + /// <summary> + /// The _task queue + /// </summary> + private readonly ConcurrentQueue<Tuple<Type, TaskExecutionOptions>> _taskQueue = + new ConcurrentQueue<Tuple<Type, TaskExecutionOptions>>(); + + /// <summary> + /// Gets or sets the json serializer. + /// </summary> + /// <value>The json serializer.</value> + private IJsonSerializer JsonSerializer { get; set; } + + /// <summary> + /// Gets or sets the application paths. + /// </summary> + /// <value>The application paths.</value> + private IApplicationPaths ApplicationPaths { get; set; } + + private readonly ISystemEvents _systemEvents; + + /// <summary> + /// Gets the logger. + /// </summary> + /// <value>The logger.</value> + private ILogger Logger { get; set; } + private readonly IFileSystem _fileSystem; + + /// <summary> + /// Initializes a new instance of the <see cref="TaskManager" /> class. + /// </summary> + /// <param name="applicationPaths">The application paths.</param> + /// <param name="jsonSerializer">The json serializer.</param> + /// <param name="logger">The logger.</param> + /// <exception cref="System.ArgumentException">kernel</exception> + 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(); + } + } + + /// <summary> + /// Cancels if running and queue. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="options">Task options.</param> + public void CancelIfRunningAndQueue<T>(TaskExecutionOptions options) + where T : IScheduledTask + { + var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); + ((ScheduledTaskWorker)task).CancelIfRunning(); + + QueueScheduledTask<T>(options); + } + + public void CancelIfRunningAndQueue<T>() + where T : IScheduledTask + { + CancelIfRunningAndQueue<T>(new TaskExecutionOptions()); + } + + /// <summary> + /// Cancels if running + /// </summary> + /// <typeparam name="T"></typeparam> + public void CancelIfRunning<T>() + where T : IScheduledTask + { + var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); + ((ScheduledTaskWorker)task).CancelIfRunning(); + } + + /// <summary> + /// Queues the scheduled task. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="options">Task options</param> + public void QueueScheduledTask<T>(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<T>() + where T : IScheduledTask + { + QueueScheduledTask<T>(new TaskExecutionOptions()); + } + + public void QueueIfNotRunning<T>() + where T : IScheduledTask + { + var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); + + if (task.State != TaskState.Running) + { + QueueScheduledTask<T>(new TaskExecutionOptions()); + } + } + + public void Execute<T>() + 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()); + } + } + } + } + + /// <summary> + /// Queues the scheduled task. + /// </summary> + /// <param name="task">The task.</param> + /// <param name="options">The task options.</param> + 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); + } + } + + /// <summary> + /// Queues the scheduled task. + /// </summary> + /// <param name="task">The task.</param> + /// <param name="options">The task options.</param> + 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) + { + Execute(task, options); + return; + } + + _taskQueue.Enqueue(new Tuple<Type, TaskExecutionOptions>(type, options)); + } + } + + /// <summary> + /// Adds the tasks. + /// </summary> + /// <param name="tasks">The tasks.</param> + public void AddTasks(IEnumerable<IScheduledTask> tasks) + { + var myTasks = ScheduledTasks.ToList(); + + var list = tasks.ToList(); + myTasks.AddRange(list.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger, _fileSystem, _systemEvents))); + + ScheduledTasks = myTasks.ToArray(); + + BindToSystemEvent(); + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + 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); + } + + /// <summary> + /// Called when [task executing]. + /// </summary> + /// <param name="task">The task.</param> + internal void OnTaskExecuting(IScheduledTaskWorker task) + { + EventHelper.FireEventIfNotNull(TaskExecuting, this, new GenericEventArgs<IScheduledTaskWorker> + { + Argument = task + + }, Logger); + } + + /// <summary> + /// Called when [task completed]. + /// </summary> + /// <param name="task">The task.</param> + /// <param name="result">The result.</param> + internal void OnTaskCompleted(IScheduledTaskWorker task, TaskResult result) + { + EventHelper.FireEventIfNotNull(TaskCompleted, task, new TaskCompletionEventArgs + { + Result = result, + Task = task + + }, Logger); + + ExecuteQueuedTasks(); + } + + /// <summary> + /// Executes the queued tasks. + /// </summary> + private void ExecuteQueuedTasks() + { + Logger.Info("ExecuteQueuedTasks"); + + // Execute queued tasks + lock (_taskQueue) + { + var list = new List<Tuple<Type, TaskExecutionOptions>>(); + + Tuple<Type, TaskExecutionOptions> 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.Server.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs new file mode 100644 index 000000000..701358fd4 --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks.Tasks +{ + /// <summary> + /// Deletes old cache files + /// </summary> + public class DeleteCacheFileTask : IScheduledTask, IConfigurableScheduledTask + { + /// <summary> + /// Gets or sets the application paths. + /// </summary> + /// <value>The application paths.</value> + private IApplicationPaths ApplicationPaths { get; set; } + + private readonly ILogger _logger; + + private readonly IFileSystem _fileSystem; + + /// <summary> + /// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class. + /// </summary> + public DeleteCacheFileTask(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem) + { + ApplicationPaths = appPaths; + _logger = logger; + _fileSystem = fileSystem; + } + + /// <summary> + /// Creates the triggers that define when the task will run + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() + { + return new[] { + + // Every so often + new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks} + }; + } + + /// <summary> + /// Returns the task to be executed + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + public Task Execute(CancellationToken cancellationToken, IProgress<double> 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); + } + + + /// <summary> + /// Deletes the cache files from directory with a last write time less than a given date + /// </summary> + /// <param name="cancellationToken">The task cancellation token.</param> + /// <param name="directory">The directory.</param> + /// <param name="minDateModified">The min date modified.</param> + /// <param name="progress">The progress.</param> + private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress<double> 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); + } + } + + /// <summary> + /// Gets the name of the task + /// </summary> + /// <value>The name.</value> + public string Name + { + get { return "Cache file cleanup"; } + } + + public string Key + { + get { return "DeleteCacheFiles"; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public string Description + { + get { return "Deletes cache files no longer needed by the system"; } + } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public string Category + { + get + { + return "Maintenance"; + } + } + + /// <summary> + /// Gets a value indicating whether this instance is hidden. + /// </summary> + /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value> + public bool IsHidden + { + get { return true; } + } + + public bool IsEnabled + { + get { return true; } + } + + public bool IsLogged + { + get { return true; } + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs new file mode 100644 index 000000000..f98b09659 --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks.Tasks +{ + /// <summary> + /// Deletes old log files + /// </summary> + public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask + { + /// <summary> + /// Gets or sets the configuration manager. + /// </summary> + /// <value>The configuration manager.</value> + private IConfigurationManager ConfigurationManager { get; set; } + + private readonly IFileSystem _fileSystem; + + /// <summary> + /// Initializes a new instance of the <see cref="DeleteLogFileTask" /> class. + /// </summary> + /// <param name="configurationManager">The configuration manager.</param> + public DeleteLogFileTask(IConfigurationManager configurationManager, IFileSystem fileSystem) + { + ConfigurationManager = configurationManager; + _fileSystem = fileSystem; + } + + /// <summary> + /// Creates the triggers that define when the task will run + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() + { + return new[] { + + // Every so often + new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks} + }; + } + + /// <summary> + /// Returns the task to be executed + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + public Task Execute(CancellationToken cancellationToken, IProgress<double> 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"; } + } + + /// <summary> + /// Gets the name of the task + /// </summary> + /// <value>The name.</value> + public string Name + { + get { return "Log file cleanup"; } + } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public string Description + { + get { return string.Format("Deletes log files that are more than {0} days old.", ConfigurationManager.CommonConfiguration.LogFileRetentionDays); } + } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + public string Category + { + get + { + return "Maintenance"; + } + } + + /// <summary> + /// Gets a value indicating whether this instance is hidden. + /// </summary> + /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value> + public bool IsHidden + { + get { return true; } + } + + public bool IsEnabled + { + get { return true; } + } + + public bool IsLogged + { + get { return true; } + } + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ReloadLoggerFileTask.cs new file mode 100644 index 000000000..032fa05a0 --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks.Tasks +{ + /// <summary> + /// Class ReloadLoggerFileTask + /// </summary> + public class ReloadLoggerFileTask : IScheduledTask, IConfigurableScheduledTask + { + /// <summary> + /// Gets or sets the log manager. + /// </summary> + /// <value>The log manager.</value> + private ILogManager LogManager { get; set; } + /// <summary> + /// Gets or sets the configuration manager. + /// </summary> + /// <value>The configuration manager.</value> + private IConfigurationManager ConfigurationManager { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="ReloadLoggerFileTask" /> class. + /// </summary> + /// <param name="logManager">The logManager.</param> + /// <param name="configurationManager">The configuration manager.</param> + public ReloadLoggerFileTask(ILogManager logManager, IConfigurationManager configurationManager) + { + LogManager = logManager; + ConfigurationManager = configurationManager; + } + + /// <summary> + /// Gets the default triggers. + /// </summary> + /// <returns>IEnumerable{BaseTaskTrigger}.</returns> + public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() + { + var trigger = new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerDaily, TimeOfDayTicks = TimeSpan.FromHours(0).Ticks }; //12am + + return new[] { trigger }; + } + + /// <summary> + /// Executes the internal. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + public Task Execute(CancellationToken cancellationToken, IProgress<double> progress) + { + cancellationToken.ThrowIfCancellationRequested(); + + progress.Report(0); + + LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging + ? LogSeverity.Debug + : LogSeverity.Info); + + return Task.FromResult(true); + } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name + { + get { return "Start new log file"; } + } + + public string Key { get; } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + public string Description + { + get { return "Moves logging to a new file to help reduce log file sizes."; } + } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + 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.Server.Implementations/ScheduledTasks/WeeklyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/WeeklyTrigger.cs new file mode 100644 index 000000000..1a944ebf2 --- /dev/null +++ b/Emby.Server.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.Server.Implementations.ScheduledTasks +{ + /// <summary> + /// Represents a task trigger that fires on a weekly basis + /// </summary> + public class WeeklyTrigger : ITaskTrigger + { + /// <summary> + /// Get the time of day to trigger the task to run + /// </summary> + /// <value>The time of day.</value> + public TimeSpan TimeOfDay { get; set; } + + /// <summary> + /// Gets or sets the day of week. + /// </summary> + /// <value>The day of week.</value> + public DayOfWeek DayOfWeek { get; set; } + + /// <summary> + /// Gets the execution properties of this task. + /// </summary> + /// <value> + /// The execution properties of this task. + /// </value> + public TaskExecutionOptions TaskOptions { get; set; } + + /// <summary> + /// Gets or sets the timer. + /// </summary> + /// <value>The timer.</value> + private Timer Timer { get; set; } + + /// <summary> + /// Stars waiting for the trigger action + /// </summary> + /// <param name="lastResult">The last result.</param> + /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param> + 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)); + } + + /// <summary> + /// Gets the next trigger date time. + /// </summary> + /// <returns>DateTime.</returns> + 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); + } + + /// <summary> + /// Stops waiting for the trigger action + /// </summary> + public void Stop() + { + DisposeTimer(); + } + + /// <summary> + /// Disposes the timer. + /// </summary> + private void DisposeTimer() + { + if (Timer != null) + { + Timer.Dispose(); + } + } + + /// <summary> + /// Occurs when [triggered]. + /// </summary> + public event EventHandler<GenericEventArgs<TaskExecutionOptions>> Triggered; + + /// <summary> + /// Called when [triggered]. + /// </summary> + private void OnTriggered() + { + if (Triggered != null) + { + Triggered(this, new GenericEventArgs<TaskExecutionOptions>(TaskOptions)); + } + } + } +} diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index 9ec0af6bb..f5b847ccf 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -4,13 +4,13 @@ using System.Globalization; using System.IO; using System.Linq; using System.Threading; -using System.Threading.Tasks; using Emby.Server.Implementations.Data; using MediaBrowser.Controller; using MediaBrowser.Controller.Security; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using SQLitePCL.pretty; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Security { @@ -50,14 +50,14 @@ namespace Emby.Server.Implementations.Security } } - public Task Create(AuthenticationInfo info, CancellationToken cancellationToken) + public void Create(AuthenticationInfo info, CancellationToken cancellationToken) { info.Id = Guid.NewGuid().ToString("N"); - return Update(info, cancellationToken); + Update(info, cancellationToken); } - public async Task Update(AuthenticationInfo info, CancellationToken cancellationToken) + public void Update(AuthenticationInfo info, CancellationToken cancellationToken) { if (info == null) { @@ -174,13 +174,13 @@ namespace Emby.Server.Implementations.Security var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); if (startIndex > 0) { var pagingWhereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM AccessTokens {0} ORDER BY DateCreated LIMIT {1})", pagingWhereText, @@ -189,7 +189,7 @@ namespace Emby.Server.Implementations.Security var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); commandText += whereText; @@ -236,7 +236,7 @@ namespace Emby.Server.Implementations.Security } } - result.Items = list.ToArray(); + result.Items = list.ToArray(list.Count); return result; }, ReadTransactionMode); diff --git a/Emby.Server.Implementations/Serialization/JsonSerializer.cs b/Emby.Server.Implementations/Serialization/JsonSerializer.cs new file mode 100644 index 000000000..c9db33689 --- /dev/null +++ b/Emby.Server.Implementations/Serialization/JsonSerializer.cs @@ -0,0 +1,227 @@ +using System; +using System.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; + +namespace Emby.Common.Implementations.Serialization +{ + /// <summary> + /// Provides a wrapper around third party json serialization. + /// </summary> + public class JsonSerializer : IJsonSerializer + { + private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; + + public JsonSerializer(IFileSystem fileSystem, ILogger logger) + { + _fileSystem = fileSystem; + _logger = logger; + Configure(); + } + + /// <summary> + /// Serializes to stream. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="stream">The stream.</param> + /// <exception cref="System.ArgumentNullException">obj</exception> + public void SerializeToStream(object obj, Stream stream) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + ServiceStack.Text.JsonSerializer.SerializeToStream(obj, obj.GetType(), stream); + } + + /// <summary> + /// Serializes to file. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="file">The file.</param> + /// <exception cref="System.ArgumentNullException">obj</exception> + public void SerializeToFile(object obj, string file) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = _fileSystem.GetFileStream(file, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read)) + { + SerializeToStream(obj, stream); + } + } + + private Stream OpenFile(string path) + { + _logger.Debug("Deserializing file {0}", path); + return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 131072); + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="file">The file.</param> + /// <returns>System.Object.</returns> + /// <exception cref="System.ArgumentNullException">type</exception> + public object DeserializeFromFile(Type type, string file) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = OpenFile(file)) + { + return DeserializeFromStream(stream, type); + } + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="file">The file.</param> + /// <returns>``0.</returns> + /// <exception cref="System.ArgumentNullException">file</exception> + public T DeserializeFromFile<T>(string file) + where T : class + { + if (string.IsNullOrEmpty(file)) + { + throw new ArgumentNullException("file"); + } + + using (Stream stream = OpenFile(file)) + { + return DeserializeFromStream<T>(stream); + } + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="stream">The stream.</param> + /// <returns>``0.</returns> + /// <exception cref="System.ArgumentNullException">stream</exception> + public T DeserializeFromStream<T>(Stream stream) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromStream<T>(stream); + } + + /// <summary> + /// Deserializes from string. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="text">The text.</param> + /// <returns>``0.</returns> + /// <exception cref="System.ArgumentNullException">text</exception> + public T DeserializeFromString<T>(string text) + { + if (string.IsNullOrEmpty(text)) + { + throw new ArgumentNullException("text"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(text); + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <param name="stream">The stream.</param> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + /// <exception cref="System.ArgumentNullException">stream</exception> + public object DeserializeFromStream(Stream stream, Type type) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream); + } + + /// <summary> + /// Configures this instance. + /// </summary> + private void Configure() + { + ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601; + ServiceStack.Text.JsConfig.ExcludeTypeInfo = true; + ServiceStack.Text.JsConfig.IncludeNullValues = false; + ServiceStack.Text.JsConfig.AlwaysUseUtc = true; + ServiceStack.Text.JsConfig.AssumeUtc = true; + } + + /// <summary> + /// Deserializes from string. + /// </summary> + /// <param name="json">The json.</param> + /// <param name="type">The type.</param> + /// <returns>System.Object.</returns> + /// <exception cref="System.ArgumentNullException">json</exception> + public object DeserializeFromString(string json, Type type) + { + if (string.IsNullOrEmpty(json)) + { + throw new ArgumentNullException("json"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + return ServiceStack.Text.JsonSerializer.DeserializeFromString(json, type); + } + + /// <summary> + /// Serializes to string. + /// </summary> + /// <param name="obj">The obj.</param> + /// <returns>System.String.</returns> + /// <exception cref="System.ArgumentNullException">obj</exception> + public string SerializeToString(object obj) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + return ServiceStack.Text.JsonSerializer.SerializeToString(obj, obj.GetType()); + } + } +} diff --git a/Emby.Server.Implementations/Serialization/XmlSerializer.cs b/Emby.Server.Implementations/Serialization/XmlSerializer.cs new file mode 100644 index 000000000..e0603a01f --- /dev/null +++ b/Emby.Server.Implementations/Serialization/XmlSerializer.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using System.Xml.Serialization; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; + +namespace Emby.Server.Implementations.Serialization +{ + /// <summary> + /// Provides a wrapper around third party xml serialization. + /// </summary> + public class MyXmlSerializer : IXmlSerializer + { + private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; + + public MyXmlSerializer(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<string, XmlSerializer> _serializers = + new Dictionary<string, XmlSerializer>(); + + private XmlSerializer GetSerializer(Type type) + { + var key = type.FullName; + lock (_serializers) + { + XmlSerializer serializer; + if (!_serializers.TryGetValue(key, out serializer)) + { + serializer = new XmlSerializer(type); + _serializers[key] = serializer; + } + return serializer; + } + } + + /// <summary> + /// Serializes to writer. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="writer">The writer.</param> + private void SerializeToWriter(object obj, XmlWriter writer) + { + var netSerializer = GetSerializer(obj.GetType()); + netSerializer.Serialize(writer, obj); + } + + /// <summary> + /// Deserializes from stream. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="stream">The stream.</param> + /// <returns>System.Object.</returns> + public object DeserializeFromStream(Type type, Stream stream) + { + using (var reader = XmlReader.Create(stream)) + { + var netSerializer = GetSerializer(type); + return netSerializer.Deserialize(reader); + } + } + + /// <summary> + /// Serializes to stream. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="stream">The stream.</param> + public void SerializeToStream(object obj, Stream stream) + { + using (var writer = new XmlTextWriter(stream, null)) + { + writer.Formatting = Formatting.Indented; + SerializeToWriter(obj, writer); + } + } + + /// <summary> + /// Serializes to file. + /// </summary> + /// <param name="obj">The obj.</param> + /// <param name="file">The file.</param> + 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); + } + } + + /// <summary> + /// Deserializes from file. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="file">The file.</param> + /// <returns>System.Object.</returns> + public object DeserializeFromFile(Type type, string file) + { + _logger.Debug("Deserializing file {0}", file); + using (var stream = _fileSystem.OpenRead(file)) + { + return DeserializeFromStream(type, stream); + } + } + + /// <summary> + /// Deserializes from bytes. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="buffer">The buffer.</param> + /// <returns>System.Object.</returns> + public object DeserializeFromBytes(Type type, byte[] buffer) + { + using (var stream = new MemoryStream(buffer)) + { + return DeserializeFromStream(type, stream); + } + } + } +} diff --git a/Emby.Server.Implementations/ServerApplicationPaths.cs b/Emby.Server.Implementations/ServerApplicationPaths.cs index b4b2bb139..675b0d78c 100644 --- a/Emby.Server.Implementations/ServerApplicationPaths.cs +++ b/Emby.Server.Implementations/ServerApplicationPaths.cs @@ -13,8 +13,8 @@ namespace Emby.Server.Implementations /// <summary> /// Initializes a new instance of the <see cref="BaseApplicationPaths" /> class. /// </summary> - public ServerApplicationPaths(string programDataPath, string appFolderPath, string applicationResourcesPath, Action<string> createDirectoryFn) - : base(programDataPath, appFolderPath, createDirectoryFn) + public ServerApplicationPaths(string programDataPath, string appFolderPath, string applicationResourcesPath) + : base(programDataPath, appFolderPath) { ApplicationResourcesPath = applicationResourcesPath; } diff --git a/Emby.Server.Implementations/ServerManager/ServerManager.cs b/Emby.Server.Implementations/ServerManager/ServerManager.cs index 7cd94c526..b267f928b 100644 --- a/Emby.Server.Implementations/ServerManager/ServerManager.cs +++ b/Emby.Server.Implementations/ServerManager/ServerManager.cs @@ -112,7 +112,7 @@ namespace Emby.Server.Implementations.ServerManager /// <summary> /// Starts this instance. /// </summary> - public void Start(IEnumerable<string> urlPrefixes) + public void Start(string[] urlPrefixes) { ReloadHttpServer(urlPrefixes); } @@ -120,7 +120,7 @@ namespace Emby.Server.Implementations.ServerManager /// <summary> /// Restarts the Http Server, or starts it if not currently running /// </summary> - private void ReloadHttpServer(IEnumerable<string> urlPrefixes) + private void ReloadHttpServer(string[] urlPrefixes) { _logger.Info("Loading Http Server"); diff --git a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs index 4d5192fea..076f50d93 100644 --- a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs +++ b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs @@ -136,7 +136,7 @@ namespace Emby.Server.Implementations.ServerManager return; } - var charset = _textEncoding.GetDetectedEncodingName(bytes, null, false); + var charset = _textEncoding.GetDetectedEncodingName(bytes, bytes.Length, null, false); if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase)) { diff --git a/Emby.Server.Implementations/Services/HttpResult.cs b/Emby.Server.Implementations/Services/HttpResult.cs index dfad09f7b..91314c15a 100644 --- a/Emby.Server.Implementations/Services/HttpResult.cs +++ b/Emby.Server.Implementations/Services/HttpResult.cs @@ -45,10 +45,15 @@ namespace Emby.Server.Implementations.Services var bytesResponse = this.Response as byte[]; if (bytesResponse != null) { + var contentLength = bytesResponse.Length; + if (response != null) - response.SetContentLength(bytesResponse.Length); + response.SetContentLength(contentLength); - await responseStream.WriteAsync(bytesResponse, 0, bytesResponse.Length).ConfigureAwait(false); + if (contentLength > 0) + { + await responseStream.WriteAsync(bytesResponse, 0, contentLength).ConfigureAwait(false); + } return; } diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs index 84dc343c3..22e1bc4aa 100644 --- a/Emby.Server.Implementations/Services/ResponseHelper.cs +++ b/Emby.Server.Implementations/Services/ResponseHelper.cs @@ -41,11 +41,11 @@ namespace Emby.Server.Implementations.Services response.StatusCode = httpResult.Status; response.StatusDescription = httpResult.StatusCode.ToString(); - if (string.IsNullOrEmpty(httpResult.ContentType)) - { - httpResult.ContentType = defaultContentType; - } - response.ContentType = httpResult.ContentType; + //if (string.IsNullOrEmpty(httpResult.ContentType)) + //{ + // httpResult.ContentType = defaultContentType; + //} + //response.ContentType = httpResult.ContentType; if (httpResult.Cookies != null) { @@ -124,7 +124,10 @@ namespace Emby.Server.Implementations.Services response.ContentType = "application/octet-stream"; response.SetContentLength(bytes.Length); - await response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); + if (bytes.Length > 0) + { + await response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); + } return; } @@ -133,7 +136,10 @@ namespace Emby.Server.Implementations.Services { bytes = Encoding.UTF8.GetBytes(responseText); response.SetContentLength(bytes.Length); - await response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); + if (bytes.Length > 0) + { + await response.OutputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); + } return; } @@ -150,8 +156,15 @@ namespace Emby.Server.Implementations.Services serializer(result, ms); ms.Position = 0; - response.SetContentLength(ms.Length); - await ms.CopyToAsync(response.OutputStream).ConfigureAwait(false); + + var contentLength = ms.Length; + + response.SetContentLength(contentLength); + + if (contentLength > 0) + { + await ms.CopyToAsync(response.OutputStream).ConfigureAwait(false); + } } //serializer(result, outputStream); diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index 1c530144c..4dc14a193 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -15,29 +15,20 @@ namespace Emby.Server.Implementations.Services public class ServiceController { public static ServiceController Instance; - private readonly Func<IEnumerable<Type>> _resolveServicesFn; - public ServiceController(Func<IEnumerable<Type>> resolveServicesFn) + public ServiceController() { Instance = this; - _resolveServicesFn = resolveServicesFn; } - public void Init(HttpListenerHost appHost) + public void Init(HttpListenerHost appHost, Type[] serviceTypes) { - foreach (var serviceType in _resolveServicesFn()) + foreach (var serviceType in serviceTypes) { RegisterService(appHost, serviceType); } } - private Type[] GetGenericArguments(Type type) - { - return type.GetTypeInfo().IsGenericTypeDefinition - ? type.GetTypeInfo().GenericTypeParameters - : type.GetTypeInfo().GenericTypeArguments; - } - public void RegisterService(HttpListenerHost appHost, Type serviceType) { var processedReqs = new HashSet<Type>(); @@ -52,36 +43,17 @@ namespace Emby.Server.Implementations.Services ServiceExecGeneral.CreateServiceRunnersFor(requestType, actions); - var returnMarker = GetTypeWithGenericTypeDefinitionOf(requestType, typeof(IReturn<>)); - var responseType = returnMarker != null ? - GetGenericArguments(returnMarker)[0] - : mi.ReturnType != typeof(object) && mi.ReturnType != typeof(void) ? - mi.ReturnType - : Type.GetType(requestType.FullName + "Response"); + //var returnMarker = GetTypeWithGenericTypeDefinitionOf(requestType, typeof(IReturn<>)); + //var responseType = returnMarker != null ? + // GetGenericArguments(returnMarker)[0] + // : mi.ReturnType != typeof(object) && mi.ReturnType != typeof(void) ? + // mi.ReturnType + // : Type.GetType(requestType.FullName + "Response"); RegisterRestPaths(appHost, requestType); - appHost.AddServiceInfo(serviceType, requestType, responseType); - } - } - - private static Type GetTypeWithGenericTypeDefinitionOf(Type type, Type genericTypeDefinition) - { - foreach (var t in type.GetTypeInfo().ImplementedInterfaces) - { - if (t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == genericTypeDefinition) - { - return t; - } - } - - var genericType = FirstGenericType(type); - if (genericType != null && genericType.GetGenericTypeDefinition() == genericTypeDefinition) - { - return genericType; + appHost.AddServiceInfo(serviceType, requestType); } - - return null; } public static Type FirstGenericType(Type type) @@ -103,11 +75,7 @@ namespace Emby.Server.Implementations.Services var attrs = appHost.GetRouteAttributes(requestType); foreach (RouteAttribute attr in attrs) { - var restPath = new RestPath(appHost.CreateInstance, appHost.GetParseFn, requestType, attr.Path, attr.Verbs, attr.Summary, attr.Notes); - - if (!restPath.IsValid) - throw new NotSupportedException(string.Format( - "RestPath '{0}' on Type '{1}' is not Valid", attr.Path, requestType.GetMethodName())); + var restPath = new RestPath(appHost.CreateInstance, appHost.GetParseFn, requestType, attr.Path, attr.Verbs, attr.Summary); RegisterRestPath(restPath); } @@ -120,8 +88,7 @@ namespace Emby.Server.Implementations.Services if (!restPath.Path.StartsWith("/")) throw new ArgumentException(string.Format("Route '{0}' on '{1}' must start with a '/'", restPath.Path, restPath.RequestType.GetMethodName())); if (restPath.Path.IndexOfAny(InvalidRouteChars) != -1) - throw new ArgumentException(string.Format("Route '{0}' on '{1}' contains invalid chars. " + - "See https://github.com/ServiceStack/ServiceStack/wiki/Routing for info on valid routes.", restPath.Path, restPath.RequestType.GetMethodName())); + throw new ArgumentException(string.Format("Route '{0}' on '{1}' contains invalid chars. ", restPath.Path, restPath.RequestType.GetMethodName())); List<RestPath> pathsAtFirstMatch; if (!RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out pathsAtFirstMatch)) diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index e0b5e69c0..5709d3e0a 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -5,12 +5,13 @@ using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; using MediaBrowser.Model.Services; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Services { public static class ServiceExecExtensions { - public static HashSet<string> AllVerbs = new HashSet<string>(new[] { + public static string[] AllVerbs = new[] { "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", // RFC 2616 "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", "LOCK", "UNLOCK", // RFC 2518 "VERSION-CONTROL", "REPORT", "CHECKOUT", "CHECKIN", "UNCHECKOUT", @@ -21,27 +22,43 @@ namespace Emby.Server.Implementations.Services "SEARCH", // https://datatracker.ietf.org/doc/draft-reschke-webdav-search/ "BCOPY", "BDELETE", "BMOVE", "BPROPFIND", "BPROPPATCH", "NOTIFY", "POLL", "SUBSCRIBE", "UNSUBSCRIBE" - }); + }; - public static IEnumerable<MethodInfo> GetActions(this Type serviceType) + public static HashSet<string> AllVerbsSet = new HashSet<string>(AllVerbs); + + public static List<MethodInfo> GetActions(this Type serviceType) { - foreach (var mi in serviceType.GetRuntimeMethods().Where(i => i.IsPublic && !i.IsStatic)) + var list = new List<MethodInfo>(); + + foreach (var mi in serviceType.GetRuntimeMethods()) { + if (!mi.IsPublic) + { + continue; + } + + if (mi.IsStatic) + { + continue; + } + if (mi.GetParameters().Length != 1) continue; var actionName = mi.Name; - if (!AllVerbs.Contains(actionName, StringComparer.OrdinalIgnoreCase) && !string.Equals(actionName, ServiceMethod.AnyAction, StringComparison.OrdinalIgnoreCase)) + if (!AllVerbs.Contains(actionName, StringComparer.OrdinalIgnoreCase)) continue; - yield return mi; + list.Add(mi); } + + return list; } } internal static class ServiceExecGeneral { - public static Dictionary<string, ServiceMethod> execMap = new Dictionary<string, ServiceMethod>(); + private static Dictionary<string, ServiceMethod> execMap = new Dictionary<string, ServiceMethod>(); public static void CreateServiceRunnersFor(Type requestType, List<ServiceMethod> actions) { @@ -58,8 +75,7 @@ namespace Emby.Server.Implementations.Services var actionName = request.Verb ?? "POST"; ServiceMethod actionContext; - if (ServiceExecGeneral.execMap.TryGetValue(ServiceMethod.Key(serviceType, actionName, requestName), out actionContext) - || ServiceExecGeneral.execMap.TryGetValue(ServiceMethod.AnyKey(serviceType, requestName), out actionContext)) + if (ServiceExecGeneral.execMap.TryGetValue(ServiceMethod.Key(serviceType, actionName, requestName), out actionContext)) { if (actionContext.RequestFilters != null) { @@ -123,7 +139,7 @@ namespace Emby.Server.Implementations.Services } if (reqFilters.Count > 0) - actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray(); + actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray(reqFilters.Count); actions.Add(actionCtx); } diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index 526e62d39..d500595ce 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -162,7 +162,11 @@ namespace Emby.Server.Implementations.Services if (RequireqRequestStream(requestType)) { // Used by IRequiresRequestStream - return CreateRequiresRequestStreamRequest(host, httpReq, requestType); + var request = ServiceHandler.CreateRequest(httpReq, restPath, GetRequestParams(httpReq), host.CreateInstance(requestType)); + + var rawReq = (IRequiresRequestStream)request; + rawReq.RequestStream = httpReq.InputStream; + return rawReq; } var requestParams = GetFlattenedRequestParams(httpReq); @@ -176,16 +180,6 @@ namespace Emby.Server.Implementations.Services return requiresRequestStreamTypeInfo.IsAssignableFrom(requestType.GetTypeInfo()); } - private static IRequiresRequestStream CreateRequiresRequestStreamRequest(HttpListenerHost host, IRequest req, Type requestType) - { - var restPath = GetRoute(req); - var request = ServiceHandler.CreateRequest(req, restPath, GetRequestParams(req), host.CreateInstance(requestType)); - - var rawReq = (IRequiresRequestStream)request; - rawReq.RequestStream = req.InputStream; - return rawReq; - } - public static object CreateRequest(HttpListenerHost host, IRequest httpReq, RestPath restPath, Dictionary<string, string> requestParams) { var requestDto = CreateContentTypeRequest(host, httpReq, restPath.RequestType, httpReq.ContentType); @@ -215,35 +209,39 @@ namespace Emby.Server.Implementations.Services if (name == null) continue; //thank you ASP.NET var values = request.QueryString.GetValues(name); - if (values.Length == 1) + if (values.Count == 1) { map[name] = values[0]; } else { - for (var i = 0; i < values.Length; i++) + for (var i = 0; i < values.Count; i++) { map[name + (i == 0 ? "" : "#" + i)] = values[i]; } } } - if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT")) && request.FormData != null) + if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT"))) { - foreach (var name in request.FormData.Keys) + var formData = request.FormData; + if (formData != null) { - if (name == null) continue; //thank you ASP.NET - - var values = request.FormData.GetValues(name); - if (values.Length == 1) + foreach (var name in formData.Keys) { - map[name] = values[0]; - } - else - { - for (var i = 0; i < values.Length; i++) + if (name == null) continue; //thank you ASP.NET + + var values = formData.GetValues(name); + if (values.Count == 1) + { + map[name] = values[0]; + } + else { - map[name + (i == 0 ? "" : "#" + i)] = values[i]; + for (var i = 0; i < values.Count; i++) + { + map[name + (i == 0 ? "" : "#" + i)] = values[i]; + } } } } @@ -270,12 +268,16 @@ namespace Emby.Server.Implementations.Services map[name] = request.QueryString[name]; } - if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT")) && request.FormData != null) + if ((IsMethod(request.Verb, "POST") || IsMethod(request.Verb, "PUT"))) { - foreach (var name in request.FormData.Keys) + var formData = request.FormData; + if (formData != null) { - if (name == null) continue; //thank you ASP.NET - map[name] = request.FormData[name]; + foreach (var name in formData.Keys) + { + if (name == null) continue; //thank you ASP.NET + map[name] = formData[name]; + } } } diff --git a/Emby.Server.Implementations/Services/ServiceMethod.cs b/Emby.Server.Implementations/Services/ServiceMethod.cs index bcbc6fb57..fa2dd43d0 100644 --- a/Emby.Server.Implementations/Services/ServiceMethod.cs +++ b/Emby.Server.Implementations/Services/ServiceMethod.cs @@ -4,8 +4,6 @@ namespace Emby.Server.Implementations.Services { public class ServiceMethod { - public const string AnyAction = "ANY"; - public string Id { get; set; } public ActionInvokerFn ServiceAction { get; set; } @@ -15,10 +13,5 @@ namespace Emby.Server.Implementations.Services { return serviceType.FullName + " " + method.ToUpper() + " " + requestDtoName; } - - public static string AnyKey(Type serviceType, string requestDtoName) - { - return Key(serviceType, AnyAction, requestDtoName); - } } }
\ No newline at end of file diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index 255b20919..df5d71374 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Reflection; using System.Text; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Services { @@ -20,8 +21,6 @@ namespace Emby.Server.Implementations.Services readonly bool[] componentsWithSeparators; private readonly string restPath; - private readonly string allowedVerbs; - private readonly bool allowsAllVerbs; public bool IsWildCardPath { get; private set; } private readonly string[] literalsToMatch; @@ -45,15 +44,7 @@ namespace Emby.Server.Implementations.Services /// </summary> public int TotalComponentsCount { get; set; } - public string[] Verbs - { - get - { - return allowsAllVerbs - ? new[] { "ANY" } - : AllowedVerbs.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); - } - } + public string[] Verbs { get; private set; } public Type RequestType { get; private set; } @@ -61,19 +52,11 @@ namespace Emby.Server.Implementations.Services public string Summary { get; private set; } - public string Notes { get; private set; } - - public bool AllowsAllVerbs { get { return this.allowsAllVerbs; } } - - public string AllowedVerbs { get { return this.allowedVerbs; } } - public int Priority { get; set; } //passed back to RouteAttribute public static string[] GetPathPartsForMatching(string pathInfo) { - var parts = pathInfo.ToLower().Split(PathSeperatorChar) - .Where(x => !String.IsNullOrEmpty(x)).ToArray(); - return parts; + return pathInfo.ToLower().Split(new[] { PathSeperatorChar }, StringSplitOptions.RemoveEmptyEntries); } public static List<string> GetFirstMatchHashKeys(string[] pathPartsForMatching) @@ -108,18 +91,13 @@ namespace Emby.Server.Implementations.Services return list; } - public RestPath(Func<Type, object> createInstanceFn, Func<Type, Func<string, object>> getParseFn, Type requestType, string path, string verbs, string summary = null, string notes = null) + public RestPath(Func<Type, object> createInstanceFn, Func<Type, Func<string, object>> getParseFn, Type requestType, string path, string verbs, string summary = null) { this.RequestType = requestType; this.Summary = summary; - this.Notes = notes; this.restPath = path; - this.allowsAllVerbs = verbs == null || String.Equals(verbs, WildCard, StringComparison.OrdinalIgnoreCase); - if (!this.allowsAllVerbs) - { - this.allowedVerbs = verbs.ToUpper(); - } + this.Verbs = string.IsNullOrWhiteSpace(verbs) ? ServiceExecExtensions.AllVerbs : verbs.ToUpper().Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries); var componentsList = new List<string>(); @@ -142,17 +120,16 @@ namespace Emby.Server.Implementations.Services } } - var components = componentsList.ToArray(); + var components = componentsList.ToArray(componentsList.Count); this.TotalComponentsCount = components.Length; this.literalsToMatch = new string[this.TotalComponentsCount]; this.variablesNames = new string[this.TotalComponentsCount]; this.isWildcard = new bool[this.TotalComponentsCount]; - this.componentsWithSeparators = hasSeparators.ToArray(); + this.componentsWithSeparators = hasSeparators.ToArray(hasSeparators.Count); this.PathComponentsCount = this.componentsWithSeparators.Length; string firstLiteralMatch = null; - var sbHashKey = new StringBuilder(); for (var i = 0; i < components.Length; i++) { var component = components[i]; @@ -171,7 +148,6 @@ namespace Emby.Server.Implementations.Services else { this.literalsToMatch[i] = component.ToLower(); - sbHashKey.Append(i + PathSeperatorChar.ToString() + this.literalsToMatch); if (firstLiteralMatch == null) { @@ -197,9 +173,6 @@ namespace Emby.Server.Implementations.Services ? this.PathComponentsCount + PathSeperator + firstLiteralMatch : WildCardChar + PathSeperator + firstLiteralMatch; - this.IsValid = sbHashKey.Length > 0; - this.UniqueMatchHashKey = sbHashKey.ToString(); - this.typeDeserializer = new StringMapTypeDeserializer(createInstanceFn, getParseFn, this.RequestType); RegisterCaseInsenstivePropertyNameMappings(); } @@ -219,26 +192,46 @@ namespace Emby.Server.Implementations.Services }; - private static List<Type> _excludeTypes = new List<Type> { typeof(Stream) }; + private static Type excludeType = typeof(Stream); - internal static PropertyInfo[] GetSerializableProperties(Type type) + internal static List<PropertyInfo> GetSerializableProperties(Type type) { - var properties = GetPublicProperties(type); - var readableProperties = properties.Where(x => x.GetMethod != null); + var list = new List<PropertyInfo>(); + var props = GetPublicProperties(type); - // else return those properties that are not decorated with IgnoreDataMember - return readableProperties - .Where(prop => prop.GetCustomAttributes(true) - .All(attr => + foreach (var prop in props) + { + if (prop.GetMethod == null) + { + continue; + } + + if (excludeType == prop.PropertyType) + { + continue; + } + + var ignored = false; + foreach (var attr in prop.GetCustomAttributes(true)) + { + if (IgnoreAttributesNamed.Contains(attr.GetType().Name)) { - var name = attr.GetType().Name; - return !IgnoreAttributesNamed.Contains(name); - })) - .Where(prop => !_excludeTypes.Contains(prop.PropertyType)) - .ToArray(); + ignored = true; + break; + } + } + + if (!ignored) + { + list.Add(prop); + } + } + + // else return those properties that are not decorated with IgnoreDataMember + return list; } - private static PropertyInfo[] GetPublicProperties(Type type) + private static List<PropertyInfo> GetPublicProperties(Type type) { if (type.GetTypeInfo().IsInterface) { @@ -268,12 +261,19 @@ namespace Emby.Server.Implementations.Services propertyInfos.InsertRange(0, newPropertyInfos); } - return propertyInfos.ToArray(); + return propertyInfos; } - return GetTypesPublicProperties(type) - .Where(t => t.GetIndexParameters().Length == 0) // ignore indexed properties - .ToArray(); + var list = new List<PropertyInfo>(); + + foreach (var t in GetTypesPublicProperties(type)) + { + if (t.GetIndexParameters().Length == 0) + { + list.Add(t); + } + } + return list; } private static PropertyInfo[] GetTypesPublicProperties(Type subType) @@ -285,19 +285,14 @@ namespace Emby.Server.Implementations.Services if (mi != null && mi.IsStatic) continue; pis.Add(pi); } - return pis.ToArray(); + return pis.ToArray(pis.Count); } - - public bool IsValid { get; set; } - /// <summary> /// Provide for quick lookups based on hashes that can be determined from a request url /// </summary> public string FirstMatchHashKey { get; private set; } - public string UniqueMatchHashKey { get; private set; } - private readonly StringMapTypeDeserializer typeDeserializer; private readonly Dictionary<string, string> propertyNamesMap = new Dictionary<string, string>(); @@ -320,8 +315,14 @@ namespace Emby.Server.Implementations.Services score += Math.Max((10 - VariableArgsCount), 1) * 100; //Exact verb match is better than ANY - var exactVerb = String.Equals(httpMethod, AllowedVerbs, StringComparison.OrdinalIgnoreCase); - score += exactVerb ? 10 : 1; + if (Verbs.Length == 1 && string.Equals(httpMethod, Verbs[0], StringComparison.OrdinalIgnoreCase)) + { + score += 10; + } + else + { + score += 1; + } return score; } @@ -345,7 +346,7 @@ namespace Emby.Server.Implementations.Services return false; } - if (!this.allowsAllVerbs && !StringContains(this.allowedVerbs, httpMethod)) + if (!Verbs.Contains(httpMethod, StringComparer.OrdinalIgnoreCase)) { //logger.Info("allowsAllVerbs mismatch for {0} for {1} allowedverbs {2}", httpMethod, string.Join("/", withPathInfoParts), this.allowedVerbs); return false; @@ -450,14 +451,13 @@ namespace Emby.Server.Implementations.Services } } - withPathInfoParts = totalComponents.ToArray(); + withPathInfoParts = totalComponents.ToArray(totalComponents.Count); return true; } public object CreateRequest(string pathInfo, Dictionary<string, string> queryStringAndFormData, object fromInstance) { - var requestComponents = pathInfo.Split(PathSeperatorChar) - .Where(x => !String.IsNullOrEmpty(x)).ToArray(); + var requestComponents = pathInfo.Split(new[] { PathSeperatorChar }, StringSplitOptions.RemoveEmptyEntries); ExplodeComponents(ref requestComponents); @@ -554,10 +554,5 @@ namespace Emby.Server.Implementations.Services return this.typeDeserializer.PopulateFromMap(fromInstance, requestKeyValuesMap); } - - public override int GetHashCode() - { - return UniqueMatchHashKey.GetHashCode(); - } } }
\ No newline at end of file diff --git a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs index fc1cf4ed9..2233bf918 100644 --- a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs +++ b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; namespace Emby.Server.Implementations.Services @@ -64,11 +63,16 @@ namespace Emby.Server.Implementations.Services if (instance == null) instance = _CreateInstanceFn(type); - foreach (var pair in keyValuePairs.Where(x => !string.IsNullOrEmpty(x.Value))) + foreach (var pair in keyValuePairs) { propertyName = pair.Key; propertyTextValue = pair.Value; + if (string.IsNullOrEmpty(propertyTextValue)) + { + continue; + } + if (!propertySetterMap.TryGetValue(propertyName, out propertySerializerEntry)) { if (propertyName == "v") @@ -115,7 +119,7 @@ namespace Emby.Server.Implementations.Services { public static Action<object, object> GetSetPropertyMethod(Type type, PropertyInfo propertyInfo) { - if (!propertyInfo.CanWrite || propertyInfo.GetIndexParameters().Any()) return null; + if (!propertyInfo.CanWrite || propertyInfo.GetIndexParameters().Length > 0) return null; var setMethodInfo = propertyInfo.SetMethod; return (instance, value) => setMethodInfo.Invoke(instance, new[] { value }); diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs index dbac76bb4..bd53da1bd 100644 --- a/Emby.Server.Implementations/Session/HttpSessionController.cs +++ b/Emby.Server.Implementations/Session/HttpSessionController.cs @@ -14,7 +14,7 @@ using System.Threading.Tasks; namespace Emby.Server.Implementations.Session { - public class HttpSessionController : ISessionController, IDisposable + public class HttpSessionController : ISessionController { private readonly IHttpClient _httpClient; private readonly IJsonSerializer _json; @@ -195,9 +195,5 @@ namespace Emby.Server.Implementations.Session return "?" + args; } - - public void Dispose() - { - } } } diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 317f40a37..0692a0ba5 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -6,11 +6,8 @@ using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Devices; @@ -32,6 +29,7 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Threading; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Session { @@ -252,7 +250,7 @@ namespace Emby.Server.Implementations.Session { try { - await _userManager.UpdateUser(user).ConfigureAwait(false); + _userManager.UpdateUser(user); } catch (Exception ex) { @@ -467,7 +465,7 @@ namespace Emby.Server.Implementations.Session if (!userId.HasValue) { - sessionInfo.AdditionalUsers.Clear(); + sessionInfo.AdditionalUsers = new SessionUserInfo[] { }; } if (sessionInfo.SessionController == null) @@ -621,7 +619,7 @@ namespace Emby.Server.Implementations.Session { foreach (var user in users) { - await OnPlaybackStart(user.Id, libraryItem).ConfigureAwait(false); + OnPlaybackStart(user.Id, libraryItem); } } @@ -649,8 +647,7 @@ namespace Emby.Server.Implementations.Session /// </summary> /// <param name="userId">The user identifier.</param> /// <param name="item">The item.</param> - /// <returns>Task.</returns> - private async Task OnPlaybackStart(Guid userId, IHasUserData item) + private void OnPlaybackStart(Guid userId, IHasUserData item) { var data = _userDataManager.GetUserData(userId, item); @@ -669,7 +666,7 @@ namespace Emby.Server.Implementations.Session data.Played = false; } - await _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false); + _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None); } public Task OnPlaybackProgress(PlaybackProgressInfo info) @@ -701,7 +698,7 @@ namespace Emby.Server.Implementations.Session { foreach (var user in users) { - await OnPlaybackProgress(user, libraryItem, info).ConfigureAwait(false); + OnPlaybackProgress(user, libraryItem, info); } } @@ -729,7 +726,7 @@ namespace Emby.Server.Implementations.Session StartIdleCheckTimer(); } - private async Task OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info) + private void OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info) { var data = _userDataManager.GetUserData(user.Id, item); @@ -741,7 +738,7 @@ namespace Emby.Server.Implementations.Session UpdatePlaybackSettings(user, info, data); - await _userDataManager.SaveUserData(user.Id, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); + _userDataManager.SaveUserData(user.Id, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None); } } @@ -841,7 +838,7 @@ namespace Emby.Server.Implementations.Session { foreach (var user in users) { - playedToCompletion = await OnPlaybackStopped(user.Id, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false); + playedToCompletion = OnPlaybackStopped(user.Id, libraryItem, info.PositionTicks, info.Failed); } } @@ -874,7 +871,7 @@ namespace Emby.Server.Implementations.Session await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false); } - private async Task<bool> OnPlaybackStopped(Guid userId, BaseItem item, long? positionTicks, bool playbackFailed) + private bool OnPlaybackStopped(Guid userId, BaseItem item, long? positionTicks, bool playbackFailed) { bool playedToCompletion = false; @@ -895,7 +892,7 @@ namespace Emby.Server.Implementations.Session playedToCompletion = true; } - await _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false); + _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None); } return playedToCompletion; @@ -1000,7 +997,7 @@ namespace Emby.Server.Implementations.Session command.PlayCommand = PlayCommand.PlayNow; } - command.ItemIds = items.Select(i => i.Id.ToString("N")).ToArray(); + command.ItemIds = items.Select(i => i.Id.ToString("N")).ToArray(items.Count); if (user != null) { @@ -1033,7 +1030,7 @@ namespace Emby.Server.Implementations.Session if (episodes.Count > 0) { - command.ItemIds = episodes.Select(i => i.Id.ToString("N")).ToArray(); + command.ItemIds = episodes.Select(i => i.Id.ToString("N")).ToArray(episodes.Count); } } } @@ -1073,7 +1070,7 @@ namespace Emby.Server.Implementations.Session DtoOptions = new DtoOptions(false) { EnableImages = false, - Fields = new List<ItemFields> + Fields = new ItemFields[] { ItemFields.SortName } @@ -1089,14 +1086,14 @@ namespace Emby.Server.Implementations.Session { var folder = (Folder)item; - var itemsResult = folder.GetItems(new InternalItemsQuery(user) + var itemsResult = folder.GetItemList(new InternalItemsQuery(user) { Recursive = true, IsFolder = false, DtoOptions = new DtoOptions(false) { EnableImages = false, - Fields = new List<ItemFields> + Fields = new ItemFields[] { ItemFields.SortName } @@ -1104,7 +1101,7 @@ namespace Emby.Server.Implementations.Session }); - return FilterToSingleMediaType(itemsResult.Items) + return FilterToSingleMediaType(itemsResult) .OrderBy(i => i.SortName) .ToList(); } @@ -1339,11 +1336,15 @@ namespace Emby.Server.Implementations.Session { var user = _userManager.GetUserById(userId); - session.AdditionalUsers.Add(new SessionUserInfo + var list = session.AdditionalUsers.ToList(); + + list.Add(new SessionUserInfo { UserId = userId, UserName = user.Name }); + + session.AdditionalUsers = list.ToArray(list.Count); } } @@ -1367,7 +1368,10 @@ namespace Emby.Server.Implementations.Session if (user != null) { - session.AdditionalUsers.Remove(user); + var list = session.AdditionalUsers.ToList(); + list.Remove(user); + + session.AdditionalUsers = list.ToArray(list.Count); } } @@ -1424,7 +1428,7 @@ namespace Emby.Server.Implementations.Session user = result; } - var token = await GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.AppVersion, request.DeviceName).ConfigureAwait(false); + var token = GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.AppVersion, request.DeviceName); EventHelper.FireEventIfNotNull(AuthenticationSucceeded, this, new GenericEventArgs<AuthenticationRequest>(request), _logger); @@ -1446,7 +1450,7 @@ namespace Emby.Server.Implementations.Session } - private async Task<string> GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName) + private string GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName) { var existing = _authRepo.Get(new AuthenticationInfoQuery { @@ -1476,12 +1480,12 @@ namespace Emby.Server.Implementations.Session }; _logger.Info("Creating new access token for user {0}", userId); - await _authRepo.Create(newToken, CancellationToken.None).ConfigureAwait(false); + _authRepo.Create(newToken, CancellationToken.None); return newToken.AccessToken; } - public async Task Logout(string accessToken) + public void Logout(string accessToken) { if (string.IsNullOrWhiteSpace(accessToken)) { @@ -1501,7 +1505,7 @@ namespace Emby.Server.Implementations.Session { existing.IsActive = false; - await _authRepo.Update(existing, CancellationToken.None).ConfigureAwait(false); + _authRepo.Update(existing, CancellationToken.None); var sessions = Sessions .Where(i => string.Equals(i.DeviceId, existing.DeviceId, StringComparison.OrdinalIgnoreCase)) @@ -1521,7 +1525,7 @@ namespace Emby.Server.Implementations.Session } } - public async Task RevokeUserTokens(string userId, string currentAccessToken) + public void RevokeUserTokens(string userId, string currentAccessToken) { var existing = _authRepo.Get(new AuthenticationInfoQuery { @@ -1533,14 +1537,14 @@ namespace Emby.Server.Implementations.Session { if (!string.Equals(currentAccessToken, info.AccessToken, StringComparison.OrdinalIgnoreCase)) { - await Logout(info.AccessToken).ConfigureAwait(false); + Logout(info.AccessToken); } } } - public Task RevokeToken(string token) + public void RevokeToken(string token) { - return Logout(token); + Logout(token); } /// <summary> @@ -1660,37 +1664,39 @@ namespace Emby.Server.Implementations.Session AddProgramRecordingInfo = false }; - dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo); - dtoOptions.Fields.Remove(ItemFields.SyncInfo); - dtoOptions.Fields.Remove(ItemFields.CanDelete); - dtoOptions.Fields.Remove(ItemFields.CanDownload); - dtoOptions.Fields.Remove(ItemFields.ChildCount); - dtoOptions.Fields.Remove(ItemFields.CustomRating); - dtoOptions.Fields.Remove(ItemFields.DateLastMediaAdded); - dtoOptions.Fields.Remove(ItemFields.DateLastRefreshed); - dtoOptions.Fields.Remove(ItemFields.DateLastSaved); - dtoOptions.Fields.Remove(ItemFields.DisplayMediaType); - dtoOptions.Fields.Remove(ItemFields.DisplayPreferencesId); - dtoOptions.Fields.Remove(ItemFields.Etag); - dtoOptions.Fields.Remove(ItemFields.ExternalEtag); - dtoOptions.Fields.Remove(ItemFields.InheritedParentalRatingValue); - dtoOptions.Fields.Remove(ItemFields.ItemCounts); - dtoOptions.Fields.Remove(ItemFields.MediaSourceCount); - dtoOptions.Fields.Remove(ItemFields.MediaStreams); - dtoOptions.Fields.Remove(ItemFields.MediaSources); - dtoOptions.Fields.Remove(ItemFields.People); - dtoOptions.Fields.Remove(ItemFields.PlayAccess); - dtoOptions.Fields.Remove(ItemFields.People); - dtoOptions.Fields.Remove(ItemFields.ProductionLocations); - dtoOptions.Fields.Remove(ItemFields.RecursiveItemCount); - dtoOptions.Fields.Remove(ItemFields.RemoteTrailers); - dtoOptions.Fields.Remove(ItemFields.SeasonUserData); - dtoOptions.Fields.Remove(ItemFields.SeriesGenres); - dtoOptions.Fields.Remove(ItemFields.Settings); - dtoOptions.Fields.Remove(ItemFields.SortName); - dtoOptions.Fields.Remove(ItemFields.Tags); - dtoOptions.Fields.Remove(ItemFields.ThemeSongIds); - dtoOptions.Fields.Remove(ItemFields.ThemeVideoIds); + var fields = dtoOptions.Fields.ToList(); + + fields.Remove(ItemFields.BasicSyncInfo); + fields.Remove(ItemFields.SyncInfo); + fields.Remove(ItemFields.CanDelete); + fields.Remove(ItemFields.CanDownload); + fields.Remove(ItemFields.ChildCount); + fields.Remove(ItemFields.CustomRating); + fields.Remove(ItemFields.DateLastMediaAdded); + fields.Remove(ItemFields.DateLastRefreshed); + fields.Remove(ItemFields.DateLastSaved); + fields.Remove(ItemFields.DisplayPreferencesId); + fields.Remove(ItemFields.Etag); + fields.Remove(ItemFields.ExternalEtag); + fields.Remove(ItemFields.InheritedParentalRatingValue); + fields.Remove(ItemFields.ItemCounts); + fields.Remove(ItemFields.MediaSourceCount); + fields.Remove(ItemFields.MediaStreams); + fields.Remove(ItemFields.MediaSources); + fields.Remove(ItemFields.People); + fields.Remove(ItemFields.PlayAccess); + fields.Remove(ItemFields.People); + fields.Remove(ItemFields.ProductionLocations); + fields.Remove(ItemFields.RecursiveItemCount); + fields.Remove(ItemFields.RemoteTrailers); + fields.Remove(ItemFields.SeasonUserData); + fields.Remove(ItemFields.Settings); + fields.Remove(ItemFields.SortName); + fields.Remove(ItemFields.Tags); + fields.Remove(ItemFields.ThemeSongIds); + fields.Remove(ItemFields.ThemeVideoIds); + + dtoOptions.Fields = fields.ToArray(fields.Count); _itemInfoDtoOptions = dtoOptions; } @@ -1699,7 +1705,7 @@ namespace Emby.Server.Implementations.Session if (mediaSource != null) { - info.MediaStreams = mediaSource.MediaStreams; + info.MediaStreams = mediaSource.MediaStreams.ToArray(); } return info; diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs index 2735bb237..a5af843db 100644 --- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs @@ -102,6 +102,7 @@ namespace Emby.Server.Implementations.Session public void Dispose() { _serverManager.WebSocketConnected -= _serverManager_WebSocketConnected; + GC.SuppressFinalize(this); } /// <summary> diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index f0ff0b5dd..ee9ee8969 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -283,6 +283,7 @@ namespace Emby.Server.Implementations.Session { socket.Closed -= connection_Closed; } + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/Social/SharingManager.cs b/Emby.Server.Implementations/Social/SharingManager.cs index 54614c879..57cf93948 100644 --- a/Emby.Server.Implementations/Social/SharingManager.cs +++ b/Emby.Server.Implementations/Social/SharingManager.cs @@ -58,8 +58,8 @@ namespace Emby.Server.Implementations.Social }; AddShareInfo(info, externalUrl); - - await _repository.CreateShare(info).ConfigureAwait(false); + + _repository.CreateShare(info); return info; } @@ -92,9 +92,9 @@ namespace Emby.Server.Implementations.Social } } - public Task DeleteShare(string id) + public void DeleteShare(string id) { - return _repository.DeleteShare(id); + _repository.DeleteShare(id); } } } diff --git a/Emby.Server.Implementations/Social/SharingRepository.cs b/Emby.Server.Implementations/Social/SharingRepository.cs index 46e9205bb..f306e76c4 100644 --- a/Emby.Server.Implementations/Social/SharingRepository.cs +++ b/Emby.Server.Implementations/Social/SharingRepository.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.IO; -using System.Threading; -using System.Threading.Tasks; using Emby.Server.Implementations.Data; using MediaBrowser.Common.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Social; using SQLitePCL.pretty; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Social { @@ -41,7 +40,7 @@ namespace Emby.Server.Implementations.Social } } - public async Task CreateShare(SocialShareInfo info) + public void CreateShare(SocialShareInfo info) { if (info == null) { @@ -86,7 +85,7 @@ namespace Emby.Server.Implementations.Social var paramList = new List<object>(); paramList.Add(id.ToGuidBlob()); - foreach (var row in connection.Query(commandText, paramList.ToArray())) + foreach (var row in connection.Query(commandText, paramList.ToArray(paramList.Count))) { return GetSocialShareInfo(row); } @@ -108,7 +107,7 @@ namespace Emby.Server.Implementations.Social return info; } - public async Task DeleteShare(string id) + public void DeleteShare(string id) { } diff --git a/Emby.Server.Implementations/Sorting/AirTimeComparer.cs b/Emby.Server.Implementations/Sorting/AirTimeComparer.cs deleted file mode 100644 index bc05e9af3..000000000 --- a/Emby.Server.Implementations/Sorting/AirTimeComparer.cs +++ /dev/null @@ -1,71 +0,0 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Sorting; -using MediaBrowser.Model.Querying; -using System; - -namespace Emby.Server.Implementations.Sorting -{ - public class AirTimeComparer : IBaseItemComparer - { - /// <summary> - /// Compares the specified x. - /// </summary> - /// <param name="x">The x.</param> - /// <param name="y">The y.</param> - /// <returns>System.Int32.</returns> - public int Compare(BaseItem x, BaseItem y) - { - return DateTime.Compare(GetValue(x), GetValue(y)); - } - - /// <summary> - /// Gets the value. - /// </summary> - /// <param name="x">The x.</param> - /// <returns>System.String.</returns> - private DateTime GetValue(BaseItem x) - { - var series = x as Series; - - if (series == null) - { - var season = x as Season; - - if (season != null) - { - series = season.Series; - } - else - { - var episode = x as Episode; - - if (episode != null) - { - series = episode.Series; - } - } - } - - if (series != null) - { - DateTime result; - if (DateTime.TryParse(series.AirTime, out result)) - { - return result; - } - } - - return DateTime.MinValue; - } - - /// <summary> - /// Gets the name. - /// </summary> - /// <value>The name.</value> - public string Name - { - get { return ItemSortBy.AirTime; } - } - } -} diff --git a/Emby.Server.Implementations/Sorting/ArtistComparer.cs b/Emby.Server.Implementations/Sorting/ArtistComparer.cs index edb195820..616aff673 100644 --- a/Emby.Server.Implementations/Sorting/ArtistComparer.cs +++ b/Emby.Server.Implementations/Sorting/ArtistComparer.cs @@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Sorting return string.Empty; } - return audio.Artists.Count == 0 ? null : audio.Artists[0]; + return audio.Artists.Length == 0 ? null : audio.Artists[0]; } /// <summary> diff --git a/Emby.Server.Implementations/SystemEvents.cs b/Emby.Server.Implementations/SystemEvents.cs new file mode 100644 index 000000000..dfff92f1e --- /dev/null +++ b/Emby.Server.Implementations/SystemEvents.cs @@ -0,0 +1,50 @@ +using System; +using MediaBrowser.Common.Events; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.System; + +namespace Emby.Server.Implementations +{ + public class SystemEvents : ISystemEvents + { + public event EventHandler Resume; + public event EventHandler Suspend; + public event EventHandler SessionLogoff; + public event EventHandler SystemShutdown; + + private readonly ILogger _logger; + + public SystemEvents(ILogger logger) + { + _logger = logger; + Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding; + } + + private void SystemEvents_SessionEnding(object sender, Microsoft.Win32.SessionEndingEventArgs e) + { + switch (e.Reason) + { + case Microsoft.Win32.SessionEndReasons.Logoff: + EventHelper.FireEventIfNotNull(SessionLogoff, this, EventArgs.Empty, _logger); + break; + case Microsoft.Win32.SessionEndReasons.SystemShutdown: + EventHelper.FireEventIfNotNull(SystemShutdown, this, EventArgs.Empty, _logger); + break; + } + } + + 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/Emby.Server.Implementations/TV/SeriesPostScanTask.cs b/Emby.Server.Implementations/TV/SeriesPostScanTask.cs index 23b6a3cb5..764df8baf 100644 --- a/Emby.Server.Implementations/TV/SeriesPostScanTask.cs +++ b/Emby.Server.Implementations/TV/SeriesPostScanTask.cs @@ -217,6 +217,7 @@ namespace Emby.Server.Implementations.TV public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } /// <summary> diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 876c5d58b..0b81f7e93 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -42,7 +42,7 @@ namespace Emby.Server.Implementations.TV int? limit = null; if (!string.IsNullOrWhiteSpace(request.SeriesId)) { - var series = _libraryManager.GetItemById(request.SeriesId); + var series = _libraryManager.GetItemById(request.SeriesId) as Series; if (series != null) { @@ -51,29 +51,34 @@ namespace Emby.Server.Implementations.TV } } - if (string.IsNullOrWhiteSpace(presentationUniqueKey) && limit.HasValue) + if (!string.IsNullOrWhiteSpace(presentationUniqueKey)) + { + return GetResult(GetNextUpEpisodes(request, user, new[] { presentationUniqueKey }, dtoOptions), request); + } + + if (limit.HasValue) { limit = limit.Value + 10; } var items = _libraryManager.GetItemList(new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(Series).Name }, - SortBy = new[] { ItemSortBy.SeriesDatePlayed }, - SortOrder = SortOrder.Descending, - PresentationUniqueKey = presentationUniqueKey, + IncludeItemTypes = new[] { typeof(Episode).Name }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DatePlayed, SortOrder.Descending) }, + SeriesPresentationUniqueKey = presentationUniqueKey, Limit = limit, ParentId = parentIdGuid, Recursive = true, DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions { - Fields = new List<ItemFields> + Fields = new ItemFields[] { - ItemFields.PresentationUniqueKey + ItemFields.SeriesPresentationUniqueKey } - } + }, + GroupBySeriesPresentationUniqueKey = true - }).Cast<Series>().Select(GetUniqueSeriesKey); + }).Cast<Episode>().Select(GetUniqueSeriesKey); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items, dtoOptions); @@ -94,7 +99,7 @@ namespace Emby.Server.Implementations.TV int? limit = null; if (!string.IsNullOrWhiteSpace(request.SeriesId)) { - var series = _libraryManager.GetItemById(request.SeriesId); + var series = _libraryManager.GetItemById(request.SeriesId) as Series; if (series != null) { @@ -103,28 +108,33 @@ namespace Emby.Server.Implementations.TV } } - if (string.IsNullOrWhiteSpace(presentationUniqueKey) && limit.HasValue) + if (!string.IsNullOrWhiteSpace(presentationUniqueKey)) + { + return GetResult(GetNextUpEpisodes(request, user, new [] { presentationUniqueKey }, dtoOptions), request); + } + + if (limit.HasValue) { limit = limit.Value + 10; } var items = _libraryManager.GetItemList(new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(Series).Name }, - SortBy = new[] { ItemSortBy.SeriesDatePlayed }, - SortOrder = SortOrder.Descending, - PresentationUniqueKey = presentationUniqueKey, + IncludeItemTypes = new[] { typeof(Episode).Name }, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DatePlayed, SortOrder.Descending) }, + SeriesPresentationUniqueKey = presentationUniqueKey, Limit = limit, DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions { - Fields = new List<ItemFields> + Fields = new ItemFields[] { - ItemFields.PresentationUniqueKey + ItemFields.SeriesPresentationUniqueKey }, EnableImages = false - } + }, + GroupBySeriesPresentationUniqueKey = true - }, parentsFolders.Cast<BaseItem>().ToList()).Cast<Series>().Select(GetUniqueSeriesKey); + }, parentsFolders.Cast<BaseItem>().ToList()).Cast<Episode>().Select(GetUniqueSeriesKey); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items, dtoOptions); @@ -167,7 +177,12 @@ namespace Emby.Server.Implementations.TV .Where(i => i != null); } - private string GetUniqueSeriesKey(BaseItem series) + private string GetUniqueSeriesKey(Episode episode) + { + return episode.SeriesPresentationUniqueKey; + } + + private string GetUniqueSeriesKey(Series series) { return series.GetPresentationUniqueKey(); } @@ -183,14 +198,13 @@ namespace Emby.Server.Implementations.TV AncestorWithPresentationUniqueKey = null, SeriesPresentationUniqueKey = seriesKey, IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.SortName }, - SortOrder = SortOrder.Descending, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Descending) }, IsPlayed = true, Limit = 1, ParentIndexNumberNotEquals = 0, DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions { - Fields = new List<ItemFields> + Fields = new ItemFields[] { ItemFields.SortName }, @@ -206,8 +220,7 @@ namespace Emby.Server.Implementations.TV AncestorWithPresentationUniqueKey = null, SeriesPresentationUniqueKey = seriesKey, IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.SortName }, - SortOrder = SortOrder.Ascending, + OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }, Limit = 1, IsPlayed = false, IsVirtualItem = false, diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Detector.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Detector.cs new file mode 100644 index 000000000..507dd5e42 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Detector.cs @@ -0,0 +1,371 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using NLangDetect.Core.Extensions; +using NLangDetect.Core.Utils; + +namespace NLangDetect.Core +{ + public class Detector + { + private const double _AlphaDefault = 0.5; + private const double _AlphaWidth = 0.05; + + private const int _IterationLimit = 1000; + private const double _ProbThreshold = 0.1; + private const double _ConvThreshold = 0.99999; + private const int _BaseFreq = 10000; + + private static readonly Regex _UrlRegex = new Regex("https?://[-_.?&~;+=/#0-9A-Za-z]+", RegexOptions.Compiled); + private static readonly Regex _MailRegex = new Regex("[-_.0-9A-Za-z]+@[-_0-9A-Za-z]+[-_.0-9A-Za-z]+", RegexOptions.Compiled); + + private readonly Dictionary<string, ProbVector> _wordLangProbMap; + private readonly List<string> _langlist; + + private StringBuilder _text; + private double[] _langprob; + + private double _alpha = _AlphaDefault; + private const int _trialsCount = 7; + private int _maxTextLength = 10000; + private double[] _priorMap; + private int? _seed; + + #region Constructor(s) + + public Detector(DetectorFactory factory) + { + _wordLangProbMap = factory.WordLangProbMap; + _langlist = factory.Langlist; + _text = new StringBuilder(); + _seed = factory.Seed; + } + + #endregion + + #region Public methods + + public void SetAlpha(double alpha) + { + _alpha = alpha; + } + + public void SetPriorMap(Dictionary<string, double> priorMap) + { + _priorMap = new double[_langlist.Count]; + + double sump = 0; + + for (int i = 0; i < _priorMap.Length; i++) + { + string lang = _langlist[i]; + + if (priorMap.ContainsKey(lang)) + { + double p = priorMap[lang]; + + if (p < 0) + { + throw new NLangDetectException("Prior probability must be non-negative.", ErrorCode.InitParamError); + } + + _priorMap[i] = p; + sump += p; + } + } + + if (sump <= 0) + { + throw new NLangDetectException("More one of prior probability must be non-zero.", ErrorCode.InitParamError); + } + + for (int i = 0; i < _priorMap.Length; i++) + { + _priorMap[i] /= sump; + } + } + + public void SetMaxTextLength(int max_text_length) + { + _maxTextLength = max_text_length; + } + + // TODO IMM HI: TextReader? + public void Append(StreamReader streamReader) + { + var buf = new char[_maxTextLength / 2]; + + while (_text.Length < _maxTextLength && !streamReader.EndOfStream) + { + int length = streamReader.Read(buf, 0, buf.Length); + + Append(new string(buf, 0, length)); + } + } + + public void Append(string text) + { + text = _UrlRegex.Replace(text, " "); + text = _MailRegex.Replace(text, " "); + + char pre = '\0'; + + for (int i = 0; i < text.Length && i < _maxTextLength; i++) + { + char c = NGram.Normalize(text[i]); + + if (c != ' ' || pre != ' ') + { + _text.Append(c); + } + + pre = c; + } + } + + private void CleanText() + { + int latinCount = 0, nonLatinCount = 0; + + for (int i = 0; i < _text.Length; i++) + { + char c = _text[i]; + + if (c <= 'z' && c >= 'A') + { + latinCount++; + } + else if (c >= '\u0300' && c.GetUnicodeBlock() != UnicodeBlock.LatinExtendedAdditional) + { + nonLatinCount++; + } + } + + if (latinCount * 2 < nonLatinCount) + { + var textWithoutLatin = new StringBuilder(); + + for (int i = 0; i < _text.Length; i++) + { + char c = _text[i]; + + if (c > 'z' || c < 'A') + { + textWithoutLatin.Append(c); + } + } + + _text = textWithoutLatin; + } + } + + public string Detect() + { + List<Language> probabilities = GetProbabilities(); + + return + probabilities.Count > 0 + ? probabilities[0].Name + : null; + } + + public List<Language> GetProbabilities() + { + if (_langprob == null) + { + DetectBlock(); + } + + List<Language> list = SortProbability(_langprob); + + return list; + } + + #endregion + + #region Private helper methods + + private static double NormalizeProb(double[] probs) + { + double maxp = 0, sump = 0; + + sump += probs.Sum(); + + for (int i = 0; i < probs.Length; i++) + { + double p = probs[i] / sump; + + if (maxp < p) + { + maxp = p; + } + + probs[i] = p; + } + + return maxp; + } + + private static string UnicodeEncode(string word) + { + var resultSb = new StringBuilder(); + + foreach (char ch in word) + { + if (ch >= '\u0080') + { + string st = string.Format("{0:x}", 0x10000 + ch); + + while (st.Length < 4) + { + st = "0" + st; + } + + resultSb + .Append("\\u") + .Append(st.SubSequence(1, 5)); + } + else + { + resultSb.Append(ch); + } + } + + return resultSb.ToString(); + } + + private void DetectBlock() + { + CleanText(); + + List<string> ngrams = ExtractNGrams(); + + if (ngrams.Count == 0) + { + throw new NLangDetectException("no features in text", ErrorCode.CantDetectError); + } + + _langprob = new double[_langlist.Count]; + + Random rand = (_seed.HasValue ? new Random(_seed.Value) : new Random()); + + for (int t = 0; t < _trialsCount; t++) + { + double[] prob = InitProbability(); + + // TODO IMM HI: verify it works + double alpha = _alpha + rand.NextGaussian() * _AlphaWidth; + + for (int i = 0; ; i++) + { + int r = rand.Next(ngrams.Count); + + UpdateLangProb(prob, ngrams[r], alpha); + + if (i % 5 == 0) + { + if (NormalizeProb(prob) > _ConvThreshold || i >= _IterationLimit) + { + break; + } + } + } + + for (int j = 0; j < _langprob.Length; j++) + { + _langprob[j] += prob[j] / _trialsCount; + } + } + } + + private double[] InitProbability() + { + var prob = new double[_langlist.Count]; + + if (_priorMap != null) + { + for (int i = 0; i < prob.Length; i++) + { + prob[i] = _priorMap[i]; + } + } + else + { + for (int i = 0; i < prob.Length; i++) + { + prob[i] = 1.0 / _langlist.Count; + } + } + return prob; + } + + private List<string> ExtractNGrams() + { + var list = new List<string>(); + NGram ngram = new NGram(); + + for (int i = 0; i < _text.Length; i++) + { + ngram.AddChar(_text[i]); + + for (int n = 1; n <= NGram.GramsCount; n++) + { + string w = ngram.Get(n); + + if (w != null && _wordLangProbMap.ContainsKey(w)) + { + list.Add(w); + } + } + } + + return list; + } + + private void UpdateLangProb(double[] prob, string word, double alpha) + { + if (word == null || !_wordLangProbMap.ContainsKey(word)) + { + return; + } + + ProbVector langProbMap = _wordLangProbMap[word]; + double weight = alpha / _BaseFreq; + + for (int i = 0; i < prob.Length; i++) + { + prob[i] *= weight + langProbMap[i]; + } + } + + private List<Language> SortProbability(double[] prob) + { + var list = new List<Language>(); + + for (int j = 0; j < prob.Length; j++) + { + double p = prob[j]; + + if (p > _ProbThreshold) + { + for (int i = 0; i <= list.Count; i++) + { + if (i == list.Count || list[i].Probability < p) + { + list.Insert(i, new Language(_langlist[j], p)); + + break; + } + } + } + } + + return list; + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/DetectorFactory.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/DetectorFactory.cs new file mode 100644 index 000000000..9d75b8356 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/DetectorFactory.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using NLangDetect.Core.Utils; +using MediaBrowser.Model.Serialization; +using System.Linq; + +namespace NLangDetect.Core +{ + public class DetectorFactory + { + public Dictionary<string, ProbVector> WordLangProbMap; + public List<string> Langlist; + + private static readonly DetectorFactory _instance = new DetectorFactory(); + + #region Constructor(s) + + private DetectorFactory() + { + WordLangProbMap = new Dictionary<string, ProbVector>(); + Langlist = new List<string>(); + } + + #endregion + + #region Public methods + + public static void LoadProfiles(IJsonSerializer json) + { + var assembly = typeof(DetectorFactory).Assembly; + var names = assembly.GetManifestResourceNames() + .Where(i => i.IndexOf("NLangDetect.Profiles", StringComparison.Ordinal) != -1) + .ToList(); + + var index = 0; + + foreach (var name in names) + { + using (var stream = assembly.GetManifestResourceStream(name)) + { + var langProfile = (LangProfile)json.DeserializeFromStream(stream, typeof(LangProfile)); + + AddProfile(langProfile, index); + } + + index++; + } + } + + public static Detector Create() + { + return CreateDetector(); + } + + public static Detector Create(double alpha) + { + Detector detector = CreateDetector(); + + detector.SetAlpha(alpha); + + return detector; + } + + public static void SetSeed(int? seed) + { + _instance.Seed = seed; + } + + #endregion + + #region Internal methods + + internal static void AddProfile(LangProfile profile, int index) + { + var lang = profile.name; + + if (_instance.Langlist.Contains(lang)) + { + throw new NLangDetectException("duplicate the same language profile", ErrorCode.DuplicateLangError); + } + + _instance.Langlist.Add(lang); + + foreach (string word in profile.freq.Keys) + { + if (!_instance.WordLangProbMap.ContainsKey(word)) + { + _instance.WordLangProbMap.Add(word, new ProbVector()); + } + + double prob = (double)profile.freq[word] / profile.n_words[word.Length - 1]; + + _instance.WordLangProbMap[word][index] = prob; + } + } + + internal static void Clear() + { + _instance.Langlist.Clear(); + _instance.WordLangProbMap.Clear(); + } + + #endregion + + #region Private helper methods + + private static Detector CreateDetector() + { + if (_instance.Langlist.Count == 0) + { + throw new NLangDetectException("need to load profiles", ErrorCode.NeedLoadProfileError); + } + + return new Detector(_instance); + } + + #endregion + + #region Properties + + public int? Seed { get; private set; } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/ErrorCode.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/ErrorCode.cs new file mode 100644 index 000000000..3ffd3b2d9 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/ErrorCode.cs @@ -0,0 +1,15 @@ +namespace NLangDetect.Core +{ + public enum ErrorCode + { + NoTextError, + FormatError, + FileLoadError, + DuplicateLangError, + NeedLoadProfileError, + CantDetectError, + CantOpenTrainData, + TrainDataFormatError, + InitParamError, + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/CharExtensions.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/CharExtensions.cs new file mode 100644 index 000000000..59076bd66 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/CharExtensions.cs @@ -0,0 +1,374 @@ +using System; + +namespace NLangDetect.Core.Extensions +{ + public static class CharExtensions + { + private const int MIN_CODE_POINT = 0x000000; + private const int MAX_CODE_POINT = 0x10ffff; + + private static readonly int[] _unicodeBlockStarts = + { + #region Unicode block starts + + 0x0000, // Basic Latin + 0x0080, // Latin-1 Supplement + 0x0100, // Latin Extended-A + 0x0180, // Latin Extended-B + 0x0250, // IPA Extensions + 0x02B0, // Spacing Modifier Letters + 0x0300, // Combining Diacritical Marks + 0x0370, // Greek and Coptic + 0x0400, // Cyrillic + 0x0500, // Cyrillic Supplementary + 0x0530, // Armenian + 0x0590, // Hebrew + 0x0600, // Arabic + 0x0700, // Syriac + 0x0750, // unassigned + 0x0780, // Thaana + 0x07C0, // unassigned + 0x0900, // Devanagari + 0x0980, // Bengali + 0x0A00, // Gurmukhi + 0x0A80, // Gujarati + 0x0B00, // Oriya + 0x0B80, // Tamil + 0x0C00, // Telugu + 0x0C80, // Kannada + 0x0D00, // Malayalam + 0x0D80, // Sinhala + 0x0E00, // Thai + 0x0E80, // Lao + 0x0F00, // Tibetan + 0x1000, // Myanmar + 0x10A0, // Georgian + 0x1100, // Hangul Jamo + 0x1200, // Ethiopic + 0x1380, // unassigned + 0x13A0, // Cherokee + 0x1400, // Unified Canadian Aboriginal Syllabics + 0x1680, // Ogham + 0x16A0, // Runic + 0x1700, // Tagalog + 0x1720, // Hanunoo + 0x1740, // Buhid + 0x1760, // Tagbanwa + 0x1780, // Khmer + 0x1800, // Mongolian + 0x18B0, // unassigned + 0x1900, // Limbu + 0x1950, // Tai Le + 0x1980, // unassigned + 0x19E0, // Khmer Symbols + 0x1A00, // unassigned + 0x1D00, // Phonetic Extensions + 0x1D80, // unassigned + 0x1E00, // Latin Extended Additional + 0x1F00, // Greek Extended + 0x2000, // General Punctuation + 0x2070, // Superscripts and Subscripts + 0x20A0, // Currency Symbols + 0x20D0, // Combining Diacritical Marks for Symbols + 0x2100, // Letterlike Symbols + 0x2150, // Number Forms + 0x2190, // Arrows + 0x2200, // Mathematical Operators + 0x2300, // Miscellaneous Technical + 0x2400, // Control Pictures + 0x2440, // Optical Character Recognition + 0x2460, // Enclosed Alphanumerics + 0x2500, // Box Drawing + 0x2580, // Block Elements + 0x25A0, // Geometric Shapes + 0x2600, // Miscellaneous Symbols + 0x2700, // Dingbats + 0x27C0, // Miscellaneous Mathematical Symbols-A + 0x27F0, // Supplemental Arrows-A + 0x2800, // Braille Patterns + 0x2900, // Supplemental Arrows-B + 0x2980, // Miscellaneous Mathematical Symbols-B + 0x2A00, // Supplemental Mathematical Operators + 0x2B00, // Miscellaneous Symbols and Arrows + 0x2C00, // unassigned + 0x2E80, // CJK Radicals Supplement + 0x2F00, // Kangxi Radicals + 0x2FE0, // unassigned + 0x2FF0, // Ideographic Description Characters + 0x3000, // CJK Symbols and Punctuation + 0x3040, // Hiragana + 0x30A0, // Katakana + 0x3100, // Bopomofo + 0x3130, // Hangul Compatibility Jamo + 0x3190, // Kanbun + 0x31A0, // Bopomofo Extended + 0x31C0, // unassigned + 0x31F0, // Katakana Phonetic Extensions + 0x3200, // Enclosed CJK Letters and Months + 0x3300, // CJK Compatibility + 0x3400, // CJK Unified Ideographs Extension A + 0x4DC0, // Yijing Hexagram Symbols + 0x4E00, // CJK Unified Ideographs + 0xA000, // Yi Syllables + 0xA490, // Yi Radicals + 0xA4D0, // unassigned + 0xAC00, // Hangul Syllables + 0xD7B0, // unassigned + 0xD800, // High Surrogates + 0xDB80, // High Private Use Surrogates + 0xDC00, // Low Surrogates + 0xE000, // Private Use + 0xF900, // CJK Compatibility Ideographs + 0xFB00, // Alphabetic Presentation Forms + 0xFB50, // Arabic Presentation Forms-A + 0xFE00, // Variation Selectors + 0xFE10, // unassigned + 0xFE20, // Combining Half Marks + 0xFE30, // CJK Compatibility Forms + 0xFE50, // Small Form Variants + 0xFE70, // Arabic Presentation Forms-B + 0xFF00, // Halfwidth and Fullwidth Forms + 0xFFF0, // Specials + 0x10000, // Linear B Syllabary + 0x10080, // Linear B Ideograms + 0x10100, // Aegean Numbers + 0x10140, // unassigned + 0x10300, // Old Italic + 0x10330, // Gothic + 0x10350, // unassigned + 0x10380, // Ugaritic + 0x103A0, // unassigned + 0x10400, // Deseret + 0x10450, // Shavian + 0x10480, // Osmanya + 0x104B0, // unassigned + 0x10800, // Cypriot Syllabary + 0x10840, // unassigned + 0x1D000, // Byzantine Musical Symbols + 0x1D100, // Musical Symbols + 0x1D200, // unassigned + 0x1D300, // Tai Xuan Jing Symbols + 0x1D360, // unassigned + 0x1D400, // Mathematical Alphanumeric Symbols + 0x1D800, // unassigned + 0x20000, // CJK Unified Ideographs Extension B + 0x2A6E0, // unassigned + 0x2F800, // CJK Compatibility Ideographs Supplement + 0x2FA20, // unassigned + 0xE0000, // Tags + 0xE0080, // unassigned + 0xE0100, // Variation Selectors Supplement + 0xE01F0, // unassigned + 0xF0000, // Supplementary Private Use Area-A + 0x100000, // Supplementary Private Use Area-B + + #endregion + }; + + private static readonly UnicodeBlock?[] _unicodeBlocks = + { + #region Unicode blocks + UnicodeBlock.BasicLatin, + UnicodeBlock.Latin1Supplement, + UnicodeBlock.LatinExtendedA, + UnicodeBlock.LatinExtendedB, + UnicodeBlock.IpaExtensions, + UnicodeBlock.SpacingModifierLetters, + UnicodeBlock.CombiningDiacriticalMarks, + UnicodeBlock.Greek, + UnicodeBlock.Cyrillic, + UnicodeBlock.CyrillicSupplementary, + UnicodeBlock.Armenian, + UnicodeBlock.Hebrew, + UnicodeBlock.Arabic, + UnicodeBlock.Syriac, + null, + UnicodeBlock.Thaana, + null, + UnicodeBlock.Devanagari, + UnicodeBlock.Bengali, + UnicodeBlock.Gurmukhi, + UnicodeBlock.Gujarati, + UnicodeBlock.Oriya, + UnicodeBlock.Tamil, + UnicodeBlock.Telugu, + UnicodeBlock.Kannada, + UnicodeBlock.Malayalam, + UnicodeBlock.Sinhala, + UnicodeBlock.Thai, + UnicodeBlock.Lao, + UnicodeBlock.Tibetan, + UnicodeBlock.Myanmar, + UnicodeBlock.Georgian, + UnicodeBlock.HangulJamo, + UnicodeBlock.Ethiopic, + null, + UnicodeBlock.Cherokee, + UnicodeBlock.UnifiedCanadianAboriginalSyllabics, + UnicodeBlock.Ogham, + UnicodeBlock.Runic, + UnicodeBlock.Tagalog, + UnicodeBlock.Hanunoo, + UnicodeBlock.Buhid, + UnicodeBlock.Tagbanwa, + UnicodeBlock.Khmer, + UnicodeBlock.Mongolian, + null, + UnicodeBlock.Limbu, + UnicodeBlock.TaiLe, + null, + UnicodeBlock.KhmerSymbols, + null, + UnicodeBlock.PhoneticExtensions, + null, + UnicodeBlock.LatinExtendedAdditional, + UnicodeBlock.GreekExtended, + UnicodeBlock.GeneralPunctuation, + UnicodeBlock.SuperscriptsAndSubscripts, + UnicodeBlock.CurrencySymbols, + UnicodeBlock.CombiningMarksForSymbols, + UnicodeBlock.LetterlikeSymbols, + UnicodeBlock.NumberForms, + UnicodeBlock.Arrows, + UnicodeBlock.MathematicalOperators, + UnicodeBlock.MiscellaneousTechnical, + UnicodeBlock.ControlPictures, + UnicodeBlock.OpticalCharacterRecognition, + UnicodeBlock.EnclosedAlphanumerics, + UnicodeBlock.BoxDrawing, + UnicodeBlock.BlockElements, + UnicodeBlock.GeometricShapes, + UnicodeBlock.MiscellaneousSymbols, + UnicodeBlock.Dingbats, + UnicodeBlock.MiscellaneousMathematicalSymbolsA, + UnicodeBlock.SupplementalArrowsA, + UnicodeBlock.BraillePatterns, + UnicodeBlock.SupplementalArrowsB, + UnicodeBlock.MiscellaneousMathematicalSymbolsB, + UnicodeBlock.SupplementalMathematicalOperators, + UnicodeBlock.MiscellaneousSymbolsAndArrows, + null, + UnicodeBlock.CjkRadicalsSupplement, + UnicodeBlock.KangxiRadicals, + null, + UnicodeBlock.IdeographicDescriptionCharacters, + UnicodeBlock.CjkSymbolsAndPunctuation, + UnicodeBlock.Hiragana, + UnicodeBlock.Katakana, + UnicodeBlock.Bopomofo, + UnicodeBlock.HangulCompatibilityJamo, + UnicodeBlock.Kanbun, + UnicodeBlock.BopomofoExtended, + null, + UnicodeBlock.KatakanaPhoneticExtensions, + UnicodeBlock.EnclosedCjkLettersAndMonths, + UnicodeBlock.CjkCompatibility, + UnicodeBlock.CjkUnifiedIdeographsExtensionA, + UnicodeBlock.YijingHexagramSymbols, + UnicodeBlock.CjkUnifiedIdeographs, + UnicodeBlock.YiSyllables, + UnicodeBlock.YiRadicals, + null, + UnicodeBlock.HangulSyllables, + null, + UnicodeBlock.HighSurrogates, + UnicodeBlock.HighPrivateUseSurrogates, + UnicodeBlock.LowSurrogates, + UnicodeBlock.PrivateUseArea, + UnicodeBlock.CjkCompatibilityIdeographs, + UnicodeBlock.AlphabeticPresentationForms, + UnicodeBlock.ArabicPresentationFormsA, + UnicodeBlock.VariationSelectors, + null, + UnicodeBlock.CombiningHalfMarks, + UnicodeBlock.CjkCompatibilityForms, + UnicodeBlock.SmallFormVariants, + UnicodeBlock.ArabicPresentationFormsB, + UnicodeBlock.HalfwidthAndFullwidthForms, + UnicodeBlock.Specials, + UnicodeBlock.LinearBSyllabary, + UnicodeBlock.LinearBIdeograms, + UnicodeBlock.AegeanNumbers, + null, + UnicodeBlock.OldItalic, + UnicodeBlock.Gothic, + null, + UnicodeBlock.Ugaritic, + null, + UnicodeBlock.Deseret, + UnicodeBlock.Shavian, + UnicodeBlock.Osmanya, + null, + UnicodeBlock.CypriotSyllabary, + null, + UnicodeBlock.ByzantineMusicalSymbols, + UnicodeBlock.MusicalSymbols, + null, + UnicodeBlock.TaiXuanJingSymbols, + null, + UnicodeBlock.MathematicalAlphanumericSymbols, + null, + UnicodeBlock.CjkUnifiedIdeographsExtensionB, + null, + UnicodeBlock.CjkCompatibilityIdeographsSupplement, + null, + UnicodeBlock.Tags, + null, + UnicodeBlock.VariationSelectorsSupplement, + null, + UnicodeBlock.SupplementaryPrivateUseAreaA, + UnicodeBlock.SupplementaryPrivateUseAreaB, + + #endregion + }; + + #region Public methods + + /// <remarks> + /// Taken from JDK source: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Character.java#Character.UnicodeBlock.0LATIN_EXTENDED_ADDITIONAL + /// </remarks> + public static UnicodeBlock? GetUnicodeBlock(this char ch) + { + int codePoint = ch; + + if (!IsValidCodePoint(codePoint)) + { + throw new ArgumentException("Argument is not a valid code point.", "ch"); + } + + int top, bottom, current; + + bottom = 0; + top = _unicodeBlockStarts.Length; + current = top / 2; + + // invariant: top > current >= bottom && codePoint >= unicodeBlockStarts[bottom] + while (top - bottom > 1) + { + if (codePoint >= _unicodeBlockStarts[current]) + { + bottom = current; + } + else + { + top = current; + } + + current = (top + bottom) / 2; + } + + return _unicodeBlocks[current]; + } + + #endregion + + #region Private helper methods + + private static bool IsValidCodePoint(int codePoint) + { + return codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT; + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/RandomExtensions.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/RandomExtensions.cs new file mode 100644 index 000000000..d55ca80df --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/RandomExtensions.cs @@ -0,0 +1,51 @@ +using System; + +namespace NLangDetect.Core.Extensions +{ + public static class RandomExtensions + { + private const double _Epsilon = 2.22044604925031E-15; + + private static readonly object _mutex = new object(); + + private static double _nextNextGaussian; + private static bool _hasNextNextGaussian; + + /// <summary> + /// Returns the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence. + /// The general contract of nextGaussian is that one double value, chosen from (approximately) the usual normal distribution with mean 0.0 and standard deviation 1.0, is pseudorandomly generated and returned. + /// </summary> + /// <remarks> + /// Taken from: http://download.oracle.com/javase/6/docs/api/java/util/Random.html (nextGaussian()) + /// </remarks> + public static double NextGaussian(this Random random) + { + lock (_mutex) + { + if (_hasNextNextGaussian) + { + _hasNextNextGaussian = false; + + return _nextNextGaussian; + } + + double v1, v2, s; + + do + { + v1 = 2.0 * random.NextDouble() - 1.0; // between -1.0 and 1.0 + v2 = 2.0 * random.NextDouble() - 1.0; // between -1.0 and 1.0 + s = v1 * v1 + v2 * v2; + } + while (s >= 1.0 || Math.Abs(s - 0.0) < _Epsilon); + + double multiplier = Math.Sqrt(-2.0 * Math.Log(s) / s); + + _nextNextGaussian = v2 * multiplier; + _hasNextNextGaussian = true; + + return v1 * multiplier; + } + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/StringExtensions.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/StringExtensions.cs new file mode 100644 index 000000000..fc6c58a95 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/StringExtensions.cs @@ -0,0 +1,25 @@ +using System; + +namespace NLangDetect.Core.Extensions +{ + public static class StringExtensions + { + /// <summary> + /// Returns a new character sequence that is a subsequence of this sequence. The subsequence starts with the character at the specified index and ends with the character at index end - 1. The length of the returned sequence is end - start, so if start == end then an empty sequence is returned. + /// </summary> + /// <param name="s"></param> + /// <param name="start">the start index, inclusive</param> + /// <param name="end">the end index, exclusive</param> + /// <returns>the specified subsequence</returns> + /// <exception cref="IndexOutOfRangeException"> if start or end are negative, if end is greater than length(), or if start is greater than end</exception> + public static string SubSequence(this string s, int start, int end) + { + if (start < 0) throw new ArgumentOutOfRangeException("start", "Argument must not be negative."); + if (end < 0) throw new ArgumentOutOfRangeException("end", "Argument must not be negative."); + if (end > s.Length) throw new ArgumentOutOfRangeException("end", "Argument must not be greater than the input string's length."); + if (start > end) throw new ArgumentOutOfRangeException("start", "Argument must not be greater than the 'end' argument."); + + return s.Substring(start, end - start); + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/UnicodeBlock.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/UnicodeBlock.cs new file mode 100644 index 000000000..71b5de75e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Extensions/UnicodeBlock.cs @@ -0,0 +1,131 @@ +namespace NLangDetect.Core.Extensions +{ + public enum UnicodeBlock + { + BasicLatin, + Latin1Supplement, + LatinExtendedA, + LatinExtendedB, + IpaExtensions, + SpacingModifierLetters, + CombiningDiacriticalMarks, + Greek, + Cyrillic, + CyrillicSupplementary, + Armenian, + Hebrew, + Arabic, + Syriac, + Thaana, + Devanagari, + Bengali, + Gurmukhi, + Gujarati, + Oriya, + Tamil, + Telugu, + Kannada, + Malayalam, + Sinhala, + Thai, + Lao, + Tibetan, + Myanmar, + Georgian, + HangulJamo, + Ethiopic, + Cherokee, + UnifiedCanadianAboriginalSyllabics, + Ogham, + Runic, + Tagalog, + Hanunoo, + Buhid, + Tagbanwa, + Khmer, + Mongolian, + Limbu, + TaiLe, + KhmerSymbols, + PhoneticExtensions, + LatinExtendedAdditional, + GreekExtended, + GeneralPunctuation, + SuperscriptsAndSubscripts, + CurrencySymbols, + CombiningMarksForSymbols, + LetterlikeSymbols, + NumberForms, + Arrows, + MathematicalOperators, + MiscellaneousTechnical, + ControlPictures, + OpticalCharacterRecognition, + EnclosedAlphanumerics, + BoxDrawing, + BlockElements, + GeometricShapes, + MiscellaneousSymbols, + Dingbats, + MiscellaneousMathematicalSymbolsA, + SupplementalArrowsA, + BraillePatterns, + SupplementalArrowsB, + MiscellaneousMathematicalSymbolsB, + SupplementalMathematicalOperators, + MiscellaneousSymbolsAndArrows, + CjkRadicalsSupplement, + KangxiRadicals, + IdeographicDescriptionCharacters, + CjkSymbolsAndPunctuation, + Hiragana, + Katakana, + Bopomofo, + HangulCompatibilityJamo, + Kanbun, + BopomofoExtended, + KatakanaPhoneticExtensions, + EnclosedCjkLettersAndMonths, + CjkCompatibility, + CjkUnifiedIdeographsExtensionA, + YijingHexagramSymbols, + CjkUnifiedIdeographs, + YiSyllables, + YiRadicals, + HangulSyllables, + HighSurrogates, + HighPrivateUseSurrogates, + LowSurrogates, + PrivateUseArea, + CjkCompatibilityIdeographs, + AlphabeticPresentationForms, + ArabicPresentationFormsA, + VariationSelectors, + CombiningHalfMarks, + CjkCompatibilityForms, + SmallFormVariants, + ArabicPresentationFormsB, + HalfwidthAndFullwidthForms, + Specials, + LinearBSyllabary, + LinearBIdeograms, + AegeanNumbers, + OldItalic, + Gothic, + Ugaritic, + Deseret, + Shavian, + Osmanya, + CypriotSyllabary, + ByzantineMusicalSymbols, + MusicalSymbols, + TaiXuanJingSymbols, + MathematicalAlphanumericSymbols, + CjkUnifiedIdeographsExtensionB, + CjkCompatibilityIdeographsSupplement, + Tags, + VariationSelectorsSupplement, + SupplementaryPrivateUseAreaA, + SupplementaryPrivateUseAreaB, + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/GenProfile.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/GenProfile.cs new file mode 100644 index 000000000..5895f68ae --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/GenProfile.cs @@ -0,0 +1,67 @@ +using System; +using System.IO.Compression; +using System.Xml; +using NLangDetect.Core.Utils; +using System.IO; + +namespace NLangDetect.Core +{ + // TODO IMM HI: xml reader not tested + public static class GenProfile + { + #region Public methods + + public static LangProfile load(string lang, string file) + { + LangProfile profile = new LangProfile(lang); + TagExtractor tagextractor = new TagExtractor("abstract", 100); + Stream inputStream = null; + + try + { + inputStream = File.OpenRead(file); + + string extension = Path.GetExtension(file) ?? ""; + + if (extension.ToUpper() == ".GZ") + { + inputStream = new GZipStream(inputStream, CompressionMode.Decompress); + } + + using (XmlReader xmlReader = XmlReader.Create(inputStream)) + { + while (xmlReader.Read()) + { + switch (xmlReader.NodeType) + { + case XmlNodeType.Element: + tagextractor.SetTag(xmlReader.Name); + break; + + case XmlNodeType.Text: + tagextractor.Add(xmlReader.Value); + break; + + case XmlNodeType.EndElement: + tagextractor.CloseTag(profile); + break; + } + } + } + } + finally + { + if (inputStream != null) + { + inputStream.Close(); + } + } + + Console.WriteLine(lang + ": " + tagextractor.Count); + + return profile; + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/InternalException.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/InternalException.cs new file mode 100644 index 000000000..32e50a219 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/InternalException.cs @@ -0,0 +1,22 @@ +using System; + +namespace NLangDetect.Core +{ + [Serializable] + public class InternalException : Exception + { + #region Constructor(s) + + public InternalException(string message, Exception innerException) + : base(message, innerException) + { + } + + public InternalException(string message) + : this(message, null) + { + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Language.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Language.cs new file mode 100644 index 000000000..f4b4b153e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Language.cs @@ -0,0 +1,45 @@ +using System.Globalization; + +namespace NLangDetect.Core +{ + // TODO IMM HI: name?? + public class Language + { + #region Constructor(s) + + public Language(string name, double probability) + { + Name = name; + Probability = probability; + } + + #endregion + + #region Object overrides + + public override string ToString() + { + if (Name == null) + { + return ""; + } + + return + string.Format( + CultureInfo.InvariantCulture.NumberFormat, + "{0}:{1:0.000000}", + Name, + Probability); + } + + #endregion + + #region Properties + + public string Name { get; set; } + + public double Probability { get; set; } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/LanguageDetector.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/LanguageDetector.cs new file mode 100644 index 000000000..fc7d420a9 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/LanguageDetector.cs @@ -0,0 +1,37 @@ +using System; +using MediaBrowser.Model.Serialization; + +namespace NLangDetect.Core +{ + // TODO IMM HI: change to non-static class + // TODO IMM HI: hide other, unnecassary classes via internal? + public static class LanguageDetector + { + private const double _DefaultAlpha = 0.5; + + #region Public methods + + public static void Initialize(IJsonSerializer json) + { + DetectorFactory.LoadProfiles(json); + } + + public static void Release() + { + DetectorFactory.Clear(); + } + + public static string DetectLanguage(string plainText) + { + if (string.IsNullOrEmpty(plainText)) { throw new ArgumentException("Argument can't be null nor empty.", "plainText"); } + + Detector detector = DetectorFactory.Create(_DefaultAlpha); + + detector.Append(plainText); + + return detector.Detect(); + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/NLangDetectException.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/NLangDetectException.cs new file mode 100644 index 000000000..e0d066020 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/NLangDetectException.cs @@ -0,0 +1,23 @@ +using System; + +namespace NLangDetect.Core +{ + public class NLangDetectException : Exception + { + #region Constructor(s) + + public NLangDetectException(string message, ErrorCode errorCode) + : base(message) + { + ErrorCode = errorCode; + } + + #endregion + + #region Properties + + public ErrorCode ErrorCode { get; private set; } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/ProbVector.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/ProbVector.cs new file mode 100644 index 000000000..c5a20dbf0 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/ProbVector.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +namespace NLangDetect.Core +{ + public class ProbVector + { + private readonly Dictionary<int, double> _dict = new Dictionary<int, double>(); + + public double this[int key] + { + get + { + double value; + + return _dict.TryGetValue(key, out value) ? value : 0.0; + } + + set + { + if (Math.Abs(value) < double.Epsilon) + { + if (_dict.ContainsKey(key)) + { + _dict.Remove(key); + } + + return; + } + + _dict[key] = value; + } + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/afr b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/afr new file mode 100644 index 000000000..be8b1722a --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/afr @@ -0,0 +1 @@ +{"freq":{"D":9246,"E":2445,"F":2510,"G":3299,"A":6930,"B":3706,"C":2451,"L":2519,"M":3951,"N":3334,"O":2514,"H":3034,"I":2837,"J":2196,"K":3663,"U":687,"T":2336,"W":2258,"V":2714,"Q":182,"P":3097,"S":8234,"R":3039,"Y":252,"X":214,"Z":422,"f":13583,"g":42805,"d":77385,"Feb":207,"e":240974,"b":21626,"c":4896,"a":128566,"n":127153,"o":86673,"l":57433,"m":31352,"j":4048,"k":45378,"h":17527,"i":140621,"w":24930,"v":32618,"u":35166,"t":82606,"s":102389,"r":98861,"q":199,"p":23331,"z":1187,"y":11757,"x":1123,"ï":264,"ë":2903,"ê":1053,"é":765,"á":212,"ü":233,"ö":184,"ó":216,"Eur":318,"Eng":637," l":3565," m":7731," n":16000," o":12065," h":7358," i":23795," j":1325," k":6363," d":33601," e":13358," f":1200," g":11018,"р":242,"с":306," a":8747,"т":161," b":8379," c":434," u":1931," t":8537," w":13128," v":24617," p":4859," s":15482," r":3617," J":2155," K":3559," H":2961," I":2185," N":3120," O":2318," L":2396," M":3803," B":3554," C":2109," A":6365," F":2371," G":3138," D":8986," E":2271,"л":219,"к":266," Z":368," Y":241,"и":371,"о":333,"н":199," S":7708,"Ger":200," R":2881,"в":199," Q":162," P":2912,"а":481," W":2205," V":2322," U":571,"е":266," T":2130,"Fra":1006,"A ":345,"Da":804,"Co":478,"Ch":621,"Du":1025,"Do":201,"De":763,"Di":5828,"Fe":367,"Eu":354,"En":721,"El":212,"Ge":659,"Ga":319,"I ":452,"Fr":1217,"Fo":165,"Fi":216,"II ":246,"C ":278,"Au":486,"Ar":425,"At":187,"As":201,"D ":158,"Ba":648,"Af":2087,"Am":566,"An":491,"Ap":353,"Al":628,"Bu":243,"Br":778,"Ca":399,"Bi":180,"Be":880,"Bo":481,"Bl":161,"Kr":224,"Ko":657,"Le":490,"Li":504,"La":658,"Lu":245,"Lo":347,"Me":800,"Mi":548,"Ma":1360,"Mu":186,"Mo":627,"Ni":257,"Ne":763,"Na":666,"No":1092,"Ok":339,"Ol":206,"Her":157,"Gr":1326,"Go":356,"Ha":534,"He":680,"II":369,"Hi":301,"Ho":503,"Hu":294,"Hy":550,"In":919,"Is":158,"It":218,"Ja":713,"Je":157,"Jo":565,"Ju":623,"Ka":1489,"Ki":194,"Ke":447,"Un":253,"Tu":248,"Tr":236,"To":272,"Th":313,"Te":262,"Ta":276,"V ":280,"Sw":402,"Sy":292,"St":964,"Su":1701,"Wo":181,"Wi":534,"Wa":412,"We":720,"Vo":315,"Vr":251,"Vi":374,"Va":314,"Ve":689,"Pr":551,"S ":157,"Pe":310,"Pa":727,"Po":681,"Pi":230,"Os":236,"Oo":423,"Or":191,"Se":814,"Sc":197,"Si":387,"Sl":222,"Sk":201,"Sp":443,"So":680,"Ru":645,"Ry":194,"Sa":728,"Re":621,"Ri":222,"Ro":746,"SA":233,"Ra":223,"Gre":501,"Gri":383,"Gra":158,"b ":1179,"Gro":254,"a ":7054,"i ":2513,"gd":570,"ge":16432,"ga":1621,"gb":319,"fk":224,"fl":183,"fg":323,"ff":351,"fi":1111,"fh":169,"fs":1224,"fr":2334,"fu":174,"ft":300,"fo":725,"Int":180,"he":6229,"ha":2610,"gn":360,"gl":334,"gi":2135,"gh":921,"gg":418,"gu":592,"gt":1512,"gs":1974,"gr":3459,"go":1385,"dt":211,"du":998,"dw":506,"g ":10256,"ea":936,"eb":3497,"ec":406,"ed":5721,"de":18394,"dd":606,"dg":161,"di":29432,"dh":249,"dj":173,"dm":299,"do":2521,"ds":2062,"dr":1453,"ew":3034,"eu":3603,"ev":2016,"ey":309,"fa":570,"h ":864,"Ind":251,"fd":469,"fe":948,"eh":993,"eg":3187,"ef":995,"ee":12296,"el":15653,"ek":7920,"ei":5726,"ep":2393,"eo":692,"en":27638,"em":4686,"et":10282,"es":15156,"er":33393,"ca":479,"e ":78745,"by":1025,"br":1953,"bu":1057,"bo":2123,"bl":1117,"bi":1966,"bb":156,"be":8513,"db":222,"In ":319,"da":3617,"f ":4067,"ct":207,"co":446,"ck":502,"ci":340,"ch":1526,"ce":547,"c ":311,"az":190,"ay":279,"ba":2057,"d ":15502,"at":11369,"as":9342,"ar":11432,"aw":597,"av":407,"au":883,"ak":2797,"al":9554,"ai":1291,"aj":155,"ap":2087,"am":3989,"an":36357,"ac":615,"ad":4564,"aa":18307,"ab":1064,"ag":2729,"ah":292,"ae":907,"af":1901,"nu":917,"nt":6760,"ns":9243,"nr":212,"no":2885,"nn":1621,"ny":191,"nw":666,"nv":455,"oe":6026,"of":3797,"oc":387,"od":1636,"oa":178,"ob":729,"om":5480,"on":10533,"ok":2525,"ol":5346,"oi":587,"og":2271,"oh":382,"ot":3827,"os":3306,"ov":1152,"ou":2993,"op":4558,"oo":12667,"or":14221,"r ":19504,"ow":1144,"pe":3683,"pg":229,"pa":2371,"pl":1195,"lê":351,"po":1932,"ph":223,"pi":1008,"lo":3369,"lm":315,"ll":2990,"ls":2634,"lp":392,"lw":311,"lv":239,"lu":1548,"lt":993,"ly":716,"o ":2083,"md":261,"ma":3853,"mb":2182,"mg":224,"me":9151,"mi":2940,"mm":802,"mp":1223,"mo":1485,"ië":1437,"mt":249,"ms":966,"mu":1085,"p ":4720,"na":6444,"nb":510,"nc":507,"nd":12581,"ne":5737,"nf":203,"ng":9804,"nh":460,"ni":6127,"nj":300,"nk":2057,"nl":616,"nm":203,"jo":532,"ki":2683,"kh":210,"kg":239,"ke":8584,"ka":6722,"m ":5913,"kw":457,"ky":282,"ks":2318,"kt":2084,"ku":1443,"ko":3908,"kr":2375,"kk":1579,"kl":2200,"km":469,"li":9515,"lh":279,"lk":1158,"lj":705,"le":10290,"ld":1944,"lg":1526,"lf":717,"la":8341,"lb":446,"n ":58065,"hr":313,"ht":702,"hu":1684,"hi":1067,"ho":3048,"dé":160,"id":5034,"ic":1058,"ib":451,"ia":2568,"ig":5540,"if":581,"ie":47836,"hy":348,"k ":9212,"ir":2359,"is":17403,"it":9361,"iu":405,"iv":1008,"iw":219,"ik":8953,"il":3774,"im":1386,"in":25004,"io":1984,"eë":1032,"ip":899,"je":609,"ji":572,"iz":156,"l ":8172,"ja":1960,"wy":994,"z ":242,"wi":1800,"wo":4179,"vy":166,"y ":4684,"wa":9856,"we":6959,"vl":1196,"vi":4040,"vu":178,"vr":662,"vo":4078,"uw":282,"uu":992,"ve":5906,"va":16173,"x ":845,"ui":7822,"uk":678,"ul":2052,"ue":905,"ug":1045,"ur":5410,"us":5098,"ut":907,"um":1711,"un":2596,"up":170,"ty":1434,"tu":2643,"tt":1277,"tw":1177,"tv":217,"ub":1182,"ua":728,"ud":950,"uc":160,"w ":232,"to":5433,"tm":201,"tl":667,"ts":3814,"tr":4026,"tg":532,"te":20430,"tk":279,"tj":177,"ti":5658,"th":1701,"tb":213,"ta":9118,"su":1177,"sv":424,"ss":2799,"st":17122,"sy":1309,"sw":531,"sl":1811,"sk":5006,"sn":242,"sm":693,"sp":2566,"oë":412,"so":3731,"sr":312,"sd":385,"sc":448,"sf":208,"se":15556,"sh":473,"sg":396,"sj":338,"si":8436,"u ":1834,"sa":2367,"sb":577,"rr":652,"rs":6262,"rt":4139,"ru":2543,"rv":1198,"rw":1199,"ry":2450,"rp":1265,"ro":8165,"rn":1586,"rm":2087,"rl":1734,"rk":2996,"ri":11752,"rh":614,"rg":2653,"rf":378,"re":10923,"rd":7372,"rc":234,"rb":955,"ra":7710,"t ":22731,"qu":168,"s ":35284,"px":614,"Hy ":529,"py":231,"pt":765,"pu":844,"pp":1058,"pr":3258,"ps":659,"wê":320,"zi":170,"ze":169,"za":209,"yg":162,"ye":406,"yf":643,"yd":927,"yw":439,"ys":1141,"yn":1041,"yl":288,"yk":1145,"Apr":247,"Aug":272,"Afr":2048,"Ame":464,"Ber":218,"Bel":171,"Bre":163,"Bra":191,"Bri":282,"Des":273,"Daa":460,"Chr":224,"Cha":171,"ër":307,"ël":325,"êr":697,"ë ":1979,"ê ":310,"é ":228,"Dit":1028,"Die":4537,"Dui":918,"Ned":417,"Nas":187,"Nov":238,"Noo":595,"Okt":256,"Oli":158,"Oos":361,"Par":313,"Pro":177,"Pre":186,"SA ":161,"Ita":207,"Jan":348,"Joh":290,"Jul":297,"Jun":245,"Kaa":543,"Kan":220,"Kat":191,"Kar":171,"Ker":270,"Kon":276,"Lat":181,"Lit":162,"Mei":281,"Mar":370,"Maa":286,"Mon":210,"Mid":157,"Wil":165,"Wes":439,"Vry":192,"Vol":161,"êre":674,"Swe":193,"Sy ":252,"Sui":1515,"Sta":443,"Ste":208,"Sep":228,"Spa":253,"Rus":560,"Sch":162,"Rep":214,"Rom":176,"Ver":555,"Uni":236,"The":196,"Tur":159,"bin":400,"blo":205,"bli":525,"bla":215,"boe":246,"boo":276,"bor":587,"bou":330,"ban":283,"bal":289,"bai":191,"baa":372,"bas":270,"bar":272,"beh":366,"beg":372,"bee":325,"bed":285,"ber":1916,"bel":540,"bek":1148,"bew":349,"bev":630,"bes":1308,"bet":510,"bie":1052,"ce ":276,"bri":159,"bro":237,"bra":211,"bre":258,"bru":1062,"bur":584,"by ":693,"am ":1182,"ake":292,"al ":2759,"ain":204,"ak ":856,"aie":241,"agt":446,"anu":467,"ann":632,"ant":1705,"ans":3841,"ane":404,"ang":1856,"ani":742,"anj":191,"ank":961,"ap ":635,"ana":788,"anc":195,"and":5528,"amm":186,"amp":480,"ami":512,"ame":657,"amb":236,"ama":204,"alt":231,"als":160,"all":667,"alk":171,"alg":320,"ali":1276,"ald":217,"ale":2352,"alf":209,"ala":367,"an ":18298,"aks":261,"akt":740,"akl":166,"abe":229,"abi":201,"aby":216,"ae ":624,"aag":175,"aad":172,"aak":679,"aai":350,"aan":6190,"aal":1515,"aam":1083,"aas":579,"aar":5293,"aap":567,"aat":1563,"ad ":2565,"afg":266,"ai ":311,"age":184,"afd":268,"adm":206,"adi":436,"ade":539,"ag ":1304,"ads":176,"ach":166,"ada":249,"af ":494,"at ":6755,"arg":256,"are":965,"ard":1124,"ara":390,"aro":332,"arn":185,"arm":157,"arl":301,"ark":397,"ari":1177,"arv":249,"ars":463,"art":1494,"ary":171,"asi":1669,"ase":210,"aso":169,"ar ":3216,"apa":189,"app":418,"aps":269,"as ":5230,"awe":308,"awi":169,"ata":346,"ast":673,"ass":518,"ato":426,"ate":1382,"ati":871,"ats":404,"atu":409,"aty":167,"aus":156,"jaa":1087,"jar":470,"je ":175,"joe":306,"jin":161,"jie":306,"ito":170,"itt":191,"its":1623,"isk":182,"ism":266,"iss":374,"ist":1582,"ita":608,"ite":1331,"itg":386,"iti":469,"ius":176,"ium":203,"ivi":590,"ive":294,"is ":12546,"ion":1252,"eër":158,"ipa":265,"ir ":1648,"isi":1018,"ise":601,"isa":220,"ire":181,"it ":3772,"kil":644,"kie":536,"kin":914,"km ":266,"kgr":173,"kee":210,"kei":339,"kel":962,"ken":2090,"kep":166,"ker":1342,"ke ":3014,"kra":345,"kse":472,"kry":1085,"kri":662,"kou":249,"kor":369,"kop":214,"koo":391,"kon":866,"kom":903,"kol":246,"koe":157,"ks ":710,"kke":1272,"kki":178,"klu":430,"kle":511,"kla":387,"kli":749,"kat":157,"kar":183,"kas":204,"kap":818,"kan":1256,"kal":611,"kaa":1596,"ka ":1388," Ga":319," Ge":658," Fo":161," Fr":1217," Fi":213," Ha":534," He":680," Go":354," Gr":1318," Hy":549," Hu":294," Ho":502," II":202," Hi":301," Ja":710," Is":157," It":218," In":916,"han":779," Ka":1486,"hal":311," Ke":447,"haw":164," Ki":192,"har":356," Jo":563," Ju":622,"haa":238,"had":164," La":657," Le":488," Li":502," Ko":657," Kr":224," Ma":1348," Mi":547," Me":799,"he ":399," Lo":346," Lu":244," Ne":762," Na":662," Ni":257," Mo":624," Mu":186,"hel":273,"hei":994,"hee":465,"hed":169,"het":2911,"her":350,"hem":255," Ap":349," Am":563," An":491," Al":626," Af":2082," Ba":645," Au":486," At":187," As":200," Ar":422," Be":877,"hie":290," Bi":179," Bl":161," Bo":479," Br":777," Bu":243,"his":173," Ca":384," Ch":612," Co":473," Da":803," Di":5802," De":761," Do":196," Du":1024," El":212," En":720," Eu":354," Fe":367," Wo":179," Wi":530," We":720," Wa":412,"god":193,"gs ":887,"gor":522,"gro":2150,"gra":537,"gri":320,"gre":401," Os":236," Or":191," Oo":422," Po":674," Pi":229," Pe":309," Pa":725,"gst":406," No":1092," Ol":205," Ok":339,"gte":962,"gti":391," Ra":221," Ro":743," Re":620," Ri":222," Pr":547,"gus":284," Sy":292," Sw":400," Su":1700," St":953," Ta":273," Th":307," Te":261," Tr":236," To":270," Ry":194," Ru":645," Sa":724," Si":385," Sc":196," Se":811," So":678," Sp":441," Sk":201," Sl":222," Va":313," Ve":669," Vi":371," Vo":314," Vr":251," Tu":243," Un":253," ja":1102,"ial":357,"ian":256," in":12303,"iaa":736," is":11238," ka":1533," ki":531," ke":481,"id ":2425," ha":612," he":3438," gr":2075," go":365,"ia ":794," hy":292," hi":477," ho":1750," hu":727,"iet":320,"ieu":180,"iew":413," ni":722,"iel":277," ne":437,"ien":998," na":2339,"ier":2228,"ies":4471,"ied":1248,"ief":177,"iek":2103," mu":691,"ig ":1346," mo":667," om":1497," on":2106," of":1952,"ifi":218," no":1205," le":910," li":598," n ":10980," la":1290," ku":387,"ich":258,"ie ":34696," km":407," kl":879,"ica":209," kr":319," ko":1672," me":4100," mi":830,"ids":257," ma":1329," lu":186,"idi":291,"ide":993,"idd":457,"ida":156," lo":197," af":820," aa":2320," ad":269," am":322," an":759," ak":286," al":829," ar":263," at":229," as":2284," ba":599,"il ":459," bi":320," be":5430," bo":565," bl":263," by":612," bu":213," br":340,"ika":2950,"igd":381,"ige":1604,"igh":698,"igi":270,"igg":185,"igt":498,"igs":156,"ik ":2305," en":9738,"imp":231," ei":517," el":502,"ime":187," ek":223," ee":1730,"ind":1030,"ina":506," fa":191,"inn":302," fo":227,"int":638,"ins":1349,"ine":545,"ing":6095," fi":368,"ini":615,"ink":417," ge":8191," ga":169,"inw":455,"ikk":629," ch":185,"ike":1814,"ila":498," da":1923,"in ":12178,"iku":209,"iks":287," do":1111,"ilo":514,"ill":662," dr":523," de":3947,"ilj":228,"ili":684,"ild":294," di":25510,"imb":245,"eë ":693,"io ":196," du":309," wê":298,"hom":166,"hou":360,"hoo":1325,"hoe":410," wy":201,"hul":552,"hui":260,"hri":224,"ht ":578," ru":233," sa":888," se":2315," si":590," sl":329," sk":1250," sp":887," so":2211," ra":237," re":1576," ri":825," ro":614," pr":1589," s ":207," px":614,"hy ":302," ou":447,"hum":674," oo":2639," op":2809," or":325," pe":402," pa":556," pl":641," po":737," lê":242," wa":7840," we":1395," wo":2888," wi":454," va":14670," ve":4043," vo":2359," vr":575," vi":2068," vl":594," ty":439," tw":582," tu":692," ui":1746," ta":895," sw":227," sy":1183," st":4293," su":859," tr":387," to":1857," th":729," ti":190," te":2715,"ffe":165,"fer":157,"fel":155,"fha":158,"fge":290,"fam":176,"fde":429,"eta":359,"ete":1299,"eti":372,"esp":358,"eso":210,"est":2951,"ess":405,"eun":234,"eto":320,"etr":438,"ets":217,"ett":493,"eve":456,"eva":262,"evo":907,"evi":274,"eur":2292,"eus":242,"ewi":337,"ewe":1704,"ewo":449,"ey ":181,"ewa":222,"epe":254,"er ":10617,"epa":228,"eor":221,"es ":4626,"ept":277,"epu":400,"epr":184,"erk":2067,"erl":875,"eri":1765,"erg":1022,"erh":416,"ere":1861,"erf":286,"erd":1514,"era":1470,"erb":529,"et ":6083,"esk":1018,"esl":228,"esi":976,"ese":3607,"eu ":338,"erv":860,"erw":949,"err":349,"ert":1101,"ers":4583,"ern":1142,"erm":861,"erp":342,"ero":382,"ekg":155,"ekk":206,"eko":474,"eks":950,"ekt":701,"en ":13492,"ela":904,"eld":1199,"elf":322,"ele":2593,"eli":1906,"elj":427,"elg":226,"elk":209,"ell":778,"elo":234,"els":1983,"elt":333,"ely":255,"emb":839,"ema":484,"eme":1266,"emo":181,"emi":456,"ep ":699,"ene":1142,"enh":254,"eng":314,"enb":269,"ena":610,"end":3112,"eno":500,"enn":400,"enk":275,"eni":1151,"ens":2864,"ent":2318,"ego":497,"ege":690,"egi":516,"eha":370,"egr":238,"egs":217,"egt":193,"eho":266,"ehe":259,"ek ":1799,"eis":330,"eil":544,"ein":1010,"eie":633,"eid":1307,"el ":3516,"eit":680,"eke":2739,"eka":220,"em ":967,"gin":784,"gie":714,"ght":548,"gep":249,"gen":1564,"get":297,"ger":1248,"ges":2014,"gev":788,"gew":944,"gee":448,"ged":475,"geb":2499,"geh":356,"geg":181,"gem":756,"gel":1995,"gek":350,"gde":427,"ge ":1916,"gaa":266,"gan":539,"ga ":157,"fst":852,"fri":2089,"for":371,"fie":369,"fil":208,"fin":174,"fis":177,"da ":327,"de ":6409,"daa":645,"dag":700,"dae":480,"dat":659,"dan":233,"dam":165,"dde":490,"ch ":316,"cha":160,"ck ":233,"che":490,"ed ":1090,"eba":159,"ebe":354,"ebi":752,"ebo":768,"ebr":1168,"ei ":821,"ega":168,"eek":631,"een":2520,"eel":2072,"eem":410,"eed":587,"ees":884,"eer":3295,"eeu":449,"eet":195,"edi":638,"ede":2561,"eda":161,"eg ":316,"eds":321,"edr":340,"ee ":892,"ef ":280,"dwe":310,"dus":171,"dor":875,"doo":416,"don":160,"dom":227,"ds ":353,"dmi":211,"doe":283,"dst":428,"dui":309,"dri":421,"dra":423,"dry":204,"dsk":181,"dse":527,"dia":294,"der":4829,"des":476,"deu":1676,"dee":1279,"del":1695,"dek":186,"den":1206,"do ":172,"din":875,"dio":177,"dis":425,"dit":656,"die":24964,"dig":1168,"dik":198,"rhe":301,"rga":496,"rgi":335,"rge":595,"ret":312,"res":944,"rg ":777,"rea":245,"ree":1091,"ref":257,"red":294,"rei":545,"reg":1039,"ren":1300,"rek":765,"rel":674,"rep":191,"rf ":180,"rdo":215,"rdi":841,"rde":1873,"re ":2607,"rd ":3667,"ras":532,"rat":587,"rbi":190,"rba":160,"rbe":287,"rag":291,"ran":2011,"ram":317,"ral":832,"rak":247,"raa":1046,"raf":284,"rad":331,"rs ":1922,"ros":273,"rot":330,"rom":305,"ron":1072,"roo":1778,"rop":575,"rou":212,"rov":708,"rod":199,"rol":315,"roe":1277,"rog":195,"rno":196,"rp ":728,"rna":508,"rne":469,"rmo":164,"rma":539,"rme":324,"rmi":175,"rlo":320,"rli":409,"rle":270,"rla":508,"rks":184,"rko":248,"rki":199,"rkl":203,"rke":440,"rka":271,"rm ":692,"rio":174,"rit":493,"ris":571,"riv":501,"rig":863,"ril":278,"rik":3384,"rin":1384,"ria":924,"ric":236,"rie":2029,"rk ":1040,"rwe":410,"rwy":498,"ryf":393,"rui":1143,"rug":256,"rum":244,"ruk":231,"rus":225,"rva":502,"rvl":353,"rvo":192,"rwa":171,"ry ":383,"rsk":872,"rsi":432,"rso":249,"rsp":591,"rsa":225,"rse":478,"rta":186,"rst":1083,"rtk":160,"rto":274,"rte":620,"rti":334,"rua":209,"rty":351,"rt ":1413,"rre":272,"saa":540,"sal":170,"sam":303,"san":408,"sas":204,"sa ":155,"ryw":338,"rys":282,"ryk":576,"sge":305,"sie":4039,"sid":185,"sia":299,"sit":436,"sis":296,"sip":279,"sin":541,"sio":799,"sil":194,"sim":173,"sik":231,"sif":160,"sig":289,"sbu":231,"se ":9840,"sch":268,"ser":501,"ses":400,"set":250,"seu":239,"sea":162,"see":618,"sed":264,"sen":1323,"sem":298,"sel":1093,"sek":186,"spo":405,"spr":756,"spe":934,"spa":260,"sow":508,"som":247,"son":545,"soo":954,"soe":195,"sok":377,"st ":267,"sli":202,"slu":297,"sky":183,"sla":1006,"sle":205,"ski":804,"sko":594,"skr":1152,"sku":244,"ska":1212,"ske":665,"sië":283,"sma":173,"sme":382,"sse":1275,"ssa":198,"ssi":922,"ste":6829,"sta":5065,"sto":805,"sti":1396,"stu":693,"str":1673,"sty":226,"sui":596,"sve":167,"sy ":1199,"swa":313,"tal":1301,"taa":2499,"tad":2323,"tau":165,"tat":456,"tas":164,"tan":1021,"te ":8469,"ta ":339,"pa ":202,"pe ":459,"par":608,"pas":176,"paa":333,"pal":324,"pan":428,"pge":207,"pen":295,"per":1379,"pes":438,"pee":201,"pel":568,"pla":660,"lê ":268,"pli":169,"ple":241,"pie":480,"por":394,"poo":160,"pos":197,"pol":518,"ppy":184,"ppe":636,"pst":229,"pub":435,"pte":575,"pra":251,"pri":484,"pre":726,"pro":1677,"pun":246,"px ":614,"py ":166,"ra ":424,"ngo":161,"ngr":289,"ngs":1292,"nge":2327,"nhe":276,"nel":314,"nen":189,"nem":225,"ner":1014,"net":468,"nes":533,"ng ":4906,"nee":762,"nce":206,"ne ":1530,"ndr":216,"nds":657,"ndo":326,"ndi":878,"nde":5081,"nda":453,"nal":790,"nam":291,"nad":316,"naf":372,"nab":229,"naa":1198,"nd ":4245,"nat":282,"nas":677,"na ":1572,"nwo":542,"nus":209,"nua":266,"ntw":393,"nto":201,"nts":300,"ntr":543,"nti":571,"ntl":164,"nta":457,"nte":1815,"nst":787,"nse":3345,"nsi":1079,"nsl":207,"nsk":498,"nt ":1757,"ns ":2476,"nog":456,"noe":477,"noo":659,"nom":368,"nne":904,"nni":442,"nië":246,"nli":373,"nke":345,"nkl":391,"nks":179,"nkr":453,"nje":156,"nig":640,"nie":1831,"nk ":274,"niv":210,"nis":1512,"nin":804,"ogr":272,"ogi":423,"oi ":216,"oha":228,"oeë":178,"ok ":1432,"ol ":554,"ock":164,"oe ":303,"ode":551,"odi":176,"ods":177,"of ":2323,"oek":499,"oel":276,"oem":563,"oeg":231,"oei":336,"oer":752,"oes":295,"oet":302,"oen":602,"oep":714,"odu":188,"oed":477,"og ":895,"ofs":803,"oew":261,"od ":254,"obe":382,"oud":510,"oue":197,"ote":350,"ott":175,"ots":913,"oto":266,"ost":637,"osi":266,"ose":346,"oss":176,"oso":190,"owa":484,"owe":208,"ovi":678,"ove":370,"ous":302,"our":167,"out":306,"opo":205,"opp":449,"ope":438,"opg":213,"opa":195,"os ":1171,"oon":731,"ool":561,"oom":393,"ook":1376,"ooi":288,"oof":1146,"oog":389,"ood":288,"or ":1152,"oot":1351,"oos":958,"oor":4776,"oop":341,"ork":260,"orl":386,"orm":964,"orp":858,"ord":4583,"ore":773,"org":587,"ori":1212,"ou ":999,"ort":1219,"ors":871,"orw":195,"ot ":1528,"orb":186,"ora":235,"ola":171,"on ":1522,"oli":772,"oll":288,"olk":702,"ole":263,"olg":904,"ols":270,"olo":636,"om ":1870,"okk":553,"ona":980,"ond":1915,"one":1178,"ong":620,"oni":1012,"onl":220,"onk":232,"onn":184,"ono":391,"ons":511,"ont":1339,"oma":425,"ome":845,"omi":324,"omm":454,"omp":297,"oms":595,"op ":2264,"la ":334,"le ":3834,"lf ":175,"lde":601,"laa":982,"lad":180,"lag":434,"lak":490,"lan":4154,"lar":155,"lat":361,"las":433,"ld ":695,"kus":410,"kun":548,"kul":242,"kwe":204,"kwa":191,"kte":822,"kst":257,"ksi":463,"ktr":342,"ktu":210,"kti":247,"kto":369,"ls ":1008,"lon":293,"lom":430,"loo":382,"loe":423,"log":655,"los":274,"lië":349,"lti":157,"lub":411,"lug":221,"lst":643,"lte":252,"lse":623,"lge":754,"lew":250,"leu":193,"les":329,"let":347,"ler":415,"lem":358,"len":1056,"lek":605,"lei":1010,"leg":257,"lee":477,"led":218,"lg ":483,"lo ":169,"lla":325,"lle":1578,"lli":615,"lke":200,"lki":447,"ljo":223,"ll ":176,"lja":430,"lit":831,"lis":504,"leë":449,"lin":1208,"lim":201,"lid":165,"lia":364,"lik":2917,"lig":818,"lie":1618,"ma ":226,"mb ":655,"maa":1244,"mag":221,"mar":331,"mas":207,"mal":270,"man":726,"mat":394,"mba":172,"mbi":179,"mbe":814,"mbo":161,"me ":936,"mde":163,"med":223,"mee":1533,"met":2981,"mes":247,"mer":991,"mel":330,"men":1550,"lui":390,"lus":194,"lwe":213,"lyk":221,"lyn":187,"mpi":220,"mpe":208,"mpo":176,"mpt":267,"ms ":488,"moe":196,"mod":233,"mon":329,"mst":248,"mus":488,"mun":417,"ër ":180,"mge":191,"min":806,"mil":465,"mit":231,"mig":184,"mie":523,"mid":310,"ië ":1136,"mme":353,"wêr":319,"yst":183,"ys ":680,"ywe":370,"ye ":306,"yf ":380,"yde":281,"yds":165,"yd ":230,"yn ":461,"yns":175,"yk ":810,"wys":531,"wor":2620,"woo":760,"won":526,"we ":1260,"wes":799,"wer":1583,"wet":305,"wen":427,"wel":545,"weg":270,"wee":1257,"wis":166,"wit":342,"wie":194,"win":417,"wil":177,"wik":231,"wan":300,"wat":5174,"war":532,"was":2236,"waa":1031,"vry":194,"vro":313,"vir":1570,"vin":921,"vie":880,"vis":289,"vla":709,"vlo":280,"voe":444,"vol":1592,"voo":1083,"vor":625,"ver":4566,"ven":170,"vem":236,"vel":250,"vee":302,"val":319,"van":14723,"vat":155,"vaa":414,"uwe":229,"uur":863,"usl":180,"usi":606,"use":380,"ust":585,"uss":1129,"ute":176,"uto":171,"us ":1998,"ure":395,"urg":669,"uri":191,"urk":167,"uro":352,"urs":211,"urt":189,"ur ":2547,"umb":689,"ume":172,"unt":325,"uns":289,"uni":820,"und":530,"um ":614,"ult":270,"ull":459,"uli":358,"un ":219,"uid":2285,"uik":850,"uim":162,"uis":508,"uk ":200,"uit":3378,"ul ":272,"ugb":161,"ugu":278,"ude":184,"udi":240,"ue ":322,"ug ":159,"ub ":406,"uar":522,"ubl":464,"ud ":181,"tyn":228,"ty ":384,"tur":232,"tus":988,"tuu":617,"tui":232,"tud":171,"tyd":628,"twi":269,"twe":751,"ts ":533,"tre":1022,"tra":1128,"tri":607,"tru":366,"tro":780,"tse":746,"tsk":298,"tsl":425,"tst":993,"tte":641,"tti":226,"to ":272,"tof":244,"toe":713,"tob":268,"tot":1108,"tom":182,"ton":586,"tol":317,"tor":808,"too":280,"til":187,"tik":334,"tie":1846,"tig":1053,"tis":241,"tin":826,"tio":267,"thu":695,"tkl":165,"tli":191,"tla":301,"tem":732,"ten":1059,"tei":844,"tek":528,"tel":2135,"tee":779,"teg":166,"ted":237,"th ":270,"teu":212,"tes":357,"ter":4231,"tge":442,"the":380},"n_words":[1541130,1808182,1328687],"name":"af"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ara b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ara new file mode 100644 index 000000000..a7b40cca0 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ara @@ -0,0 +1 @@ +{"freq":{"و":674395,"ى":83925,"ي":1050070,"ً":13534,"َ":5694,"ُ":4812,"ـ":6044,"ف":291773,"ق":234289,"ك":238048,"ل":1258387,"م":769173,"ن":600182,"ه":275861,"ّ":6098,"ِ":3286,"ْ":2044,"خ":81779,"د":374335,"ج":159763,"ح":207504,"ت":462068,"ث":62775,"ب":456733,"ة":436596,"ئ":43113,"ا":1630465,"ؤ":8533,"إ":87017,"آ":11409,"أ":206598,"ء":28935,"غ":62643,"ع":367154,"ظ":26879,"ط":114141,"ض":60872,"ص":101344,"ش":119185,"س":320648,"ز":83586,"ر":577132,"ذ":48426,"،":89553,"؛":1398," ،":20335," ن":38705," ه":63492," ل":88748," م":255388," ق":40529," ك":61242," ف":145932," ي":66494," و":214375," ص":12486," ش":28169," ط":11510," ض":8567," ر":24040," ذ":6579," س":49888," ز":6199," ع":110158," ظ":1667," غ":11703," إ":56701," ا":619492," آ":6461," أ":122164," ج":33981," ح":46703," خ":15646," د":26005," ب":145150," ت":96353," ث":8150,"ア":1366,"ا، ":7320,"ئة ":2129,"ؤسس":2077,"إن ":1277,"أيض":3023,"أور":2981,"أهم":1974,"أهل":1229,"أول":9618,"أنو":1568,"أنه":3955,"أمي":2439,"ألم":3407,"أما":1795,"ألف":1545,"أمر":6318,"أكب":2802,"أكت":1724,"أكث":2574,"أفر":1800,"أعل":1292,"أعم":1551,"أغس":1326,"أصل":1634,"اث ":2044,"ئي ":3037,"ب، ":1611,"ات ":57401,"إضا":1407,"اح ":3081,"اج ":4358,"إسب":3960,"ئل ":2536,"اة ":4792,"إسل":3234,"اب ":9098,"إسر":1395,"إدا":2059,"اء ":22733,"إحد":6124,"إذا":1265,"ئر ":2350,"ة، ":15452,"اي ":2212,"بت ":1435,"بب ":1489,"اه ":2688,"بة ":12759,"ان ":40858,"با ":4030,"بد ":6780,"بح ":1410,"اً ":10489,"اف ":3597,"إيط":2527,"إير":1277,"ام ":31875,"ال ":23428,"ئرة":2003,"اك ":2756,"اق ":4807,"اع ":5640,"إلي":1606,"إلى":18043,"إما":1946,"اض ":1731,"إقل":1614,"اط ":2017,"إنج":4004,"إنت":2754,"إنس":1518,"ار ":15484,"اد ":13875,"اص ":1586,"از ":3651,"اس ":4999,"بي ":11247,"ت، ":2665,"اضي":4506,"اصر":1618,"بو ":3109,"اصم":3245,"اعب":4589,"اعة":3428,"اعت":1731,"اعد":2039,"اعر":1432,"اطع":4959,"اطق":1642,"اطي":1824,"اعي":4248,"ادا":1408,"اخل":1728,"احي":1991,"اخت":2071,"احل":1721,"احت":2360,"احة":4653,"احد":2974,"ارب":3471,"ارة":7735,"ارا":5132,"ادي":11501,"ادة":5295,"بق ":1932,"ادر":1555,"ازي":2304,"است":9208,"اسة":1966,"اسا":1699,"اري":13333,"اره":1487,"ارو":1690,"ارك":3428,"ارع":1412,"ارس":4342,"بل ":7375,"ارد":1984,"ارت":2585,"ارج":1460,"اصة":1686,"اشم":2112,"به ":4466,"اسم":7414,"اشت":1547,"اسي":6201,"اسع":1320,"بن ":14722,"ئلة":1510,"بع ":5351,"ائد":1719,"ائر":5727,"ائز":1678,"ائم":1524,"ائل":4622,"ائي":8565,"ابا":4420,"ابت":1320,"ابة":2266,"ابر":1286,"ابع":5010,"ابي":3084,"ات،":1833,"ابل":1965,"ابق":3015,"ابن":2545,"اتح":2012,"اتب":1961,"ئيس":4458,"اتي":3444,"اته":3712,"ئية":4071,"اجت":1267,"ئيل":1637,"بر ":15051,"بط ":1447,"آخر":1604,"أن ":6708,"آن ":1439,"أس ":2019,"أبر":1929,"أبي":2141,"أبو":3598,"أحد":5818,"أحم":2690,"أخر":2780,"أحي":1348,"أرا":1757,"أرب":1317,"أرض":1852,"أرد":4510,"أست":1490,"أسا":2106,"أسس":2383,"أشه":1227,"أصب":1379,"أو ":17977,"أي ":2409,"جزي":2701,"جدي":2169,"جزء":1922,"حل ":2135,"جرا":1466,"جري":2220,"جزا":2275,"جتم":2280,"ثير":2870,"جات":1361,"ثنا":1548,"جار":2741,"جال":2447,"جان":2465,"جبا":1237,"جام":4767,"جبل":1832,"جلي":4317,"جما":2589,"جلس":2643,"حاف":7429,"حال":5921,"حاك":1299,"جهة":1426,"جنو":6846,"جها":2454,"جمي":2428,"حاد":3278,"حار":1507,"جنس":1263,"حاس":1289,"جمع":2692,"جمه":2396,"جمو":3506,"خط ":1642,"خر ":2126,"حي ":2379,"د، ":2106,"دث ":1521,"حصل":1369,"دة ":22913,"دت ":1894,"حسب":1473,"دا ":3896,"حسي":1367,"حسن":1628,"حرك":2813,"حرا":2117,"حرب":2616,"خل ":1874,"حزب":1786,"حري":2754,"دأ ":1419,"حدث":1823,"حدة":6151,"حدا":1890,"حدي":3344,"حدو":1601,"حدى":6092,"حتى":2850,"حتو":1235,"جية":1498,"جيا":1555,"جيد":1284,"جين":1406,"جود":2059,"ختص":1274,"حول":2075,"حوض":3972,"حوا":3753,"خاص":2779,"خار":1757,"حمل":1584,"خاب":1378,"حلي":1951,"حمد":7071,"حما":1348,"حكو":1587,"حكم":2998,"حقي":1342,"دس ":1564,"در ":3643,"دد ":5353,"ذا ":6858,"دن ":3532,"ده ":2855,"دو ":1586,"دى ":7927,"خصي":1891,"ر، ":3918,"دي ":16032,"حيا":3483,"ختل":2576,"حيث":5743,"حية":2840,"حيو":1435,"خدا":1713,"خدم":4681,"خرا":1406,"دل ":1527,"خرج":2035,"خرى":2288,"دم ":12380,"خلي":2944,"خلا":4049,"دان":2670,"دام":2603,"دال":1357,"داي":1553,"داء":1232,"دائ":2836,"دار":5259,"دات":2179,"داخ":1695,"داد":3415,"ذي ":7019,"رج ":3503,"رة ":42156,"رت ":3799,"رد ":2816,"را ":5024,"رب ":12795,"ذه ":5431,"درس":2590,"درج":3597,"درا":3796,"دري":2750,"دول":7090,"دون":2547,"دوا":2452,"دود":1701,"دور":4858,"دها":2546,"دني":4787,"ذات":1939,"رف ":5073,"زء ":1646,"ديو":1641,"ديم":4297,"دين":17630,"ديا":3615,"دية":10224,"ديس":2111,"ديد":5637,"دير":2378,"ديث":1831,"رس ":4802,"رز ":1453,"رع ":2500,"دما":2598,"رض ":4034,"اقي":2703,"اقت":1926,"اقة":1778,"افي":2956,"اقع":1373,"الق":27005,"الف":20852,"الل":14610,"الك":19511,"الي":32249,"ان،":1862,"امت":1485,"امج":2075,"اما":2969,"الن":19094,"الم":106832,"امة":2785,"الو":15207,"اله":10510,"امر":2004,"امع":4584,"الأ":53765,"الآ":3087,"الج":24268,"اكي":1240,"الث":10222,"الت":44136,"الة":4500,"الب":27575,"الا":23279,"اكم":1385,"الإ":23108,"الس":25474,"الش":23985,"الر":18584,"الز":4628,"الد":22592,"الذ":9992,"الح":28530,"الخ":10845,"الع":45326,"الغ":7597,"الط":9353,"الص":10951,"الض":2239,"افة":3763,"افظ":6821,"اين":1399,"ايو":2112,"بتم":1591,"ايا":4981,"اية":7953,"اير":3864,"بدأ":2040,"، ":87650,"بحي":1333,"بحر":3662,"اهر":2224,"اني":27995,"انه":3927,"انو":4021,"بان":8783,"بال":24841,"باد":1374,"اند":2371,"بار":7325,"انس":1452,"باس":3805,"انا":3741,"باب":2616,"انب":1315,"انة":1432,"بات":4730,"انت":10216,"امي":6789,"باح":1289,"امل":2591,"بائ":1535,"اوي":2785,"اول":1939,"اهي":1800,"تا ":1767,"تب ":3208,"بشك":1596,"بدا":2243,"برا":7053,"برت":1316,"برل":1347,"برو":1928,"برن":1554,"بري":6364,"تر ":3568,"بطو":2790,"بعد":8590,"بعة":3652,"بغد":1205,"بعض":3329,"بني":2271,"بها":4540,"بنا":4249,"ئ ":1205,"ا ":148281,"بلي":1501,"بلا":3530,"ب ":70841,"بلغ":5588,"بلد":6651,"ء ":25878,"بقا":1527,"أ ":2761,"ح ":16042,"خ ":7746,"د ":111902,"ذ ":7044,"بين":10021,"ة ":417779,"بيل":2585,"بيض":1538,"بيع":2501,"ت ":98281,"بيا":2983,"بية":13845,"بير":5823,"بيت":1659,"بون":1363,"ث ":14734,"بول":3156,"بور":2404,"ج ":16315,"بوا":1540,"تي ":19035,"ثة ":2508,"تو ":1236,"تى ":3327,"ته ":7416,"تل ":1533,"تم ":5813,"ثر ":3741,"؛ ":1372,"تأس":2342,"تبر":4383,"تبع":2953,"تال":2664,"تان":2849,"تبا":1684,"تبة":1215,"تار":5301,"تاب":6518,"تاج":2425,"تبل":2737,"تجا":3016,"تخد":5000,"تخب":1329,"تخا":1370,"تحد":6290,"تحر":1572,"تحا":3110,"تحت":3198,"تدا":1332,"ثم ":2995,"تري":1455,"ترو":2478,"ثل ":4130,"ترا":5683,"ترة":2099,"ترك":2885,"تشا":2599,"تسم":2030,"تست":1924,"تصا":3295,"تشر":1532,"جة ":6594,"تشي":1720,"تضم":1238,"تطو":1569,"تعا":1531,"تعت":2311,"تعم":2414,"تعل":2476,"تعر":2059,"تعد":2614,"جد ":3856,"جر ":1340,"تفا":2566,"تقا":2028,"تقد":2088,"تقر":1287,"تقس":2440,"تقع":8338,"تقل":2844,"تهر":1315,"ثال":2031,"تها":6374,"ثان":4499,"تنظ":2616,"تمي":2924,"تنا":1728,"تمد":1486,"تمر":1589,"تلف":3439,"تلك":1400,"تما":2848,"تمب":1576,"تكو":3404,"تلا":1846,"تين":4590,"تية":1561,"تيا":2052,"تون":4528,"توي":1644,"توف":2858,"تول":1447,"تور":2920,"توس":1688,"توب":2148,"توا":1906,"تهم":1291,"جه ":1478,"جم ":2117,"جل ":2059,"جي ":1843,"حة ":7424,"حت ":2989,"حر ":2424,"حد ":6903,"ثلا":2751,"ثما":1889,"ثقا":1374,"وي":38534,"ي،":8021,"وو":3027,"وى":2435,"ية":149201,"يب":15166,"يا":76978,"يئ":2097,"يض":5937,"يط":9332,"يع":16206,"يز":13642,"يس":24541,"يش":6638,"يص":2709,"يخ":8388,"يد":33231,"ير":50995,"يت":21919,"يث":8777,"يج":6934,"يح":6752,"يه":17510,"ين":82989,"ًا":1622,"يو":34779,"يك":18257,"يق":23953,"يم":33457,"يل":36829,"يف":12030,"يغ":2332,"يي":7762,"فع":3459,"فض":3349,"فص":2010,"فظ":7666,"فز":1405,"فر":20396,"فس":4079,"فة":10560,"فت":8107,"ق،":1414,"فا":19253,"فب":1563,"قف":1276,"قع":16814,"قط":5495,"قض":1727,"قص":4820,"قش":1443,"قس":4834,"قر":18930,"قد":24585,"فى":1203,"قت":5868,"في":137714,"فه":4197,"قب":10150,"قة":17223,"فو":7133,"فم":1876,"فن":5345,"قا":33043,"فك":2212,"فل":7982,"فق":4801,"لأ":58367,"لآ":3323,"كف":1496,"كس":5921,"قي":21786,"كث":5852,"ل،":2207,"كذ":1298,"كر":19872,"كز":7004,"كأ":1420,"قل":10832,"قم":3276,"كا":41128,"قن":3553,"كب":9528,"قه":2295,"كة":14080,"قو":10571,"كت":14016,"قى":1403,"لك":43877,"مؤ":5145,"لق":35996,"لف":31832,"لط":12463,"لض":2442,"لص":14130,"لش":25578,"لغ":17940,"لع":56838,"لظ":1228,"لخ":11729,"لد":39289,"لج":27745,"لح":34548,"لز":5989,"لس":38336,"لذ":10795,"لر":20100,"كم":13188,"لا":89050,"كن":10747,"كل":17531,"لإ":25479,"لت":54464,"م،":3972,"كي":22561,"لث":10985,"لب":37291,"كه":2654,"كو":22542,"لة":26342,"مع":31975,"مغ":4324,"مص":12239,"مض":1909,"مط":2885,"مف":2713,"مق":12733,"مك":8220,"مل":28998,"مت":25250,"لى":49564,"مة":21124,"لو":37077,"مج":15409,"ن،":5643,"لي":91040,"مث":7965,"لم":137485,"لل":37112,"مب":12595,"له":28033,"ما":84509,"لن":25730,"مز":2658,"مر":34445,"مش":6760,"مس":26092,"مخ":5223,"مح":22151,"مذ":1262,"مد":31562,"نغ":3178,"نظ":9512,"نع":2681,"نط":11265,"نل":1207,"نم":4711,"نق":5444,"نك":3963,"نف":6969,"نح":3012,"نج":9690,"مي":49166,"ه،":2071,"مى":3142,"نت":26741,"نة":26561,"مو":33352,"مه":13330,"نب":6671,"نا":51288,"من":110993,"مم":11520,"نص":4888,"نش":6378,"نس":20514,"نز":3094,"نر":1454,"نذ":4480,"ند":18475,"هـ":2446,"وأ":7843,"وإ":2408,"هل":3624,"هم":13508,"هن":5865,"وا":96512,"هب":2043,"نه":22166,"ها":63427,"هت":1254,"نى":2312,"نو":28243,"هة":2492,"هج":2434,"و،":1267,"ني":68053,"هذ":11164,"هد":6895,"هز":1306,"هر":13839,"وغ":3162,"وظ":1284,"وع":15945,"وق":15305,"وك":13977,"وف":17742,"ون":47917,"وه":18574,"ول":64949,"وم":36461,"هي":33444,"وث":2062,"وت":24045,"هو":37979,"وة":2112,"وب":25979,"ود":18341,"وخ":2267,"وح":8074,"وج":13010,"وس":25063,"وز":7609,"ور":46060,"وذ":2568,"وط":5229,"وض":6816,"وص":4846,"وش":3688,"دة":23918,"خو":3104,"دت":2861,"دا":34518,"دب":3013,"دخ":1822,"دث":2213,"خي":4889,"خل":11579,"خم":2109,"دأ":2148,"خط":4248,"خر":10258,"خد":6707,"خص":5211,"ده":6608,"دو":24057,"دى":7961,"دي":71508,"ر،":3948,"دف":3789,"دق":1886,"دك":1306,"دل":4421,"دم":20032,"ذا":11430,"دن":9851,"دع":2356,"دد":6837,"در":20942,"دس":4645,"حث":1327,"جي":13871,"حج":2300,"حة":7643,"جو":9984,"حت":11398,"جن":11985,"حا":28730,"حب":2668,"جه":7398,"جل":12168,"جم":17274,"جع":2397,"جس":2540,"جز":8412,"جر":7944,"جد":8657,"خت":6160,"حي":21851,"د،":2117,"حم":14977,"حن":1639,"خا":10036,"خب":2705,"حو":13676,"حف":3106,"حق":4632,"حك":5593,"حل":8199,"حض":1296,"حص":3737,"حز":2507,"حر":15992,"حس":5733,"حد":30065,"تغ":2721,"تف":6519,"تم":21550,"تل":11923,"تك":7075,"تق":23507,"تى":3340,"ثة":2642,"تو":27372,"ته":18459,"ثا":9771,"تن":10701,"تج":7596,"تح":21120,"تت":7159,"تر":25584,"تخ":11500,"تد":5897,"تش":11506,"تص":9178,"تز":2287,"تس":9386,"تع":17161,"تض":2140,"تط":3895,"ثق":2026,"ثل":9196,"ثن":2113,"جا":22121,"ثم":5275,"جة":6738,"ثو":2447,"جب":5048,"ثي":5910,"جت":3434,"تي":34720,"ثر":5818,"بغ":2025,"بع":25200,"به":11285,"بن":26227,"بم":5940,"بل":28735,"بك":4252,"بق":7310,"بد":14809,"بج":2196,"اً":11293,"بح":10218,"بت":8320,"اي":29388,"ة،":15567,"بب":2982,"اه":11841,"او":11068,"بة":13305,"بط":8037,"بش":3786,"بص":1566,"بس":4381,"بر":41886,"تا":29084,"تب":19287,"تأ":5378,"بو":18997,"ت،":2681,"بي":60818,"ئد":1726,"ئر":5978,"ئز":1688,"إن":13110,"ئا":1293,"إم":3605,"ئة":2198,"ا،":7371,"إي":6297,"اء":25293,"ئل":4704,"ائ":31094,"ئم":1653,"از":9640,"ار":69575,"اذ":2153,"اد":41536,"اض":8516,"اص":11589,"اش":9130,"اس":39158,"ات":77501,"اة":4919,"ئه":1298,"اب":38588,"اخ":6254,"اح":20482,"اج":12583,"اث":6287,"ئي":14445,"ب،":1623,"اف":23866,"بأ":2984,"اق":16552,"ام":64051,"با":69767,"ان":106270,"اك":11934,"ال":726452,"بإ":1475,"اع":27489,"اغ":2741,"اط":14678,"ؤس":2217,"أو":36459,"أه":4128,"أي":8325,"أل":9391,"أك":9086,"أن":19914,"أم":14875,"إس":11365,"إر":1668,"إذ":1752,"إد":2895,"إخ":1619,"إح":7179,"إب":1901,"إل":22468,"إق":2002,"إع":1925,"إض":1479,"آخ":1667,"آل":2561,"أت":2542,"آن":1925,"أب":10779,"أح":11512,"أخ":6156,"أث":2807,"أج":3225,"أر":12567,"أد":4137,"أص":5345,"أش":3739,"أس":15627,"أغ":3162,"أع":5434,"أط":1989,"أق":3836,"أف":5069,"غي":8633,"غو":4024,"غن":2949,"غل":3357,"عي":17935,"غد":1582,"غر":13200,"غس":1789,"غز":1267,"عق":2845,"عل":49520,"عم":19388,"غا":8614,"عن":19968,"عه":6016,"غة":3737,"عو":7644,"ظي":3474,"عث":1594,"عت":10284,"عة":23777,"عد":27555,"عش":4458,"عس":1709,"عز":2669,"عر":25424,"عظ":2315,"عط":1205,"عض":5918,"عص":2498,"عا":50253,"ظه":2422,"عب":25388,"ظم":4301,"ظا":4120,"طن":4817,"طل":7662,"طق":11023,"طف":1950,"طع":6327,"ظر":2587,"طي":9898,"طو":11014,"ظة":6299,"ضم":8353,"ضل":2264,"ضع":1853,"طس":1527,"طر":9793,"ضي":7171,"طح":1428,"طا":16584,"طب":7274,"طة":4986,"ضو":3284,"صل":10145,"صف":5067,"صط":2224,"صص":1416,"صغ":2398,"ضر":2826,"ضة":1642,"صو":8178,"صم":4802,"صن":4515,"ضا":11319,"صي":8440,"شف":1822,"شك":5750,"شق":1763,"شع":5311,"شغ":1513,"صح":4260,"صد":4269,"صر":13415,"شم":11602,"صا":13513,"صب":5260,"شه":5994,"صة":3495,"شو":3361,"شي":12032,"سع":7475,"سط":12291,"سس":4815,"سف":3591,"شأ":1378,"سي":47561,"شت":5440,"سو":18175,"سه":3635,"شب":4456,"شا":16192,"سن":12898,"سم":24549,"سل":21272,"سك":11128,"شر":23735,"شد":1209,"شخ":3092,"زع":1204,"سب":17052,"زه":1918,"زن":1607,"سا":35091,"ست":30958,"سة":7853,"زو":4517,"زم":3202,"زل":2051,"سد":1627,"سر":8485,"سج":2382,"زي":20894,"رس":13875,"رش":2594,"رز":2717,"رط":1498,"رض":6362,"رع":5610,"رغ":2804,"زء":1924,"رل":3156,"رك":24686,"رق":13754,"رف":9661,"رو":32705,"زة":4009,"زب":2789,"ره":9008,"زا":10186,"رن":13036,"رم":7236,"س،":1548,"ري":92759,"رى":6117,"زر":4095,"ذر":1628,"ذك":2116,"رأ":2244,"رئ":5538,"ذل":5170,"رب":36257,"ذه":6871,"را":67798,"رت":12252,"رة":43634,"ذو":1454,"رج":14223,"ذي":9511,"رخ":1356,"رح":4450,"رد":11552,"ف ":28941,"ـ ":3661,"ع ":53161,"غ ":7968,"ص ":6276,"ض ":14917,"ط ":15243,"ظ ":1554,"ر ":119691,"ز ":20518,"س ":42343,"ش ":6531,"ً ":11009,"ي ":305236,"ه ":68493,"ن ":236663,"ى ":82765,"و ":86344,"ك ":22299,"ق ":30798,"م ":131428,"ل ":111126," ، ":18980," و ":12423," م ":5345," جن":4512," حا":7431," جه":1218," جم":4339," جي":2378," جو":3451," حت":2592," جد":1981," جز":3197," جر":1610," ثل":1523," ثم":3265," جا":6114," جب":2225," تي":1533," خل":4736," دا":4684," خط":2109," حق":1280," حك":2014," حل":1546," حي":8173," حم":2037," خا":3436," حو":8126," حر":3258," حس":2733," حد":2242," بك":1952," بق":1818," به":5365," بن":17676," بم":5621," بل":8899," بغ":1392," بع":9614," بس":2145," بر":8567," بط":3259," بش":2647," بت":3125," بد":4624," بج":1734," بح":3333," بأ":2828," ال":581886," بإ":1446," با":31729," ان":6245," ام":2207," اع":1488," ار":1569," اس":7954," اب":3029," ات":1745," اح":1418," اخ":1766," تو":6684," ثا":1511," تن":5058," تم":5949," تل":2911," تك":2690," تق":13534," تع":7393," تط":1471," تش":4009," تص":2525," تس":4420," تر":4248," تخ":1540," تد":1553," تج":1794," تح":6360," تت":4407," تا":4988," تب":4366," تأ":3604," بو":6771," بي":13768," أل":4956," أك":6683," أن":14293," أم":6327," أو":27007," أه":2795," أي":6316," آل":1841," أب":8228," أخ":2816," أح":8158," أج":2000," أث":1423," أر":3743," أد":2035," أص":3105," أس":5597," أش":2245," أع":3015," أغ":2285," أف":3376," أق":2564," إي":4306," إن":5007," إم":1413," إب":1312," إس":5794," إر":1268," إذ":1294," إد":1530," إح":6465," إل":21224," إق":1208," طو":2165," عش":2714," عر":3955," عد":6773," عا":21951," عب":8841," عي":1567," غر":3853," عل":33952," عم":7142," عن":15313," غا":2188," غي":2774," سع":2415," سي":7136," شب":1886," سو":5683," سم":1931," سن":7850," شا":3992," سك":3794," سل":4129," شر":6157," شخ":1437," شع":1651," شك":1235," شي":2028," شم":4082," صا":1583," شه":2018," صح":1413," ضم":5470," طا":1844," طب":1958," طر":3408," در":2995," دي":6094," دو":6652," ذا":1885," رئ":2370," ذل":2035," را":2673," رس":1784," ري":3022," رق":1403," رو":5273," زي":1372," سب":3177," سا":6895," ست":1885," لك":4551," مؤ":2595," لق":1950," لع":2571," لغ":1253," لص":2532," لج":1545," لح":1350," لد":1501," لب":2260," كو":5523," لت":3577," كي":3645," كل":6741," لإ":1374," كم":7185," كن":1321," لا":10830," مل":4355," مك":2868," مق":7894," مغ":1598," مع":14545," مص":6997," مس":11150," مش":2698," مر":11437," مد":14412," مح":14231," مخ":2723," لي":4897," مث":3231," مج":7634," لو":4068," مت":7729," لن":2133," ما":17956," مب":2224," له":5386," لل":21688," لم":6816," نف":1935," نق":1569," نظ":2491," نس":4267," نش":1472," مم":3100," نا":8059," من":85288," مه":1676," مو":12716," مي":4669," نج":1432," وأ":7664," هـ":2402," هن":1965," وا":50314," وإ":2381," هذ":9093," نو":6152," ها":3011," نه":2387," ني":2637," فر":6896," فب":1504," فا":3547," فت":2193," قص":1901," قط":1391," فق":1797," فل":2626," فن":1697," قا":5741," فو":2197," فه":1391," قب":5253," في":115948," قد":7793," قر":6492," لأ":2928," قل":1628," كت":3116," قو":2125," كب":2590," كا":17231," قي":2400," كث":1288," كر":7439," ود":1531," وخ":1367," وح":3870," وج":3378," هي":20610," وت":16290," هو":22238," وب":6445," وص":1974," وش":2083," وس":5388," وز":1947," ور":2782," وذ":1466," وغ":1624," وع":5254," ون":2492," وه":15877," ول":15982," وم":13412," وق":7666," وك":6757," وف":4804," وو":1985," وي":13320," يا":1484," يب":2139," يح":3014," يج":1805," يت":5470," ير":1696," يد":1787," يص":1234," يش":1764," يس":4063," يع":6186," يل":3428," يم":2984," يق":8446," يك":1977," يو":8148," ين":4302,"فس ":1508,"فر ":2554,"فع ":1454,"فا ":1471,"ق، ":1401,"فة ":10112,"قع ":14708,"فار":1789,"فات":2286,"فال":1824,"فاع":2545,"فان":1282,"فبر":1355,"فتر":2588,"قب ":1566,"قا ":1491,"قت ":1589,"قة ":16768,"في ":111805,"قد ":7827,"عظم":1719,"عضو":1448,"عشر":3482,"عسك":1369,"عزي":1296,"عري":1226,"عرو":2224,"عرف":3788,"عرض":1945,"عرب":8060,"عرا":4113,"عدة":2689,"عدا":2204,"عدد":5430,"عدي":2807,"عتم":1554,"ظيم":2842,"ظهر":1451,"عبر":1705,"عبد":6249,"عبي":2224,"عتب":4439,"عات":3583,"عائ":1805,"عاب":1251,"عال":9007,"عام":18844,"عبا":2776,"عاص":3770,"عار":1586,"عاد":3689,"ظمة":1530,"غسط":1434,"غدا":1272,"غرا":1470,"غرب":8757,"عية":4635,"عيد":1672,"عين":3620,"عمل":7530,"عمو":1379,"عمر":2346,"عها":1818,"عني":1581,"غال":2120,"عند":3134,"عهد":2118,"عود":4342,"علا":3567,"علي":8023,"على":25792,"علو":2893,"عما":5586,"علم":6076,"غني":1336,"غير":5788,"شعر":1240,"شعب":2093,"شما":7339,"شكل":4349,"صال":3820,"شهر":2525,"صبح":1804,"صاد":2357,"صار":2022,"شمي":2083,"صدر":2012,"شير":1659,"شيخ":2626,"طة ":4836,"ضي ":2799,"صطل":1544,"صري":4147,"ضم ":1876,"طب ":1314,"طس ":1466,"صغي":1584,"صول":1823,"صور":2575,"ضاف":1670,"ضاء":2485,"صنا":1592,"صمة":2695,"طق ":1799,"صية":1437,"صين":1293,"طي ":1477,"ظة ":6257,"طان":3004,"طال":3847,"طاق":1625,"طار":1511,"طائ":1561,"ضمن":5751,"طبي":3127,"ضية":1599,"طري":4168,"ظم ":1728,"عب ":10724,"عة ":23265,"طعة":4116,"عد ":10757,"عر ":1910,"طلح":1521,"طلق":2117,"طلا":1304,"عض ":2738,"طقة":8653,"طول":4093,"طوي":1533,"طور":2637,"ظام":2445,"طني":2154,"طين":2907,"عل ":1213,"غة ":3658,"عن ":10475,"عه ":1714,"عي ":3208,"س، ":1536,"ري ":14515,"رن ":3048,"زب ":1762,"ره ":3780,"زة ":3835,"رو ":2228,"رى ":5751,"رق ":5370,"رك ":3561,"رجي":1396,"ردن":4580,"ردي":1386,"رتب":1460,"ربع":2964,"ربي":13069,"رجة":3401,"رجا":1686,"ذين":1312,"رتف":1376,"رته":1217,"رتي":1328,"ذلك":5018,"ران":5308,"ربا":2177,"راه":1718,"راي":2650,"رة،":1284,"راً":1437,"راط":1969,"راض":2661,"راع":2044,"راف":2275,"راك":1677,"راق":4338,"رام":2614,"رال":1755,"راب":2845,"رائ":2827,"راج":1725,"رات":7689,"رئي":4628,"رار":2322,"راد":1959,"راز":1251,"راس":3033,"راء":3735,"ذكر":1364,"رأس":1309,"سس ":1682,"سر ":1409,"زي ":2367,"سة ":7637,"ست ":2491,"رسة":1580,"رسا":1400,"سا ":2325,"رسو":1660,"رسم":1498,"رسي":1211,"سب ":2371,"سم ":8379,"زرا":1870,"سل ":2019,"ريو":1361,"ريم":1723,"رين":5069,"ريك":7429,"ريل":2022,"ريف":1889,"ريق":6975,"ريا":9368,"ريب":2334,"ريخ":4312,"ريد":2596,"ريت":1569,"رية":19287,"ريط":2009,"رير":1548,"ريس":2387,"روي":1263,"روف":2873,"رون":3533,"روم":2673,"روع":1294,"روس":3818,"روت":1414,"روا":3408,"روب":3276,"رها":3942,"رنس":4822,"زار":1503,"رنا":1951,"زائ":1892,"سع ":1228,"ركي":2730,"ركز":6519,"ركا":1845,"رقم":1561,"ركة":6574,"سط ":4117,"رقي":3306,"رفي":1260,"رقة":1238,"شر ":3663,"سن ":1880,"سي ":9223,"سري":1260,"سرا":2022,"صب ":1600,"ساع":1424,"سام":1889,"سال":1558,"سبب":1717,"سان":4418,"سبا":5421,"سبت":1759,"سبة":1761,"ساح":5795,"ساس":2185,"سائ":1433,"سات":2066,"ساب":4056,"ستخ":5235,"ستا":3297,"ستر":2386,"زوج":1305,"زيو":1415,"ستع":2199,"ستق":2335,"زيا":2152,"ستي":2146,"زية":3984,"ستو":3126,"زيز":1328,"زير":3447,"صر ":6441,"سلة":1569,"سكن":1586,"سلا":5866,"سكر":1892,"سلي":1241,"سمب":1534,"سمة":2358,"سلم":2588,"سما":2312,"سلط":1809,"سلس":3040,"سكا":4595,"سطس":1421,"سطي":2518,"صة ":3360,"سعو":3150,"شرك":4217,"شرق":6331,"شرو":1260,"شري":3368,"صل ":5101,"ضة ":1538,"ضا ":2191,"سوف":1368,"سون":1558,"شتا":1442,"سوي":1779,"سوا":1477,"سود":1542,"سور":3979,"شاع":1427,"سمى":2128,"سنة":6767,"سمه":2089,"شار":4714,"سمي":3653,"شخص":2650,"صف ":1872,"سين":3825,"سيم":3305,"سيق":1533,"سيس":1471,"سير":1927,"سيد":1957,"سية":7660,"سيا":7442,"شته":1322,"يين":4613,"يقو":1288,"يقي":3960,"يقع":4212,"يكا":2890,"يكي":7123,"يلع":3028,"يلة":3508,"يكو":2936,"يلا":3946,"يلي":4907,"ين،":2158,"يلم":2210,"يما":3516,"يمة":2518,"يلو":2309,"يمت":1285,"ينا":6385,"يمن":1503,"يمك":1768,"ينت":2412,"يمي":5784,"ينة":14065,"ينو":1382,"يني":7771,"ينم":1347,"ينه":1443,"يها":5753,"يوس":2044,"يور":1429,"يوج":1408,"يوا":1512,"يون":8407,"يوي":1456,"يوم":3633,"يول":2410,"يقا":3504,"يقة":2474,"يفي":1837,"يفة":1491,"يضا":3644,"يسي":3184,"يسم":2811,"يزي":6603,"يست":3754,"يسا":1431,"يره":2025,"يرو":2802,"يري":3325,"يعي":2030,"يعر":1330,"يعة":1447,"يعت":2839,"يطا":4786,"يجي":2143,"يتا":1503,"يتو":1517,"يتي":2848,"يتم":2214,"يته":1496,"يدي":4565,"يرا":5132,"يرة":7852,"يحي":1325,"يدة":3171,"يدا":2277,"يال":1789,"يبا":1460,"يان":5624,"يام":1663,"ية،":7809,"ياً":2041,"يبل":2267,"يبي":2606,"يئة":1233,"يا،":2810,"ياس":4902,"يار":3005,"ياد":1919,"ياض":3099,"ياء":2370,"يات":14201,"ياب":2680,"يائ":1532,"وز ":1740,"ور ":10877,"ود ":7936,"وض ":4335,"نفس":2468,"وس ":4788,"هاد":1315,"هاج":1381,"هاز":1295,"هار":1592,"هاش":2115,"نما":2137,"ها،":1369,"وع ":4025,"نقل":1354,"وط ":1225,"نيس":1670,"نيا":8848,"نية":21320,"نوي":1623,"نون":2797,"نور":1366,"نوب":7417,"نهم":1521,"نوا":4198,"نوف":1932,"نوع":3104,"هاي":1376,"هام":1659,"نها":10954,"نهر":1868,"وف ":3389,"هذا":5637,"وق ":2861,"نين":2937,"نيو":3670,"وم ":10050,"ون ":24085,"هرة":1975,"هذه":5272,"هرب":1206,"وك ":1613,"ول ":15598,"وي ":5541,"ي، ":7950,"وى ":2336,"مغر":2269,"معي":2389,"معل":1517,"معه":1532,"معر":3470,"معت":1206,"معة":3514,"معا":4652,"هد ":3199,"هر ":6421,"مقا":7017,"مقر":1875,"مقد":1322,"ملة":1472,"ملا":2140,"مكن":2428,"مكا":1474,"مكت":1317,"منا":3879,"ممل":5220,"نائ":1835,"ناء":3405,"ناد":6151,"منذ":4141,"منت":3699,"نات":4769,"منظ":1521,"منط":9032,"ناط":2245,"ناص":1498,"منص":1619,"ناس":1610,"ناع":1893,"ملك":8686,"مما":1241,"ملي":3442,"ممث":1944,"مهو":2239,"موا":8484,"نبي":1323,"موج":1832,"مور":1727,"مود":1263,"موس":3401,"موع":3576,"موق":1778,"ناك":1264,"نام":2198,"نان":5318,"نبا":1540,"مها":3875,"منه":3913,"ناي":2308,"مني":1297,"نتق":1216,"نتش":1566,"نتخ":2464,"نتج":1837,"نتر":1240,"نتا":3081,"مون":2835,"موم":1267,"مول":1330,"ميل":3548,"ميع":1518,"ميد":1868,"ميز":2165,"مير":3381,"نتم":1247,"ميا":3833,"ميت":1549,"مية":10968,"نتي":2558,"نجل":4522,"مين":4370,"هـ ":2122,"ندا":2054,"ندم":1329,"ندو":1295,"ندر":1700,"ندس":1559,"ندي":3768,"هل ":1310,"هم ":9416,"نسا":3625,"نسب":2400,"وا ":3570,"نسم":2218,"نشا":1687,"نسي":6788,"وب ":7482,"هو ":28172,"وة ":2028,"وت ":2509,"هي ":25821,"نطق":9203,"نظا":2438,"نظر":1914,"نظم":2245,"نظي":2652,"ومن":4650,"ونا":4025,"ومي":3551,"ونس":2979,"وما":5525,"وله":2128,"ولي":9104,"ومة":1640,"ولو":3124,"ولى":4041,"ومت":1425,"ولك":1651,"يع ":3808,"ولة":5953,"وكي":1778,"ولا":11130,"ولد":6407,"وكا":4860,"يط ":1772,"وقا":1242,"وفم":1445,"وفي":6567,"يض ":1235,"وقد":4338,"وقع":2237,"وفا":1769,"يش ":2562,"يس ":7953,"يق ":5733,"يف ":4553,"وين":2166,"ويو":1325,"ويق":1310,"ويل":2767,"ويس":2024,"ويع":1988,"وية":5123,"ويت":3787,"وير":2162,"ويد":1280,"وهي":6413,"وهو":7384,"وني":7306,"يه ":8938,"يو ":7129,"يم ":12246,"ين ":40630,"ًا ":1445,"يك ":2151,"يل ":12694,"وتو":2723,"وتق":1399,"هير":1949,"وتع":2163,"هول":1332,"وتر":1472,"وتت":1213,"وجه":1246,"وجي":2191,"وجو":2155,"وحد":1804,"هيم":1268,"وجد":2346,"واع":2005,"واس":3039,"وار":3337,"هند":2766,"واد":3067,"واح":3498,"واج":1496,"وات":4032,"واب":1388,"هنا":1458,"وائ":3044,"واء":1341,"هما":1800,"هور":3656,"وبي":4664,"وبل":1243,"وبر":3000,"واي":2060,"واق":2063,"وال":49239,"وان":5702,"وبا":3324,"وري":12364,"وسا":1602,"وزي":2144,"يا ":24320,"وسط":5112,"وسي":5438,"يب ":4787,"ية ":139658,"ودا":1655,"ودة":1389,"ودي":4370,"ورا":3830,"ورد":1319,"ورت":1259,"ورة":4176,"وزا":1263,"ورو":3091,"يد ":18420,"ير ":22585,"يز ":3857,"يث ":7060,"يت ":4897,"يج ":1671,"وطن":2615,"يح ":1259,"وعة":3516,"وعا":1992,"يخ ":5401,"وعي":1203,"لد ":7149,"لس ":3640,"لة ":25605,"كو ":1397,"لت ":2572,"لا ":8651,"كن ":4742,"قسم":1469,"لب ":3341,"قسي":2428,"لح ":4377,"لث ":1339,"م، ":3933,"كي ":5663,"لق ":2574,"لف ":3842,"كثي":2170,"له ":10668,"كسي":1295,"ما ":21645,"كرو":1414,"لم ":13383,"كري":3468,"لك ":9653,"كرا":1233,"كرة":8153,"كات":3795,"قنا":1376,"كار":2777,"لغ ":5250,"قلي":3507,"قيم":1916,"قيق":2120,"كثر":3184,"قية":4744,"كتو":3421,"قيا":3458,"كتب":2651,"كتا":3440,"قوم":2204,"قوا":2182,"كبي":3060,"كبر":3750,"كان":20675,"كام":2151,"كال":2865,"قني":1349,"كر ":2225,"كز ":6044,"كس ":1605,"قل ":2905,"فرا":2274,"قم ":1363,"فري":3990,"فرن":4775,"فرق":1262,"كا ":2472,"كة ":13804,"قى ":1356,"ل، ":2187,"قي ":5360,"فضل":1264,"فظة":6038,"فير":1961,"فيز":1412,"فية":2824,"فيد":1310,"فيل":3788,"فيه":4815,"فين":1921,"قتص":1591,"فيا":1360,"قدر":1289,"قدم":9632,"قدي":3437,"قرن":2599,"كم ":5038,"قرى":1679,"قري":5990,"كل ":7728,"قرا":2563,"قرب":1568,"فلس":2794,"فلا":1746,"قاط":5379,"قاف":1502,"قال":3148,"قائ":2080,"قاب":1505,"فنا":1210,"قات":2176,"قاد":1517,"قار":3777,"فمب":1413,"فور":1725,"قبل":4422,"قان":1522,"قام":2893,"لمع":7155,"لمغ":2396,"ماء":2699,"لمر":5941,"لمس":9884,"لمش":2559,"لمص":4216,"لمط":1236,"لمت":9057,"للو":1687,"لمة":1580,"لمج":4154,"للي":1280,"لمخ":2131,"لمح":5998,"لمد":5967,"لمؤ":2072,"للم":3559,"لمب":2156,"لله":4901,"لما":10778,"لنف":1218,"لنس":1662,"ماس":1244,"لنظ":1668,"ماع":3269,"لمي":7408,"مات":4917,"مار":7604,"ماد":2511,"لند":3683,"لمل":4323,"لمك":1995,"لمق":3111,"لمو":6905,"لمه":2311,"لنب":1670,"لنا":3789,"لمن":8707,"لمم":6914,"مائ":1529,"مؤس":2067,"لكر":4170,"لقي":1879,"لكب":1845,"لكا":2896,"لكت":3059,"لكة":5304,"لقو":2652,"للغ":3104,"للع":2547,"للح":1276,"لكي":2900,"للت":1711,"لكو":3675,"للب":1703,"لكه":1307,"للا":2747,"لكن":3420,"لكل":2395,"للأ":1511,"لفر":5137,"لفا":3058,"لفة":1423,"لفت":1915,"لقر":6914,"لقد":5675,"لقص":1290,"لقط":1312,"لفل":2420,"لقب":2460,"لقا":4848,"لفن":2512,"لفي":3665,"نس ":2245,"ند ":3871,"نذ ":4066,"لعب":7815,"لعا":12423,"لعد":3105,"لعش":1359,"لعز":1344,"لعر":10614,"لعص":1325,"لعل":5280,"لغا":2170,"لعم":4185,"لغة":3148,"لغر":4050,"لطب":2889,"لطا":3030,"لطر":1829,"ه، ":2068,"مي ":10289,"لطي":1270,"و، ":1265,"ني ":19921,"نى ":2242,"مصر":6502,"مصط":1846,"نو ":1687,"هة ":2433,"مصا":1239,"مسل":3430,"نه ":6502,"مسي":2261,"مشا":1795,"ها ":46135,"مست":5627,"مسا":7688,"مرك":7198,"مري":7170,"مرو":1205,"مرا":3794,"مرة":1768,"مرب":1566,"مرت":1375,"مدي":14448,"مدر":2755,"مدن":2068,"مخت":2389,"مدا":1536,"محل":1510,"محم":5603,"ليو":6519,"ليه":5228,"مجا":2341,"لين":3186,"مجم":3939,"محا":8346,"مجل":3322,"ليا":10564,"ليب":2394,"لية":13788,"متو":1712,"ليز":4850,"ليس":2021,"ليد":6582,"ليم":5806,"ليل":2383,"مثل":6304,"ليف":2446,"لوي":1597,"لون":3102,"متا":1234,"لول":3949,"لوم":4251,"متر":3819,"متد":1293,"متح":5418,"متع":1688,"لهن":1850,"لوا":3317,"لهو":1322,"مبي":1451,"لوج":1868,"لوح":1460,"لور":2028,"لوس":2838,"لوط":2044,"لوك":1356,"مال":13395,"مام":2587,"لنق":1670,"لنو":1865,"مان":13056,"مبا":2715,"لها":8071,"ماي":3281,"لهج":1315,"مبر":6074,"لأص":1592,"لأس":4356,"لأر":8270,"لأد":1635,"لأع":1940,"لأخ":2355,"لأح":2438,"لأب":1984,"لأف":1387,"لأل":2944,"لأك":1560,"لأن":3516,"لأم":7460,"لأو":8534,"لأي":1221,"لإس":5236,"كلا":1532,"مر ":4953,"مس ":1733,"مد ":7895,"مة ":20092,"لو ":1775,"مت ":2546,"لى ":49394,"لي ":18230,"ن، ":5582,"مج ":2119,"لسف":1264,"لشا":2194,"لسن":1963,"لسك":1528,"لسل":6280,"لسي":5235,"لشب":1219,"لسو":4213,"نب ":1230,"مه ":3791,"لسع":2105,"لسط":2488,"لسا":4332,"من ":76224,"نا ":5184,"لصو":1503,"مى ":3080,"نت ":7260,"لصي":1707,"لشم":4027,"لصا":2983,"لشه":1224,"لصح":2065,"نة ":25901,"لشي":3442,"لشر":6885,"لشع":2442,"لدي":8697,"لدو":6858,"لدر":3930,"لخل":2460,"لدا":2727,"لدة":1345,"لحي":2699,"لري":2867,"لرو":3390,"لرس":1728,"مل ":8293,"لذي":7896,"لرئ":2291,"لرا":2519,"لته":1222,"كيا":1952,"لتن":1720,"لثا":5157,"كية":5479,"لتو":2940,"لتي":15294,"كيل":2229,"كيم":1808,"لجا":2810,"لتا":4876,"كون":7678,"كوم":2797,"لتح":2710,"لتج":1719,"كوي":2650,"لتر":3418,"لتص":1218,"لتش":1260,"لتع":2665,"لتل":1255,"لتق":2650,"لحد":2696,"لجو":1720,"لجي":2140,"لحر":4857,"لحس":1519,"لحم":1993,"لخا":2598,"لحق":1482,"لحك":2052,"لجد":1516,"لجب":1382,"لجز":3847,"لحا":4240,"لجن":5221,"لجه":1784,"لجم":3177,"لاث":2511,"لاج":1537,"لاح":3135,"لاد":4259,"كند":1265,"لار":1311,"لاب":1932,"لات":8075,"لاق":3425,"لاف":2118,"لاس":6196,"لاع":5890,"كلي":3267,"لإي":1693,"مع ":8709,"كلم":2454,"لإم":2003,"لإن":6523,"كما":4559,"كور":1677,"لبو":1874,"لبي":3816,"لبل":3617,"لبن":3363,"كول":1392,"لبر":5552,"كهر":1331,"لبح":3898,"لاي":9010,"كنه":1287,"لام":9049,"لان":6278,"لبا":3771,"لال":6356,"لبط":1368},"n_words":[11749565,13990834,9440598],"name":"ar"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ben b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ben new file mode 100644 index 000000000..69083369c --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ben @@ -0,0 +1 @@ +{"freq":{"D":455,"E":376,"F":388,"G":399,"A":894,"B":684,"C":848,"L":430,"M":683,"N":429,"O":309,"H":360,"I":507,"J":241,"K":244,"T":598,"W":240,"V":199,"P":651,"S":947,"R":531,"f":1089,"g":1979,"d":2581,"e":8201,"b":1267,"c":2589,"a":8669,"n":6047,"o":5561,"l":3930,"m":2503,"j":208,"k":699,"h":3040,"i":6685,"w":672,"v":711,"u":2926,"t":5635,"s":4238,"r":5985,"p":1752,"z":245,"y":1310,"x":420,"এলা":514,"ক। ":614,"ঐতি":234," l":233," m":235," o":526," i":296," d":312," f":245," a":616," b":228," c":315," t":765," p":493," s":393," r":292," J":235," K":227," H":321," I":408," N":324," O":231," L":375," M":610," B":602," C":719," A":760," F":332," G":372," D":404," E":296," S":771," R":448," P":577," W":226," T":506,"ا":336,"Co":219,"উ":9536,"এ":27004,"ঃ":514,"ং":15654,"ঁ":2141,"ই":18078,"আ":10399,"অ":13627,"চ":16928,"ছ":9717,"ঘ":1893,"ঙ":3088,"ঞ":3794,"ট":30397,"জ":27267,"ঝ":790,"ও":9899,"ঐ":344,"খ":8927,"গ":20205,"ঔ":204,"ক":78264,"ন":86702,"ফ":6705,"প":46274,"ভ":18017,"ব":70605,"য":69717,"ম":48748,"ড":11071,"ঠ":3258,"ণ":10122,"ঢ":578,"থ":13519,"ত":69776,"ধ":12543,"দ":33053,"স":56165,"হ":25168,"়":39420,"া":175719,"ি":114763,"র":156970,"ল":52543,"Ma":241,"শ":24901,"ষ":17272,"ৎ":1686,"্":145506,"ৌ":1675,"ো":19195,"ৈ":1879,"ে":113569,"ৃ":4705,"ূ":5615,"ু":27604,"ী":22483,"৭":2295,"৬":2181,"৯":5541,"৮":2706,"৩":2127,"২":3895,"৫":2215,"৪":1978,"১":8858,"০":4887,"৷":254,"In":199,"।":25409,"Th":253,"b ":285,"a ":1054,"i ":350,"ge":332,"ga":252,"he":773,"ha":472,"gh":243,"g ":316,"ea":343,"ec":205,"ed":350,"de":506,"di":332,"এছা":284,"h ":358,"el":402,"en":818,"em":278,"et":317,"es":737,"er":1291,"ca":315,"e ":2258,"be":225,"da":210,"f ":445,"ct":266,"co":263,"ci":201,"ch":362,"ce":347,"c ":220,"এটি":2063,"d ":875,"at":923,"as":401,"ar":1026,"al":912,"ai":231,"am":360,"an":1536,"ac":322,"ad":251,"ag":317," ১":7243,"nt":573,"ns":267,"no":211," ৯":250," ৮":298," ৭":311," ৬":364," ৫":417," ৪":387," ৩":666," ২":2429,"of":407,"om":400,"on":1111,"ol":393,"ot":205,"os":230,"ou":252,"or":795,"r ":1035,"pe":220,"lo":359," ঢ":514," ড":1933,"ll":307," ঠ":230," ধ":2352," দ":9809," থ":3157," ত":9984," ফ":3863," প":28296," ন":11037," য":6674," ম":15133," ভ":9746," ব":28530," ল":4344," র":8416,"o ":382," শ":7392,"ma":464,"mb":342," স":27697,"me":396," হ":13181,"mi":232,"একট":5136,"একজ":1493,"na":524,"একক":204,"nc":255,"nd":698,"ne":429,"ng":599,"ni":414,"একা":295," ।":1901,"m ":412," এ":26382," উ":6430,"এখা":461," অ":13571," আ":10126," ই":6407,"li":503," জ":9765," ট":1754,"le":571," ঘ":968," ছ":3198," চ":4584," ক":22576,"la":589," ঔ":203," গ":7129," খ":2591," ঐ":343," ও":5820,"n ":1470,"ht":261,"hu":305,"hi":274,"ho":238,"id":213,"ic":689,"ia":484,"ig":326,"ie":307,"ir":212,"is":631,"it":565,"il":352,"in":1040,"io":639,"l ":743,"এবং":4187,"এপ্":233,"y ":803,"ve":326,"x ":253,"ul":217,"ur":460,"us":340,"ut":207,"um":443,"un":241,"to":352,"tr":334,"te":708,"ti":997,"th":909,"ta":488,"ss":271,"st":614,"se":325,"এমন":239,"si":361,"rt":257,"ry":236,"ro":438,"ri":872,"re":667,"rd":212,"ra":839,"t ":920,"s ":1577,"এদে":277,"এই ":3233," �":274,"এক ":911,"এর ":2530,"উনি":291,"উন্":360,"উদ্":622,"উপা":289,"উপর":460,"উপন":490,"উরো":279,"উল্":354,"উৎস":239,"উৎপ":278,"উৎ":563,"উর":543,"উপ":2213,"উস":347,"উল":530,"উক":210,"উজ":216,"উচ":390,"উট":503,"উত":973,"উন":827,"উদ":753,"ইন":1626,"ইব":205,"ইম":223,"ইয":591,"ইর":537,"ইল":683,"ইস":741,"উই":375,"এছ":287,"এখ":589,"এক":9005,"এম":465,"এব":4214,"এপ":275,"এন":320,"এদ":306,"এট":2154,"এই":3366,"ছর ":262,"ংশ":1413,"ংস":1069,"ংল":2600,"ংর":2237,"ংব":422,"ংঘ":236,"ংগ":523,"ংখ":753,"ংক":757,"ঁর":727,"ৎ ":620,"ইত":723,"ইট":668,"ইড":241,"ইজ":233,"আস":454,"আল":1088,"ইক":452,"আয":323,"অ্":840,"আম":516,"আর":1419,"আফ":296,"আব":708,"আধ":289,"আদ":422,"আন":1004,"ইউ":806,"ইং":2317,"আছ":551,"অস":568,"আগ":507,"আক":520,"অল":207,"অর":1154,"অভ":838,"অব":2125,"অফ":360,"অপ":433,"অন":3326,"অধ":754,"আই":743,"অথ":198,"অঞ":597,"অত":316,"অক":381,"অঙ":287,"অং":592,"ঙা":410,"চট":225,"চত":213,"চন":791,"ঙ্":2470,"৩ ":950,"চর":577,"চল":2320,"চী":679,"চু":374,"চা":2514,"চি":4076,"চে":985,"চ্":2421,"ছব":324,"৪ ":965,"ছর":393,"জগ":223,"ঘট":513,"গা":2158,"গস":249,"গি":590,"গী":642,"গু":2497,"গো":907,"গ্":3546,"গে":1783,"১ ":1256,"চক":208,"২ ":1015,"ঝা":497,"গোল":259,"৭ ":899,"টক":320,"টপ":202,"টন":552,"ঞ্":2042,"টব":433,"ঞা":1608,"টা":3413,"৮ ":899,"টর":259,"জন":5856,"ছে":4099,"জধ":330,"ছি":2738,"ছু":520,"গ্র":2862,"ছা":810,"গ্য":399,"জর":278,"৫ ":1051,"জল":300,"ছো":231,"জম":242,"জয":281,"জো":267,"জে":2691,"জু":830,"জী":975,"জি":3650,"জা":4328,"৬ ":1035,"জ্":3683,"গের":766,"ওয":1866,"ক।":744,"ঐত":235,"এশ":223,"এল":685,"এর":2874,"এস":513,"ক্":11379,"খন":635,"কে":8760,"কো":2299,"কী":339,"কি":3416,"কা":12553,"কৃ":1298,"কু":1325,"কস":263,"গর":1257,"০ ":1923,"গল":479,"খে":1085,"গন":254,"গব":429,"খ্":2313,"গঠ":636,"খি":334,"খা":2637,"খু":253,"গড":267,"গত":723,"গণ":853,"কল":1752,"খক":249,"কভ":207,"কম":1122,"কয":216,"কর":9263,"কব":584,"কথ":578,"কদ":234,"কন":446,"কত":422,"কট":5691,"কজ":1571,"কক":371,"পক":777,"নো":1529,"নৈ":281,"ন্":18037,"পথ":251,"পত":1140,"পন":1278,"পদ":1221,"পড":271,"পট":230,"পঞ":305,"নর":378,"৷ ":217,"নন":368,"ধে":496,"নপ":524,"নব":764,"নভ":385,"ধ্":3005,"নম":449,"নয":630,"নু":2067,"নী":3272,"নে":8228,"নস":741,"নি":10383,"না":9095,"বচ":430,"বছ":386,"বঙ":528,"বক":640,"ফল":533,"ফর":691,"পৌ":262,"প্":14673,"পো":493,"বপ":409,"বন":1731,"ফে":647,"বদ":516,"বত":795,"ম।":432,"ফু":801,"বড":289,"ফি":694,"ফা":803,"পশ":1040,"পস":313,"পল":236,"পম":204,"পর":6275,"পে":1955,"পৃ":469,"পূ":1624,"বই":313,"পি":1741,"পা":6024,"পু":2560,"পী":458,"বং":4443,"ভর":238,"ব্":5813,"মক":698,"মগ":375,"ভি":3000,"ভা":10166,"মত":941,"র।":1267,"ভু":429,"ভূ":887,"মণ":247,"ভে":813,"মন":1866,"মদ":356,"মধ":1657,"মব":565,"ভো":225,"মপ":208,"বব":837,"ফো":381,"বয":356,"ফ্":917,"বর":3916,"বল":2788,"বশ":202,"বহ":1569,"বস":2742,"বা":13175,"বি":13020,"বী":1634,"বু":748,"য।":373,"বৃ":690,"বে":6807,"বৈ":512,"বো":1000,"ভব":322,"রগ":376,"রক":3370,"রও":363,"রট":549,"যা":13478,"য়":35819,"রজ":517,"রচ":1226,"যস":235,"রঙ":226,"রদ":1297,"রধ":882,"রত":4811,"রথ":1065,"ল।":866,"যু":2179,"রণ":2957,"যি":521,"রম":1030,"রয":914,"যো":1322,"রব":1734,"যৌ":231,"রভ":428,"রপ":736,"রন":1614,"যে":3967,"মল":265,"যক":743,"ময":969,"ভ্":389,"মর":648,"মহ":1061,"মস":593,"মূ":1527,"মৃ":459,"যত":845,"যদ":240,"ঙাল":366,"মা":10507,"মি":3934,"মী":801,"মু":1962,"মো":1026,"যব":1634,"মৌ":259,"যম":725,"ম্":4843,"যন":902,"মে":4592,"ড়":3388,"ডা":1047,"ডি":1739,"ঠি":877,"ঠা":1161,"৯ ":835,"টে":2184,"ঠন":362,"ট্":2862,"টো":693,"টু":322,"টি":14501,"ণী":616,"ণি":777,"দ।":351,"ণা":1071,"তক":615,"ণত":463,"ঢা":467,"ড্":286,"ডো":228,"ডে":1416,"ত।":1976,"থা":4072,"থি":1849,"ন।":3725,"থন":275,"তে":6636,"তৈ":476,"থব":514,"তো":511,"ত্":11770,"থম":1047,"দক":1036,"তা":9664,"তি":11706,"তৃ":563,"তী":2327,"তু":1609,"তথ":334,"তত":465,"তন":1191,"ণে":1383,"ণ্":713,"তম":1948,"তব":730,"তল":215,"তর":2978,"নট":466,"ধা":3367,"নত":805,"নদ":832,"ধি":1235,"ধী":706,"ধু":525,"দো":593,"দ্":6813,"ধন":270,"দে":7678,"দৈ":238,"নক":807,"নগ":632,"ধর":1424,"নও":200,"দস":274,"দশ":433,"দূ":217,"ধত":234,"দৃ":215,"দী":1553,"দু":1592,"দা":3394,"দি":3189,"থে":3273,"দন":421,"ছে ":1536,"জন ":2036,"দল":773,"দর":900,"থ্":402,"হন":525,"সে":5003,"সী":651,"সু":1284,"সূ":479,"হণ":341,"হত":965,"সৃ":307,"সা":9422,"সি":3847,"সহ":471,"হচ":543,"হল":1575,"স্":12917,"হম":242,"হর":1722,"হয":5736,"সো":556,"হে":854,"হৃ":361,"়।":3879,"হু":683,"হি":3582,"হী":535,"হা":4314,"হ্":705,"হো":256,"়ক":477,"়ত":462,"়ন":1084,"া।":1709,"়ম":211,"়র":208,"ি।":908,"়ু":308,"়ী":503,"াং":3360,"ছু ":408,"াঁ":1482,"়ি":1178,"়া":8455,"়ো":436,"াই":3512,"়ে":7915,"াউ":581,"াও":962,"াক":5532,"়্":205,"াচ":1101,"াছ":570,"াজ":4489,"াখ":950,"াগ":2341,"াঙ":862,"াথ":1203,"াত":6156,"াণ":1382,"ী।":871,"াড":1549,"িং":1140,"াঠ":366,"াট":1770,"াঞ":296,"াভ":908,"াব":4643,"াফ":353,"াপ":2739,"ান":18665,"িউ":1255,"াধ":2334,"াদ":5045,"িক":11087,"িখ":922,"াল":10227,"িও":631,"ার":30756,"িএ":231,"াম":7273,"ায":8979,"িছ":516,"িজ":2552,"াস":5883,"িচ":1754,"াহ":2942,"িগ":546,"াশ":1723,"াষ":6041,"িট":1865,"িড":639,"িত":12239,"িণ":858,"িদ":2453,"িন":8978,"িধ":463,"িপ":1269,"িব":2698,"িফ":329,"িম":2790,"িভ":1825,"াৎ":271,"িয":6762,"ির":6023,"িল":5504,"ীক":817,"িশ":3794,"ীগ":209,"িষ":2506,"িস":4278,"িহ":941,"ুই":664,"ীদ":382,"ীত":1782,"ীপ":505,"ীন":1798,"ীয":4089,"িৎ":317,"ীম":347,"ীব":842,"ীল":338,"ীর":2436,"ুগ":541,"ুক":2294,"ুখ":360,"ুজ":362,"ুট":930,"র্":19499,"রো":2284,"রে":15121,"রূ":464,"রু":2561,"রী":3578,"রা":17630,"রি":11429,"রস":1549,"রহ":932,"রশ":407,"রল":454,"লয":931,"লম":504,"লব":520,"লন":1184,"লত":1046,"লট":257,"লচ":904,"লগ":240,"লক":1697,"ল্":3376,"লো":3053,"লে":9966,"লী":1486,"লু":671,"লা":9534,"লি":6096,"লস":278,"শক":649,"শব":592,"শন":1507,"ষক":239,"শর":329,"স।":308,"শত":558,"শট":242,"শে":3570,"ষম":327,"শ্":3936,"শো":350,"ষয":380,"সক":584,"শহ":1521,"শু":848,"শী":865,"সং":3293,"শি":3267,"শা":2252,"ষণ":732,"সন":1003,"ষে":1161,"সফ":273,"সব":1306,"সভ":427,"সম":3977,"ষ্":5176,"সর":1993,"সল":739,"হক":226,"সঙ":453,"ষা":5502,"ষি":1250,"সত":301,"সদ":563,"ৎস":482,"ৎপ":325,"্শ":719,"্স":2033,"্ষ":4401,"্ম":4357,"্ভ":1012,"্র":30653,"্য":25184,"্ল":2305,"্ত":14406,"্ণ":1498,"্ড":2937,"্ঠ":1626,"্ট":7869,"্ঞ":1750,"্ব":10276,"্প":3453,"্ন":2407,"্ধ":2336,"্দ":4738,"্থ":5602,"ৌল":231,"ৌর":302,"্ছ":784,"্জ":1742,"্চ":4084,"্গ":2822,"্ঘ":304,"্ক":3885,"োয":771,"োর":1773,"োল":1204,"োব":621,"োভ":229,"োম":910,"োষ":455,"োস":598,"োহ":395,"োঝ":365,"োজ":493,"োড":367,"োট":842,"োদ":303,"োত":491,"োপ":763,"োন":1801,"োধ":294,"োক":1031,"োচ":456,"োগ":1362,"গঠি":273,"খান":1047,"গঠন":344,"ৈর":614,"েশ":5180,"েল":4085,"ের":25063,"েয":1289,"েম":1903,"েভ":263,"েব":2130,"েপ":618,"েন":8060,"ৈত":343,"েহ":255,"েষ":1422,"েস":1309,"েও":994,"েখ":1729,"েক":4154,"েই":1429,"েউ":248,"েট":1435,"েড":786,"েত":1719,"েদ":505,"েগ":411,"েছ":3105,"েজ":2937,"ে।":4052,"ৃথ":340,"ৃত":2338,"ৃহ":465,"ৃষ":756,"ূত":331,"ূপ":414,"ূম":517,"ূর":2094,"ূল":1187,"ূহ":378,"ুত":1038,"ুড":349,"ুন":1462,"ুদ":1447,"ুব":643,"ুপ":599,"ুয":1183,"ুর":4508,"ুভ":198,"ুম":876,"ুল":3399,"ুস":1262,"ুষ":874,"ুশ":279,"কেট":226,"কেন":738,"কের":985,"কোন":942,"ক্ত":2888,"ক্ট":455,"ক্ষ":3987,"ক্ল":430,"ক্র":1781,"ক্য":806,"ক্স":679,"কিছ":467,"কাহ":230,"কিন":953,"কাব":216,"কায":382,"কার":4553,"কাল":1045,"কাশ":812,"কিল":233,"কিস":331,"কুল":267,"কুর":331,"কুম":261,"কৃত":1025,"কৃষ":259,"কে।":511,"কেই":224,"৮০":213,"৭১":230,"৯৯":610,"৯০":387,"৯৫":459,"৯৬":482,"৯৭":685,"৯৮":501,"৯১":321,"৯২":343,"৯৩":359,"৯৪":434,"৮৯":204,"৮৮":200,"গুর":367,"গুল":1495,"৩০":296,"২৪":220,"গীত":413,"৫০":212,"গান":542,"গার":291,"গায":230,"১৬":326,"১৫":332,"১৮":996,"১৭":415,"১২":292,"১১":238,"১৪":244,"১৩":256,"১৯":3860,"২০":1142,"০০":1455,"১০":452,"গস্":210,"্র।":452,"্যক":735,"্মা":901,"্মী":308,"্মি":327,"্যন":687,"্মে":324,"্যত":807,"্যম":709,"্যব":1629,"্রচ":617,"্যস":234,"্রক":1414,"্যু":488,"্যি":244,"্যা":10276,"্রজ":405,"গবে":354,"্বত":419,"্বন":491,"্বপ":359,"্বব":695,"্বর":1021,"্বা":1809,"্য।":373,"্বি":841,"্বী":559,"্বে":1025,"্বো":213,"্মগ":199,"্ভা":239,"্লা":616,"্লি":367,"গরে":240,"্লে":524,"্রব":578,"্যো":301,"্রম":577,"্রভ":304,"্রয":464,"্রত":2154,"্রণ":361,"্রদ":1113,"্রথ":1019,"্রন":758,"্যে":2625,"্রধ":869,"্রপ":383,"্রা":4952,"্রি":3967,"্রী":1344,"্রু":685,"খ্য":1786,"্রশ":293,"খ্র":509,"্রস":463,"্রহ":735,"্রো":780,"্রে":2630,"্ষণ":271,"গণি":276,"্ষি":1061,"্ষা":679,"্ষে":819,"্ষম":296,"গড়":257,"্শন":406,"খেল":564,"্সে":379,"্সি":438,"গত ":349,"খা ":665,"কজন":1518,"খে ":204,"। ":19077,"কলে":496,"কল্":282,"করত":378,"করণ":527,"করে":4422,"করা":2433,"কলক":407,"কর্":871,"কম্":406,"কাজ":532,"কাছ":278,"কাত":521,"কান":552,"গে ":596,"গর ":415,"কটি":5240,"ঃ ":340,"ং ":5055,"কবি":409,"ই ":6830,"উ ":312,"কথা":468,"ও ":6690,"এ ":847,"চ ":769,"খ ":354,"গ ":1629,"ক ":11586,"ত ":12607,"ণ ":3613,"ঠ ":296,"ড ":1706,"ট ":3372,"জ ":1903,"ব ":3202,"ফ ":611,"প ":1284,"ন ":20715,"ধ ":808,"দ ":2233,"থ ":1007,"কা ":1480,"ল ":8450,"ওয়":1861,"ভ ":587,"ম ":6723,"কি ":282,"য ":4809,"র ":54334,"হ ":1019,"় ":12855,"শ ":3191,"খন ":279,"কে ":5302,"ষ ":1259,"স ":4530,"া ":26160,"ী ":7142,"ু ":2897,"ি ":25805,"ো ":2835,"্ ":1910,"কল ":227,"ে ":37314,"তর ":887,"ডার":368,"ডিস":334,"ডিয":319,"তন ":462,"ণে ":593,"তম ":977,"ড়া":1089,"ড়ি":682,"ড়ে":451,"১৯০":231,"১৯১":267,"তু ":433,"১৯৪":366,"১৯৫":361,"১৯২":273,"১৯৩":285,"১৯৮":393,"১৯৯":498,"১৯৬":398,"১৯৭":613,"তী ":298,"তে ":4456,"ডের":406,"ডেন":243,"তি ":2372,"তা ":2207,"ঠান":465,"ঠিত":686,"২০০":842,"দ। ":304,"ণা ":499,"টাব":261,"টান":241,"টিক":566,"টার":1384,"টাল":237,"টিত":421,"টিন":246,"টিশ":274,"টির":990,"টাই":256,"ডে ":223,"ণত ":291,"টোব":204,"ট্র":2092,"ট্য":377,"ট্ট":258,"টেম":345,"টের":443,"টেল":237,"ঞান":1488,"০০০":220,"ত। ":1457,"ডি ":251,"ঞ্চ":1271,"ঞ্জ":764,"টবল":369,"ড় ":618,"টি ":10700,"জ্ঞ":1748,"টা ":567,"জ্য":1590,"টে ":252,"ঠন ":205,"ঝায":280,"ঠা ":199,"ছোট":215,"জয়":273,"টন ":232,"জান":513,"জাত":1408,"জার":1034,"জিক":202,"জিত":234,"জীব":714,"জুল":281,"জুন":236,"জেন":272,"জেল":1183,"জের":493,"চ্চ":1435,"চ্ছ":780,"ছবি":323,"ছিল":2594,"ছাড":436,"জধা":329,"ছেন":778,"জনপ":400,"জনী":266,"জন্":2129,"ছে।":1579,"জি ":2005,"৭১ ":202,"ঙ্গ":2125,"ঙ্ক":292,"জা ":285,"চনা":453,"চন্":198,"জে ":350,"চলি":385,"চলে":500,"চলচ":862,"চরি":276,"চিত":2401,"চাল":768,"চার":933,"চিম":924,"The":204,"চেয":454,"চীন":632,"পৃথ":340,"মক ":218,"পূর":1563,"পুর":1770,"পুত":228,"বংশ":207,"পের":502,"পেন":312,"পশ্":957,"পাশ":229,"পিত":257,"পাক":348,"পান":707,"পিউ":331,"পাত":414,"পাদ":424,"পাধ":205,"পার":1335,"পাল":505,"পায":279,"পাও":244,"পরে":327,"পর্":1509,"বী ":353,"পরি":2733,"য। ":281,"পরব":233,"বে ":2767,"পন্":745,"পদা":548,"পদ্":310,"বা ":2607,"বি ":661,"পঞ্":305,"বর ":1036,"পড়":268,"বল ":484,"পত্":595,"পতি":403,"বন ":272,"ন্ত":3819,"ন্ড":1774,"ন্ট":1141,"ন্স":716,"ন্থ":421,"ন্দ":2863,"ন্ধ":523,"ন্ন":1373,"ন্ম":1138,"ন্য":3823,"ম। ":348,"নেক":580,"নেত":451,"নের":3172,"নৈত":249,"নোব":216,"নুয":400,"নুষ":645,"নুস":424,"নিস":305,"নীত":622,"নীয":704,"নীর":259,"নিত":220,"নিজ":306,"নির":1511,"নিয":1391,"নিব":223,"নিম":242,"নাথ":204,"নী।":283,"নাট":333,"নিক":1359,"নাল":376,"নার":884,"নায":377,"নাম":2830,"নিউ":358,"নান":283,"নাই":230,"না।":209,"পে ":392,"বং ":4190,"নয়":574,"ধ্য":2527,"পি ":200,"নভে":235,"ধ্ব":397,"নপ্":410,"নদী":606,"ধের":201,"নতা":305,"নটি":399,"al ":424,"পর ":878,"ধার":1388,"ধিক":529,"ধান":1581,"ধুন":236,"ধীন":509,"and":351,"an ":333,"নগর":339,"ধর্":622,"নকা":301,"দ্দ":285,"দ্র":1656,"দ্য":1705,"দ্ব":1242,"দ্ভ":351,"দ্ধ":1443,"ধরণ":208,"ধরন":300,"দোল":241,"ধতি":214,"দেখ":386,"দেশ":3340,"দেব":447,"দের":2400,"দেয":262,"দীর":527,"দুই":388,"দুর":229,"পক ":215,"ati":407,"দর্":464,"০০ ":448,"দলে":293,"নী ":1022,"দশক":219,"নে ":2592,"নো ":750,"দস্":252,"দায":342,"দান":683,"দিক":556,"দার":1068,"দিয":527,"দিন":460,"ন্ ":258,"থিত":1239,"থিব":279,"থান":907,"থার":216,"থাপ":342,"থের":228,"থেক":1914,"থ্য":318,"নি ":3145,"না ":2078,"ত্ত":2681,"ত্ব":1563,"ত্র":5371,"ত্য":1749,"ত্ম":200,"১০ ":255,"ধি ":218,"দক্":833,"ধে ":246,"থাক":949,"তাঁ":801,"তি।":212,"তাক":433,"তা।":273,"তিত":496,"তিন":2758,"তিব":469,"তিয":323,"তির":977,"তিহ":514,"তিষ":915,"তিস":234,"তাদ":379,"তান":831,"তাব":456,"তায":251,"তার":2316,"তাল":484,"তিক":1444,"তুল":199,"তুর":359,"তীর":252,"তীয":1406,"তৃত":307,"তের":1547,"তৈর":454,"থবি":319,"তর্":666,"দী ":536,"তরা":670,"তরে":281,"দু ":322,"ণ্ড":418,"দা ":406,"তমা":738,"দি ":552,"ণ্য":221,"তবে":327,"দে ":324,"ণিত":430,"দর ":218,"তন্":360,"ণের":721,"তথ্":200,"তত্":385,"থা ":838,"ন। ":2670,"থে ":916,"তকে":220,"ঢাক":444,"থম ":866,"রকা":1796,"লত ":375,"রচন":240,"রকে":273,"রক্":515,"লন ":417,"য়ক":403,"য়ন":1056,"য়ত":420,"রজা":344,"য়র":205,"য়ম":204,"য়ো":399,"য়ে":7441,"য়ু":262,"য়ী":440,"য়ি":464,"য়া":7334,"রচল":394,"রচি":290,"য়।":3790,"যুগ":221,"যুক":999,"যুদ":441,"যাক":626," । ":1068,"যাট":233,"যাত":1108,"যাদ":399,"যান":2143,"যাপ":621,"যাব":244,"যাম":399,"যাল":1187,"যার":1249,"যায":1288,"যিক":236,"যাস":933,"রটি":492,"যিন":243,"রথম":978,"রত্":227,"রতে":1478,"রতি":1816,"রতী":622,"রণে":668,"রণা":328,"রণত":263,"রপত":250,"ion":522,"রন্":434,"রনা":231,"রনে":444,"যেম":243,"যের":1196,"রধা":866,"রদে":667,"রদা":349,"রভা":262,"লি ":1224,"রবা":369,"রবি":326,"লা ":2174,"রবর":362,"যোগ":846,"রমা":242,"লী ":505,"রয়":679,"লে ":3437,"রহণ":319,"রস্":785,"লো ":880,"ল্ ":250,"রাই":307,"রাক":460,"রাচ":539,"রাজ":2647,"রাখ":212,"রাণ":570,"রাপ":301,"রাব":230,"রান":1015,"রিক":1905,"রার":655,"রাম":984,"রায":1265,"রিজ":258,"রাস":948,"রিচ":1336,"রাহ":202,"রাশ":201,"রাষ":1115,"রিত":670,"রিট":394,"রিম":358,"রিব":807,"রিন":213,"রিস":680,"রিয":1449,"রিল":310,"রীক":256,"রীয":402,"রীর":289,"রুয":235,"রুত":425,"রূপ":403,"রে।":1025,"রেন":1720,"রের":3004,"রেল":310,"রেশ":198,"রেছ":854,"রেজ":2190,"রেট":233,"রেক":207,"রেস":215,"রোম":235,"রোপ":366,"রোগ":263,"র্ণ":1236,"র্ত":1912,"র্ড":513,"র্ট":567,"র্ব":2473,"র্ধ":342,"র্ন":427,"র্থ":1669,"র্দ":480,"র্ল":198,"র্য":1584,"র্ম":2023,"র্ভ":416,"র্স":595,"র্ষ":411,"র্শ":716,"র্চ":340,"র্জ":782,"র্ক":1521,"র্ঘ":284,"র্গ":673,"লকা":488,"লচ্":855,"লক্":395," Ma":238,"he ":468,"লতে":397," Co":216,"লটি":222,"লনা":313," Th":233,"লয়":917,"লম্":237,"লাই":481,"লাক":628,"লান":256,"লাদ":1657,"লাস":227,"লিখ":198,"লিক":746,"লার":1528,"লাভ":487,"লায":309,"লাম":488,"লিপ":223,"লিন":254,"লিত":865," of":374," an":214,"লে।":338,"লেও":259,"লের":1832,"লেন":1829,"লেজ":413,"লেখ":829,"লেক":269,"লীন":213,"লিম":293,"লিয":577,"লির":379,"ing":263,"লীয":377,"in ":228,"ল্প":990,"ল্ড":206,"ল্য":834,"ল্ল":756,"স। ":246,"লোচ":236,"লোম":202,"লোর":312,"লোয":202,"লোক":706,"শন ":671,"hum":238," th":574,"মত ":200,"মন ":560,"ফরা":505,"র। ":1082,"প্ত":664,"প্য":216,"প্র":13060,"প্ল":304,"প্ট":290,"পৌর":203,"ভা ":303,"বনি":284,"er ":443,"বনে":288,"বন্":515,"es ":375,"ফেব":217,"বচে":366,"বঙ্":528,"ent":254,"বছর":385,"ফুল":203,"বড়":273,"ফুট":478,"ফার":283,"বলে":833,"মে ":1672,"বস্":2112,"বহু":351,"বহৃ":337,"বহা":619,"ফোর":229,"ববি":644,"বপূ":262,"মি ":517,"ফ্র":706,"মা ":428,"বয়":292,"মী ":371,"বলা":524,"বলত":367,"বর্":2305,"বৃহ":359,"বেক":203,"বেল":404,"বের":931,"বেশ":937,"বেষ":386,"বোঝ":365,"য় ":12199,"বাই":313,"বাং":2410,"বান":279,"বাদ":861,"বাধ":440,"বার":1699,"বাম":198,"বায":216,"বাঙ":403,"বাজ":214,"বাচ":199,"বিত":730,"বিদ":1525,"বিধ":272,"বিন":362,"বিপ":215,"বিব":278,"বিভ":1099,"বিয":248,"বির":389,"বাল":212,"বিখ":512,"বিক":671,"বাহ":872,"বিচ":203,"বাস":937,"বিজ":1409,"রও ":300,"বীর":327,"বীপ":377,"বিষ":640,"বিস":375,"বিশ":2344,"ভাই":208,"রম ":217,"মগ্":268,"রন ":224,"যে ":1841,"রত ":384,"রণ ":1177,"ল। ":672,"ব্র":1160,"ব্য":3166,"ব্দ":1107,"যা ":1724,"রা ":4296,"রি ":1578,"ভ্য":238,"মবঙ":362,"মন্":664,"ভেম":223,"মধ্":1555,"মতা":307,"ভূম":496,"ভুক":240,"ভাগ":718,"ভার":2311,"ভাব":1222,"ভাষ":4828,"ভিয":254,"ভিন":1250,"ভিত":372,"ed ":213,"মাই":303,"মিন":199,"মিত":518,"মিট":419,"মাস":327,"মিক":501,"মাল":710,"মার":1752,"মান":3429,"মাত":575,"মাধ":574,"মাণ":369,"মাজ":400,"রো ":310,"মহা":801,"মস্":221,"রে ":4008,"যক্":405,"রু ":494,"রী ":1730,"ময়":958,"মৌল":207,"ম্র":226,"ম্য":700,"ম্ভ":243,"ম্ম":363,"ম্ব":1398,"ম্প":1633,"যমে":422,"যন্":880,"যবস":455,"যবহ":926,"মেন":347,"মের":1210,"মিশ":280,"মিল":414,"মীয":198,"মুখ":293,"মুক":494,"মুদ":244,"মুস":261,"মূল":1049,"লক ":453,"মূহ":371,"মৃত":392,"যতম":572,"সলা":347,"re ":199,"হচ্":536,"সাং":239,"সাম":709,"সায":256,"সার":942,"সাল":2557,"সিক":500,"সাধ":708,"সান":242,"সাব":458,"সিত":294,"সাহ":727,"সাই":326,"সাথ":746,"সাগ":439,"সীম":247,"সিন":266,"সির":308,"়ক ":242,"সূর":236,"সত্":211,"সদস":228,"ষেত":374,"সন্":338,"ষের":340,"সবচ":368,"সবা":223,"ষ্ক":275,"ষ্ণ":260,"ষ্ট":2671,"সভা":316,"ষ্ঠ":1554,"সময":711,"ষ্য":236,"সমা":613,"সমূ":375,"সম্":1299,"সরক":840,"সর্":566,"়ন ":433,"হিন":860,"হিস":1250,"হাদ":208,"হান":202,"হাম":272,"হায":221,"হার":1136,"হাস":659,"হিত":775,"হাজ":205,"হৃত":340,"সেই":206,"সেম":294,"সেব":1065,"সেপ":226,"সেন":564,"হতে":419,"সৃষ":262,"হত্":332,"সের":1064,"হয়":5615,"া। ":1439,"স্ক":1611,"স্ট":2276,"স্ত":2428,"স্থ":3469,"স্প":563,"স্ব":1109,"স্য":561,"হলে":402,"হলো":289,"হরে":416,"াগ ":429,"াও ":315,"াক ":329,"়া ":2568,"়ি ":218,"হ্য":294,"হের":399,"াই ":889,"়ে ":3374,"়ী ":420,"ি। ":726,"াল ":1724,"িও ":348,"ার ":13003,"াম ":1773,"াভ ":401," ১০":339,"াব ":352," ৩০":204," ১২":242,"়নে":202," ১৩":220," ১৪":201," ১৫":282," ১৬":286," ১৭":371," ১৮":940," ১৯":3783,"াহ ":308," ২০":1046,"াস ":1335,"াশ ":330,"িক ":5573,"িং ":561,"ী। ":724,"াট ":241,"াজ ":536,"াপ ":211,"ান ":5410,"াদ ":431,"াণ ":268,"াত ":1005," এই":3270," উৎ":560,"ng ":235,"শে ":909," উদ":684," উন":258," উত":959," উচ":373," উল":389," উপ":2191," ইত":669," আস":453," আয":322," অ্":835," আম":509," আর":1370," আল":1083," আধ":289," আদ":422," আন":905," ইউ":775," আফ":294," আব":706," উই":304," ইস":476," ইল":209,"nd ":283," ইর":274," ইয":287," ইন":731," অঙ":286," অক":379," অত":316," অঞ":596," অপ":429," অফ":358," অব":2124," অথ":198," আই":665," অধ":751," অন":3315," অল":206," আক":517," অভ":831," অর":1146," আছ":551," আগ":504," অস":564," ইং":2299,"শি ":343," অং":591,"শী ":336,"ষণ ":226," জ্":458," জা":2134," জি":334," জী":551," জু":646," জে":1308," জো":204," জল":229," ছো":231," ছি":1929," ছা":399," জন":3064," ছব":300," চা":848," চি":755," চে":275," চল":1081," চর":388," ২ ":205," ১ ":302," গ্":1853," গো":546," গে":282," গু":745," গি":203," ঘট":372," গা":986," গব":363," খ্":684," খে":607," গণ":589," গঠ":432," খা":596," খু":226," কা":3277," কি":1369," কু":537," কৃ":271," কে":1060," কো":1627," ক্":2305," কন":254," কথ":522," কব":408," কর":8000," কম":804," কল":1072," ওয":520," এস":383," এশ":223," এর":2835," এল":645," ঐত":234," এছ":286," এখ":588," এক":8988," এম":399," এব":4212," এপ":273," এন":256," এদ":302," এট":2135," ফে":435," বন":336," ফা":463," বড":264," ফি":389," ফু":675," বছ":364," পো":225," পৌ":257," প্":11714," ফর":609," ফল":347," বে":1555," বো":669," বৈ":440," বি":7573," বা":7403," বৃ":550," বু":368," বস":531," বহ":441," ফ্":592," বল":1749," বর":1400," মধ":1533," মন":645," ভে":259," ভূ":442,"শক্":282," মত":465," ভা":7371," ভি":710,"শকে":227," ব্":3507," ম্":464," মৌ":257," মো":583," মে":1083," মৃ":318," মূ":802," মু":1346," মি":1118," মা":4397,"সন ":262,"ষে ":226," মহ":923," মর":212," ধা":649," নদ":623," দে":2058," দৈ":202," দ্":1551," ধর":1182," নগ":253," না":3576," নি":3394," নী":245," নে":783," ধ্":292," নভ":274,"of ":368," পঞ":266," পড":228," পদ":913," পত":409," ন্":272," নো":287,"সব ":353," পু":1605," পা":3594," পি":495," পে":490," বই":234," পূ":997," পৃ":428," পর":4825," পশ":1001," তব":328," তত":253," তথ":332," তি":2653," তা":3867," তু":325," দক":818," ত্":257," তৈ":474,"ষা ":1614," তে":303," থা":1028," দল":654," দর":261," থে":1958," দি":1421," দা":849," দু":810," দশ":293," টা":272," টি":345," টে":546," ট্":234," ডি":734," ডা":459," ডে":331," ঢা":461," হয":5669," স্":3980," সো":334," হল":1487," সি":1221," সা":6870," সহ":408," হচ":537," সে":1681," হত":623," সৃ":267," সূ":402," সু":981," সী":216," সব":807," সম":3235," সন":329," সর":1532," সঙ":383," সত":207," সদ":329," হো":212," হ্":276," হা":1267," হি":1859," হে":312," শক":251," শা":1199," শি":1188," সং":2886," শু":645," শহ":1500," সক":314," শে":357," শ্":581," শত":509," শব":479,"on ":532," রি":295," রা":3902," রে":556," রু":295," রূ":298," রো":452," রক":302," যা":2826," রচ":547," যু":1137," যি":261," রয":403," রব":219," যো":242," যৌ":226," যে":1328," লি":670," লা":967," লে":811," লো":608," লক":345,"স্ ":266," ও ":4589,"শাখ":311,"শাস":697,"শিত":339,"হর ":728,"শাল":206,"শিক":625,"le ":226,"শহর":1422,"সে ":658,"হন ":263,"সী ":240," এ ":753,"হণ ":261,"সি ":877,"শব্":493,"সা ":275,"শনে":210,"শনা":303,"শতক":230,"শতা":251,"শটি":231,"mb ":231,"ষাত":229,"ষিণ":767,"ষায":1936,"ষার":498,"ষাব":214," স ":339,"ষা।":354,"সঙ্":452," র ":316,"়। ":2782,"ষয়":378,"হী ":223,"শ্র":601,"শ্য":362,"শ্ব":1645,"ষমত":242,"শ্চ":1032,"শেষ":751,"শের":1660,"ষণা":351,"শুর":445,"সংব":214,"হল ":715,"সংস":804,"শিয":443,"শিল":531,"সংক":417,"সংগ":424,"সংখ":731,"সংঘ":234,"শিষ":385,"ুসা":325,"ুষ্":372,"ুসল":207,"ূমি":444,"ূলক":257,"ূলত":394,"ে। ":2956,"ূর্":1748,"ুক্":1812,"ুটি":275,"ুড়":269,"ুটব":355,"ুপ্":205,"ুনি":328,"ুদ্":1024,"ুত্":534,"ুলা":360,"ুলি":957,"ুলো":677,"ুরস":488,"ুরা":502,"ুরু":902,"ুরে":214,"ুর্":475,"ুয়":999,"ুমা":378,"ৃহত":230,"েও ":751,"েক ":677,"েজ ":442,"েট ":476,"েড ":233,"েত ":298,"েন ":2383,"ৃতি":667,"ৃথি":275,"ৃত্":530,"ৃষ্":660,"েই ":990,"াচী":479,"াঙা":392,"াঙ্":430,"াজে":291,"াজ্":1187,"াজা":637,"াজি":350,"াজধ":330,"াজন":429,"াছে":290,"াখা":510,"াগর":531,"ীন ":996,"াকা":1674,"াকৃ":214,"াকি":417,"াক্":624,"াকে":1517,"াগা":228,"াগু":251,"াগে":340,"ীত ":407,"াওয":538,"ুই ":270,"াপে":239,"াপি":216,"াপা":332,"াপ্":438,"াবল":223,"াব্":798,"াবে":1282,"াবি":607,"াবা":550,"ামক":357,"ার।":391,"াথে":795,"াদা":503,"াদি":433,"াদী":233,"াদে":2459,"াদ্":228,"ানক":226,"াধি":292,"াধী":407,"াধা":767,"িউট":438,"াধ্":701,"ানম":216,"ানব":285,"ানা":935,"ানি":1277,"ানী":1247,"ানু":818,"ানে":2964,"ান্":3257,"ানো":483,"াপক":268,"াপন":257,"াণী":233,"াণি":288,"াতী":444,"াতি":1024,"াতা":904,"াতন":242,"াণে":256,"ান।":554,"াত্":1070,"াতে":889,"ীর ":1512,"াটি":687,"াঞ্":296,"াট্":216,"াড়":1116,"িন ":1620,"িদ ":390,"িত ":5217,"িণ ":578,"িজ ":216,"়ের":988,"়েল":232,"াইল":290,"িস ":391,"়েন":224,"়েত":314,"়েছ":1789,"িশ ":479,"াইক":267,"াইন":398,"াইট":347,"়িত":393,"াঁর":695,"াংশ":369,"িল ":1310,"াংল":2405,"়াড":214,"াৎ ":225,"়াল":346,"়াম":294,"ির ":3233,"়ার":2357,"়ান":720,"়াত":233,"িম ":623,"িহা":558,"ংশ ":608,"িস্":1568,"িসা":395,"িসি":199,"িসে":1302,"ূল ":317,"িরি":292,"িরা":288,"ির্":1412,"িলা":304,"িলি":409,"িলে":1534,"িল্":792,"িলো":314,"িশন":236,"িষ্":1946,"িশি":298,"িশে":548,"িষয":343,"িশ্":1581,"ীবন":365,"ীমা":216,"ীয়":4081,"ীর্":354,"ীরে":207,"ৃত ":857,"umb":265,"ীতি":604,"ীতে":555,"ীদে":242,"ীনত":266,"াহা":469,"িচা":733,"াহী":229,"িচি":688,"াহি":1315,"াস্":708,"াসে":596,"াসি":1223,"াসা":419,"াসী":261,"াষ্":1171,"াসন":338,"াষা":4713,"াশি":537,"ুর ":1172,"িটি":780,"িটা":629,"িজ্":1437,"িজে":324,"িছু":475,"ালক":364,"ালয":874,"ালন":396,"ারী":1146,"ারি":1557,"ারা":1659,"ার্":5067,"ারে":2345,"ায়":8671,"ারক":300,"ারন":347,"ারণ":1235,"ারত":1942,"ামি":443,"ামা":748,"াম্":609,"ামে":1488,"ামী":317,"াশন":211,"িখ্":507,"ুন ":561,"িকা":1858,"িকি":198,"িকে":1068,"িক্":1074,"ালী":661,"ালা":739,"ালি":1410,"ালো":249,"ালে":2817,"াল্":297,"িপি":219,"িপ্":331,"িনে":565,"িনা":408,"িনি":2917,"িনী":642,"িনয":241,"িন্":1908,"িমি":290,"িম্":258,"িমে":259,"িমা":636,"িল।":473,"িয়":6354,"িবা":741,"িবী":293,"িবি":361,"িবে":347,"িবর":417,"িভি":889,"িভা":580,"িমব":382,"tio":423,"thu":236,"িদ।":233,"ুল ":613,"িডি":222,"িত।":1272,"িদ্":1210,"িদে":199,"িনট":209,"িধা":259,"ter":251,"িতী":319,"িতি":339,"িতা":574,"িতে":1209,"িত্":2907,"the":401,"ঁর ":674,"্র ":2468,"্য ":4783,"োঝা":363,"্ম ":1055,"্ব ":1443,"্প ":322,"োগ্":438,"্ন ":1119,"্স ":725,"্ষ ":348,"ংশে":259,"ংসদ":201,"্ট ":1640,"্জ ":260,"্চ ":547,"ংলা":2409,"ংরে":2127,"্দ ":444,"োকে":215,"্ধ ":572,"্ত ":2310,"ংবা":245,"্থ ":613,"্ণ ":661,"্ঠ ":206,"্ড ":1005,"্ক ":455,"্গ ":569,"ংক্":310,"ংখ্":741,"্ঞা":1605,"্জা":489,"্জি":208,"্জে":211,"্জন":340,"্ছে":599,"্ত।":316,"্ডি":303,"্ডা":322,"্ডে":556,"্ঠা":754,"্ঠি":421,"্টি":1218,"্টা":1173,"্টো":370,"্ট্":1738,"্টে":710,"্দ্":1049,"আর ":224,"্দো":445,"্দা":237,"্দি":541,"্দী":307,"্দে":669,"্দু":407,"্ধত":232,"্দর":217,"্থা":2220,"্থি":1299,"্থে":279,"্থন":231,"্তে":276,"্থব":329,"্ত্":1963,"্তা":1329,"্তি":2212,"্তী":445,"্তু":740,"্তৃ":252,"্তন":456,"্তম":911,"্তর":2524,"্বক":355,"্প্":259,"্পে":443,"্পা":452,"্পী":215,"্পি":552,"্পর":340,"্পন":198,"অংশ":574,"্না":360,"্নি":236,"্ধে":424,"্ধি":256,"্ধা":305,"অক্":342,"ইন ":402,"অঙ্":286,"্কি":934,"্কা":944,"্কৃ":335,"্কে":282,"্গত":198,"্চা":486,"্চি":1888,"্চল":770,"্গে":523,"্গী":329,"্গা":318,"অফ ":315,"ংস্":691,"োনো":215,"োনা":252,"োপা":229,"োমা":248,"োমি":242,"োয়":741,"োরি":210,"োর্":375,"োলা":267,"োলন":236,"েছি":696,"েছে":2368,"েজি":1969,"ইংর":2136,"েক্":594,"আমে":217,"েকে":2070,"েখক":248,"অ্য":839,"আয়":311,"েখা":876,"আবি":225,"েকট":292,"ইউন":276,"আধু":208,"ইউর":313,"�":1457,"আন্":621,"আলো":342,"আর্":422,"আরব":337,"ইটি":293,"অঞ্":595,"অবস":1435,"অভি":728,"আইন":296,"অধি":383,"অনু":1003,"অধ্":210,"অন্":1608,"অনে":547,"আকা":241,"েশ ":1172,"েস ":337,"অর্":1060,"েষ ":526,"েল ":879,"আছে":543,"ের ":22964,"অস্":383,"োর ":595,"োন ":788,"োট ":334,"ৈরী":206,"ৈরি":250,"উচ্":373,"ৈতি":259,"োগ ":311,"উটা":283,"োক ":321,"উত্":954,"েস্":373,"ইত্":216,"ইতি":273,"ইন্":608,"েরা":505,"েরি":683,"েলে":417,"েলি":409,"েলা":1478,"েলো":239,"ইয়":586,"েশন":465,"েশী":418,"েশি":582,"েষণ":370,"ইরা":327,"েশে":1749,"েষ্":229,"েন্":1439,"েনে":324,"েনি":277,"েনী":276,"েনা":409,"েপ্":238,"েবে":991,"েব্":240,"েয়":1277,"েম্":732,"েমি":222,"েমন":290,"ইসল":353,"েটি":246,"েডি":240,"েতা":376,"েত্":488,"েন।":2598},"n_words":[1969690,2210879,1502429],"name":"bn"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/bul b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/bul new file mode 100644 index 000000000..201663afc --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/bul @@ -0,0 +1 @@ +{"freq":{"D":2636,"E":1936,"F":2232,"G":2334,"A":4351,"B":3121,"C":4592,"L":2480,"M":3950,"N":1781,"O":1368,"H":1934,"I":6368,"J":1261,"K":1010,"T":2986,"W":1604,"V":1965,"P":3771,"S":5211,"R":2316,"X":1029,"f":3146,"g":5865,"d":9193,"e":32549,"b":4459,"c":9844,"a":30637,"n":21831,"o":21963,"l":16413,"m":12336,"k":7480,"h":8702,"i":28615,"w":2350,"v":3143,"u":15394,"t":17966,"s":19762,"r":22456,"p":5894,"z":1439,"y":4095,"x":1681,"²":3527,"̀":1150,"μ":1054,"ν":2280,"ο":2756,"ι":1833,"κ":1014,"λ":1144,"ε":1298,"α":2356,"ί":816,"σ":1479,"ς":1823,"ρ":1221,"τ":1963,"ь":4950,"ю":16520," o":1042,"я":119927,"ш":24527,"щ":37947,"ъ":118638," k":4461," d":1024,"ф":35061,"х":26992," e":2141,"ц":57885,"ч":69969,"р":442208,"с":363493," a":954,"т":513431,"у":110117,"ѝ":1026," t":1519," p":1297," s":806,"Й":1921,"И":10722,"Л":9341,"К":22064,"Н":13530,"М":19622,"П":22329,"О":13337,"Б":18556,"А":21177,"Г":11598,"В":16284,"Е":7594,"Д":15403,"З":5627,"Ж":1534," J":1196," K":898,"Ш":3131," H":1769,"Щ":2903," I":3444," N":1367,"Ю":3236,"Я":1596," O":956," L":2204," M":3517," B":2694,"Т":16259,"У":4389," C":3884,"Р":16110," A":3726,"С":33637," F":2034,"Ц":2988," G":2045,"Ч":3270,"Ф":8267," D":2259," E":1564,"Х":7715,"л":282008,"к":273267,"й":56719,"и":734943,"п":177542,"о":637033,"н":589099,"м":161532,"г":129585," S":4264," R":2038,"в":294348,"б":87024," P":3303,"а":881417," W":1432,"з":132692,"ж":46599," V":1365,"е":647345,"д":212987," T":2518," А":17337," Б":18206," В":15997," Г":11364," Д":15029," Е":7181," Ж":1503," З":5448," И":10217," Й":1919," К":20624," Л":9135," М":19107," Н":12710," О":12505," П":21699,"Co":972,"I ":2499," б":25135," а":29615," г":41568," в":81473," е":87884," д":46722," з":26978," ж":5999," и":93394," л":8242," к":53137," н":137556," м":36472," п":102853," о":88041," Р":15097," С":31643," Т":15680," У":4153," Ф":7812," Х":7558," Ц":2895," Ч":3246," Ш":3096," Ю":3200," Я":1567," т":27331," у":9960," р":36272," с":111437," ц":6298," ч":13239," ф":16514," х":6966," ш":3296," щ":6810," ю":3698," я":2381,"Ca":930,"Ma":1469,"II":1888,"Th":962,"b ":891,"a ":4950,"i ":1873,"ge":970,"he":2112,"ha":1204,"g ":1075,"ea":1397,"ec":826,"ed":916,"de":1775,"di":1045,"do":824,"h ":1014,"el":2062,"en":3274,"et":1200,"es":2494,"er":5287,"ca":1035,"e ":9458,"da":1108,"f ":974,"co":1092,"ci":1241,"ch":1482,"ce":1332,"d ":2383,"at":2587,"as":1457,"ar":3743,"al":2739,"ai":928,"am":1115,"an":4726,"ac":1396,"ad":830,"ae":1227,"nu":977,"nt":2097,"ns":1121,"no":824,"of":927,"om":1215,"on":3740,"ol":1525,"m²":3381,"ot":815,"os":1234,"ou":906,"or":3049,"r ":3015,"pe":805,"lo":1036,"ll":2061,"o ":2327,"ma":1173,"mb":856,"me":1262,"mi":900,"na":1825,"nd":1832,"ne":1694,"ng":1442,"ni":2114,"m ":2526,"km":4286,"li":2736,"le":2314,"la":2281,"n ":4895,"hu":824,"hi":896,"id":1203,"ic":2468,"ia":2261,"ig":1082,"ie":1280,"k ":904,"ir":844,"is":2366,"it":1525,"iu":2316,"il":1887,"in":4071,"io":1821,"l ":2342,"y ":2050,"vi":1029,"ve":1027,"x ":1094,"ul":1045,"ur":1295,"us":5560,"um":1527,"un":918,"tu":1122,"to":1372,"tr":962,"te":2234,"ti":2705,"th":2095,"ta":1616,"ss":891,"st":2061,"se":1041,"si":1173,"rt":1054,"ro":1958,"rn":867,"ri":3533,"re":2281,"rd":988,"ra":2624,"t ":3334,"s ":10393,"² ":3527,"ς ":1819,"ν ":1021,"К ":979,"В ":2290,"юг":1081,"юз":1052,"юж":980,"юл":1213,"юн":1123,"юр":1010,"ют":1002,"юц":3295,"юч":2002,"яд":1101,"яг":923,"яв":7999,"ян":5481,"ям":2556,"ял":2107,"як":3070,"ях":803,"яс":1766,"ят":23106,"яр":1490,"ящ":989,"щи":5926,"ще":7866,"ща":13149,"щт":2297,"що":3015,"щн":816,"ъв":5386,"ъг":8535,"ъд":2915,"ъе":2628,"ъж":1821,"ъз":5682,"ъб":2128,"ът":9515,"ъч":1319,"ъц":2116,"ъщ":3958,"ъл":18163,"ък":3158,"ън":6470,"ъм":3577,"ъп":2106,"ъо":998,"ъс":7274,"ър":28553,"ьо":4687,"хе":1611,"хи":3810,"хн":1728,"хо":7132,"хр":1667,"ху":1707,"ха":4667,"ци":32071,"цк":2149,"ца":7811,"це":9248,"чл":917,"чн":11748,"чо":1988,"чи":7731,"чк":2263,"чу":949,"чр":804,"цъ":803,"че":23255,"ча":14633,"чв":2213,"шн":3596,"шк":2046,"ши":6517,"ше":4003,"шв":1228,"ша":3103,"ск":74214,"см":3598,"сл":11817,"со":8891,"сн":7769,"ср":4324,"сп":8021,"св":7943,"се":41908,"си":23052,"рш":1570,"ръ":16028,"ря":3303,"са":17003,"рс":15501,"рт":9867,"ру":13758,"рх":2778,"рц":2298,"тн":10904,"тл":2176,"тк":3861,"тс":3598,"тр":27985,"то":91021,"те":76446,"тд":804,"тв":20249,"ти":47326,"сь":1346,"съ":18957,"ся":1659,"та":97852,"тб":3928,"су":2617,"ст":96170,"сц":1590,"ур":10561,"уп":6474,"ут":4765,"ус":9980,"ум":6401,"ул":6590,"ун":6478,"уи":1236,"уз":3299,"ук":5239,"уд":4037,"уг":3988,"уж":1616,"уе":1334,"уа":3124,"тя":2319,"уб":6162,"ув":3514,"тъ":10928,"тт":3628,"ту":8218,"фу":2995,"фс":1030,"фр":3456,"фо":5112,"фи":11161,"фе":4259,"фа":3044,"уч":6066,"уш":4842,"ух":1233,"уц":1227,"Щ ":2591," I ":819," II":1042," Ma":1457,"а ":358572,"С ":937," Ca":925," Co":962,"Ис":1007,"Им":977,"Ин":1158,"к ":21804,"Из":2286,"Ив":1372,"й ":18686,"Ле":1710,"Ли":1795,"Ла":1638,"Ку":1413,"Кл":1286,"Ко":5445,"м ":14788,"Кр":2175,"Ке":836,"Ки":1609,"Ка":6073,"л ":25621,"Йо":1544,"На":5278,"Не":1875,"Ни":2119,"Мо":2461,"о ":136170,"Ма":9260,"Ми":2960,"Ме":2505,"Ло":1497,"н ":69303,"Лу":1452,"Па":3246,"Пе":2744,"Пи":1272,"Пл":3225,"с ":29451,"По":4526,"Оп":1050,"р ":30654,"Ос":2133,"Ор":1247,"От":1087,"Об":2207,"Ок":2446,"Но":2049,"п ":2647,"в ":63211,"Ам":1040,"Ан":3455,"Ал":2956,"Ав":1300,"Ба":2769,"Ат":831,"Ар":1719,"б ":1391,"АЩ":2595,"Во":969,"д ":24331,"Ве":2399,"Ви":2290,"Въ":2366,"Га":1581,"Бо":2717,"г ":21217,"Бр":1925,"Бе":2785,"Би":1506,"Бъ":3741,"Ва":2968,"Бу":1134,"Ди":2316,"Дж":3197,"Де":2501,"Др":1035,"До":1935,"ж ":1730," Th":951,"Ед":825,"Ев":1551,"Ге":2579,"Гр":2290,"е ":164103,"Го":1786,"Гъ":1180,"Да":1394,"и ":202644,"За":3607,"Ел":966,"з ":12874,"Ша":824,"Юж":1162,"ю ":929," km":4266,"я ":66327,"Ст":4040,"Та":1626,"Съ":4599,"Ти":1166,"Те":2600,"ф ":1914,"То":5455,"Тр":1786,"Ту":994,"Тя":1180," e ":1798,"х ":2350,"Пр":4433,"Пъ":1179,"СА":2694,"Ра":3306,"Ре":3655,"Ри":2528,"т ":98842,"Ро":3022,"Ру":2132,"СС":822,"Са":2940,"Св":1625,"Си":2245,"Се":4020,"Сл":1252,"Ск":946,"Ср":881,"Сп":1322,"Со":2387,"у ":10195,"Це":1510,"ш ":1936,"Че":1438,"щ ":4203,"ц ":3623,"Фо":984,"Фр":2381,"Фе":819,"Фи":1127,"Фл":885,"Ха":2310,"Хр":971,"Хо":1081,"ч ":2829,"Хе":1295,"лю":6411,"мб":1834,"ля":9658,"ма":34017,"мв":3536,"ме":34130,"ми":25035,"лм":3442,"лн":16796,"ло":33848,"лс":4866,"лт":3196,"лу":5370,"лъ":2856,"къ":5642,"лв":914,"лб":2941,"ла":34165,"лж":1120,"ле":40750,"лд":1625,"лг":12737,"лк":4727,"ли":64840,"лз":2343,"км":1179,"кн":2476,"кл":6420,"кр":18141,"кс":6288,"ко":52495,"кт":11901,"ку":5862,"кц":1433,"ка":68697,"ки":58354,"кв":3364,"ке":7674,"йн":7255,"йо":1892,"йк":1995,"йл":1354,"йм":901,"йс":13136,"йт":4652,"ия":73064,"ищ":2902,"иш":2457,"йд":1453,"йв":1615,"ио":15275,"ип":3934,"им":23532,"ин":58356,"ик":36656,"ил":29439,"ии":4086,"ий":12560,"иц":13361,"ич":23215,"иф":2446,"их":3360,"ит":63592,"ир":17875,"ис":34276,"ри":74729,"рк":5043,"рл":2965,"рм":7553,"рн":12220,"ро":46663,"рп":941,"ра":98873,"рб":2434,"рв":7403,"рг":7600,"рд":5085,"ре":68474,"рж":3084,"рз":1336,"пъ":7097,"пр":53247,"пт":2156,"пс":2576,"пу":5784,"пи":12418,"по":49161,"пл":7108,"оя":7068,"па":18259,"пе":14376,"ощ":6422,"ош":1648,"оч":6409,"оц":2874,"ос":31400,"ор":52184,"оп":12711,"оо":918,"ох":1705,"оф":5618,"оу":1691,"от":71852,"ок":20081,"ол":46187,"ом":18413,"он":40545,"ож":8402,"оз":8385,"ои":10610,"ой":13778,"ов":49786,"ог":14314,"од":35825,"ое":7078,"оа":1786,"ня":5762,"об":22311,"нъ":1330,"нц":6022,"нч":1314,"нт":20098,"нс":29338,"нф":1197,"ну":2379,"но":61747,"нн":7922,"нр":827,"нк":4229,"нз":932,"ни":106631,"не":37699,"нг":9593,"нд":12141,"мя":2035,"на":206302,"мъ":3046,"му":8961,"мс":4731,"мп":7095,"мо":14552,"мн":4561,"ге":6356,"ги":12185,"гн":1340,"го":24434,"гл":8226,"гр":23857,"гу":2534,"гъ":1359,"дв":5622,"да":30493,"вг":1251,"вд":1142,"ве":44922,"ви":31125,"вк":2396,"вл":5218,"вн":10484,"во":35579,"вр":11007,"вс":5682,"ву":1966,"вт":3431,"вш":985,"въ":12004,"га":25651,"вя":3485,"би":11046,"бе":7947,"бр":9346,"бн":1672,"бо":12574,"бл":10831,"бу":4434,"бс":2154,"бя":950,"ва":58204,"бъ":10139,"бщ":5858,"ад":29187,"ае":3072,"аж":2734,"аз":20177,"аб":6725,"ав":32263,"аг":6621,"ам":19866,"ан":92124,"ап":10532,"аи":1848,"ай":16768,"ак":18833,"ал":43351,"ах":2622,"аф":3137,"ач":7356,"ац":9711,"ас":30917,"ар":52528,"ау":3593,"ат":95702,"ая":1940,"ба":6691,"ащ":6812,"аш":2543,"зт":3682,"зс":1637,"зр":2676,"зп":8092,"зх":1144,"зу":1891,"зк":2737,"зи":16355,"зо":4852,"зн":6991,"зм":2937,"зл":3437,"ив":14438,"иг":8987,"иа":9057,"иб":2301,"иж":2121,"из":36345,"ид":10074,"ие":26794,"зъ":1412,"жо":1971,"жу":937,"жи":10091,"жк":1307,"жн":4179,"за":35424,"зб":1209,"зв":12292,"зг":1227,"зд":6172,"зе":4307,"еф":2109,"ет":45213,"ес":32066,"ер":49860,"еп":8513,"ео":5548,"ен":105327,"ем":23126,"ел":47225,"ек":18670,"ей":11615,"еи":962,"ез":20414,"еж":9844,"ее":2077,"жд":7425,"же":11581,"жа":5863,"ея":1281,"ещ":3642,"еч":4774,"еш":4262,"ех":2366,"ец":5302,"дс":7551,"др":9809,"ду":10303,"дн":14843,"дм":2251,"дп":805,"до":23013,"ди":35808,"дл":987,"дк":815,"де":31362,"дж":3808,"еб":3744,"ев":22477,"ег":6758,"ед":43311,"еа":2059,"дя":1235," th":1043,"дъ":7215," ар":2430," ас":835," ба":2316," ав":2928," ад":1436," ал":2238," ак":2281," ан":5186," ам":5117," ап":1113," бу":1045," ва":1142," бъ":8445," би":3599," бе":1826," бр":3218," бо":2578," бл":1708," вт":1082," въ":7192," ви":5408," ве":5179," во":6415," вс":1918," вр":3197," вл":1868," вк":1271," дв":3064," да":7239," го":11993," гл":1931," гр":14818," ге":2801," ев":904," ед":7019," дъ":3603," дн":1385," до":9466," др":4782," ду":4688," де":7755," ди":3107," же":950," еп":830," ел":1747," ек":959," ез":2706," зе":1022," за":22793," зв":852," жи":3991," зн":1109," иг":2469," ид":823," из":17689," ил":7883," ин":3652," им":7956," ит":1193," ис":3053," ка":12665," ки":1971," кр":5742," ко":21829," кн":1333," км":1031," кл":2272," ку":1841," ла":1472," къ":3355," ли":3157," ле":2135," ме":7169," ми":3625," ма":9333," мо":4895," мн":1906," му":6862," ни":1121," не":9125," на":119378," но":5035," ок":9717," оз":981," од":1340," об":13021," ня":1648," ощ":1554," оф":1095," от":45416," ор":4392," ос":5533," оп":3022," по":33250," пл":5058," пи":3055," пе":4542," па":4088," Ре":3648," Ра":3274," Ро":3019," Ри":2525," Пр":4415," СА":2616," Пъ":1174," Пе":2739," Па":3238," с ":12955," По":4518," Пл":3222," Пи":1267," От":1080," Ос":2127," Ор":1245," Оп":1048," Те":2595," Ти":1162," То":5392," Тр":1782," Ст":4014," Съ":4598," Та":1620," Св":1624," Си":2198," Се":4013," Сл":1251," Ск":944," Сп":1315," Ср":879," Со":2383," Ру":2131," Са":2935," Фр":2376," Фо":984," Фи":1126," Фл":885," Фе":819," Тя":1180," Ту":993," Це":1509," Хр":970," Хо":1079," Хе":1290," Ха":2307," Ша":822," Че":1435," Юж":1162," Ба":2734," Ат":830," Ар":1714," в ":45152," Ан":3448," Ам":1038," Ал":2947," Ав":1297," Ва":2965," Бъ":3733," Бу":1133," Бо":2714," г ":8207," Бр":1924," Бе":2781," Би":1492," а ":4115," Ед":825," Ев":1550," Ди":2315," Дж":3188," Де":2497," Др":1035," До":1933," Ел":962," Въ":2363," Га":1572," Ве":2397," Ви":2282," Во":966," Гъ":1180," Да":1391," Ге":2574," е ":70638," Го":1784," Гр":2287," Ис":1003," Ин":1152," Им":970," Йо":1543," Ки":1607," Ке":833," Ка":6065," и ":47012," За":3604," Ив":1368," Из":2283," Мо":2455," На":5243," Не":1867," Ни":2110," Но":2047," Об":2206," Ок":2446," Кл":1282," Ко":5424," Кр":2158," Ку":1412," Ла":1629," Ле":1707," Ли":1793," Ло":1496," н ":881," Лу":1447," Ма":9223," Ме":2502," Ми":2950," В ":2161,"Зап":1336,"Ива":1277,"II ":1339,"Кар":1717,"Кал":1241,"Кон":1216,"Кол":892," ра":14338," ре":11569," ри":1504," ро":5884," пр":44389," пс":1741," пу":1035," пъ":4915," св":5747," си":8451," се":28117," сл":4935," см":1742," ск":1388," сп":4517," ср":3911," со":1964," ру":1874," са":8475," ти":1471," те":8827," то":4709," тр":4417," сц":1244," ст":9556," су":971," та":2605," съ":15734," ус":1789," уп":1428," ун":1177," ту":1481," тя":1501," тъ":1070," фо":2263," фр":2272," фу":2793," фе":1675," фи":5383," фа":1634," уч":2779," хр":1022," хо":1370," ху":840," хи":1498," ха":1277," це":3524," чо":1060," чл":866," чи":1314," че":4520," ча":4234,"Мак":3324,"Мар":2452," ша":881," ща":6448," юж":900," юг":1007,"Южн":1054,"Нам":821,"Нас":1183,"Ник":1456,"ад ":8166,"ав ":839,"ам ":1105,"ан ":12026,"ак ":1047,"ал ":5489,"ай ":7880,"Окр":2063,"авт":1723,"ага":1670,"авя":1374,"агр":1076,"аго":1396,"ада":3119,"ади":3451,"аде":5585,"адо":1154,"адм":1400,"адн":2853,"аем":863,"би ":1015,"ажд":973,"Опе":874,"аба":833,"або":2518,"ава":11168,"авн":2861,"авл":2542,"аво":1409,"аве":2231,"ави":4818,"алс":906,"алн":8729,"ало":2628,"алб":1650,"ала":2998,"алк":1807,"али":10040,"але":5565,"амо":2012,"амп":965,"ама":2784,"ами":3947,"аме":7196,"анн":912,"ано":4066,"анс":13953,"ант":4813,"анц":1702,"ана":8635,"анд":5902,"анг":4584,"ани":19618,"ане":11702,"анк":1502,"азр":1036,"азп":4124,"азо":828,"азн":1081,"азл":1632,"ази":2620,"азв":2060,"аза":1484,"айс":963,"айк":1056,"айо":1501,"айн":2031,"акт":4848,"ако":1531,"акс":811,"аке":4784,"аки":1127,"ака":2207,"Пар":949,"ас ":2329,"ар ":3643,"ат ":10948,"Пло":2474,"ба ":1349,"ая ":1362,"ащ ":1410,"Пет":1186,"Пър":1058,"САЩ":2595,"Пол":1310,"При":1038,"Пре":1768,"Про":1122,"Рим":1524,"АЩ ":2589,"Род":1271,"Раз":1500,"Реп":2237,"Але":1070,"Сан":921,"Ант":866,"Рус":1292,"Соф":1291,"Сев":1817,"Све":1167,"Бра":846,"Съе":2317,"Тя ":1123,"Ста":1292,"Сто":900,"Бел":1301,"Тов":901,"Той":2267,"Вел":1059,"Бъл":3319,"Гра":1071,"Вът":1318,"Фра":1531,"Гер":981,"Гео":1043,"Дим":1088,"Хри":815,"Гър":1058,"Джо":1453,"Цен":1121,"Евр":1146,"лбу":1567,"лам":805,"лан":5659,"лас":5904,"лат":3266,"лги":963,"ме ":3219,"лга":11038,"ма ":9888,"ля ":1353,"лав":4235,"лаг":1602,"лад":2109,"къс":900,"към":1928,"кус":995,"кул":1639,"кци":1405,"коя":2700,"кре":815,"кра":5743,"кри":2482,"кръ":8385,"кса":1220,"кси":1227,"кте":804,"кти":2426,"кто":3328,"ктр":1676,"кла":1490,"ло ":7485,"кло":1049,"клю":1993,"кни":998,"ког":1332,"ков":4810,"ком":4727,"кон":4363,"коп":1296,"кор":1875,"кос":1575,"кот":3860,"кое":2107,"кои":3390,"кой":3594,"кол":6405,"кин":1233,"кия":7501,"лм ":1747,"кит":4721,"ле ":963,"кед":4374,"ли ":17289,"ква":2572,"кат":20763,"кар":2222,"кан":8113,"как":1566,"кал":2533,"каз":1398,"ла ":6130,"йто":3630,"йск":8916,"йст":3543,"кт ":1337,"йна":2642,"йно":1113,"йни":1595,"кс ":1165,"йон":1165,"ко ":8475,"км ":856,"ки ":42277,"йво":1025,"ият":14767,"од ":4250,"нац":1700,"нау":1528,"нач":4474,"ог ":1478,"нан":1145,"нам":2383,"нал":6581,"мят":820,"нат":17022,"нас":8028,"нар":6159,"нап":1914,"над":1993,"наг":991,"най":5108,"наз":881,"нде":899,"нда":1986,"нгл":4272,"нга":993,"нем":1875,"нен":7192,"ои ":1291,"нер":3755,"нес":1561,"нет":4998,"нег":1689,"нев":1009,"нди":2598,"ндо":877,"ндс":1234,"ндр":1171,"нив":1213,"низ":3481,"ник":6697,"ниг":977,"ние":16641,"ок ":2212,"ой ":4351,"ня ":922,"ов ":8975,"нав":1281,"нт ":3764,"мпи":1340,"мпе":2702,"мпа":913,"мот":885,"мск":3992,"мун":847,"муз":1721,"мик":1065,"мил":1270,"мич":1772,"мин":5435,"мис":1421,"мир":3990,"мит":3385,"мия":2187,"но ":26769,"мна":831,"мно":2749,"мод":977,"мов":951,"мож":1224,"мон":1361,"мол":819,"мос":1285,"мор":2165,"нс ":993,"нд ":1174,"мац":839,"мал":2220,"мак":2180,"май":1485,"лят":839,"мат":5742,"мас":872,"мар":1751,"ляр":941,"нг ":1106,"ман":6016,"лян":866,"лям":2082,"люц":3280,"люч":1984,"ляв":2485,"маг":843,"мес":1879,"мет":5373,"мен":8396,"ни ":29732,"мер":7582,"мей":1790,"меж":2783,"мед":1422,"мвр":3060,"не ":9731,"на ":142528,"лощ":4100,"му ":4914,"лни":5607,"лно":5548,"лна":4870,"лог":4324,"лож":4131,"лор":940,"лос":1248,"лот":2604,"лом":832,"лон":1406,"лов":4045,"луч":1122,"лст":1405,"лск":2670,"лта":884,"лзв":2068,"лиа":1575,"лиг":889,"лив":1397,"лиз":3791,"лим":1095,"лий":4336,"лик":5518,"леж":946,"лев":1784,"лед":5662,"лер":878,"ми ":2984,"лен":16713,"лем":2731,"лек":3978,"лет":2054,"мо ":1651,"лищ":1562,"лиц":2347,"лич":3301,"лис":3220,"лит":6583,"лиф":806,"лин":3617,"лия":3676,"лко":1751,"лка":1568,"оят":3638,"пат":1787,"ояв":887,"пад":4016,"рг ":1045,"оян":1222,"пан":2587,"пар":3257,"рд ":1208,"ре ":1433,"ра ":12349,"пит":1282,"пис":5195,"пла":2637,"пле":1081,"ро ":1581,"пло":2643,"ри ":13979,"пер":6644,"пет":985,"пей":864,"пен":871,"пец":914,"рк ":1201,"ори":9957,"орд":1685,"оре":5253,"орг":4291,"орс":1471,"оро":2299,"орм":3070,"орн":2306,"опу":959,"ора":5790,"опе":1825,"опи":2343,"опо":1901,"опр":1742,"опа":1705,"оте":1711,"отк":1219,"отл":842,"оти":2542,"ото":15284,"отн":1748,"отр":1056,"отв":1153,"отб":1366,"ота":1480,"осе":1009,"оси":1734,"осл":2267,"осм":1054,"осн":3443,"осо":2118,"ост":14287,"орт":2090,"оръ":1155,"осв":865,"оми":2906,"оме":3032,"оля":2830,"ома":3616,"олю":3412,"олу":2069,"олс":1164,"олн":1271,"по ":9531,"оло":11644,"олк":1549,"оле":5004,"оли":8455,"олз":2123,"ола":2641,"окр":6747,"окт":1051,"око":5161,"оня":990,"онс":3193,"онт":1752,"они":6360,"оно":4114,"онн":3311,"она":6297,"онд":803,"оне":3282,"омо":1980,"омп":2499,"оше":916,"очи":922,"очн":3093,"още":1644,"ощт":2295,"офе":923,"офи":2989,"оце":1219,"оци":1428,"няк":1962,"няв":1202,"ова":9654,"общ":5055,"обр":3456,"обо":1542,"обн":833,"обл":3221,"оби":2313,"обе":2463,"па ":3482,"оит":3156,"ойв":1029,"ойт":3479,"ойс":1115,"ойн":2834,"ока":2144,"ожн":1229,"ози":2118,"оза":2042,"озн":2520,"оиз":4705,"одн":3018,"оди":10451,"оду":932,"одр":1677,"одс":1049,"одо":2573,"оем":891,"оен":1806,"оет":2833,"оже":5313,"ове":9903,"ови":7840,"ово":5297,"овн":3952,"овс":1386,"ога":2254,"оги":3492,"ого":3019,"огр":2846,"ода":3875,"оде":5129,"от ":40884,"нот":4382,"нос":7389,"нош":880,"нор":1012,"ос ":1874,"ном":2595,"ное":844,"ног":2289,"нов":10487,"ор ":8928,"нно":1572,"нни":2936,"нна":3374,"нко":832,"он ":7439,"нка":817,"ом ":1452,"ния":18624,"нир":1151,"нис":3663,"нит":11345,"ним":1508,"нин":2416,"ол ":1852,"нич":2172,"ниц":3898,"нце":866,"нци":4501,"ощ ":1985,"нтъ":2337,"нуа":804,"нта":3339,"нте":1868,"нти":4317,"нто":1031,"нтр":2358,"нск":22095,"нст":3816,"сам":1827,"сан":2444,"сат":1871,"сва":1135,"сво":1889,"те ":30876,"све":3239,"свъ":838,"сев":2490,"сед":1178,"сел":9974,"сек":1165,"сеп":870,"ти ":11022,"сен":2491,"сем":2208,"сет":920,"сер":1205,"сия":1303,"сич":1328,"сис":1833,"сит":2033,"сих":1495,"син":1858,"сил":2220,"сим":1511,"ски":43899,"ска":20500,"сле":5451,"сла":2258,"ско":7743,"сми":843,"слу":1333,"то ":53757,"сло":1460,"сна":1239,"сни":1224,"соб":1154,"сов":1181,"сок":1395,"сно":4759,"спе":2031,"спа":1513,"спи":822,"соф":1092,"соц":1039,"сре":3295,"спо":2745,"роц":854,"рот":1758,"роф":1212,"роп":2362,"рос":2878,"ст ":15103,"роя":1120,"рта":1478,"рти":2728,"рск":11358,"рси":1583,"руг":2898,"руп":3391,"рус":2190,"рум":975,"рци":1577,"рхи":885,"ръц":1917,"ръс":815,"ръг":7752,"ръж":849,"ръб":829,"та ":68838,"рад":11688,"рае":904,"раж":1539,"раз":12192,"раб":3055,"рав":5786,"рам":2735,"ран":13900,"рай":2815,"рак":2465,"рал":6906,"раф":2143,"рац":1472,"рас":2637,"рат":10837,"рая":1251,"ращ":1083,"рби":1070,"рва":2274,"рди":900,"рдж":839,"реб":1455,"рев":6384,"рег":1970,"ред":14324,"рет":1976,"рес":2290,"реп":1732,"си ":5183,"рен":6538,"рем":3987,"рел":1209,"рек":2832,"рей":892,"рез":11468,"реж":2438,"ржа":2590,"рещ":1470,"реч":1092,"реш":2153,"се ":16807,"рво":979,"рве":1684,"рви":2226,"рга":3761,"рги":1489,"рда":805,"рия":9828,"рио":1833,"рим":2306,"рин":4333,"рик":7682,"рил":2477,"рий":2243,"рич":4087,"рит":6765,"рир":851,"рис":4939,"рка":815,"риа":2344,"риг":1450,"рив":950,"рие":1786,"рид":1515,"риз":1180,"рни":3773,"рна":4116,"рок":1893,"рол":1507,"ром":2389,"рон":2340,"роз":1160,"рои":4466,"рой":1470,"ров":7381,"рог":1151,"род":7855,"рое":938,"рно":2617,"рла":1189,"рми":2339,"рма":3665,"пра":5058,"при":9598,"пре":21619,"про":14907,"поп":1206,"пор":4301,"пос":3943,"пот":1094,"поч":1394,"рт ":2255,"пое":904,"под":4233,"пов":2082,"пон":1889,"пом":919,"пол":13153,"пок":1115,"поз":1787,"пуб":3689,"пул":1018,"пте":935,"пси":1481,"са ":8477,"пър":3460,"път":1769,"пъл":1566,"вар":1920,"ват":9299,"ващ":3095,"ван":13950,"вал":2194,"га ":4136,"бщи":2449,"бъд":803,"бър":1419,"бъл":7641,"бща":1581,"бще":1011,"бум":1554,"бук":823,"бск":1045,"вто":2970,"вси":896,"вск":2447,"вст":1194,"вре":3504,"ври":3322,"вро":1874,"връ":1065,"вол":4504,"вой":3658,"вое":1398,"вод":4759,"вот":3890,"вор":2694,"вни":3836,"вна":3375,"вно":2879,"вля":1602,"вле":1219,"вли":1041,"вла":1152,"го ":2882,"вкл":1196,"виц":847,"вич":1491,"вия":2762,"виз":1513,"виж":1141,"вил":1146,"вин":3278,"вис":2864,"вит":3903,"вид":3578,"вие":1422,"веч":1347,"вес":4369,"вет":7499,"вер":5871,"вен":9985,"ги ":2787,"вел":1221,"век":3636,"веж":1619,"вед":2219,"вгу":856,"ва ":24595,"бан":1118,"ачи":1132,"аши":924,"аща":2195,"ащи":2202,"ащо":823,"афс":811,"афи":915,"ача":3148,"аче":1418,"аци":9279,"апр":1718,"апа":4649,"апо":1282,"апи":1535,"арх":1193,"арс":9548,"арт":4677,"аса":1041,"аре":2062,"ард":1683,"ара":4896,"арн":1173,"арм":1084,"аро":3343,"ари":12961,"арл":1170,"арк":1896,"аст":14401,"ася":976,"ата":47391,"аси":2434,"асе":6138,"асо":1029,"ату":1909,"ате":8423,"ати":9387,"ато":12657,"атр":1084,"бол":3321,"бор":2442,"бот":2082,"бро":1543,"бри":1900,"бре":1262,"бра":3810,"бла":3919,"бли":5668,"во ":9926,"ви ":4285,"бен":998,"бер":1182,"без":1026,"бед":1013,"бел":1391,"бек":854,"бит":1770,"бил":1742,"бик":912,"бив":1415,"ве ":3400,"дан":2923,"дар":1829,"дат":3453,"дви":1371,"два":2719,"две":833,"ед ":5333,"дал":1095,"дад":3266,"дав":2214,"ев ":3676,"дее":1168,"дек":992,"дей":1639,"дем":1659,"дел":3837,"ден":12663,"дер":1762,"джи":1277,"ей ":1537,"дес":1272,"дет":1508,"ез ":10672,"дст":4125,"дск":2604,"дро":826,"дру":2364,"дре":1806,"дри":2347,"дра":1827,"ет ":4265,"душ":3708,"ец ":2918,"ен ":33180,"дия":1914,"диц":1640,"ем ":1311,"див":1005,"дим":1128,"дин":15737,"дио":936,"ел ":8445,"дис":974,"дит":1804,"дие":842,"ек ":3487,"доб":1818,"дов":2389,"ес ":1992,"дос":1220,"дор":1353,"док":903,"дон":5500,"дна":5206,"дни":3855,"дне":986,"ер ":6034,"дно":4679,"дми":1636,"да ":13229,"вяв":1024,"гал":815,"вят":853,"гат":2134,"ган":4672,"гар":12015,"де ":1425,"and":809,"an ":963,"във":2376,"въз":2174,"вър":4758,"гол":3089,"гор":2288,"гов":3764,"год":7938,"гру":3152,"ду ":2227,"гръ":1949,"гра":16257,"гри":1115,"гус":909,"ген":2209,"гер":1710,"ди ":4057,"гио":1272,"гия":3508,"гич":1145,"ati":807,"гле":897,"гла":2323,"до ":6155,"гли":4051,"жан":924,"жав":2301,"за ":15694,"еще":814,"жит":2528,"жив":1957,"жис":1541,"жес":1221,"жду":3122,"зи ":3101,"жен":7044,"жда":3366,"жно":1097,"жни":1433,"жна":1550,"ея ":816,"жа ":1065,"дъл":1733,"дър":3663,"еец":1133,"ежи":2367,"ежд":5041,"едс":4153,"жи ":1063,"еза":1907,"езо":914,"ези":4043,"ева":1249,"еви":2758,"еве":5028,"его":2858,"едв":1395,"еда":2616,"еде":4183,"еди":11058,"едо":5545,"едн":6376,"евн":1170,"ево":4583,"же ":1283,"евр":1969,"ега":870,"еги":1678,"ент":10211,"енс":4280,"енц":1053,"ени":27128,"ено":7268,"енн":2947,"ена":10075,"ене":4173,"енд":1760,"еор":1928,"епт":1100,"епу":3069,"епо":1006,"ерс":2306,"ерт":1057,"ерм":2802,"ерн":4552,"еро":3866,"ери":14051,"ерг":986,"ере":1937,"ера":7049,"ерв":1379,"ейн":1799,"ейс":4529,"еке":826,"еки":1118,"еко":1156,"ект":4178,"екс":3530,"ека":2557,"елн":4078,"ели":9768,"елс":1847,"ело":4047,"еле":11585,"елг":908,"ела":1732,"емо":966,"еми":3799,"емс":1747,"еме":6592,"еля":2163,"ема":3994,"емв":2337,"ехн":1011,"еци":1425,"ече":2969,"ешн":2173,"еща":1146,"еса":875,"есе":2292,"еси":1554,"еск":7153,"есн":1000,"ест":15331,"ета":4044,"ети":4225,"ете":3470,"етр":1876,"ето":20630,"етн":1476,"етс":1612,"етъ":1538,"иве":2646,"иви":1509,"ива":2727,"иал":3813,"иан":3297,"иен":1203,"иет":8077,"иже":812,"иев":1368,"игр":2806,"иго":824,"ида":1273,"иди":1105,"иде":2406,"иво":2091,"ивн":2071,"ивш":976,"ига":2136,"иги":1169,"икн":877,"ико":3994,"йн ":1098,"ики":1147,"ика":16650,"ийс":6452,"иит":965,"изъ":865,"изх":1032,"изс":1113,"изт":2743,"изп":3253,"изм":1954,"изл":1205,"изо":1731,"изн":1188,"изи":3858,"изк":1474,"изд":1669,"иза":5067,"изв":5752,"ион":10338,"инц":2399,"иня":874,"иод":1232,"ине":4216,"ини":7734,"ино":2511,"инс":5959,"инт":1527,"ина":17378,"инд":1369,"инг":2575,"ими":3098,"име":5126,"имс":2034,"имо":1892,"имп":3052,"имн":924,"има":3880,"или":12587,"иле":1355,"илм":2481,"илн":880,"ило":3073,"ила":2122,"иси":1489,"иса":3563,"ист":15576,"исп":938,"исо":1673,"исл":1753,"иск":1625,"ити":5468,"ите":38859,"ита":6132,"исъ":1087,"ись":1263,"иту":932,"ито":6371,"итн":995,"ира":10008,"ири":1911,"иро":1628,"ихо":1462,"ице":1072,"ица":5886,"ици":6007,"ифо":843,"ище":1958,"ичи":1220,"ичк":1339,"ичн":6798,"ича":3197,"иче":8842,"ка ":28086,"ив ":1131,"зав":1648,"зае":830,"ид ":2167,"зви":1188,"зве":5171,"зва":3840,"зац":2538,"зат":1310,"зар":1064,"зап":3505,"зан":2665,"защ":954,"зда":4154,"зво":872,"ие ":14021,"ий ":4437,"ии ":2933,"зем":1420,"зик":4455,"зир":1742,"ил ":4244,"ик ":10314,"ин ":8393,"им ":2180,"зия":1529,"зит":1037,"ип ":824,"зма":848,"ио ":855,"зли":2352,"зна":4787,"зни":1000,"зно":822,"ир ":1662,"зов":1006,"ис ":2255,"зон":1141,"зпо":5089,"ит ":1689,"зпр":1401,"зра":1726,"зпъ":815,"зсл":944,"зто":3205,"ич ":1609,"зхо":1090,"ия ":57202,"ius":2045,"is ":934,"ion":1052,"ьор":2769,"km ":885,"южн":872,"km²":3379,"ъцк":1859,"ътр":1736,"ъще":1730,"ъщо":1266,"he ":1146,"ъде":1407,"ъед":2623,"ъве":1335,"ъзд":2638,"ълн":1684,"ълг":11342,"ълж":1010,"ърн":1183,"ърк":1004,"ърж":2771,"ърз":1179,"ърх":1303,"ърт":1540,"ърс":856,"ърш":1020,"ърц":1189,"ъст":3892,"ъпр":1168,"ърв":4886,"ърд":852,"ia ":930,"er ":1669,"es ":1352,"яко":2322,"яло":937,"ява":6515,"юци":3278,"ючв":950,"ят ":9602,"яне":821,"яни":1186,"яма":1227,"ята":8869,"ято":2957,"уци":861,"уча":2759,"учи":956,"уче":1377,"уши":3537,"фес":938,"фер":834,"фан":1085,"фин":933,"физ":1170,"фил":3622,"фия":1796,"фиц":1324,"фут":2220,"фре":1952,"фор":3324,"фон":806,"ца ":4811,"ци ":3879,"хан":805,"хар":1263,"хол":1095,"хор":974,"хов":933,"ход":1906,"хим":863,"стн":3691,"сто":10615,"стр":11666,"ств":16841,"сте":8055,"сти":11129,"ста":11874,"стъ":2246,"сту":903,"стт":2922,"сце":1326,"съд":995,"съв":1667,"съз":2361,"със":4442,"сък":852,"сън":863,"същ":2787,"сьо":1331,"тав":5484,"так":1485,"тал":3945,"тан":6731,"тай":879,"тат":3225,"тар":3238,"тбо":3512,"твъ":860,"тво":9227,"тви":1621,"тве":3786,"тва":3607,"тех":952,"тем":3541,"тел":16601,"тео":1008,"тен":6993,"тер":6816,"тет":1731,"тес":853,"тез":1494,"тек":1131,"тив":4139,"тие":1898,"тка":1702,"ум ":1519,"тич":5203,"тиц":909,"тия":3555,"тин":3775,"тик":4630,"тил":1307,"тир":2210,"тис":902,"тит":2981,"тла":1006,"тно":3117,"ток":1533,"тол":2748,"той":1268,"тов":5201,"тни":5121,"тна":2467,"тре":4236,"тра":10350,"три":4952,"тор":11467,"тот":821,"том":2089,"тон":2179,"ус ":1180,"топ":1014,"точ":3383,"тоя":1817,"тта":3294,"тро":5709,"тру":1929,"тск":2626,"тур":4751,"тър":5898,"тът":942,"тън":1062,"ува":2742,"уги":1696,"уга":1360,"уар":1716,"убл":3878,"узи":1937,"уди":922,"удо":1145,"уме":1194,"ума":1453,"улт":1584,"ули":1004,"ула":1122,"укт":810,"ука":1012,"упр":1211,"ура":2417,"ург":1080,"ури":1177,"упа":3307,"уна":1368,"уни":1783,"уст":2872,"утб":2290,"урс":982,"урн":1905,"уск":2598,"уси":1038,"що ":2387,"шни":1037,"шна":1940,"шин":804,"ще ":3484,"шен":1940,"щи ":1591,"ъв ":2817,"ът ":6352,"ъс ":1987,"ър ":7548,"ън ":3472,"ъм ":3109,"щит":1320,"щин":2379,"ъл ":2252,"ък ":1412,"щен":865,"щес":2508,"ъг ":7573,"щат":7215,"m² ":3381,"on ":1530,"щта":2294,"че ":2916,"цен":4575,"чи ":992,"цел":1258,"цес":947,"цер":828,"циа":2597,"ции":1846,"цио":6596,"цит":1550,"ция":11555,"ча ":1350,"цар":1123,"цат":1708,"цки":1353,"чев":1376,"чен":5933,"чес":8800,"чер":977,"ши ":3970,"чет":1965,"чле":872,"чки":1198,"чин":1845,"чит":1626,"ша ":1093,"чва":2149,"час":5618,"чал":1786,"чан":1529,"чав":2550,"ща ":4581,"чре":802,"чна":4150,"чов":1436,"чни":4370,"чно":3174,"us ":4874,"ter":901},"n_words":[7994134,9177756,6462334],"name":"bg"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ces b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ces new file mode 100644 index 000000000..e46e24f29 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ces @@ -0,0 +1 @@ +{"freq":{"D":14883,"E":9868,"F":10603,"G":9505,"A":22558,"B":22848,"C":16455,"L":15978,"M":26754,"N":16476,"O":10801,"H":14139,"I":10554,"J":20213,"K":19386,"U":5533,"T":19206,"W":5350,"V":19456,"P":31985,"S":35760,"R":13848,"Y":1260,"Z":7679,"f":46799,"g":61772,"d":331353,"e":908926,"b":175631,"c":304749,"a":764805,"n":728035,"o":890229,"l":442609,"m":328621,"j":233650,"k":440118,"h":259891,"i":521717,"w":9425,"v":451146,"u":342714,"t":548551,"s":514164,"r":514188,"q":1288,"p":289793,"z":213126,"y":191798,"x":11788,"í":321621,"é":145384,"á":236804,"ý":129650,"ú":13969,"ó":5647,"ě":138011,"ď":2560,"Č":7702,"č":98194,"ř":105343,"Ř":1405,"ň":6555,"Ž":1649,"ž":81570,"ť":3583,"Š":3572,"š":60015,"ů":48717," l":32594," m":62986," n":107131," o":79037," h":32176," i":15946," j":127655," k":89036," d":65217," e":11656," f":19925," g":5629,"р":1443," a":90604,"с":1165," b":47368," c":20381," z":85758," u":20743," t":59923," w":1272," v":146123," p":164476," s":159790," r":52674," J":20168," K":19243," H":14014," I":10456," N":16390," O":10658," L":15894," M":26594," B":22644," C":16189," A":22443," F":10496," G":9381," D":14695," E":9809," Z":7643," Y":1252,"и":1928,"о":2213,"н":1523," S":35443," R":13762,"в":1172," P":31807,"а":2293," W":5251," V":19363," U":5519,"е":1554," T":19078," ú":11862," č":34240," Č":7692," ž":9995," Ž":1647," Š":3567," š":7349," ř":11127," Ř":1403,"A ":3554,"Da":2148,"Co":3211,"Ce":1274,"Ch":3956,"Do":2726,"De":2027,"Di":1704,"Ev":1845,"Ge":1462,"Ga":1606,"I ":2501,"Fr":2934,"Fo":1409,"Fi":1671,"C ":2405,"Au":1413,"Ar":2392,"As":1426,"D ":1568,"Ba":3474,"Am":1706,"An":3282,"Al":3092,"By":2085,"Bu":2103,"Br":3950,"Ca":2582,"Bi":1362,"Be":3232,"Bo":3007,"Ku":1175,"Kl":1430,"Kr":2544,"Ko":4086,"Le":3365,"Li":3491,"La":2847,"Lu":1426,"Lo":2548,"Me":3379,"Mi":4015,"O ":1633,"Ma":8187,"Mo":4597,"Ni":1492,"Ne":3393,"Na":4223,"P ":1532,"No":2609,"Ob":1767,"Gr":1729,"Ha":2931,"He":2201,"Ho":2992,"Hr":1212,"In":2920,"Ja":4326,"L ":1226,"Ji":2201,"Je":8576,"Jo":1796,"Ju":1244,"Ka":5031,"M ":1302,"Tu":1161,"Tr":2534,"To":2275,"Th":2120,"Ti":1361,"Te":3239,"Ně":1339,"Ta":2435,"V ":4585,"St":6172,"Sv":1697,"Su":1422,"Wi":1615,"Wa":1205,"Vy":1686,"Vo":1294,"Vi":2012,"Va":1654,"Ve":3321,"Pr":7552,"S ":3112,"Pe":2524,"Pa":5499,"Pl":1516,"Po":7183,"Pi":1236,"Os":1168,"Or":1234,"R ":1716,"Se":3431,"Sc":1219,"Si":1856,"Sl":2584,"Sk":1212,"Sp":2686,"So":3053,"Ru":1888,"Sa":3516,"Re":2582,"Ná":1404,"Ro":3655,"Ra":2507,"b ":5436,"Zá":1325,"a ":217661,"Př":2063,"Za":1646,"Ze":1335,"i ":90037,"fy":1326,"ge":8367,"ga":7746,"bý":4615,"fi":13067,"ač":14478,"fr":4738,"fu":2046,"ft":1555,"fo":9138,"bí":5183,"j ":5728,"gy":1560,"dá":9259,"he":13421,"ha":16982,"bě":8276,"gn":2020,"gl":5355,"gi":10280,"gh":1578,"gu":3569,"gr":6781,"cí":27801,"go":4942,"du":15000,"dv":6535,"dy":13097,"g ":5595,"ea":6165,"eb":20255,"ec":32017,"ed":50406,"de":36807,"dd":1592,"di":24806,"dh":1175,"dk":3086,"dm":3275,"dl":11857,"do":40054,"dn":44007,"dp":2177,"ds":6618,"dr":15992,"ew":1387,"ex":5658,"eu":3247,"ev":22848,"ey":1497,"ez":19185,"fa":3278,"h ":68060,"fe":4502,"bá":2585,"eh":9007,"eg":5751,"ef":3385,"ee":1918,"el":51949,"ek":22014,"ej":27806,"ei":3682,"ep":11390,"eo":6058,"en":103592,"em":54636,"et":33365,"es":44385,"er":89316,"ca":4919,"e ":246825,"bv":2259,"by":26507,"bs":4261,"br":9964,"bu":11101,"bn":7303,"bo":26250,"bj":2483,"bl":11541,"bi":8921,"bc":3044,"bd":1995,"be":13547,"dc":2442,"db":1918,"da":22450,"f ":2962,"cy":1677,"cu":2117,"ct":4541,"cr":1140,"co":10175,"cn":2818,"ck":45489,"ci":24104,"ch":106800,"ce":56738,"c ":9636,"az":14206,"ay":1595,"ba":13431,"d ":32945,"at":54683,"as":30808,"ar":43773,"ax":1424,"av":34552,"au":9271,"ak":35472,"al":52089,"ai":4202,"aj":15958,"ap":12841,"am":28407,"an":76603,"ac":26092,"ad":38615,"ab":9081,"ag":6085,"ah":10143,"ae":4121,"af":3809,"nu":14720,"nt":27386,"ns":25831,"ič":7118,"jí":23302,"no":57801,"nn":8311,"nz":2252,"ny":17200,"oe":1227,"ká":21030,"of":6319,"oc":21110,"od":69409,"oa":1996,"ob":47136,"ké":50289,"om":27583,"on":44356,"ok":26216,"ol":47354,"oi":2071,"oj":17875,"og":10937,"oh":13386,"ot":27460,"os":56160,"ov":112940,"ou":73196,"op":21879,"oo":2643,"or":53147,"r ":22705,"ox":1211,"ow":2081,"oz":27164,"lá":15416,"pe":15026,"pa":25836,"ký":35391,"pc":1302,"pl":12514,"lé":7239,"pn":3046,"po":81579,"ph":1918,"pi":14831,"eň":2211,"lo":61865,"ln":20483,"hé":2618,"lm":4934,"ll":7520,"ls":8702,"dů":3418,"lu":15908,"lt":4743,"lz":1355,"ly":9717,"o ":138337,"ma":25523,"eř":2784,"mb":4786,"hý":1516,"me":40325,"iá":5235,"ml":2209,"eš":4400,"mi":28342,"mn":8112,"mm":1350,"mp":4986,"mo":29298,"mr":1370,"ií":2470,"ms":3506,"mu":15591,"my":5631,"p ":4419,"na":97771,"nc":16128,"nd":14047,"ne":57176,"já":1158,"nf":2490,"ež":8504,"ng":13163,"ni":45831,"nk":8297,"jv":3866,"ju":1525,"eč":10324,"js":11164,"jn":5134,"jo":3496,"jm":7494,"ki":3600,"ke":11246,"kd":5064,"kc":3108,"ka":39832,"m ":95402,"ců":2079,"ky":30906,"kt":39344,"ku":33102,"kv":3857,"ko":71233,"kr":19435,"kl":18948,"km":3641,"kn":3161,"li":57563,"lk":10732,"le":77448,"há":9650,"ld":2521,"lf":1159,"la":65008,"dř":2617,"lc":1721,"lb":2945,"n ":43523,"hr":15902,"dí":8010,"hv":1306,"ht":2875,"hu":12412,"hi":7867,"hn":5204,"ho":73846,"hl":13059,"hm":1256,"dé":2586,"id":15111,"ic":65339,"dý":1471,"ib":5266,"ař":4683,"ia":10547,"ih":5555,"ig":6211,"if":3335,"eá":1247,"ie":19796,"hy":6927,"k ":33844,"ir":8411,"is":36532,"it":38607,"iu":2679,"iv":18333,"aš":1639,"ii":6209,"ij":4185,"ik":23953,"il":27036,"im":9173,"in":70373,"io":12386,"ip":4762,"je":121519,"až":7470,"ji":17967,"iz":8625,"l ":42283,"bř":2940,"ja":17600,"dě":13132,"xi":2953,"té":13825,"tí":14980,"pů":6675,"xt":1600,"z ":24530,"př":32632,"ož":13354,"tá":14232,"nž":1154,"oš":2365,"sé":1859,"sí":5664,"rč":2879,"nů":2947,"vy":26292,"vz":6628,"y ":96008,"rý":11309,"oř":9947,"wa":2470,"sá":2703,"we":1453,"vl":7295,"ré":10396,"vk":3052,"nš":1672,"vi":26093,"mž":1362,"vu":5429,"vr":8123,"vs":6209,"vn":24780,"vo":37739,"uz":6709,"mů":3291,"uv":3489,"ve":47740,"rá":30974,"vc":2056,"va":51428,"pě":4347,"x ":2742,"ui":1687,"uj":20016,"uk":7056,"ul":12653,"ue":2392,"ug":1937,"uh":10244,"ur":17880,"us":20839,"ut":14862,"um":13455,"un":12543,"up":13452,"ty":13294,"tz":1768,"tu":25069,"tt":3192,"lů":2536,"tv":17643,"ub":11697,"ua":2086,"ud":12808,"uc":6671,"w ":1552,"to":60100,"tn":18581,"tm":1809,"tl":6035,"ts":8087,"oč":8726,"tr":38784,"pí":3163,"te":85042,"pá":2981,"tk":8430,"ti":58581,"lš":2281,"th":6153,"v ":66402,"tb":1873,"tc":1257,"ta":58747,"ně":45741,"su":6657,"sv":12247,"ss":3706,"st":145711,"sy":7700,"ků":5193,"sl":22654,"sk":92692,"sn":8865,"sm":8745,"sp":20097,"so":35354,"sr":1708,"nč":1796,"sc":4718,"se":52884,"sh":2118,"si":15634,"rz":2926,"u ":121101,"mě":22506,"sa":15498,"kř":3224,"sb":1371,"ný":29623,"rr":2082,"rs":10884,"rt":11161,"ru":27381,"rv":11951,"ry":11066,"ní":119912,"rp":2592,"ro":116857,"rn":21334,"rm":10574,"né":26518,"rl":3217,"rk":6663,"ri":39119,"jš":5173,"rh":1365,"rg":7113,"iž":5869,"ná":41081,"re":36192,"rd":6788,"rc":6965,"mý":1831,"rb":3000,"ra":81349,"t ":42900,"mí":11983,"mé":6077,"iš":4295,"má":9760,"lý":4646,"s ":40054,"py":1779,"pt":3558,"pu":7668,"hů":2019,"lí":8097,"pr":57083,"ps":5342,"zý":1387,"zá":15336,"už":12787,"vš":5164,"zí":7043,"vů":2483,"uš":4102,"tš":4235,"vě":25419,"tř":15220,"tů":3818,"rž":1454,"vý":29752,"zh":2175,"zi":13719,"rš":2140,"zb":2038,"zd":9382,"ze":35435,"vá":31782,"tě":14576,"za":24684,"yz":2224,"rů":8094,"zv":6153,"zy":3702,"zs":3415,"uč":6510,"zr":1709,"zu":4066,"zt":1618,"zo":8118,"zn":27029,"ví":13118,"zp":5782,"zk":6049,"zm":2157,"vé":19370,"zl":2273,"yh":1425,"yc":3822,"yd":3200,"tý":6426,"yb":3071,"yv":3371,"yu":1291,"yt":7847,"ys":11111,"yr":3273,"yp":5097,"yn":5498,"ym":4086,"yl":23502,"yk":5878,"zš":1160,"yř":1210,"yš":3131,"ěžn":1182,"ám":8120,"án":28607,"áp":5503,"áj":1550,"ák":7074,"ál":25430,"áh":2531,"áb":3286,"ác":7677,"ád":11483,"áz":13195,"áv":12832,"ár":9720,"át":14731,"ás":12931,"á ":61028,"íč":1699,"ód":1198,"ón":1579,"éž":3751,"ív":7836,"íz":3776,"ín":7431,"ím":27488,"íp":2283,"ír":5728,"ít":5219,"ís":9896,"íh":10920,"ík":10708,"íl":6160,"íj":1652,"íc":36122,"íd":6139,"íb":1336,"í ":168172,"áž":2247,"él":1388,"áš":2438,"ém":16118,"én":5964,"ét":2091,"ér":4128,"ář":4474,"éd":1164,"éh":25602,"é ":80173,"áč":1328,"úč":1787,"ýc":33402,"ýz":2981,"ýv":5852,"ýs":1457,"ýt":1801,"ýr":2669,"ým":16378,"úz":3790,"ý ":58367,"ús":1640,"íš":1631,"íř":2525,"íž":4061,"ě ":45418,"ěh":2633,"ěj":8834,"ěd":3131,"ěc":1612,"ěz":2258,"ěs":10757,"ět":15295,"ěv":1529,"ěr":3724,"ěk":7417,"ěl":9917,"ěm":5852,"ěn":11047,"ěž":3582,"ěř":2184,"ýš":1701,"Če":5023,"či":11688,"čk":4324,"čl":2919,"če":26348,"ča":7771,"ď ":1420,"č ":2311,"čá":8501,"čn":16418,"čo":3182,"čt":3695,"ču":2648,"čí":6991,"ň ":2419,"š ":1248,"ří":28277,"řá":2554,"řn":1352,"ři":14008,"řs":2960,"ře":44896,"řa":3989,"ší":18419,"ť ":1589,"še":8882,"ša":2373,"šn":3181,"šk":3546,"šl":1812,"ši":4496,"št":7997,"ňu":1474,"ř ":4182,"žs":2453,"žn":8213,"žo":1725,"že":16587,"žd":1803,"žk":1495,"ži":11885,"ž ":17370,"ží":12326,"žá":1346,"ů ":27572,"ům":2630,"ůl":1327,"ůs":3997,"ův":4803,"ůz":2205,"šš":1500,"ůž":1940,"čás":7287,"čí ":1292,"čít":2030,"čís":1405,"čtv":1158,"čuj":2526,"ční":7738,"čné":1325,"čný":1279,"čně":1729,"ěji":2384,"ěko":1330,"ěkd":1747,"ělo":1511,"ěle":2558,"ěkt":1458,"ěme":3785,"ěls":1244,"ětš":3901,"ěta":1179,"ěto":2030,"ěný":1390,"ěst":9587,"ějš":4291,"ění":3741," Ga":1588," Ge":1446," Fo":1382," Fr":2926," Fi":1650," Ha":2917," He":2194," Gr":1717," Hr":1206," Ho":2982," Ji":2194," Je":8552," Ja":4310," In":2868," Ka":5019," Jo":1792," Ju":1242," La":2820," Le":3350," Li":3464," Kl":1383," Ko":4081," Kr":2542," Ku":1171," Ma":8133," Mi":3991," Me":3365," Lo":2542," Lu":1423," Ne":3375," Na":4212," Ni":1486," Mo":4565," Am":1697," An":3275," Al":3081," Ba":3436," Au":1408," As":1420," Ar":2370," Be":3213," Bi":1350," Bo":2981," Br":3935," Bu":2094," By":2085," Ca":2514," Ce":1267," Ch":3924," Co":3154," Da":2135," Di":1684," De":2001," Do":2665," Ev":1844," Př":2056," Wi":1593," Wa":1184," Vy":1684," Ze":1330," Za":1643," a ":53430," Zá":1320," Os":1166," Or":1230," Po":7138," Pl":1502," Pi":1231," Pe":2516," Pa":5464," No":2595," Ob":1764," Ra":2495," Ro":3640," Re":2567," Ná":1395," Pr":7523," Sv":1696," Su":1408," St":6100," Ně":1337," Ta":2426," V ":3746," Th":2108," Ti":1351," Te":3210," Tr":2526," To":2242," Ru":1883," Sa":3503," Si":1839," Sc":1168," Se":3406," So":3031," Sp":2664," Sk":1209," Sl":2578," Va":1650," Ve":3306," Vi":1986," Vo":1286," Tu":1143," ja":14129," dě":2397," bř":1481," ji":8392," až":2786," je":93301," in":6001," it":1175," ka":8683," m ":1247," kd":3115," ke":1672," jm":2892," js":6707," ha":1600," bě":2145," he":2509," dá":1402," cí":2459," gr":1666," k ":5918," hi":2201," hl":5156," ho":6862," dí":1705," hr":6552," hu":3075," ni":2426," ne":33309," na":43193," my":1417," mu":2661," mo":9457," mn":2424," ok":4623," oc":1666," od":14999," of":1957," ob":22345," no":3710," le":12637," li":8468," la":3675," dř":1310," kv":1829," ku":2340," kt":24717," kn":2205," km":3399," kl":3809," kr":8199," ko":16866," me":11211," mi":4779," ml":1339," o ":7191," ma":9419," dů":1272," lo":3118," ab":1328," am":3804," an":6347," ap":1198," ak":1935," al":5289," au":3694," ar":3304," at":1332," as":2951," ba":3819," bi":2222," be":2412," bo":3752," by":19260," bu":3054," br":3187," en":1401," el":2125," fa":1772," ex":2023," fu":1558," fr":2890," fo":4715," fi":6203," ge":1763," bý":3017," i ":5273," co":2133," ce":6243," ch":5478," da":4034," do":19631," dn":2609," dl":1361," dr":8732," de":7028," di":4948," dv":4297," du":1944," vý":12688," zk":2698," ví":2124," zp":3908," zn":6476," rů":1942," zv":2770," tě":2639," za":18239," zd":2577," vá":3060," ze":8914," tý":1167," té":5230," pů":4589," z ":20036," př":29127," vš":2884," už":1794," zá":11557," tř":3845," vě":4981," ru":2498," ry":1961," u ":3351," sa":3585," mě":10287," kř":2709," se":38618," sc":1843," si":3884," sn":1263," sm":2713," sl":8492," sk":7519," sr":1447," sp":14637," so":12794," mí":3137," ra":2856," ná":11985," re":10229," ro":31079," ní":1455," pr":44618," ps":1456," s ":10437," má":2572," os":6522," ot":1283," ov":1214," op":3355," or":4357," oz":5841," lá":1294," pe":2741," pa":10148," pl":5963," po":56929," vy":18421," vz":6214," sí":2537," pě":1240," va":1643," ve":20353," uv":1309," mů":1354," vo":5885," vr":1606," vi":2111," vl":5324," ty":2521," tv":3467," tu":1727," us":1203," ur":2603," um":2673," un":1389," ta":9553," ně":9405," v ":54233," sy":4875," st":28273," sv":11047," su":1768," pí":1932," tr":6193," to":5957," th":1725," ti":1444," pá":1635," te":10751," Če":5018," čí":2219," čá":5494," čt":2423," če":12226," čl":2635," či":5961," ča":2613,"ňuj":1462," ús":1372," úz":3683," úč":1533," šk":1284," řa":1815," ře":4682," ří":3390," ži":4198," že":3745,"Evr":1575,"Fra":1982,"šší":1462,"ším":3926,"šíc":3060,"Byl":1846,"šíř":1269,"ší ":8873,"Cha":1224,"Nov":1143,"Par":1206,"Pro":2287,"Pra":2828,"Pod":1248,"Pol":1195,"ůzn":1758,"ůso":2743,"ůvo":3624,"Jed":1974,"Jeh":1143,"Je ":2998,"ům ":1924,"Kar":1595,"Mar":2760,"řez":1271,"řev":1736,"řet":1507,"řes":3291,"řen":6131,"řel":1284,"ři ":4648,"řed":13088,"řej":1316,"řek":2349,"řeb":1351,"řec":3115,"ře ":3029,"řad":2628,"ého":25401,"ém ":11396,"řsk":2573,"áře":1219,"ému":2422,"éna":1816,"éno":1417,"éri":1326,"Sta":2172,"Spo":1540,"Slo":1556,"Vel":1392,"The":1321,"šec":1390,"šen":2332,"še ":1844,"šak":1283,"šti":2097,"šní":1582,"ško":1848,"šin":1751,"ště":3036,"átu":1328,"bje":2435,"áte":1666,"átk":2625,"átn":2002,"áto":1624,"bit":1438,"ást":9035,"bil":2518,"bo ":10795,"ávi":1211,"bli":4783,"ávn":2176,"bla":3565,"áva":2824,"bod":1239,"bol":1903,"boj":1202,"blí":1257,"ázv":1186,"ává":2557,"áze":5164,"bor":3758,"bov":1176,"bou":1297,"álk":1854,"áln":9542,"álo":2573,"álu":1211,"ákl":2414,"bal":2672,"áko":1419,"án ":4623,"ále":4254,"bar":2156,"áli":1317,"áns":1949,"bdo":1660,"áno":2096,"ány":1316,"ánu":1360,"ámo":1148,"bce":1301,"ána":2621,"áni":1332,"bec":2884,"ber":2768,"ben":2163,"bez":1903,"ápa":4357,"ámě":1142,"ání":9623,"át ":2061,"áro":4387,"árn":3371,"ámý":1162,"áda":1737,"ách":3663,"áce":1349,"ádá":1824,"ábě":1152,"ca ":1459,"ák ":1153,"ál ":2023,"ce ":37517,"ám ":1274,"bri":1805,"bro":1589,"bra":3506,"bu ":2220,"bní":3217,"bsk":1200,"bsa":1785,"bur":1260,"bud":1860,"bvy":1413,"by ":4307,"byl":18860,"byv":1815,"am ":2742,"ake":1229,"aji":2410,"al ":7387,"adě":2234,"aje":2039,"ak ":5398,"ahu":2375,"ahr":2506,"aha":1562,"ací":4252,"aké":5289,"anu":1370,"any":1635,"ano":3773,"ann":1847,"ant":5679,"ans":3967,"ají":6907,"ane":2662,"ang":5036,"ani":8977,"ank":1763,"ana":4560,"anc":5148,"and":5394,"amu":1194,"amo":2812,"amn":1598,"ami":3729,"ame":8001,"ama":1900,"aly":1179,"als":1998,"alo":7874,"all":1742,"ali":6637,"ale":6714,"ala":3987,"alb":1604,"an ":5076,"aku":1247,"akt":3867,"ako":12804,"abe":1141,"abs":1339,"ae ":1943,"ad ":4944,"afi":1777,"age":1161,"ael":1206,"ado":1550,"adl":1340,"adn":6465,"adi":3651,"ade":3282,"ady":1580,"adu":2552,"aco":1432,"aci":3453,"ach":6559,"ace":7532,"ada":3897,"arš":1293,"azu":1350,"aze":2771,"azy":2655,"até":1146,"apř":2101,"ba ":3672,"azý":1373,"avě":1439,"atř":2572,"at ":6248,"aná":3560,"are":2437,"ard":3288,"arc":2227,"ara":4391,"aro":4126,"arn":1320,"arm":1290,"ané":4536,"arl":1695,"ark":1851,"ází":4141,"ari":4139,"ars":2390,"art":3122,"asa":1162,"amě":1185,"asi":3609,"aný":5688,"ase":1167,"aso":1587,"asn":2528,"ask":1257,"ar ":2605,"alá":1216,"ape":1349,"alé":1624,"apo":2941,"as ":2058,"alý":1783,"ava":3516,"aut":3726,"avs":1166,"avo":2741,"avn":5290,"avi":3981,"ave":3850,"avy":1957,"avu":1943,"av ":1604,"ata":3060,"aně":2278,"ast":13117,"atn":1969,"atk":1885,"atr":1563,"ato":5121,"ate":11112,"ati":10351,"alš":1631,"atu":2078,"aur":1970,"řád":2065,"ří ":6262,"řív":1184,"říz":2145,"říc":1240,"říp":1616,"řís":1609,"řím":2008,"řík":1716,"říd":3286,"říž":1421,"až ":2790,"jeh":3911,"jej":4795,"jed":12881,"jek":1841,"jem":2659,"jen":5483,"jev":2523,"ji ":4802,"ažd":1260,"bře":2487,"děl":3685,"jak":10723,"děn":1255,"děj":2198,"jaz":2568,"je ":83650,"jme":2592,"jno":1257,"jov":2720,"jin":3546,"jih":2344,"jic":2414,"ito":2582,"itu":2506,"its":1828,"ity":1661,"isk":2395,"ism":2509,"isl":2097,"iso":2022,"ist":15778,"ině":2331,"ita":3897,"ite":5726,"iti":3568,"ivo":2672,"ivn":3856,"ium":1381,"iva":2483,"ivi":1448,"ive":2466,"is ":3839,"ion":6938,"iro":1733,"irm":1303,"ise":1488,"iný":1514,"iná":3960,"it ":3805,"dě ":4195,"itý":2115,"ití":1214,"ité":1984,"itá":1643,"izo":2349,"iza":2404,"km ":2378,"kdy":3252,"kej":1210,"kem":3800,"ket":1376,"ke ":1607,"kce":1649,"kde":1621,"kra":5687,"kre":3334,"kt ":1234,"ku ":19613,"kro":2033,"kov":11417,"kou":9659,"kos":4285,"kor":1310,"kop":1321,"kon":10573,"kom":4572,"kol":7494,"úze":3480,"klá":2870,"kni":1628,"klu":1477,"ko ":14736,"kle":2073,"kla":8470,"klo":1299,"jso":6864,"jsk":2959,"ečn":6772,"jmé":3893,"eče":1504,"již":2514,"kaz":1148,"kat":3393,"kar":1707,"kap":1616,"kan":2047,"kal":2034,"kam":1509,"kac":1503,"ka ":20272,"jvě":1879,"ha ":4741,"bě ":2724,"han":1905,"hal":1464,"har":2922,"běh":2126,"he ":2188,"dá ":2060,"dál":1753,"dáv":1525,"her":2617,"dán":2244,"hem":3497,"his":2398,"běž":1211,"hla":5571,"hle":2243,"hlo":1435,"ho ":41844,"gli":3394,"cí ":18956,"cíc":3683,"gra":4857,"cím":1211,"ial":1377,"ian":1754,"ic ":2965,"ibl":1394,"ia ":4182,"ien":1656,"aří":2027,"ier":1153,"ifi":1720,"ict":1675,"ick":33133,"ici":3981,"ich":6375,"ice":11279,"ie ":13367,"ica":1513,"ido":1643,"idl":1498,"ide":3474,"ida":1748,"il ":4856,"ika":5332,"ii ":5869,"igi":1176,"icí":1825,"iho":2925,"ik ":2696,"imo":1396,"ime":1223,"inc":4325,"ind":2184,"ina":8223,"inn":2167,"ino":5250,"int":2630,"ins":4625,"inf":1536,"ine":3495,"ing":4248,"ini":3264,"ink":1380,"iká":1715,"inu":3551,"iny":6607,"iko":2695,"ikl":2333,"ila":2431,"in ":6095,"iky":3097,"ikt":1203,"iku":2133,"ilo":3489,"ill":1963,"iln":1971,"ilm":2591,"ili":3988,"ile":1526,"hok":1282,"hol":1704,"hot":1459,"hou":1879,"hov":5549,"hor":3514,"dí ":3801,"hod":8706,"hni":1267,"huj":1855,"hud":2458,"hu ":4702,"hro":1617,"hrn":1403,"hra":7196,"díl":2411,"hyb":1243,"hož":1183,"hy ":3116,"hum":1365,"hrá":2941,"evš":1525,"ext":1409,"etí":2247,"exi":1437,"ezn":2836,"eze":2667,"ezi":7262,"eně":1924,"eta":2522,"ete":4466,"eti":3348,"etn":2128,"esp":1404,"esn":2468,"eso":1292,"est":7801,"ev ":3656,"eto":3093,"etr":4039,"erá":7485,"eve":6187,"evn":2175,"eré":8410,"evi":2322,"erý":10219,"er ":7795,"eor":1444,"es ":7550,"epu":2593,"elé":1267,"epr":1430,"eri":9740,"erg":1674,"ere":2706,"ená":5438,"era":5702,"et ":4584,"emí":4275,"esk":11348,"esi":1360,"ený":6913,"ese":3215,"emě":2087,"erz":1749,"erv":3468,"eru":1909,"ení":16758,"ert":1878,"ers":3684,"ern":7190,"erm":2474,"ené":4823,"ero":6299,"ekl":1253,"eko":2098,"ekt":6413,"en ":12357,"ela":2337,"ele":12125,"eli":4792,"elm":1412,"eln":3331,"elk":5262,"ell":1825,"elo":2426,"els":2269,"ema":1842,"eme":2383,"emn":1840,"emo":2184,"emi":4395,"ene":4580,"ena":4918,"end":1571,"enc":3468,"eno":6243,"enn":2162,"eni":2669,"ens":7642,"ent":12967,"ejí":5227,"eny":2102,"egi":1835,"ej ":1214,"edí":1331,"eho":5425,"ek ":7971,"ein":1192,"el ":8637,"ejs":2194,"ejn":3303,"ejm":2020,"eji":2735,"em ":31739,"ejv":3622,"gin":1170,"gio":1330,"gie":2007,"gic":2475,"gii":1170,"gen":3213,"býv":3044,"být":1189,"gan":3061,"ga ":1144,"íže":1335,"íž ":1472,"fun":1501,"fra":2633,"ače":3487,"ačo":2232,"ačn":3017,"aču":2194,"for":4925,"fot":2015,"bí ":2241,"fic":2581,"fil":3337,"fik":2015,"fin":1574,"fir":1363,"da ":6390,"de ":6350,"dal":3374,"daj":1518,"dat":3084,"dan":2182,"dce":1208,"ctv":1837,"cně":1190,"cko":3237,"chá":6943,"cky":4430,"ciá":2350,"co ":1224,"cká":6180,"cké":15214,"cov":2906,"cou":2423,"cký":12856,"ch ":62063,"ces":2551,"cen":5710,"cem":1899,"cel":4240,"ci ":10328,"cha":4867,"chu":1777,"chy":1469,"cia":1607,"cie":2249,"che":3452,"chl":1932,"chi":2422,"cho":11778,"chn":2940,"cht":1572,"chr":1838,"ed ":3026,"ebn":2564,"ebo":12455,"ec ":4754,"edl":1223,"edm":1145,"edn":17139,"edi":5930,"ede":6652,"eda":1810,"edy":1655,"eds":1915,"edo":3095,"eck":8996,"ech":12275,"eci":1513,"ecn":1350,"dy ":11421,"drá":1267,"dvo":3395,"dva":1139,"dor":1289,"dop":2114,"dom":1869,"dol":1600,"dok":1496,"dov":6030,"dou":1896,"dos":2695,"dpo":1574,"dna":2226,"dne":2707,"dni":1534,"dno":8163,"dob":7531,"dst":2606,"íře":1323,"dně":4952,"duc":1342,"dné":1547,"dra":2227,"dná":2916,"du ":8252,"dro":2166,"dní":18004,"dru":7228,"dsk":2773,"dic":1916,"dia":1263,"der":3512,"des":2009,"dev":1882,"deb":1947,"dec":1456,"del":3171,"den":6683,"dem":3354,"di ":2989,"dle":4381,"dla":1946,"do ":8212,"dlo":2844,"div":1579,"din":4766,"dio":1325,"dis":2494,"die":1484,"rga":2761,"rgi":1143,"ižn":3600,"ret":1327,"res":5841,"nás":2254,"náv":1475,"rez":1829,"náz":3803,"rač":1242,"iž ":1205,"rea":1647,"nác":1291,"rec":1925,"reg":1788,"nám":4897,"rem":3700,"ren":2252,"rek":1273,"nál":3115,"nár":3570,"rep":3246,"rdi":1273,"ná ":14630,"re ":2546,"rch":3978,"rce":1159,"raz":3775,"rd ":1372,"ras":1475,"rat":6479,"rav":9308,"raj":4559,"rah":1855,"ran":13598,"ram":4289,"ral":1943,"rak":3296,"rab":1667,"raf":2398,"rad":5238,"rac":4788,"ros":9033,"rot":4473,"rom":4735,"ron":3499,"rop":5057,"roz":10708,"rou":3738,"rov":17134,"rob":3794,"rod":11155,"roc":8820,"ní ":79844,"roj":4450,"rol":2078,"rok":8745,"rof":1452,"rog":2059,"rno":1887,"rnu":1168,"rna":1957,"rež":1163,"rni":1331,"ném":2468,"rmo":1370,"jší":4959,"ro ":11368,"rma":3339,"riá":1833,"néh":5048,"né ":18438,"raž":1181,"rit":3911,"ris":3258,"rig":1476,"rik":1662,"rin":2410,"ria":2007,"ric":8579,"rid":1291,"rie":3806,"rk ":1359,"ryc":1171,"ruh":6961,"rum":1222,"ruk":1449,"rus":3302,"rva":1915,"rve":2525,"rvn":4272,"ry ":6263,"rsk":6183,"rně":2168,"rst":1339,"rto":1577,"rti":1692,"rub":1147,"rtu":1152,"ním":14655,"ník":6579,"níh":7211,"rmá":1574,"níc":9560,"rt ":1561,"rné":1326,"ru ":6692,"rní":7275,"sah":2489,"měl":2079,"sam":2091,"nýc":8901,"ným":4766,"měn":2340,"san":1523,"sau":1548,"měs":9181,"měr":2410,"sa ":1633,"mě ":2287,"ruž":1312,"ný ":15629,"si ":3518,"měř":1748,"sin":1775,"sil":2216,"se ":32266,"sch":2059,"sev":4239,"ser":1773,"sed":1877,"kří":1234,"sen":1348,"sem":1612,"sel":1714,"spo":10422,"spr":1930,"spe":2260,"spi":1842,"ský":19060,"sou":17153,"sov":4194,"ské":26627,"son":1432,"ská":8637,"sof":1375,"soc":1565,"sob":5198,"su ":2847,"sní":1788,"sné":1153,"st ":11395,"slo":9919,"slu":2567,"sky":9407,"sla":4078,"sle":3342,"skl":1707,"sko":9797,"sku":8770,"ska":4807,"ske":1405,"sni":1352,"smu":2054,"stí":6180,"sté":3269,"stá":6877,"syn":1327,"sys":2806,"stě":3272,"své":1798,"smě":1301,"ste":9093,"sně":1417,"sta":23517,"stn":5308,"sto":14050,"sti":18925,"stl":1904,"stv":6645,"stu":6506,"str":16919,"sts":1291,"ků ":4430,"sty":1890,"sva":1646,"svo":1261,"sy ":1657,"něj":4079,"tak":7734,"něk":4566,"něl":1306,"tal":4758,"tac":1310,"tad":1311,"tba":1700,"tav":8149,"tat":3631,"tas":1264,"tar":5738,"tan":5175,"něn":3988,"něm":4105,"te ":2317,"svě":5020,"stř":6161,"éž ":3711,"ně ":25254,"ta ":12315,"ký ":20031,"ouž":6121,"ozá":1627,"pa ":1199,"ově":6255,"lá ":1917,"kýc":10186,"kým":4999,"par":3389,"pat":3635,"pad":7309,"pak":1199,"pal":1582,"pam":1204,"pan":2500,"pec":1647,"lád":4346,"lán":1802,"pen":1946,"per":4148,"lát":1414,"pla":3524,"ple":1738,"plo":2559,"lé ":2839,"pic":1267,"pin":4585,"pis":3803,"poz":3018,"por":4291,"pop":2679,"pov":4058,"pou":6174,"pot":2565,"pos":5385,"poj":5321,"poh":2575,"pom":2458,"pon":2428,"pok":1746,"pol":12866,"pob":1330,"poc":1426,"pod":13049,"láš":1492,"po ":3633,"lí ":2188,"psk":1538,"hů ":1499,"pub":3056,"poč":3912,"pra":9290,"prv":4970,"psa":1291,"pu ":1292,"pri":1503,"pre":2679,"pro":30809,"prá":4755,"poř":1288,"py ":1312,"prů":1838,"lý ":2387,"má ":3426,"mát":1458,"mán":1640,"išt":1515,"mén":4741,"mí ":3982,"mís":2771,"mír":1517,"mín":2069,"ra ":9350,"eži":1875,"ngl":4299,"ni ":2504,"nge":1442,"nej":9246,"nek":1332,"nen":1766,"nem":4884,"nep":1631,"ner":3084,"net":2605,"nes":3430,"ež ":1798,"ng ":3190,"neb":12487,"nec":2031,"ned":1356,"nfo":1282,"nač":7033,"nez":1422,"nco":2679,"nci":5166,"nce":5874,"ne ":3607,"ndo":1521,"ndi":1883,"nde":1639,"nda":1497,"nak":1732,"nal":3376,"nam":6213,"nan":1425,"nap":3429,"nar":1416,"nac":3724,"nad":3749,"nd ":2404,"nav":1415,"nat":3143,"nas":1417,"naz":1632,"na ":53204,"mys":1461,"mož":1630,"nož":1329,"ny ":15609,"nuj":1460,"nut":2319,"nto":3206,"ntu":1650,"ntr":2728,"nti":4061,"nta":3294,"nte":4199,"nst":3785,"nsk":18177,"nu ":7672,"ičn":2337,"nné":1576,"nt ":3215,"jím":1621,"jíc":10934,"noh":2321,"nol":1273,"nom":2363,"not":3595,"nos":13323,"nor":2008,"nov":9782,"nou":8746,"než":1270,"nno":1485,"nič":2090,"jí ":9261,"neš":1391,"no ":7023,"nka":1355,"nko":1306,"eží":3799,"nih":1649,"nie":1760,"nic":12884,"niz":2240,"niv":1387,"nis":3526,"nit":3056,"nin":2133,"nik":6308,"ogr":3240,"ogi":4525,"odí":1145,"ohl":1659,"oho":4168,"oha":1909,"obě":2552,"oj ":1676,"ok ":1263,"ohy":1525,"ojo":1142,"ojm":1998,"oji":1192,"oje":7276,"odě":2068,"obř":1215,"ol ":1430,"oce":9242,"och":4480,"oci":2151,"ock":1389,"obs":1745,"obv":2042,"obu":1622,"oby":3426,"ká ":15983,"ode":4045,"odl":3777,"odi":2898,"odo":4607,"odp":1587,"odn":14263,"ods":1272,"odr":1258,"of ":1489,"oda":2197,"kán":1145,"ody":1671,"odv":1246,"odu":5226,"ofi":1587,"obí":2810,"oba":1485,"od ":15166,"obo":2639,"obr":2915,"obl":4657,"obn":3328,"obj":2067,"obi":2455,"obd":1788,"obc":2803,"obe":3958,"ový":12973,"orů":1170,"ové":14190,"ozn":6156,"ozl":1181,"ouč":4572,"ozo":1460,"ozd":2636,"oze":3842,"ová":16410,"ozi":1341,"oty":1225,"oud":1374,"oub":1598,"ouc":1601,"otk":1156,"oti":3017,"ote":2572,"oto":6726,"otn":1824,"ost":32198,"ota":1788,"otb":1150,"ov ":3056,"osi":1402,"osk":1491,"ose":1306,"osp":1323,"osm":1339,"osl":4606,"oso":3077,"ovy":1368,"ovi":10902,"ovn":5524,"ovo":6751,"ovs":3742,"ouz":3479,"ova":19936,"ove":6197,"ouh":2082,"oun":1766,"oup":1457,"ous":3223,"out":2402,"opo":2402,"opi":2216,"ope":2692,"opa":2307,"os ":1967,"opu":1150,"opr":3218,"olí":1626,"ops":1833,"or ":5513,"ork":1330,"orm":4795,"orn":2809,"oro":4330,"ord":1649,"ore":3272,"oná":1885,"org":3417,"ori":6242,"ou ":37147,"omě":1557,"osa":2963,"ort":3045,"ors":1818,"oru":3220,"ory":1722,"omá":2183,"ora":3762,"ívá":2944,"íze":1985,"ola":2087,"on ":7329,"oli":8828,"ole":10375,"ols":1995,"oln":2388,"olo":8650,"oly":1795,"olu":2611,"oka":1642,"om ":1785,"íst":3954,"ké ":30775,"ísl":1496,"oke":1629,"íta":1783,"okr":4661,"oko":4002,"íků":1200,"oku":8537,"ona":3352,"ond":1711,"onc":1948,"one":2668,"ong":1188,"oni":3548,"ono":3674,"ons":4146,"ont":3048,"onu":1779,"ony":1528,"oma":2266,"ome":3465,"omi":2447,"kéh":13733,"kém":5563,"omp":1767,"omo":5000,"omu":2175,"íva":3319,"la ":20221,"ími":2048,"íms":1206,"íns":1474,"ím ":20382,"kvě":1156,"ín ":1890,"íle":1385,"le ":15329,"íro":1439,"írk":1295,"íse":1140,"lac":1653,"lad":8838,"ípa":1629,"lan":4986,"lam":1157,"lat":5358,"las":7702,"lav":8047,"krá":4170,"kup":4964,"kum":1330,"kul":2572,"ky ":27061,"ích":18473,"kte":27582,"íce":2062,"ídl":1751,"ců ":1941,"ktr":2141,"ktu":2012,"kti":3026,"kto":1589,"kyt":2072,"ík ":3909,"ící":14415,"ího":9884,"lok":1275,"lon":1573,"lké":1191,"lom":1730,"lod":1650,"loh":1236,"log":5594,"lký":1221,"los":3409,"lou":5777,"lov":17182,"lni":1153,"lež":2967,"lič":1203,"lmi":1186,"ltu":1148,"dů ":1701,"lub":1957,"lsk":6596,"lně":2708,"lné":1553,"lní":11343,"lu ":4880,"lný":1549,"liš":1271,"li ":6590,"lez":2008,"ház":6195,"lev":1768,"les":3807,"let":9902,"ler":1221,"lem":5693,"len":8028,"lek":3907,"lej":1379,"led":7715,"lec":1964,"eň ":1751,"lo ":9285,"lla":1318,"lle":1365,"lli":1334,"lko":2458,"lky":2194,"lka":1525,"leč":4689,"hé ":1767,"lm ":1297,"ll ":1176,"lit":5959,"lis":4420,"lin":6175,"liz":1555,"liv":3315,"lic":7730,"lid":2928,"lia":1350,"lik":5494,"lig":1241,"lie":1691,"ma ":3621,"mac":1223,"maj":1332,"mar":1328,"mal":2994,"man":3894,"mat":5599,"me ":1813,"med":1375,"mec":4748,"met":4900,"mer":5988,"mem":1269,"iál":4186,"men":11122,"mez":6394,"ly ":6413,"lož":5290,"moc":2506,"mob":1461,"mod":2374,"mon":2073,"mov":3077,"mor":1679,"mos":2024,"mot":2793,"mou":1328,"mní":1927,"mu ":8025,"msk":2845,"moř":3176,"my ":2400,"mus":1983,"mun":1943,"mi ":12425,"ešn":1222,"min":3830,"mil":1861,"mis":1525,"ešt":1436,"mic":2749,"mo ":1420,"ií ":2195,"mno":2859,"tří":4710,"tši":1374,"tší":2640,"ůže":1655,"Čes":3563,"vě ":4735,"věz":1289,"vět":11745,"tři":1228,"věk":2228,"tře":8474,"věd":2018,"výr":2025,"výs":1250,"vým":2640,"výz":2611,"výš":1486,"čas":5969,"zná":4232,"uča":1905,"zní":1327,"víc":1941,"čen":7616,"čel":3765,"čet":1680,"čes":6771,"čer":2858,"zný":1440,"zu ":1323,"zsk":2646,"učá":1855,"či ":4977,"rů ":3148,"zuj":1535,"čit":1616,"způ":1462,"čin":2747,"růz":1961,"čka":1735,"zyk":1998,"čle":1629,"čov":3019,"vý ":6798,"čno":3388,"výc":8997,"zi ":5006,"zač":1189,"zej":2847,"zev":2458,"zen":7446,"ván":11057,"zem":8432,"vál":2700,"zel":1300,"zer":1349,"vá ":12375,"ze ":9310,"zde":1205,"zab":1246,"zac":2566,"těj":1439,"zah":1842,"těn":1733,"zal":3135,"těl":1552,"zas":1298,"ví ":7249,"zor":1418,"zov":3172,"zpr":1480,"vém":1518,"rší":1390,"véh":3281,"zna":13601,"zni":4038,"vé ":13437,"zko":1259,"zkr":2046,"zdí":1212,"zař":1286,"zin":1828,"zit":1344,"zdě":2035,"těž":1441,"yrá":1302,"yva":1858,"ytu":1246,"ytv":1652,"yto":1723,"yst":4390,"yso":1389,"ysk":1190,"ysl":1771,"tě ":5527,"za ":5089,"ych":2524,"tým":1477,"tý ":2037,"týc":2116,"ykl":2523,"yla":6390,"ylo":2929,"yly":1314,"yl ":10326,"tím":1511,"tém":3602,"tí ":11245,"též":3726,"pův":2875,"půs":2701,"ože":4937,"ožn":1513,"oži":1506,"tán":1850,"pří":8711,"tát":4498,"ož ":2063,"tál":2187,"té ":3506,"xis":1170,"př ":1535,"tá ":1819,"při":7219,"pře":14856,"sér":1644,"síd":1352,"rče":1253,"oří":2027,"vzn":2563,"vzd":1455,"vyk":2012,"vyr":1739,"vyd":1992,"vys":3366,"vyt":1966,"vyv":1398,"rý ":8817,"vyš":2053,"rýc":1165,"oři":1304,"oře":3041,"vní":15429,"vro":2455,"vrc":1706,"vst":1754,"vsk":4082,"vu ":2977,"nů ":2566,"vně":2710,"vuj":1416,"vy ":4952,"voř":3595,"vil":1507,"vin":6325,"vic":2325,"vid":2543,"viz":1532,"vit":4611,"vis":2095,"ré ":7668,"vla":2806,"vo ":2147,"vna":1206,"vno":1207,"vni":1709,"vod":8774,"voj":3429,"vol":2921,"vor":1476,"vot":1529,"vov":1657,"vou":5924,"voz":2714,"vlá":2701,"vi ":1398,"ver":8833,"ves":2177,"rát":2382,"ráv":4812,"mž ":1199,"rán":2154,"ven":9163,"vem":1785,"rál":6073,"vel":5581,"ráb":1423,"ved":2640,"rác":2253,"ve ":12748,"rá ":6574,"val":7096,"van":12007,"var":2621,"vat":8883,"pěv":1148,"vaz":1671,"vac":2111,"vad":1154,"vaj":2879,"můž":1309,"va ":9872,"uze":1855,"uzs":2041,"utí":1162,"urč":2415,"usk":3978,"use":1494,"umě":1413,"ust":3573,"ute":1270,"mů ":1642,"uto":4678,"us ":7285,"ut ":1210,"ura":2035,"ure":1155,"uri":1389,"urn":1235,"uro":1540,"uru":1160,"ury":1381,"upi":4594,"upe":1451,"upn":1306,"umo":1169,"umb":1314,"ume":1179,"ují":7869,"unk":1600,"uni":2964,"uko":1228,"um ":4532,"ult":2459,"ulo":1228,"uhé":1788,"uli":1303,"ula":1664,"uje":11818,"ucí":1196,"uho":1206,"ude":2608,"udi":1376,"ubo":1407,"uce":1140,"uch":2624,"uh ":1827,"udo":2156,"ub ":1463,"ubl":3299,"ud ":1221,"trů":1395,"tví":6726,"typ":2401,"ty ":7625,"tvr":1530,"očí":2254,"tvo":4249,"trá":2691,"tva":2695,"tur":4631,"tuj":2396,"tup":3639,"tud":1736,"pís":1810,"oče":1902,"tre":1691,"tra":10732,"tné":1153,"oči":1195,"tri":3505,"tru":3242,"tro":11520,"očn":1259,"tní":9445,"tu ":7164,"tný":1437,"tsk":6630,"tně":1562,"lů ":2152,"to ":14761,"lší":1771,"tna":1155,"tno":1779,"toh":1166,"tou":3172,"tov":8578,"tos":1217,"tom":3677,"ton":3319,"tok":1791,"tol":3953,"tor":9066,"top":2079,"til":1384,"tik":3154,"tit":2068,"tis":2205,"tin":7629,"tio":2588,"thu":1152,"tic":11897,"teč":1644,"tiv":5666,"tko":1227,"tka":3033,"tli":2690,"tky":1508,"tla":1310,"tem":4570,"ten":3204,"teo":1298,"tej":1972,"tek":2779,"tel":12611,"tec":6325,"ted":1925,"tev":1290,"ter":37331,"ti ":14561,"tač":2083,"the":1375,"ží ":4449,"žíc":1641,"žív":5443,"yšš":1364,"zýv":1380,"žil":1490,"živ":2602,"žit":2707,"žij":1345,"žov":1554,"že ":5417,"žel":1619,"žen":7485,"záv":1903,"záp":4090,"zák":3066,"uži":2255,"ýt ":1211,"ýro":1252,"ým ":11479,"ými":4161,"žní":2919,"ých":32937,"žsk":1623,"žně":2362,"vší":1568,"zí ":4964,"vša":1280,"vše":1958,"uží":6581,"tů ":3433,"ýzn":2182,"ývá":1959,"ýva":2863,"uše":1228},"n_words":[11333226,13010717,8780627],"name":"cs"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/dan b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/dan new file mode 100644 index 000000000..23e865876 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/dan @@ -0,0 +1 @@ +{"freq":{"D":31963,"E":16857,"F":19795,"G":13674,"A":25625,"B":25733,"C":16797,"L":17275,"M":22557,"N":16361,"O":9041,"H":24577,"I":12015,"J":9674,"K":25355,"U":7743,"T":19455,"W":7598,"V":12180,"P":17849,"S":49336,"R":17256,"Y":1840,"Z":1413,"f":221888,"g":349504,"d":493190,"e":1436845,"b":166372,"c":57573,"a":587527,"n":746797,"o":488340,"l":487393,"m":293320,"j":42561,"k":286164,"h":119659,"i":613022,"w":11095,"v":176622,"u":183003,"t":621215,"s":567338,"r":850344,"q":1336,"p":139855,"z":8890,"y":86732,"x":5939,"Å":1900,"Ø":2784,"é":2737,"æ":62497,"å":62645,"ä":1464,"ü":1583,"ø":71666,"ö":1579," l":35858," m":66057," n":25041," o":98877," h":49372," i":113380," j":6194," k":49552," d":112412," e":192889," f":104584," g":23827," a":95172," b":68676," c":8562," u":24358," t":58677," w":1082," v":42657," p":52152," s":123480," r":22226," J":9634," K":25242," H":24422," I":11943," N":16289," O":8943," L":17176," M":22363," B":25561," C":16566," A":25498," F":19659," G":13552," D":31783," E":16778," Z":1391," Y":1835," S":49095," R":17196,"а":1047," P":17741," W":7540," V":12125," U":7720," T":19345," å":3941," æ":1756," ø":5351," Å":1898," Ø":2782,"A ":4032,"F ":2501,"Da":6717,"Cl":971,"Co":3707,"Ce":1101,"Ch":3540,"Do":1568,"De":17413,"Di":2020,"Fe":1146,"Fa":2183,"Eu":1618,"Er":1008,"Et":1623,"En":5373,"El":1343,"Ge":1911,"Ga":1871,"I ":3326,"Fr":4782,"Fo":3851,"Fl":1651,"Fi":2355,"C ":1471,"Au":1064,"Ar":2625,"As":2462,"Ba":5317,"Aa":1418,"Am":3646,"An":3500,"Al":3794,"By":1617,"Bu":1524,"Br":3812,"Ca":3808,"Bi":1743,"Be":3864,"Bo":3085,"Bl":1436,"Kl":1826,"Kr":1747,"Ko":8878,"Le":2792,"Li":3203,"La":5071,"Lu":1291,"Lo":2732,"Me":3324,"Mi":3899,"Ma":7557,"Mu":1568,"Mo":3310,"Ni":2023,"Ne":2682,"Na":2422,"No":4840,"Gi":973,"Gr":3579,"Go":1190,"Gu":1554,"Ha":6824,"He":6629,"Hi":1514,"Ho":4306,"Hu":1589,"In":3339,"Is":1195,"Ja":2348,"L ":1217,"Je":1924,"Jo":2770,"Ju":1199,"Ka":3252,"M ":1238,"Ki":2897,"Ke":1081,"Un":2388,"Ty":1556,"Tr":2242,"To":2011,"Th":4228,"Ti":1419,"Te":2146,"Ta":2888,"Sy":2480,"St":10943,"Sv":1640,"Su":1509,"Wo":997,"Wi":1997,"Wa":1860,"We":1192,"Vo":988,"Vi":3450,"Va":1711,"Ve":4334,"Pr":4633,"S ":1850,"Pe":2483,"Pa":3757,"Po":2392,"Pi":1096,"Or":1531,"Kø":2561,"Se":2517,"Sc":1974,"Si":2298,"Sh":1188,"Sl":1960,"Sk":3103,"Sp":1977,"So":7973,"Ru":1537,"Sa":4145,"Re":4467,"Ri":2574,"Ro":3970,"Ra":2483,"b ":7025,"a ":44327,"Yo":1017,"Sø":1957,"bø":1832,"i ":102076,"fy":1735,"gd":2544,"ge":89823,"ga":13601,"gb":1002,"bæ":1473,"fj":1452,"fl":7833,"ff":4196,"fi":15203,"bå":1373,"fh":1152,"fs":1525,"fr":23015,"fu":3863,"ft":15592,"fo":54992,"j ":3361,"gy":1588,"he":22182,"ha":30491,"gn":17858,"gl":6422,"gi":15986,"gh":4618,"gg":16392,"gu":4973,"gt":15761,"gs":16863,"gr":16831,"go":3646,"dt":26827,"du":5081,"dv":6155,"dy":2631,"g ":111365,"ea":8665,"eb":9181,"ec":4319,"ed":75055,"de":218146,"dd":6228,"dg":5250,"df":2420,"di":20969,"dh":1605,"dk":4450,"dj":1187,"dm":1943,"dl":12465,"do":7994,"dn":3058,"ds":29024,"dr":12885,"ew":2085,"ex":1370,"eu":3377,"ev":22509,"ey":2555,"ez":1521,"fa":10884,"h ":6139,"fe":8693,"eh":3909,"eg":21663,"ef":12940,"ee":3853,"el":91687,"ek":16142,"ej":9330,"ei":7265,"ep":6194,"eo":4491,"en":269379,"em":29799,"et":141301,"es":67128,"er":363438,"ca":5613,"e ":256545,"by":15888,"bs":2188,"br":14152,"bu":7411,"bo":14081,"bj":2063,"bl":20954,"bi":8379,"bb":2090,"be":49808,"db":9039,"da":25268,"f ":48816,"cu":1080,"ct":2015,"co":4730,"ck":5340,"ci":7534,"ch":11084,"ce":13957,"c ":1829,"az":1010,"ay":3869,"ba":15017,"d ":83491,"at":56481,"as":18978,"ar":71549,"av":20381,"au":6593,"ak":8835,"al":58276,"ai":4230,"aj":1819,"ap":5563,"am":30979,"an":131829,"ac":6807,"ad":19629,"aa":1902,"ab":11909,"ag":21569,"ah":1853,"ae":3053,"af":53343,"nu":5799,"nt":31384,"ns":60694,"nr":1599,"no":15192,"nn":14628,"jø":1567,"ny":4222,"nv":2608,"oe":2046,"of":9995,"oc":5289,"od":18682,"oa":1343,"ob":5028,"om":68251,"on":52834,"ok":6768,"ol":36629,"oi":1528,"kæ":2283,"og":81449,"oh":1849,"ot":9072,"os":11517,"ov":19468,"ou":6113,"op":19430,"oo":2822,"or":109199,"kø":2883,"r ":303465,"ow":2461,"pe":19212,"pf":1434,"pa":11174,"pl":7694,"po":10483,"ph":1997,"pi":13460,"lå":3180,"læ":7117,"lo":18381,"lm":9161,"ll":54007,"ls":28805,"lr":2728,"lp":1954,"lv":5002,"lu":8894,"lt":13794,"ly":5517,"hø":4198,"o ":13391,"ma":28771,"mb":6952,"mh":1531,"me":79970,"mf":2516,"mk":2192,"ml":2687,"mi":18259,"mn":1374,"mm":27337,"mp":7909,"mo":10889,"mr":3179,"mt":7052,"ms":5339,"mu":15391,"my":1487,"p ":7331,"na":26783,"nb":2591,"nc":5256,"nd":115468,"ne":83213,"nf":2882,"ng":65185,"nh":5629,"ni":34813,"jæ":2156,"nj":1002,"nk":9744,"nl":3415,"nm":3852,"jy":1603,"ju":2882,"js":1575,"jo":3376,"jl":1331,"fæ":2974,"ki":13129,"gå":3551,"ke":62501,"kb":1624,"ka":33369,"m ":58614,"fø":16135,"ky":2485,"ks":11787,"kt":15601,"ku":9611,"kv":2686,"ko":24231,"kr":19731,"kk":11850,"kl":9428,"km":2041,"kn":3763,"li":70659,"hå":1642,"lh":1724,"lk":6427,"hæ":2028,"le":98770,"ld":24706,"lg":4872,"lf":2530,"la":47170,"lb":6128,"gø":1910,"n ":242497,"hr":2287,"hv":9222,"ht":1466,"hu":6980,"dæ":994,"hj":3040,"hi":7688,"hn":1182,"ho":15697,"id":25624,"ic":10962,"ib":6095,"ia":12086,"ig":59928,"if":7649,"ie":27731,"hy":1292,"k ":53472,"dø":3867,"ir":14180,"is":62018,"it":24973,"iu":2399,"iv":18874,"ik":30570,"il":63431,"im":7762,"in":99762,"io":27519,"ip":4261,"je":15216,"jd":2875,"få":1004,"iz":977,"l ":57442,"ja":3097,"tæ":3691,"tå":3749,"z ":1958,"sø":4093,"wi":999,"så":7469,"sæ":4934,"y ":17470,"rø":5891,"wa":2989,"we":1786,"ræ":12201,"rå":5052,"vi":25451,"vs":4402,"vn":10855,"vo":8670,"ve":64168,"vd":1809,"va":25040,"x ":2713,"ui":2354,"uk":3985,"ul":11807,"ue":7203,"uf":1429,"ug":8656,"ur":17879,"us":20761,"ut":8713,"um":12141,"un":39154,"up":6927,"ty":12222,"tz":1053,"tu":11275,"tt":18340,"tv":2718,"ub":5076,"ua":3814,"ud":21845,"uc":3424,"w ":2415,"to":25039,"tn":4704,"tm":1160,"tl":7804,"ts":12139,"tr":31125,"tf":1908,"te":116420,"tj":2329,"pæ":1318,"på":21476,"ti":89903,"th":7738,"v ":18910,"tb":1612,"ta":40351,"su":4879,"sv":6120,"ss":17007,"st":117117,"sy":9417,"sl":10786,"sk":90052,"sn":3225,"sm":6568,"sp":18285,"so":39577,"sr":1826,"sd":1411,"sc":3973,"sf":3067,"se":58416,"sh":5513,"sg":1978,"sj":1417,"si":34046,"u ":4030,"sa":20739,"sb":7435,"rr":10396,"rs":33077,"rt":26331,"ru":25205,"rv":5600,"ry":5622,"rp":2368,"ro":34074,"rn":23969,"rm":13546,"rl":8366,"rk":22061,"næ":3458,"nå":1618,"ri":66660,"rh":5594,"rg":18288,"rf":5902,"re":122058,"rd":25935,"rc":2308,"rb":9120,"ra":54038,"t ":215608,"mø":1338,"qu":972,"mæ":2988,"må":5133,"lø":4835,"s ":87017,"pt":4539,"pu":4408,"pp":6074,"pr":20775,"ps":3450,"zi":1962,"ze":1041,"za":1046,"væ":10057,"yg":7090,"ye":6589,"yd":11050,"ya":1357,"yb":1013,"tø":6010,"yt":3483,"ys":11680,"yr":5643,"yp":2457,"yn":4794,"ym":2136,"yl":4209,"yk":3734,"År":1234,"å ":31271,"Øs":1854,"æv":1666,"æs":6691,"ær":17270,"æt":3678,"æn":8602,"æk":5318,"æl":6220,"æg":5488,"æd":2878,"ån":3755,"ås":1047,"år":11909,"åe":2110,"ål":3106,"åb":1474,"åd":6195,"ør":20663,"øs":5971,"øv":2281,"øj":4875,"øk":983,"øn":5238,"øl":3077,"øm":1629,"øb":5904,"øg":2353,"øe":2140,"ød":12599,"ø ":2608," Ga":1860," Ge":1892," I ":2530," Fo":3830," Fr":4772," Fi":2339," Fl":1645," Ha":6811," He":6623," Go":1179," Gr":3557," Gu":1534," Hu":1582," Ho":4265," Hi":1510," Je":1919," Ja":2336," Is":1181," In":3319," Ka":3227," Ke":1072," Ki":2888," Jo":2762," Ju":1199," La":5040," Le":2776," Li":3188," Kl":1820," Ko":8866," Kr":1743," Ma":7451," Mi":3885," Me":3307," Lo":2724," Lu":1285," Ne":2661," Na":2409," Ni":2020," Mo":3297," Mu":1554," Am":3639," An":3489," Al":3774," Aa":1413," Ba":5300," Au":1061," As":1298," Ar":2597," Be":3849," Bi":1733," Bl":1427," Bo":3066," Br":3787," Bu":1519," By":1610," Ca":3749," Ce":1081," Ch":3522," Co":3667," Da":6687," Di":2014," De":17357," Do":1505," El":1337," Et":1617," Er":1002," En":5365," Eu":1616," Fe":1132," Fa":2149," Sø":1956," Wo":983," Wi":1981," We":1181," Wa":1857," Yo":1015," Kø":2558," Or":1513," Po":2365," Pi":1093," Pe":2468," Pa":3735," No":4834," Ra":2473," Ro":3958," Re":4459," Ri":2570," Pr":4618," Sy":2476," Sv":1637," Su":1503," St":10885," Ta":2881," Th":4217," Ti":1411," Te":2130," Tr":2230," To":1975," Ru":1535," Sa":4126," Sh":1168," Si":2284," Sc":1958," Se":2497," So":7960," Sp":1954," Sk":3100," Sl":1954," Va":1707," Ve":4322," Vi":3432," Vo":984," Ty":1554," Un":2381," ja":1664," få":1001," in":18970," ik":2700," is":1666," ka":10401," fø":12841," ki":4060," ke":5007," jo":1235," fæ":1545," ju":2042," ha":16862," he":5872," gi":1512," gr":8357," gu":1731," dø":1180," hi":2424," hj":2649," ho":5868," hu":1995," hv":8333," ne":2244," na":5975," mu":3617," mo":5717," om":10735," og":60338," of":4764," ny":1418," nu":1920," no":8819," le":3614," li":12024," hå":1306," la":9917," kv":1456," ku":4034," km":1736," kl":2396," kr":4395," ko":12549," me":34653," mi":5228," hø":2581," ma":10653," lu":1103," ly":1210," lo":1691," af":47341," ad":2058," am":5476," an":9937," ap":1120," ak":1320," al":5943," au":1423," ar":5256," at":12715," ba":5812," bi":2763," be":21652," bo":2959," bl":16483," by":7166," bu":1513," br":6861," ca":2244," er":79580," et":23500," en":65390," el":13704," ek":1980," ef":3944," eg":1315," fe":2371," fa":4879," fu":1922," fr":19782," fo":43206," fl":5239," fi":8516," bå":1058," ge":4611," ga":3502," bø":1211," i ":86016," fy":1194," co":1546," ce":1786," ci":1062," da":14483," do":1734," dr":1947," de":85238," di":4041," dy":1311," væ":5438," tæ":998," sø":1940," ru":2426," sa":10706," se":8834," si":12012," sm":1227," sl":3070," sk":10508," sp":8070," so":28866," ra":1828," re":10118," nå":1108," ri":1551," næ":2233," ro":3386," pr":10950," lø":1660," s ":1355," må":3141," ov":4934," op":11111," or":3538," kø":1518," pe":4046," pa":3870," pl":3433," po":4785," lå":2186," pi":1184," læ":1975," så":2369," sæ":2010," va":14642," ve":13203," vo":1548," vi":7015," ræ":1334," ud":14434," ty":5331," tv":1505," un":6550," ta":3468," sy":6433," st":20417," sv":2066," su":1555," tr":6706," to":3836," th":1962," på":21281," ti":28004," te":4720," År":1234," Øs":1852," år":3117," øs":2023,"Årh":1078,"Fil":1000,"Et ":1446,"Eur":1467,"En ":3727,"Fra":1859,"Fre":1891,"For":2210,"Hel":1134,"Her":3429,"Han":2509,"Ind":1212,"Øst":1835,"Hol":1719,"As ":1183,"Bay":1295,"Amt":2376,"And":1120,"Bye":1086,"Car":1184,"Ber":1053,"EF ":1275,"De ":1771,"Det":5562,"Den":6802,"Dan":4528,"Chr":1315,"Cha":1198,"New":1218,"Nor":4041,"Køb":2308,"Par":1507,"Pro":2885,"SA ":2039,"SAs":1153,"Joh":1172,"Kir":1207,"Kon":1132,"Kom":6411,"Lan":2730,"Man":1218,"Mar":2635,"Søn":999,"Syd":1794,"Sve":1310,"Str":999,"Sti":2399,"Sto":1709,"Sta":3406,"Ste":1353,"Tab":1274,"Sog":4806,"Sch":1301,"San":1256,"Reg":1718,"Ros":1109,"åen":1002,"åde":4772,"ål ":1259,"ånd":1467,"åne":2057,"åle":1126,"åre":1034,"ård":2059,"år ":6325,"Ver":993,"Ves":1255,"Uni":1434,"æde":2099,"Tys":1072,"æge":1409,"ægt":2411,"æll":2133,"ækk":2758,"æld":2168,"æns":1603,"æng":3355,"ænd":2342,"ær ":2495,"æsk":1388,"æse":1314,"ært":1291,"ærk":2357,"ære":6027,"ærd":1139,"ætt":1489,"æst":1815,"ævn":987,"The":2590,"bje":1890,"bil":1901,"bin":2468,"blo":1344,"ble":11852,"bli":3619,"bla":2817,"bol":3467,"bog":1211,"bor":5893,"bbe":1641,"be ":1587,"ban":5529,"bal":1468,"bag":1151,"bas":2113,"bar":1770,"bej":2245,"beg":2119,"bef":974,"bed":1902,"ber":10275,"ben":6123,"bel":6286,"bez":990,"bev":1288,"bes":5570,"bet":8125,"ca ":2352,"ce ":2816,"bri":2216,"bro":1760,"bra":1230,"bre":2307,"bru":5207,"bur":1375,"bun":1225,"bum":1745,"by ":6807,"bye":2309,"byg":4928,"am ":2554,"al ":9518,"ain":1470,"aj ":1010,"agt":3576,"anv":1364,"anu":1902,"ann":5158,"anm":3219,"ant":6958,"ans":23197,"ane":4038,"ang":12562,"ani":4609,"ank":4263,"ana":2737,"anc":2097,"and":39458,"amt":2475,"amm":7240,"aml":2016,"amp":2062,"ami":2635,"ame":7259,"ama":1553,"alv":1423,"alt":4977,"als":1981,"alr":2167,"alm":1522,"all":6438,"alg":1439,"ali":5360,"ald":6029,"ale":8208,"ala":1794,"alb":2973,"an ":17044,"akt":3338,"abe":4887,"ad ":3260,"ab ":2197,"aft":1820,"afs":1107,"afh":1105,"afi":1171,"age":8240,"adm":1030,"adi":3138,"ade":6627,"ag ":3450,"ads":1953,"ack":1318,"ach":1746,"ace":1610,"af ":43757,"aye":1830,"at ":17462,"are":4543,"ard":3649,"arb":2537,"ara":2794,"arm":1244,"arl":1801,"ark":7252,"ari":4342,"arv":1066,"arr":1598,"ars":2045,"art":9040,"au ":1067,"asi":1827,"ase":2004,"ask":1161,"ar ":24485,"as ":3170,"avd":1374,"avn":8812,"avi":1508,"ave":5203,"ay ":1009,"av ":1155,"ata":1987,"ast":4061,"ass":3627,"ato":1943,"ate":7241,"ati":16074,"att":4875,"ats":1271,"atu":2072,"jer":5562,"jek":1076,"jem":1846,"jen":1901,"jet":1025,"jan":1060,"je ":1645,"jde":2262,"jor":2291,"fær":971,"fæl":1337,"itu":1780,"itt":1519,"isk":22022,"ism":1473,"iss":2416,"ist":15812,"iv ":2118,"ita":3145,"ite":4554,"iti":5826,"ium":1528,"iva":1011,"ivi":1481,"ive":12562,"ipt":1296,"is ":8187,"ion":21894,"irk":6542,"isi":1236,"ise":3850,"isa":1650,"ire":2379,"it ":2641,"kil":3875,"kib":1205,"kin":2032,"kir":1742,"går":2699,"kis":983,"km ":1307,"ked":1397,"kel":4377,"ken":10401,"kes":1300,"ker":9106,"ket":3222,"ke ":28879,"kra":3109,"kre":5594,"kt ":3134,"kse":1892,"kro":1365,"kri":8221,"kov":1285,"kor":3059,"kon":5299,"kom":8214,"kol":2985,"ks ":2322,"kni":2413,"kke":10909,"klu":1988,"kle":1997,"kla":3032,"kli":1244,"jyl":1350,"jul":1124,"kba":1487,"kat":1697,"kar":1404,"kas":971,"kan":11432,"kal":6243,"kam":1128,"kab":5579,"ka ":2541,"før":6664,"fød":7830,"føl":1523,"ham":1255,"han":5336,"hal":2007,"hav":7061,"har":10554,"he ":3841,"hel":2400,"hed":6692,"her":3250,"hen":2397,"hin":1447,"his":2209,"hje":2112,"gle":3411,"gn ":5722,"gla":1189,"gni":1875,"gne":9082,"gs ":1501,"gsb":1331,"gsk":1233,"gru":5085,"gra":4027,"gt ":9775,"gre":2783,"gst":2115,"gte":3224,"gti":1404,"grø":1000,"gså":4604,"gus":1029,"græ":2818,"ial":2412,"ian":3001,"ic ":1068,"ibo":1076,"ølg":1529,"øn ":1089,"id ":2460,"ibe":2142,"ia ":3660,"øje":1642,"iet":2644,"iel":2523,"ien":9683,"ier":4656,"ig ":12921,"ift":4749,"ør ":3471,"ici":1501,"ich":2160,"ice":1664,"ie ":4513,"ica":1606,"ids":2132,"idt":1926,"idl":3701,"idi":1064,"ide":10399,"idd":1704,"ønd":1642,"øst":4212,"il ":24604,"im ":977,"ika":7541,"ige":19623,"iga":1060,"igh":3457,"igi":1414,"igg":9753,"igt":6078,"igs":1981,"ign":1642,"øre":4495,"ørs":6046,"ørr":1963,"ørt":1508,"ik ":5837,"ørn":1192,"ime":1521,"ind":23824,"ina":3988,"int":3500,"ins":7738,"ine":6155,"ing":36509,"ini":3271,"ink":1131,"iod":1188,"ikl":2029,"ikk":5095,"ike":2959,"ikb":1260,"in ":7601,"ikt":1780,"iks":1269,"ilo":3003,"ill":15072,"ilk":1504,"øve":1134,"ilm":4941,"ilh":993,"ili":3480,"ild":2323,"ile":1492,"io ":1215,"ils":1343,"hol":6737,"hov":3711,"hri":1405,"hvo":4960,"hum":1081,"hun":1070,"hus":3072,"hve":1568,"hvi":2196,"døs":1339,"død":1050,"ffe":2245,"ffi":1018,"fes":1566,"fer":1682,"fen":1036,"fas":1001,"fat":2864,"far":1600,"fam":1418,"fan":1048,"fal":1044,"ezi":1048,"evæ":1177,"eta":3145,"ete":8817,"eti":2099,"esp":2172,"est":19859,"ødt":7615,"ess":3934,"esv":1081,"ev ":11307,"etr":1299,"ets":3278,"ett":4721,"ety":1926,"øen":1132,"ew ":1416,"eve":5776,"eva":1631,"øge":1365,"evi":1173,"øj ":1036,"ey ":1638,"er ":229484,"epa":1085,"eor":1469,"eol":1033,"ød ":1370,"es ":24995,"øbe":3709,"ept":1210,"erk":1552,"erl":2388,"eri":19046,"erg":5102,"erh":1890,"ere":36721,"erf":2743,"erd":3362,"era":4483,"erb":2464,"et ":110723,"esk":4356,"esl":1065,"esi":2775,"øde":1837,"ese":1937,"erv":2764,"eru":2635,"err":4661,"ert":4521,"ers":15033,"ern":16903,"erm":1970,"ero":1448,"egå":1006,"ekr":1629,"eks":4054,"ekt":4817,"en ":174071,"ela":1844,"eld":1116,"ele":6394,"eli":11128,"ell":22146,"elv":2251,"els":21491,"elt":4815,"emb":3551,"ema":1766,"eme":3075,"emm":3388,"emo":1300,"emi":2222,"emt":1052,"emp":1313,"ems":1366,"enf":1295,"ene":9879,"enh":4546,"eng":3572,"enb":1247,"ena":1550,"end":24965,"enc":1233,"enn":5553,"enk":1120,"eni":2823,"ens":17443,"ent":14377,"enr":1262,"egn":6321,"ege":4459,"egi":3950,"eha":1147,"egr":1976,"eho":1258,"eis":2241,"ein":2075,"ejd":2400,"el ":14709,"ejs":1068,"ejl":1164,"eje":2612,"em ":8110,"gis":2194,"giv":4136,"gin":973,"gio":2383,"gie":1747,"ghe":2580,"gge":15510,"gi ":1776,"gen":19301,"geo":1146,"get":6054,"ger":26388,"ges":3499,"gem":1137,"gel":6514,"gde":1133,"ge ":22940,"gad":1042,"gar":1035,"gav":1126,"gam":1188,"gan":5170,"fte":8906,"fun":1949,"ft ":4358,"fra":16811,"fre":2876,"fri":2352,"for":48487,"fol":2294,"fod":2203,"fle":2554,"fla":1188,"flo":1580,"fly":1416,"båd":1117,"fic":1488,"fil":4788,"fik":1836,"fin":3119,"fir":1330,"fis":991,"da ":2439,"dbr":1439,"dbo":3204,"de ":51365,"dby":3214,"dal":1321,"dag":2881,"dat":1966,"dan":12624,"dam":1233,"dda":1566,"dde":3541,"com":1147,"ch ":2261,"cer":3808,"ces":1087,"cen":3123,"cha":1908,"cia":1876,"ck ":2373,"cie":1532,"che":2404,"cke":1007,"ed ":35220,"ebe":1273,"ebo":1021,"ebr":1930,"eal":1397,"eat":1418,"efi":1531,"efo":3934,"eft":4164,"een":1037,"edl":1944,"edi":2262,"ede":18829,"eda":1072,"edt":1636,"eds":6584,"edr":1723,"eci":1115,"ece":1005,"dyr":1288,"dvi":2440,"dve":2150,"don":1291,"dom":2065,"ds ":4746,"dmi":1103,"dni":1787,"dst":6032,"dsp":2071,"dti":2638,"dte":2421,"dtr":1052,"duk":1051,"duc":1998,"dri":1805,"dra":1347,"dt ":18171,"dre":7141,"dro":1133,"dsk":3064,"dsb":2127,"dsa":1334,"dse":2268,"dgi":2184,"dia":1005,"der":53839,"des":7277,"det":27574,"deb":1003,"deh":997,"del":20136,"den":48394,"dem":1809,"di ":1057,"dga":1116,"dle":3278,"dla":1839,"dkr":1756,"dli":6294,"din":2827,"dio":1576,"dis":4268,"dit":1114,"die":2342,"dig":3302,"rhu":1754,"rho":1270,"rga":2811,"ri ":2041,"rgi":1032,"rge":3583,"ret":16711,"res":7617,"rev":3074,"rfa":1970,"rfo":1099,"rds":1442,"rdv":999,"rg ":8008,"reb":1759,"rea":2289,"ref":3055,"red":12454,"rei":2319,"reg":5210,"rem":3072,"ren":13272,"rek":1859,"rel":3506,"rer":8658,"rep":1174,"rda":1335,"rdl":1187,"rdi":2720,"rde":7501,"re ":32700,"rbu":1055,"rbr":1012,"rd ":6821,"ras":1016,"rat":6278,"rbi":1442,"rba":1156,"rbe":2916,"rag":1612,"ran":8553,"ram":2785,"ral":3419,"rak":1777,"raf":2970,"rad":2370,"rs ":4872,"ros":1298,"rot":1028,"rom":2663,"ron":3183,"rop":3118,"rov":4008,"rod":3399,"roc":1755,"rol":2335,"rof":1572,"rog":3109,"rna":2635,"rne":13393,"rni":1274,"ro ":1858,"rma":3375,"rme":5215,"rli":2882,"rla":2011,"rn ":3815,"rks":2467,"rko":1321,"rki":1210,"rke":7276,"rka":1044,"rm ":1940,"næs":1010,"nær":1381,"rip":1436,"rio":1666,"når":1017,"rit":3128,"ris":7929,"riv":2443,"rig":7130,"ril":1328,"rik":9410,"rin":12007,"rim":1705,"ria":2312,"rib":1119,"ric":1788,"rid":1336,"rie":7227,"rif":1151,"rk ":5973,"rug":4144,"rue":1823,"rup":5078,"run":5278,"rum":2612,"ruk":1154,"rus":1691,"rva":1035,"rvi":1176,"rve":2295,"ry ":1399,"rsk":6329,"rsl":985,"rsi":2088,"rso":2553,"rsa":1053,"rse":2094,"rta":1313,"rst":8534,"rte":6848,"rti":3566,"rts":2294,"rt ":7502,"rri":1525,"rre":6580,"sag":1459,"sal":1002,"sam":8006,"sbe":2183,"san":3521,"sat":3398,"ryk":1357,"sho":1591,"sie":1150,"sid":5798,"sk ":33968,"sit":3034,"sis":4442,"sin":4733,"sio":2930,"sik":3367,"sig":4968,"sby":2385,"se ":14360,"sch":1769,"ser":12739,"ses":2382,"set":2238,"sfo":1331,"sep":1174,"sen":14543,"sem":1108,"sel":4270,"sek":1218,"spo":1957,"spr":2788,"spe":2284,"slæ":1631,"spi":8255,"spa":1108,"sol":1008,"som":26634,"son":4747,"sor":1570,"sog":2156,"st ":15643,"sli":981,"slu":1369,"sky":1101,"sla":3115,"sle":2180,"ski":4168,"skl":1367,"sko":3585,"skr":6518,"sku":2545,"ska":8399,"ske":25508,"sni":1817,"sma":1205,"sme":2348,"stæ":1164,"stå":3319,"syd":3714,"stø":3565,"syn":1352,"sys":1619,"sse":5630,"ssa":1137,"sso":1208,"ssi":4603,"ste":30468,"sta":15172,"stn":1107,"sto":7688,"sti":13739,"stj":1076,"stl":3640,"stu":1392,"str":12753,"sty":2236,"sva":1612,"sve":1375,"svi":1847,"tal":8954,"tag":2922,"tab":1032,"tad":2960,"tat":8263,"tar":2918,"tan":5101,"tam":1561,"te ":23992,"ta ":2303,"pa ":1106,"køb":1295,"pe ":3064,"par":4298,"pan":2233,"lå ":2263,"pec":1027,"pen":2557,"per":8319,"pel":1218,"pla":4596,"ple":1353,"læg":3305,"læn":1040,"lær":1638,"pil":7538,"pis":1494,"por":2733,"pop":989,"pos":979,"pol":3456,"ppe":4792,"pst":1130,"pte":1387,"pti":1074,"pri":5464,"pre":2422,"pro":9553,"pun":1123,"præ":2064,"løb":1835,"løs":1373,"mæn":1058,"mær":1139,"mål":1925,"mån":1657,"ra ":16943,"ngi":1084,"ngl":1961,"ngs":7820,"ni ":1743,"nge":21530,"ngd":1418,"nha":2979,"nhe":1266,"nel":5371,"nek":1429,"nen":7128,"nem":2182,"ner":14377,"net":9752,"nes":8157,"ng ":25397,"ned":2644,"nfo":1407,"nce":2989,"ne ":28324,"ndt":10291,"ndr":5292,"nds":9100,"ndo":2080,"ndl":3623,"ndk":1968,"ndi":3782,"nde":48861,"ndb":3975,"nda":1742,"nal":7713,"nan":1050,"nar":1016,"nd ":19511,"nav":5158,"nat":4037,"nas":1015,"na ":3264,"nve":1870,"nus":1183,"nto":1311,"ntr":3209,"nti":2579,"ntl":1237,"nta":2683,"nte":11676,"nsp":982,"nst":8074,"nse":6294,"nsi":1207,"nsk":23035,"nsb":1130,"nt ":5652,"ns ":13305,"nog":1664,"nom":1719,"nor":6469,"nov":1161,"nne":10196,"nni":1944,"nma":3344,"nli":1178,"nla":1269,"nke":3504,"nkt":1750,"jæl":1755,"nie":2401,"nk ":979,"niv":1911,"nis":7071,"nit":1685,"nio":1012,"nin":14093,"nik":1101,"ogs":5045,"ogr":2357,"ogi":3275,"ogl":1041,"ogn":7366,"oge":2091,"ol ":1201,"oci":1344,"ock":2154,"ode":4999,"ods":1493,"of ":2459,"odb":2119,"odu":2868,"og ":59080,"oft":2765,"off":2072,"ofe":1326,"od ":3992,"obe":1539,"nyt":1313,"ote":1650,"ott":1354,"oto":1594,"ost":2113,"ov ":1326,"osk":985,"ose":1440,"ovi":1957,"ovs":2306,"ove":11716,"oun":1213,"our":1852,"opl":974,"ope":1372,"opf":1235,"opa":1354,"os ":2264,"opr":3026,"opt":1105,"ops":1721,"or ":31324,"ork":2427,"orl":1427,"orm":8791,"orn":2079,"ord":14176,"ore":6583,"orf":2453,"org":9163,"orh":1310,"ori":4799,"ort":7693,"ors":6893,"orv":1018,"ot ":1242,"orb":3261,"ora":1624,"old":10067,"on ":17437,"oli":4334,"oll":3644,"olk":2982,"ole":3254,"ols":1497,"olm":1298,"olo":4008,"oka":1272,"om ":32517,"ona":4226,"ond":1810,"one":10149,"ong":2553,"oni":2635,"ono":1620,"ons":4853,"ont":2499,"oma":2195,"ome":4668,"omi":1702,"omh":1267,"omm":13262,"omk":1807,"omp":2560,"omr":2620,"oms":1669,"op ":2057,"la ":1857,"gør":1749,"le ":18274,"lde":9460,"ldt":2484,"lds":2126,"lac":1163,"lad":4353,"lag":4790,"lan":22791,"lam":1129,"lar":1164,"lat":2523,"las":2596,"lav":1728,"lba":1173,"ld ":5587,"lbo":1181,"lbu":1855,"kvi":1085,"kva":1167,"kun":3121,"kul":1926,"kte":2817,"kst":2005,"kso":1301,"kue":1399,"ktr":1143,"kti":4258,"kto":1463,"ktø":1090,"ls ":1795,"lok":1028,"lom":2968,"lod":2232,"log":4064,"los":1196,"lot":1245,"lov":1376,"lmi":1310,"lme":1724,"lti":975,"ltu":1430,"lub":2283,"lsk":4901,"lst":4539,"lta":1027,"lte":2079,"lse":13829,"lre":2112,"lt ":6296,"lge":2455,"li ":1269,"lev":14315,"les":5717,"let":5891,"ler":27840,"lem":6534,"len":6881,"lek":2168,"leg":1270,"led":4289,"lla":4918,"lle":37621,"lli":6167,"lke":3500,"hæn":1282,"lm ":3777,"ll ":2166,"lit":4876,"lis":3436,"lin":9392,"hån":1024,"liv":2785,"lia":1325,"lik":2160,"lil":1691,"lig":34196,"lie":4111,"ma ":1277,"mag":1391,"mar":6718,"mas":1505,"mal":1831,"man":9443,"mat":3311,"mbe":3163,"me ":4862,"med":21647,"meg":1181,"met":7243,"mes":4874,"mer":15160,"mel":6023,"men":16847,"lut":1751,"lys":1458,"høj":2362,"hør":1554,"mpe":2509,"ms ":982,"mod":4612,"mon":1609,"mor":1053,"mt ":4527,"mst":1872,"mrå":2725,"mus":3381,"mul":1155,"mun":9999,"mhe":1090,"min":6763,"mil":3215,"mis":2297,"mid":2156,"mle":1475,"mkr":1669,"mmu":9493,"mme":16141,"vær":6621,"zir":1025,"væg":1206,"ytt":1956,"yst":3197,"ysk":5330,"yre":2022,"yr ":1010,"yde":3637,"yer":2527,"yen":3113,"yd ":1599,"ykk":1287,"yll":1699,"ynd":1352,"ygg":4471,"tør":4175,"tær":1046,"tæn":1204,"tår":2373,"sæt":2008,"så ":5902,"sær":1369,"røn":1765,"rød":1365,"vst":2580,"vir":2222,"vik":2041,"vil":2648,"vin":4397,"vig":1873,"råd":3726,"vid":3491,"vis":5672,"ræs":2950,"ræn":2483,"ræk":2614,"vn ":4721,"vne":3693,"vns":1255,"vok":971,"vor":5368,"ver":19395,"ves":5050,"vet":6585,"vej":1947,"ven":7443,"vem":1052,"vel":2142,"ved":12182,"vde":1584,"ve ":6698,"val":2588,"van":4077,"var":14654,"vat":1120,"usk":1540,"usi":3385,"use":2336,"ust":3006,"uss":1778,"uti":1400,"ute":1658,"us ":6486,"ut ":1499,"ure":2206,"urg":1747,"uri":1026,"urn":1614,"uro":2454,"urt":1085,"ur ":2594,"upp":2843,"umm":1471,"umb":1127,"ume":1120,"uns":1753,"unk":1906,"uni":2675,"und":15503,"una":2326,"ung":3315,"une":7027,"up ":2829,"ukt":2014,"um ":5774,"ult":2011,"uli":1842,"ule":1205,"uld":1327,"un ":2311,"uge":2701,"ugl":1024,"ugu":1009,"ugt":1589,"udb":1145,"udd":1881,"ude":3316,"udg":3260,"udi":978,"ue ":1121,"uce":1989,"uer":2229,"ues":1633,"udv":2056,"uds":2177,"udt":1177,"uel":1000,"ub ":1257,"uar":1965,"ubl":1141,"ubb":1133,"ud ":2370,"typ":1409,"tyr":2052,"tys":3953,"ty ":1687,"træ":3121,"tur":4777,"tut":1397,"tun":1107,"tud":1198,"tyd":2007,"ts ":4804,"tre":5166,"tra":6691,"tri":4615,"tru":5093,"tro":3770,"try":1478,"tv ":1126,"tte":14611,"to ":3441,"tni":3342,"tne":990,"tof":1468,"tod":1141,"tog":1011,"ton":2739,"tol":1446,"tor":9016,"top":1001,"til":27566,"tik":5022,"tif":3307,"tie":1611,"tig":3596,"tit":2754,"tis":8549,"tin":4128,"tio":14633,"thu":1021,"tia":1323,"tid":6831,"tiv":4885,"tje":1256,"tli":4586,"tla":1138,"tle":1766,"tem":5581,"ten":11717,"tek":2453,"tel":3444,"teg":5502,"ted":5198,"th ":1733,"tet":9121,"tes":3522,"ter":41030,"på ":20701,"ti ":3596,"the":2230},"n_words":[9674395,11309170,8090238],"name":"da"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/deu b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/deu new file mode 100644 index 000000000..94ebdbbdc --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/deu @@ -0,0 +1 @@ +{"freq":{"D":565432,"E":313466,"F":303463,"G":350968,"A":448295,"B":452862,"C":218833,"L":272371,"M":385363,"N":224760,"O":171336,"H":264836,"I":169730,"J":158568,"K":336559,"U":140118,"T":243403,"W":221377,"V":203138,"Q":15370,"P":333284,"S":807982,"R":282432,"Y":16379,"X":9646,"Z":96079,"f":1052401,"g":2011313,"d":3686275,"e":12779820,"b":1254948,"c":2286896,"a":5009484,"n":7859499,"o":2714321,"l":3150399,"m":2035145,"j":85201,"k":1042619,"h":3128015,"i":7539051,"w":833806,"v":645462,"u":3015383,"t":5309288,"s":5151894,"r":6424621,"q":20503,"p":756433,"z":844832,"y":283697,"x":72882,"Ü":10506,"ß":107796,"Ö":13881,"í":8823,"é":38695,"ä":358815,"á":12062,"ü":397123,"ö":249595," l":98174," m":186199," n":127225," o":112357," h":112970," i":1142912," j":27689," k":107425," d":1491422," e":826321," f":160920," g":218820," a":569210," b":294630," c":26306," z":200898," u":467824," t":56510," w":322251," v":371555," p":57089," s":347463," r":56139," J":156270," K":328020," H":253550," I":146651," N":212076," O":159226," L":260916," M":370185," B":437655," C":196607," A":413316," F":291285," G":334059," D":543793," E":298852," Z":93212," Y":15401," S":736164," R":264582," Q":14562," P":316134," W":214460," V":189915," U":132267," T":228797," ä":10185," ö":18488," ü":31572," Ö":12893," Ü":10208,"A ":22760,"Da":90985,"Cl":9563,"Co":64248,"Ch":45017,"G ":11776,"Du":11229,"Do":28882,"Dr":19902,"De":166635,"Di":188563,"Fe":38252,"Fa":46184,"Eu":13931,"Er":67899,"Es":30499,"En":32393,"Ei":81512,"El":17463,"Ge":151044,"Ga":33294,"I ":13640,"Fu":26023,"Fr":58870,"Fo":32048,"Fl":33310,"Fi":36767,"B ":10700,"C ":14623,"Au":73540,"Ar":58134,"At":9258,"As":17569,"D ":9913,"Ba":87454,"Ab":25174,"Ad":11158,"Am":21201,"An":55559,"Ap":14324,"Al":66179,"Bu":55758,"Br":45253,"Ca":33967,"Bi":31885,"Be":143843,"Bo":32121,"Bl":15582,"Ku":30221,"Kl":25047,"Kr":46024,"Ko":56995,"Le":49783,"Li":55021,"La":89578,"Lu":17469,"Hö":9378,"Lo":26047,"Me":64987,"Mi":68245,"Ma":116460,"Mu":29273,"Mo":46837,"Ni":23664,"Ne":44049,"Na":66351,"P ":9001,"No":53500,"Ok":13364,"Ol":9042,"Ob":22144,"Gi":11262,"Gl":11809,"Gr":74845,"Go":17306,"Gu":11007,"Ha":86398,"He":62608,"Hi":21572,"Dé":12333,"Ho":42207,"Hu":11017,"Im":11278,"In":78332,"Is":10695,"Ja":77663,"Je":11227,"Jo":24131,"Ju":32751,"Ka":74688,"Ki":37983,"Ke":14966,"Um":8765,"Un":54096,"Tu":10377,"US":39827,"Tr":32100,"To":24574,"Th":35305,"Ti":19953,"Te":52263,"Ta":27705,"V ":9454,"Sy":15026,"St":193472,"Su":18450,"Wo":21476,"Wi":47351,"Wa":44055,"We":77082,"Vo":36505,"Vi":22665,"Va":14430,"Ve":104056,"Mä":13878,"Pu":10703,"Pr":83211,"S ":48175,"Pe":31242,"Pf":21717,"Pa":56041,"Pl":15401,"Po":48441,"Pi":16961,"Ph":15188,"Os":17404,"Or":58036,"R ":11116,"Kö":16414,"Se":64611,"Sc":120209,"Si":90352,"Sh":10028,"Sp":54743,"So":39076,"Ru":19547,"Sa":63564,"Re":106782,"Ri":24028,"Rh":15491,"Ro":44332,"Qu":12167,"SA":9500,"Ra":38143,"Mü":11354,"b ":47610,"a ":292619,"Sü":22392,"Ze":31894,"Zi":10309,"Zu":19954,"Zw":11243,"i ":187041,"ge":787899,"ga":94286,"fl":45063,"fg":17796,"ff":81186,"fi":73360,"fs":18166,"fr":68277,"fu":19769,"ft":140067,"fo":55471,"he":941699,"hb":12648,"ha":293469,"gn":22363,"gl":78298,"gk":13841,"gi":130788,"gh":20146,"gg":10845,"gu":58531,"gt":76690,"gs":110120,"gr":125748,"go":29970,"dt":100722,"du":88105,"dw":22283,"g ":403400,"ea":71177,"eb":165228,"ec":131420,"aß":17528,"ed":151386,"de":1831853,"dg":9266,"di":398882,"dh":11418,"dk":27018,"dl":45536,"do":69104,"dn":16795,"ds":46937,"dr":54467,"ew":66696,"ex":29126,"eu":212719,"ev":25427,"ey":30641,"ez":98518,"fa":86743,"h ":463041,"fe":136348,"eh":196157,"eg":232810,"ef":68699,"ee":58149,"el":553287,"ek":82123,"ei":1578594,"ep":49360,"eo":41207,"en":2309793,"em":396788,"et":380175,"es":772223,"er":2971302,"ca":38911,"bz":11720,"e ":2082290,"bs":31297,"br":69597,"bu":78689,"bt":20985,"bo":31335,"bl":45392,"bg":11719,"bi":136887,"be":567764,"db":9156,"da":176290,"f ":156375,"cu":10926,"ct":17144,"co":32151,"ck":133244,"ci":25902,"ch":1933159,"ce":45478,"c ":18586,"az":20071,"ay":30095,"ba":134727,"d ":722683,"at":393648,"as":323772,"ar":487358,"ax":8820,"aw":12659,"av":27657,"au":496496,"ak":51121,"al":571224,"ai":78558,"ap":48798,"am":283487,"an":921405,"ac":186135,"ad":167659,"aa":47275,"ab":98737,"ag":124899,"ah":148615,"ae":30527,"af":117969,"nu":74735,"nt":478161,"ns":309893,"nr":20689,"no":90394,"nn":190420,"nz":136146,"ny":13727,"nw":36447,"nv":14218,"oe":10022,"of":64141,"oc":78480,"od":135885,"oa":14277,"ob":51225,"om":176521,"on":667125,"ok":27868,"ol":220141,"oi":24320,"og":71416,"oh":66434,"ot":88470,"os":118609,"ov":54069,"ou":69753,"op":68308,"oo":24531,"or":433879,"r ":1993661,"ow":58643,"oz":19078,"kö":10263,"pe":109404,"pf":29697,"pa":81077,"kü":12292,"pl":26694,"po":71059,"ph":41272,"lä":41208,"pi":98645,"lo":124488,"ln":33301,"lm":52275,"ll":300411,"ls":178640,"lr":10222,"lp":20136,"lv":15360,"lu":97812,"lt":212969,"lz":28989,"hö":49290,"ly":20012,"o ":123676,"iß":9834,"ma":207608,"hü":11610,"mb":77222,"me":410943,"mf":12265,"ml":10335,"mi":238709,"mm":108620,"mp":57358,"mo":55705,"mt":36178,"ms":30817,"mu":48362,"p ":27276,"na":304264,"nb":61884,"nc":42156,"nd":1104110,"ne":802403,"nf":54695,"ng":588331,"nh":45861,"ni":342822,"nk":102273,"nl":39986,"nm":15381,"ki":44691,"ke":186644,"ka":155408,"fü":107647,"m ":660573,"ks":34677,"kt":124687,"ku":45967,"ko":74144,"kr":80423,"kl":44918,"km":33455,"li":562165,"hä":31781,"lh":12595,"lk":36060,"le":501436,"ld":86618,"lg":41891,"lf":32687,"la":312768,"lc":19357,"lb":59934,"n ":2940210,"hr":245096,"hs":72646,"hw":53275,"ht":189239,"hu":73471,"hk":8886,"hi":180846,"hn":163077,"ho":102479,"hl":130889,"hm":50687,"id":80042,"eß":9854,"ic":534870,"ib":46123,"ia":115654,"ih":35970,"ig":262184,"if":71985,"ie":1150659,"hy":13546,"k ":140095,"ir":170539,"is":1295546,"it":570135,"iu":24806,"iv":65304,"ik":165059,"il":298251,"im":289814,"in":1828758,"io":214368,"ip":33386,"je":30947,"fä":14922,"iz":46043,"l ":312169,"ja":19963,"tä":51288,"xi":15762,"z ":144384,"sü":19128,"sä":14628,"wi":176498,"wo":47417,"wu":73059,"rö":38038,"y ":99455,"wa":198781,"rü":63451,"we":246633,"rä":41054,"vi":76382,"vo":299196,"uz":17658,"ve":197477,"va":38019,"x ":21295,"ui":24830,"uk":24301,"ul":92478,"ue":71615,"uf":143869,"ug":74097,"uh":10714,"ur":375391,"us":360270,"ut":230981,"um":178633,"un":921062,"up":64261,"ty":34073,"tz":131414,"tu":172266,"tt":172596,"tw":53648,"ub":43047,"ua":44618,"ud":39409,"uc":128427,"w ":36904,"to":167744,"tn":11002,"tm":18841,"tl":110769,"ts":280176,"tr":215121,"tp":9922,"tg":32640,"tf":25417,"te":1203919,"tk":15341,"ti":420789,"pä":14388,"th":119533,"v ":14300,"tb":22514,"ta":360262,"su":36834,"sv":12561,"ss":289880,"st":1222626,"sy":19371,"sz":17514,"sw":26360,"sl":40519,"sk":49450,"sm":28595,"sp":131491,"so":116426,"sr":21109,"sd":16337,"sc":827974,"oß":20955,"sf":20622,"se":456715,"sh":47160,"sg":56341,"si":322120,"nö":10879,"rz":76103,"u ":108662,"sa":109787,"sb":46727,"rr":85173,"rs":267473,"rt":385464,"ru":174667,"rv":18995,"rw":59814,"ry":19301,"rp":30886,"ro":256692,"rn":187691,"rm":96942,"rl":93135,"rk":131828,"ri":506618,"rh":58397,"rg":185502,"rf":74192,"re":658545,"rd":287337,"rc":86223,"rb":105570,"ra":423969,"t ":1627252,"mö":8912,"qu":17893,"mä":18127,"lü":10612,"s ":1183348,"pt":54028,"pu":30332,"pp":47091,"pr":99340,"ps":12738,"zä":9571,"zö":21005,"wä":21780,"zi":99549,"zb":8992,"ze":213386,"za":20320,"zw":56096,"zu":170081,"zt":32056,"zo":13315,"ye":15230,"uß":27824,"ya":11551,"tü":14407,"yt":8983,"ys":38183,"yr":10616,"yp":13299,"yn":15755,"ym":18550,"yl":11401,"äc":27469,"Üb":9926,"ßb":17940,"ße":45162,"ßt":14023,"ép":12471,"ät":44405,"äu":30285,"äl":29341,"än":69784,"äs":15220,"är":37279,"äd":10841,"äg":13766,"äf":13624,"äh":39944,"ün":62239,"üs":17438,"ür":122114,"üt":16867,"üb":39622,"üc":24866,"üg":9236,"üd":43250,"üh":43336,"öß":14937,"ör":67546,"ös":54393,"ön":22557,"öl":13380,"öm":9902,"öh":14808,"öf":13450," Ga":33168," Ge":150714," Fo":31900," Fu":25992," Fr":58787," Fi":36574," Fl":33229," Ha":86258," He":62512," Go":17225," Gr":74652," Gu":10914," Gi":11192," Gl":11774," Hu":10983," Ho":42078," Dé":12331," Hi":21530," Je":11187," Ja":77578," Is":10643," Im":11222," In":77993," Ka":74525," Ke":14835," Ki":37849," Jo":24054," Ju":32722," La":89327," Le":49575," Li":54819," Kl":25011," Ko":56929," Kr":45960," Ku":30157," Ma":116111," Mi":68090," Me":64810," Lo":25969," Hö":9372," Lu":17420," Ne":43845," Na":66181," Ni":23603," Mo":46674," Mu":29161," Ap":14296," Am":21144," An":55404," Al":65979," Ad":11104," Ab":25090," Ba":87247," Au":73430," At":9235," As":17394," Ar":57936," Be":143584," Bi":31731," Bl":15450," Bo":31991," Br":45134," Bu":55625," Ca":33546," Ch":44814," Cl":9441," Co":63874," Da":90740," Di":188080," De":166199," Dr":19868," Do":28619," Du":11174," El":17420," Ei":81331," Es":30480," Er":67840," En":32299," Eu":13899," Fe":38170," Fa":46079," Sü":22387," Wo":21330," Wi":47141," We":76915," Wa":43907," Zu":19747," Zw":11238," Ze":31828," Zi":10283," Kö":16410," Os":17332," Or":58009," Po":48260," Pl":15331," Pi":16916," Ph":15079," Pf":21701," Pe":31180," Pa":55779," No":53429," Ol":9032," Ok":13357," Ob":22103," Ra":37989," Mü":11350," Qu":12048," Ro":44140," Re":106629," Ri":23976," Rh":15474," Pr":83041," Pu":10674," Mä":13877," Sy":14940," Su":18414," St":192451," Ta":27626," Th":35151," Ti":19864," Te":52071," US":39409," Tr":31991," To":24396," Ru":19497," Sa":63396," Sh":9926," Si":90133," Sc":119896," Se":64226," So":38900," Sp":54582," Va":14382," Ve":103873," Vi":22523," Vo":36449," Tu":10321," Um":8742," Un":54031," je":12055," im":207684," in":455196," is":439990," it":10403," ka":23448," fü":85353," ha":41553," he":33774," gi":8908," gl":12278," gr":31732," ih":21981," hi":13984," ho":9452," ni":22730," ne":14510," na":48500," od":67197," of":20927," nu":10713," no":19195," le":19412," li":42027," la":25753," ku":12534," km":15800," kl":13510," ko":18379," me":26065," mi":107786," ma":27726," ab":26560," am":69685," an":87925," al":101826," au":256133," ba":8860," bi":45326," be":204994," br":14611," bz":9809," er":81246," et":21454," es":15402," en":55368," ei":604709," eh":21203," fr":36324," ge":155650," ch":11442," da":104895," dr":12440," de":1066350," di":258330," du":31949," zu":137283," zw":39753," ze":10132," sü":17881," ru":14611," se":68014," sc":24771," si":106825," sp":27646," so":41648," re":21422," pr":15398," po":16457," wa":91486," we":72625," wu":68805," wi":72114," ve":73784," vo":278143," vi":13609," um":38406," un":417759," st":39848," tr":12290," th":15725," te":8776," Üb":9908," ös":13916," üb":31186,"Fer":11772,"Fil":18131,"Fam":19152,"Es ":23376,"Eur":10652,"Ein":58080,"Eis":15092,"Er ":28197,"Ent":11856,"Gem":51515,"Geb":17190,"Ges":25022,"Ger":10345,"Gen":10761,"Gat":12348,"Fuß":15716,"Flu":13729,"Fra":28567,"Fri":10250,"Fre":14074,"For":20619,"Dép":12076,"Hei":15430,"Her":23305,"Hal":8751,"Han":15746,"Hau":30716,"Gre":10954,"Gra":17232,"Gru":19222,"Gro":14185,"Int":14682,"Ins":19291,"Ind":10322,"In ":14119,"Hoc":11500,"Art":17165,"Aut":13725,"Aus":25209,"Aug":12878,"Auf":14417,"Ban":13867,"Bad":10629,"Bar":8982,"Bas":9343,"Bau":14505,"Als":17057,"Alt":10907,"Ant":9903,"Bun":26145,"Bur":11846,"Car":9966,"Bez":18543,"Bes":11001,"Ber":42078,"Bei":10336,"Beg":14069,"Bre":9847,"Bra":12567,"Dez":9022,"Der":97305,"Deu":28251,"Das":56242,"Chr":9059,"Chi":9883,"Cha":13525,"Com":14437,"Cou":18879,"Die":157652,"Dre":10394,"Dor":10511,"Neu":14698,"Nat":19706,"Nie":12050,"New":10171,"Nam":20762,"Nac":12244,"Nov":10049,"Nor":35685,"Okt":8850,"Obe":15435,"Ort":33777,"Ost":13628,"Pla":10533,"Pfl":9335,"Pfa":9319,"Per":13707,"Par":21713,"Pro":54127,"Pri":9311,"Pol":21608,"Mär":10626,"Jan":11806,"Jah":47539,"Joh":10371,"Jul":9776,"Jun":10796,"Kan":19278,"Kar":13767,"Kir":12749,"Kil":10995,"Kla":9457,"Kon":17432,"Kom":17455,"Kre":22963,"Kri":9328,"Kul":11508,"Lei":11844,"Lan":56584,"Lin":9234,"Lis":12636,"Men":8765,"Met":15567,"Man":15071,"Mal":9073,"Mar":33951,"Mai":15148,"Mon":12046,"Mit":29518,"Min":10015,"Mus":19078,"Süd":20812,"Wil":11137,"Wie":10497,"Wei":14673,"Wel":14947,"Wer":11351,"Wes":22169,"Was":9091,"Wal":11499,"Vor":17501,"Vol":11987,"Zei":17372,"Str":23794,"Stu":11271,"Sta":109473,"Ste":21247,"Tei":19885,"Sit":13505,"Sie":53287,"Ser":9549,"Sep":9592,"Sei":11021,"See":8773,"Spi":16479,"Spr":13123,"Sch":114345,"San":12822,"Rhe":11094,"Rec":10719,"Rei":15453,"Reg":42336,"Rom":8900,"Ver":96243,"Uni":18259,"Unt":29085,"The":20642,"US ":31557,"Tra":12824,"bis":44646,"bil":24249,"bin":15696,"ble":9072,"bli":23577,"be ":15350,"ban":20200,"bal":24830,"bah":12251,"bac":14708,"bau":19849,"bar":18594,"bei":74577,"bef":14886,"bed":10076,"ber":182051,"ben":84728,"bel":16201,"bek":17699,"bez":50353,"bew":10065,"bes":47672,"bet":15480,"bie":27376,"bge":10311,"bzw":9957,"ca ":13669,"ce ":20992,"bt ":13539,"bri":17955,"bra":14742,"bre":12676,"bru":12222,"bst":12657,"bur":42376,"bun":13485,"am ":57496,"al ":67162,"ain":24754,"ais":13530,"ahm":10952,"ahn":21966,"ahl":22279,"ahr":74469,"anu":15776,"anz":50908,"ano":9997,"ann":95807,"ant":49762,"ans":31362,"ane":16424,"ang":74734,"ani":87171,"ank":29449,"ana":30762,"anc":17098,"and":264094,"amt":12217,"amm":42375,"amp":12259,"ami":43004,"ame":78887,"amb":11361,"ama":13307,"alz":12079,"alt":72681,"als":84009,"all":87642,"ali":76090,"ald":16999,"ale":62596,"ala":15461,"alb":20979,"an ":124982,"akt":19509,"abe":38207,"ae ":18008,"aat":34161,"ad ":15688,"ab ":9708,"aft":77933,"aff":9982,"ai ":14358,"age":54066,"adi":20643,"ade":24209,"ag ":17784,"adt":77282,"ack":9729,"ach":145520,"ace":11312,"aye":9954,"at ":58813,"are":33081,"ard":28108,"arc":10050,"arb":19113,"ara":24649,"aro":9777,"arl":16356,"ark":32666,"ari":41626,"arr":11665,"ars":12931,"art":72580,"au ":29621,"asi":19652,"ase":11784,"ar ":124263,"as ":155043,"aut":27334,"ay ":9249,"ata":11051,"ast":27543,"ass":73183,"ato":14091,"ate":62804,"ati":113716,"ath":22536,"auc":75721,"att":42075,"ats":11481,"atu":18974,"atz":18097,"aum":14540,"aup":28995,"aus":149891,"aue":19995,"auf":98508,"itu":19936,"itt":50909,"its":25338,"itz":41656,"ism":9438,"iss":46444,"ist":567635,"ita":30952,"ite":83935,"itg":12750,"iti":55617,"ium":14795,"ivi":10241,"ive":36462,"is ":120788,"ion":169772,"irt":10794,"irk":24645,"isi":17517,"ish":14382,"ise":39335,"isc":434611,"isa":10445,"ire":14375,"ird":46859,"irc":21452,"it ":186965,"itä":20849,"izi":17119,"ize":13649,"kir":9307,"kis":9934,"km ":11509,"ki ":9579,"kei":25216,"kel":18319,"ken":38622,"ker":44613,"key":12420,"ke ":26956,"kra":15849,"kre":43910,"kt ":30020,"kri":11594,"kon":15402,"kom":22572,"ks ":9057,"kma":10480,"kle":18061,"kla":10851,"kat":15038,"für":75640,"kan":77012,"kal":10319,"füh":22557,"ka ":18181,"han":36578,"hal":38788,"hau":37347,"har":21603,"hat":27886,"haf":79189,"hab":9073,"he ":213315,"hel":11970,"hei":73898,"hec":9261,"heu":16839,"hes":34182,"her":185057,"heo":9547,"hen":324438,"hem":37228,"hie":35579,"hic":13745,"hin":28238,"hil":15183,"his":35328,"hl ":14867,"hn ":19219,"hla":28455,"hle":29146,"hli":16905,"hlo":9385,"hlu":9270,"gle":20084,"gli":40281,"gke":10880,"gs ":14145,"gsb":9179,"gsg":11045,"gro":10882,"gru":14203,"gra":25992,"gt ":53228,"gri":24893,"gre":15248,"gst":11232,"gss":10565,"gte":17882,"grö":13018,"grü":19508,"gus":11665,"gun":24014,"ial":21666,"ian":25164,"iat":10334,"ibt":8975,"id ":10846,"ibe":11815,"ia ":36994,"iet":30400,"iel":84385,"ien":123978,"ier":122946,"ies":42285,"ied":66086,"ieg":57690,"ief":8944,"ieh":10954,"ig ":34684,"iec":11989,"ieb":29946,"ift":20078,"iff":26227,"ick":25712,"ich":454249,"ie ":537544,"ica":15678,"ide":33142,"ida":13186,"ieß":9409,"il ":53074,"im ":225234,"ika":58499,"ige":123608,"iga":12204,"igk":10797,"igi":12120,"igu":13208,"igt":19283,"ign":9138,"ihe":9068,"ihr":18848,"ik ":39429,"imm":16766,"ime":10380,"ind":156874,"ina":40189,"inn":28145,"ino":11205,"int":30667,"ins":51098,"inf":10131,"ine":425715,"inh":13926,"ing":93214,"ini":56092,"inl":11619,"ink":12759,"inw":21089,"inz":40189,"ike":34841,"in ":793598,"ilo":17887,"ill":36002,"ilm":27378,"ili":52680,"ild":30027,"ile":21718,"ima":11905,"io ":15324,"hr ":43100,"hol":19495,"hor":9009,"hof":13254,"hoc":13003,"hni":15320,"hnu":17265,"hne":77095,"hme":30297,"hul":13709,"htu":10990,"hts":18003,"hti":8985,"hte":48599,"hst":18465,"hse":23032,"hrt":21145,"hre":87475,"hri":38046,"ht ":81034,"hwa":10659,"hwe":33406,"hum":9803,"hun":26557,"ffe":34346,"fes":13275,"fer":33138,"fen":43852,"fel":18220,"fge":10643,"fas":17434,"fan":11879,"fal":21835,"fah":14992,"ff ":20858,"fe ":14115,"ewä":9115,"eze":57686,"ezi":30267,"eta":11725,"ete":74739,"eti":14295,"eso":11977,"est":128414,"ess":60542,"eue":13801,"eug":13587,"etr":30198,"ett":26303,"etw":18129,"etz":35905,"ew ":11648,"eut":121638,"eur":19487,"ewi":9238,"ewe":18343,"ey ":16388,"erö":10701,"er ":1578023,"eor":17275,"es ":365853,"ept":13647,"epu":9001,"erk":45646,"erl":56900,"eri":118551,"erg":76890,"erh":33322,"ere":140461,"erf":36150,"erd":42731,"era":58724,"erb":63293,"et ":137716,"esi":26333,"esc":45868,"ese":67043,"esa":12858,"erz":20677,"erv":14305,"eru":46595,"erw":47997,"err":51760,"ert":122552,"ers":190257,"ern":139910,"erm":29678,"erp":11457,"ero":15582,"ekt":37882,"en ":1453342,"elb":18844,"ela":19480,"eld":20851,"elc":11326,"elf":9116,"ele":71198,"eli":22926,"elm":9454,"eln":17751,"ell":119434,"els":30215,"elt":58131,"ehö":33094,"eiß":9569,"emb":35370,"ema":36279,"eme":116815,"emi":15129,"enf":15937,"ene":83278,"enh":15362,"eng":41769,"enb":41104,"ena":52256,"end":112707,"eno":10734,"enn":31346,"enk":30270,"enl":8977,"eni":28822,"ens":113000,"ent":181395,"enr":9992,"enz":28843,"ege":66150,"egi":51407,"egr":34898,"egt":35267,"ehm":19125,"ehr":37443,"ehe":47146,"eib":17640,"eic":136250,"eht":23060,"eis":113764,"eim":26661,"eil":79634,"ein":827667,"eih":11402,"eie":15075,"eid":22147,"eig":23796,"el ":101100,"eiz":17159,"eit":174763,"efü":9260,"eka":19118,"em ":162112,"gis":26824,"gin":15255,"gio":29407,"gie":31403,"gen":239581,"get":10602,"ger":96243,"ges":76492,"gew":20591,"geb":50080,"geh":39393,"geg":29832,"gef":16578,"gem":34840,"gel":53887,"ge ":89868,"gab":8826,"gar":15096,"gan":29626,"ga ":12696,"frü":9222,"fte":22800,"ftl":11215,"fun":10974,"fts":18001,"ft ":64901,"fra":26521,"fre":14454,"fri":12770,"for":35090,"fol":14926,"fla":12837,"flu":9809,"fil":11145,"fin":25920,"da ":17513,"de ":197184,"das":76737,"dar":15587,"dam":14425,"ckl":11099,"chä":10997,"ch ":425455,"cha":118322,"chw":51871,"chu":40552,"ck ":31790,"che":671441,"chl":70583,"chi":103178,"cho":20768,"chm":11901,"chn":86780,"chs":68005,"cht":155579,"chr":43254,"cke":51895,"ed ":20514,"eba":8988,"ebe":60498,"ebi":30463,"ebr":17022,"ebu":9376,"eat":10811,"efi":14121,"efe":11305,"ei ":84962,"ega":9107,"eer":10701,"edi":25198,"ede":66213,"eg ":9875,"eck":32288,"ech":81379,"aße":12922,"ee ":17886,"dwe":14218,"dur":31652,"dor":21874,"don":10905,"ds ":13347,"dun":25608,"dri":12382,"dt ":65936,"dre":16392,"dsc":11728,"der":838163,"des":213577,"det":50672,"deu":71719,"del":34612,"den":286768,"dem":104609,"dkr":22973,"dli":27133,"din":14965,"dis":37105,"die":268782,"dig":18151,"rhe":18402,"rha":21798,"rga":19288,"rgi":14417,"rge":50622,"ret":20023,"res":34677,"reu":13265,"rfa":14831,"rfo":9599,"rg ":68697,"rea":10702,"rec":32717,"raß":12628,"rei":196090,"reg":17320,"rem":14552,"ren":145744,"rer":33774,"rf ":19644,"rdn":11514,"rdl":8810,"rdi":14216,"rde":136404,"re ":80803,"rbr":9368,"rch":72681,"rd ":68822,"rap":8929,"rar":8924,"ras":13690,"rat":45378,"rau":34010,"rbi":13086,"rba":21515,"rbe":36419,"rai":10459,"rag":25026,"ran":87263,"ram":18048,"ral":31964,"rab":8938,"raf":18926,"rad":17310,"rac":30425,"rs ":37799,"ros":12129,"rot":11834,"rom":12509,"ron":32055,"rop":24374,"rov":26322,"rod":18103,"rol":12320,"rof":8772,"rog":9738,"rns":12992,"rna":25318,"rne":34331,"rni":11673,"ro ":10671,"rma":31109,"rme":19061,"rmi":10506,"rli":33691,"rle":11502,"rla":23240,"rn ":74871,"rks":11567,"rke":27812,"rm ":16219,"rit":36924,"ris":65792,"rig":20472,"ril":13027,"rik":52744,"rin":60346,"ria":21040,"ric":47382,"rie":98836,"rif":31298,"rk ":38902,"rwe":21555,"rz ":21038,"ruc":12341,"rup":19176,"run":74339,"rum":15222,"rus":14979,"rwa":28214,"ry ":12420,"rsi":21022,"rso":11863,"rsp":15246,"rsc":59984,"roß":19513,"rsa":9024,"rse":16931,"rta":10712,"rst":71108,"rte":100313,"rth":11159,"rti":23089,"rua":8770,"rts":42716,"rtr":18145,"rt ":139444,"rro":10371,"rri":12758,"rre":38535,"rra":9354,"sam":29233,"sbe":20860,"san":12568,"sat":17995,"rze":22030,"sha":10198,"sho":11670,"sge":44768,"sie":44959,"sic":57522,"sit":30295,"sis":59876,"sin":51565,"sio":15881,"sik":20202,"se ":74178,"oße":10850,"sch":817718,"ser":52310,"ses":13066,"set":25883,"seu":12734,"sei":61074,"seh":13958,"see":12215,"sen":104567,"sem":11510,"sel":53325,"spo":10155,"spr":34328,"spe":13644,"spi":46629,"spa":12483,"sow":18519,"sol":10161,"son":33802,"sor":15536,"sre":10655,"st ":524603,"ss ":36271,"sla":20592,"ski":8870,"ska":11035,"so ":11408,"swe":11000,"stä":18451,"sse":110613,"ssa":12522,"sso":12151,"ssi":42403,"sst":37624,"ste":300373,"stf":9710,"sta":116653,"sto":29905,"sti":57375,"stl":38070,"stu":17599,"str":60741,"sun":13352,"sve":8840,"tal":50681,"tag":11693,"taa":33781,"tad":80208,"tbe":10504,"tau":10504,"tat":27116,"tar":23114,"tan":59689,"tam":12219,"te ":230506,"ta ":18923,"pe ":20233,"par":30140,"pan":20821,"läc":9211,"län":14161,"phi":11788,"pen":21299,"per":31265,"pel":10530,"pla":12193,"pie":61526,"por":21385,"pol":21212,"ppe":33120,"pub":8976,"pte":12552,"pts":12222,"pra":20767,"pri":21158,"pre":14559,"pro":24883,"ra ":23418,"ngi":9157,"ngl":32203,"ngs":81612,"ni ":15548,"nge":150664,"nga":14715,"nha":17909,"nhe":16114,"neh":18303,"nel":12298,"nen":124634,"nem":32650,"ner":149716,"net":57023,"nes":53346,"neu":10682,"ng ":256902,"nfo":9002,"nfa":11653,"nce":12344,"nch":15880,"ne ":310275,"nbu":15121,"ndt":9026,"ndu":21347,"ndr":11275,"nds":26772,"ndo":18073,"ndl":16133,"ndk":23064,"ndi":40257,"nde":333302,"nda":14652,"nal":58896,"nam":18687,"nan":39807,"nar":14659,"nac":41308,"nad":10470,"nah":12864,"nbe":18026,"nd ":563951,"nba":15883,"nau":11932,"nat":30766,"na ":34549,"nz ":37982,"nwo":19169,"nve":9948,"nun":33102,"nur":9530,"nua":9860,"nty":16624,"ntw":17792,"nto":23385,"nts":23619,"ntr":27593,"nti":33190,"nth":12699,"ntl":20923,"nta":24938,"nte":156191,"nsp":11166,"nst":73244,"nse":37942,"nsi":11408,"nsc":47879,"nsa":13614,"nsb":9715,"nt ":97967,"ns ":52604,"nom":14191,"nor":17522,"nne":52732,"nni":11264,"nnt":52262,"nns":10154,"nli":11747,"nn ":35057,"nla":20752,"no ":11518,"nke":16356,"nkm":14368,"nkt":16086,"nkr":10153,"nig":30567,"nie":44175,"nic":23391,"nia":9121,"niv":12854,"nis":144657,"nit":17226,"nin":9152,"nik":13041,"ogr":16058,"ogi":20348,"oge":19173,"ohl":8865,"ohn":34927,"och":36284,"ock":28973,"ode":93686,"of ":22612,"odu":15579,"off":17101,"nzö":20567,"obe":24203,"nze":40975,"nzi":11904,"owi":20813,"ozi":9366,"ow ":10053,"oti":8974,"oth":10089,"ote":15159,"ott":13896,"oto":13207,"ost":26924,"ose":16100,"oss":15828,"ovi":27674,"ove":15851,"oun":22912,"our":13749,"oph":11323,"opa":9142,"os ":20626,"or ":51491,"ork":11076,"orm":35190,"orn":17190,"ord":64827,"ore":22869,"orf":23363,"org":24171,"ori":35553,"ort":57075,"ors":22259,"ora":13071,"ola":9778,"old":10163,"on ":380926,"oli":42117,"oll":31645,"olk":11956,"ole":12997,"olg":16083,"olo":30821,"om ":33290,"ona":50054,"ond":30722,"one":41633,"ong":12616,"oni":29183,"onn":12427,"ono":12443,"ons":40673,"ont":24319,"oma":20160,"ome":26297,"omi":13337,"omm":35850,"omp":19252,"omo":11157,"la ":19811,"lb ":10692,"le ":103052,"lch":16014,"lde":27222,"lac":9475,"lag":29983,"lan":114878,"lar":12710,"lat":31357,"las":30573,"lau":19611,"lba":8767,"ld ":26676,"lbe":17468,"kur":12239,"kun":14388,"kte":20495,"ktr":9556,"ktu":9324,"kti":30020,"kto":15493,"ls ":107647,"lon":9380,"lom":14967,"log":27324,"los":22267,"lti":11054,"ltu":37425,"lug":9766,"lsp":9315,"lst":14411,"lte":61749,"lsc":14894,"lt ":63451,"lge":22548,"li ":14630,"les":24231,"let":14648,"ler":100316,"lem":16242,"len":91180,"lek":12889,"lei":58951,"leg":20421,"leb":11626,"lls":25768,"llu":11230,"llt":17543,"lla":17394,"lle":120640,"lli":30333,"ln ":17395,"lm ":19332,"ll ":39906,"lit":40830,"lis":62203,"lin":51826,"lic":170755,"lia":13089,"lik":12998,"lig":41309,"lie":114815,"ma ":15588,"mar":19548,"mal":49935,"man":57586,"mat":30614,"mbe":37028,"me ":36368,"met":20898,"mes":11403,"mer":74569,"mel":10134,"men":133736,"mei":94533,"meh":11820,"mfa":9540,"lve":9179,"lun":37355,"lus":22607,"lz ":10714,"hör":33720,"mpf":9424,"ms ":14667,"mon":13165,"mt ":15320,"mte":10917,"mus":17368,"mun":19505,"min":21460,"mil":28731,"mis":23371,"mit":124264,"mig":9701,"mie":12587,"mmu":13317,"mmt":13008,"mme":52772,"zt ":19861,"zte":9874,"zu ":51921,"zw ":9786,"zug":11138,"zur":37734,"zum":31618,"zun":15443,"zus":11821,"zwe":22370,"zwi":20415,"zei":75965,"zeu":11441,"zes":9884,"zen":43803,"zem":9613,"zel":10023,"zer":23898,"ze ":15773,"zia":11658,"zie":29129,"zig":9649,"zir":18395,"yst":17491,"ußb":14873,"uße":8940,"yer":10735,"tän":11031,"tät":24189,"süd":17890,"wur":70546,"woh":26117,"wes":27777,"wer":58987,"wen":21225,"wel":20147,"wei":83410,"weg":12299,"wir":55249,"wis":33738,"wie":34766,"wic":21374,"wa ":19878,"röß":14321,"wan":13038,"rün":30393,"wal":31257,"war":103047,"rüh":12452,"rüc":12801,"vin":25318,"vie":18884,"von":226355,"vom":22538,"vor":35872,"räg":10007,"ver":144066,"ven":17663,"vem":8808,"ve ":14670,"van":10775,"usi":22265,"usg":18900,"use":25762,"usa":16989,"ust":38480,"uss":45929,"usp":9564,"uti":13537,"ute":38886,"utz":15915,"uts":91328,"uto":20186,"us ":143584,"ut ":20376,"urd":76437,"urc":36382,"ure":16506,"urg":50861,"uri":14126,"urn":9214,"uro":18224,"urs":13370,"urt":10114,"urz":14868,"ur ":74659,"upp":21507,"upt":28543,"ums":9212,"umb":12929,"ume":14114,"umf":9413,"unt":60343,"uns":11344,"unk":20377,"uni":19103,"und":450828,"ung":313251,"ukt":12384,"um ":104918,"ult":19564,"uli":15580,"ule":13595,"ula":10852,"uge":19918,"uft":12442,"ugu":12915,"uf ":70919,"ude":15376,"ue ":12656,"uch":109126,"uck":11441,"uer":24349,"ufe":13329,"ufg":14459,"uen":13989,"uel":10929,"uar":22497,"ubl":12721,"tzt":23155,"tzu":9903,"tze":24373,"ty ":26382,"twa":23393,"tur":43568,"tun":79448,"tum":9791,"tz ":51212,"twi":14763,"twe":10501,"ts ":32847,"tre":34672,"tt ":15987,"tra":75255,"tri":43316,"tru":19097,"tro":30104,"tsc":125606,"tsg":8757,"tsp":10708,"tst":44445,"tte":89035,"tti":9403,"ttu":15931,"to ":13838,"tob":10974,"tom":9404,"ton":34822,"tor":56677,"tik":35201,"tie":28029,"tig":44003,"tit":14488,"tis":66050,"tin":30024,"tim":13478,"tio":114009,"thu":10251,"tiv":26072,"tli":78058,"tla":9588,"tle":19198,"tem":46999,"ten":278529,"tei":81154,"tel":91292,"teh":26143,"tec":9644,"tfa":9048,"th ":15758,"tet":40557,"tes":39452,"ter":318918,"tgl":9160,"tge":13122,"tho":19217,"the":36369,"tha":11467,"zös":20559,"zäh":9158,"épa":12146,"ähl":11359,"ähr":16538,"äch":26798,"äng":21244,"änd":29875,"ält":11293,"ät ":14412,"ärz":9551,"äte":10008,"äuf":9858,"ßte":10219,"ßen":17047,"ßer":9786,"ßba":15077,"ße ":16400,"Übe":9600,"üdl":8991,"ühe":8949,"übe":35449,"ück":19105,"ünd":28744,"ür ":75451,"üns":8869,"ühr":24588,"ößt":9800,"öst":25495,"ösi":20607,"ört":26727,"örd":14857,"öni":10085,"öff":11553,"ürt":8780},"n_words":[87197534,99298261,71857404],"name":"de"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ell b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ell new file mode 100644 index 000000000..9ef014bcb --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ell @@ -0,0 +1 @@ +{"freq":{"D":1964,"E":1941,"F":1941,"G":1852,"A":4125,"B":2624,"C":3923,"L":2060,"M":3387,"N":1723,"O":1910,"H":2233,"I":2360,"J":1156,"K":1166,"U":1129,"T":2696,"W":1311,"V":1075,"P":2832,"S":4250,"R":1938,"f":2440,"g":5100,"d":7728,"e":26057,"b":4017,"c":7473,"a":25408,"n":18610,"o":18497,"l":12659,"m":7083,"k":2907,"h":7717,"i":21525,"w":1649,"v":2733,"u":9674,"t":15175,"s":12992,"r":19022,"p":4711,"z":1248,"y":3535,"x":1425,"μ":190953,"ν":363085,"ξ":16299,"ο":514934,"θ":54925,"ι":405235,"κ":245170,"λ":175427,"δ":87843,"ε":333395,"ζ":19116,"η":223442,"α":554256,"β":36747,"γ":101330,"έ":90196,"ά":106544,"ί":162652,"ή":98446,"Ω":1026,"Υ":1630,"Τ":16684,"Χ":5356,"Φ":5011,"Ρ":4090,"Π":18130,"Σ":17983,"Ο":20140,"Μ":17575,"Ν":8294,"Κ":18111,"Λ":6273,"Θ":3309,"Ι":8695,"Ζ":1967,"Η":13434,"Δ":9926,"Ε":15220,"Β":10823,"Γ":10307,"ΐ":1269,"Α":27922,"Ό":1024,"Ή":969,"Έ":4042,"Ά":2718,"΄":1288,"ϊ":3454,"ω":82386,"ψ":4318,"ώ":40333,"ύ":61448,"ό":136039,"σ":232383,"ς":240747,"ρ":274072,"π":191347,"χ":59122,"φ":44210,"υ":205289,"τ":474096," o":780," d":1163,"р":660," a":888," t":1268," p":1168," s":849," r":827," J":1101," K":1080," H":2002," I":1555," N":1284," O":1504," L":1764," M":2988," B":2227," C":3233," A":3004," F":1657," G":1632," D":1595," E":1570,"и":935,"о":946," S":3325," R":1624," P":2318,"а":1103," W":1185," V":798," U":829,"е":697," T":2305," Ι":8408," Θ":3256," Λ":6140," Κ":17657," Ν":8118," Μ":17373," Ο":19727," Α":26876," Γ":10190," Β":10719," Ε":14504," Δ":9620," Η":13284," Ζ":1948," Έ":4041," Ή":969," Ό":1018," Ά":2711,"A ":657," υ":7977," τ":169076," χ":14827," φ":8389," ρ":2618," π":75432," σ":77620," ύ":1013," ό":12814," ω":4856," ψ":866," ζ":1711," η":13278," δ":29475," ε":62623," β":11610," γ":22099," α":74025," ξ":1157," ο":35203," μ":51074," ν":14449," κ":74116," λ":7381," θ":8090," ι":6475," Χ":5293," Φ":4909," Υ":1521," Τ":16381," Σ":17547," Ρ":3989," Π":17476," ί":1230," ή":17892," έ":20443," ά":5017," Ω":1004,"Co":724,"H ":665,"C ":687,"O ":936,"Ma":1040,"To":652,"b ":924,"a ":4343,"i ":1712,"ge":831,"he":1545,"ha":1115,"gh":801,"g ":1029,"ea":941,"ed":859,"de":1790,"di":1004,"do":657,"h ":975,"el":1708,"en":2808,"em":659,"et":1060,"es":2097,"er":4530,"ca":818,"e ":6418,"f ":722,"co":859,"ci":771,"ch":1350,"ce":966,"d ":2124,"at":2084,"as":1170,"ar":3025,"al":2276,"ai":668,"am":1144,"an":4262,"ac":959,"ad":799,"nt":1738,"ns":835,"of":654,"om":903,"on":3275,"ol":1227,"os":875,"ou":924,"or":2245,"r ":2839,"pe":702,"lo":869,"ll":1391,"o ":2523,"ma":1208,"mb":957,"me":1201,"na":1567,"nc":799,"nd":1677,"ne":1562,"ng":1277,"ni":1477,"m ":1364,"li":1620,"le":1892,"la":1782,"n ":4655,"ht":808,"hu":877,"hi":783,"ic":1794,"ia":1591,"ig":1086,"ie":1115,"k ":870,"ir":779,"is":1816,"it":1405,"il":1191,"in":3273,"io":1643,"l ":2336,"y ":1749,"vi":759,"ve":914,"x ":1036,"ul":682,"ur":1293,"us":1362,"um":1309,"un":754,"to":1131,"tr":915,"te":1980,"ti":2250,"th":1729,"ta":1485,"ss":802,"st":1761,"se":995,"si":952,"rs":663,"rt":997,"ro":1924,"ri":2929,"re":1965,"rd":715,"ra":2129,"t ":3000,"s ":5020,"ώρα":1560,"ώτο":1121,"ώτη":1214,"ώσσ":997,"ώσε":810,"όεδ":664,"όδο":943,"όγο":980,"όν ":1172,"ός ":18179,"ϊκή":860,"ώθη":1056,"ώνε":1144,"ώνα":1750,"ώνη":931,"ώνυ":1219,"ώμα":1362,"ών ":13524,"ύου":1130,"ύμφ":1059,"ύμε":885,"ύμα":648,"ύντ":1574,"ύνο":857,"ύσε":1378,"ύτε":2598,"ύστ":2139,"ώς ":2025,"ύπο":1064,"ύρι":1436,"ύθη":1068,"όλο":1532,"όλε":1360,"όλη":2622,"όμω":688,"όμα":718,"όμε":2708,"όμο":1617,"όντ":1036,"όνι":1308,"όνο":4918,"ύν ":1686,"όπω":1790,"όπο":2513,"ύο ":1340,"όρο":2945,"όρη":995,"όρε":1336,"όρι":647,"όσμ":1304,"όστ":662,"όσο":1170,"ύς ":3624,"ότε":4438,"ότη":3717,"ότα":2254,"ότι":2195,"χώρ":2395,"χωρ":2665,"χρη":1672,"χρι":1320,"χρο":1146,"χρό":1127,"χολ":997,"χος":1298,"χου":1973,"χνη":657,"χιλ":816,"χικ":844,"χθη":1072,"χημ":1273,"χεδ":695,"χεί":1404,"χει":4759,"χετ":1198,"χαι":840,"χαί":1771,"χαρ":1871,"χαν":1478,"φόρ":1260,"χές":666,"χής":681,"χία":1887,"φων":1670,"φυσ":992,"φος":1513,"φορ":4132,"φου":862,"χε ":1257,"φικ":1262,"φιλ":1198,"φθη":729,"φερ":660,"φία":1007,"χή ":2299,"φαί":1221,"φαι":2017,"φαν":1114,"φαλ":712,"ωτο":763,"ωπα":870,"ωνσ":715,"ωνι":2150,"ωνα":1612,"ωνί":1735,"ωστ":3134,"ωτα":785,"ωτε":1561,"ωτι":1342,"ωση":2679,"ωρι":2402,"ωπο":844,"ωρί":1331,"ωρε":765,"ωμέ":1015,"ωμα":2019,"ωγή":1132,"ωγρ":700,"ως ":10658,"ων ":25196,"τά ":6317,"σήμ":967,"σία":5336,"σίλ":677,"τή ":2856,"σεω":1071,"σει":4874,"τε ":2677,"σημ":4910,"σης":5924,"σας":901,"σαν":2104,"σαλ":862,"τα ":16925,"σμι":908,"σμο":3140,"σμό":3646,"σου":1542,"σπα":974,"σιο":1662,"σικ":3297,"σιλ":2336,"σιμ":2018,"σκε":4485,"τη ":14833,"σια":1815,"σιά":738,"σμα":2223,"σμέ":1983,"τι ":2082,"σκο":2292,"σκη":760,"συσ":899,"σφα":2732,"συγ":2509,"συμ":1798,"συν":5781,"στρ":4375,"στό":2708,"σχε":1174,"σχο":662,"σπο":1081,"το ":35834,"στο":18068,"στι":9089,"στη":20031,"στε":4570,"στα":7955,"στί":782,"σσό":800,"στέ":1100,"στή":4608,"στά":1775,"σσε":911,"σσα":2647,"ρόε":683,"ρόσ":877,"ρότ":966,"ρόμ":822,"ρόν":1720,"ρόπ":819,"ρωτ":3312,"ρωσ":834,"ρωπ":1145,"ρωμ":989,"ρων":1731,"ρχα":2526,"ρχί":1672,"ρχε":1183,"ρχι":1336,"ρχη":823,"ρχο":1048,"ρυσ":751,"σα ":3872,"ρύθ":842,"ρώτ":2338,"ρώπ":1017,"ρών":1362,"σι ":958,"ση ":12367,"σε ":13475,"σο ":1455,"τότ":864,"τός":2183,"τύπ":651,"φή ":1774,"τών":2189,"Α ":1540,"υαρ":1339,"υβέ":734,"υγο":1001,"υγγ":1153,"Β ":722,"υγκ":1660,"Η ":10508,"υθο":2042,"υκλ":727,"υλί":1002,"υλι":722,"υλο":1136,"υμα":785,"υμβ":739,"υντ":1338,"υνθ":722,"υνο":1544,"υνα":2074,"υνε":870,"υνδ":710,"υνί":677,"υνή":706,"υνέ":720,"υμο":1114,"υμπ":1569,"υμμ":700,"υπη":741,"υπά":768,"υπή":1017,"υρο":983,"υρω":883,"υρί":1627,"υρά":671,"υπό":808,"υργ":2911,"υρα":699,"υρκ":776,"υρι":1000,"υπο":3053,"υτα":731,"υτι":3118,"υστ":2102,"υτή":1523,"υσα":1288,"υσί":1021,"υσμ":1067,"υσι":2818,"υση":1190,"΄ ":1237,"υτό":1999,"υτο":2715,"φέα":711,"φέρ":3057,"τάλ":737,"τάθ":737,"τάν":734,"τάσ":1170,"τέλ":1720,"τές":1644,"τέρ":1900,"σότ":899,"τέχ":815,"σωπ":940,"ταφ":747,"ταν":14808,"ταξ":1725,"ταρ":960,"τας":2802,"τασ":3623,"τατ":1252,"ταθ":1117,"ται":21198,"ταμ":1209,"ταλ":2606,"ταγ":1554,"τής":3962,"τό ":2629,"τήρ":1568,"τήμ":1493,"σύμ":1096,"σύν":1327,"τίσ":697,"τίτ":882,"τίο":1122,"τίν":835,"τία":2320,"τεί":2724,"τελ":4578,"τεμ":808,"τει":1045,"τες":1997,"τερ":11689,"τεχ":1125,"τεύ":1209,"τια":1887,"τιο":1754,"τιν":1951,"τισ":2348,"τις":8696,"τιμ":802,"τικ":22901,"της":36695,"τηρ":3076,"την":27288,"τημ":2854,"τηλ":655,"τηκ":1948,"τηγ":801,"τησ":1537,"τητ":3914,"τμή":1027,"τλο":835,"τρω":752,"τρό":832,"τρο":5304,"τρι":3975,"τρε":1070,"τρα":4343,"τρί":1148,"τού":2364,"του":50266,"τομ":1711,"τολ":2689,"τον":13580,"τοπ":1407,"τος":5084,"τορ":3232,"τογ":1175,"τοι":2194,"τοκ":1571,"τοί":1186,"υν ":3485,"τυπ":686,"υς ":13808,"τσι":825,"των":12537,"νή":7879,"νέ":3576,"μό":8452,"μώ":1755,"νί":9927,"να":62303,"νδ":5696,"νγ":910,"νε":15475,"νθ":2946,"νη":14939,"νι":23024,"μμ":4065,"μν":1567,"μο":26826,"μπ":8431,"μυ":2965,"μφ":2313,"μω":1439,"νά":5541,"ξα":1561,"νώ":4161,"ξε":3656,"ξι":1797,"ξη":2494,"νο":34560,"νν":4891,"νσ":1980,"ντ":28913,"νυ":1752,"ξά":881,"νό":10195,"νω":9532,"οδ":7658,"ού ":14320,"ογ":13258,"οε":2833,"οί":10846,"οβ":2978,"οα":1081,"ομ":21099,"ολ":23701,"οξ":882,"ον":36237,"οθ":2077,"οκ":6497,"οι":21065,"οία":2635,"ξο":1094,"οίκ":1187,"οέ":928,"ξύ":1306,"οίο":3618,"πη":2710,"πε":16079,"πα":18678,"πο":60271,"πν":700,"πλ":7083,"πι":10919,"ου":129022,"οφ":4209,"οσ":11327,"οτ":9541,"ορ":21585,"ος":37589,"οπ":16190,"πή":2566,"ού":30889,"πί":4948,"πά":3903,"πέ":3142,"οχ":4794,"ια":39925,"ιβ":2565,"ιγ":2579,"ιδ":8147,"ιε":6521,"ιζ":1197,"ιη":883,"ιθ":2601,"θω":1118,"ιά":10102,"θό":672,"ιέ":2080,"ιή":692,"θώ":1191,"θρ":2531,"θυ":2592,"θι":1852,"θλ":2017,"θν":3266,"θμ":2061,"θο":6015,"κδ":1079,"κε":22387,"κι":6089,"κη":5418,"κά":15567,"ιό":6367,"κέ":4956,"ιω":2086,"κα":65846,"κή":24785,"κί":3700,"ιώ":5059,"ιτ":9070,"ισ":25486,"ις":13132,"ιρ":6633,"ιχ":2933,"ιφ":1609,"ιμ":6598,"ιλ":8668,"ικ":79288,"ιπ":2073,"ιο":29123,"ιν":16499,"λη":19148,"λι":20827,"λκ":1174,"λγ":684,"λε":18373,"λί":8413,"κώ":4252,"λα":15386,"λβ":741,"λά":7390,"λέ":5224,"κό":26772,"κύ":1477,"λή":4583,"κω":1706,"κυ":3709,"κτ":10513,"κο":23779,"κρ":10237,"κπ":708,"κλ":5937,"κκ":1326,"μι":14565,"μη":6074,"με":36995,"μβ":5397,"μα":35176,"λύ":3607,"μή":3752,"μί":4420,"λώ":2414,"μά":7858,"λό":3924,"μέ":15352,"λω":3053,"λφ":1355,"λυ":3470,"λτ":890,"λπ":663,"λο":25987,"λμ":1804,"λλ":20970,"δη":5995,"δε":9279,"δι":23594,"δο":11445,"δρ":8223,"δυ":2966,"εά":775,"δω":1451,"εί":44740,"δώ":1804,"δύ":1829,"δό":1968,"εδ":3726,"εγ":5939,"εβ":1575,"εα":1003,"εζ":688,"εθ":3485,"ει":35123,"εκ":9726,"ελ":15989,"εμ":6248,"εν":19361,"εξ":4958,"εο":2282,"επ":13811,"ερ":40179,"ες":14762,"εσ":7584,"ετ":27314,"εφ":1836,"ευ":8533,"εχ":2179,"εω":4500,"εό":1241,"εώ":702,"ζί":1027,"εύ":4761,"ζα":1710,"ος ":37511,"ζε":6065,"ζι":1237,"ζη":738,"ζο":2939,"ζό":1259,"ζω":1103,"ηγ":3510,"ου ":87770,"ηλ":4366,"ημ":19012,"ην":37308,"ηθ":2646,"ηκ":9969,"ησ":11936,"ητ":11258,"ηρ":6263,"ης":54552,"θέ":3061,"θά":1066,"θή":2250,"ηχ":968,"θε":10322,"θη":10944,"θα":2622,"αί":10379,"ώ ":1686,"ακ":15045,"αι":93478,"αμ":10092,"αλ":21090,"αξ":3125,"αν":58537,"απ":33497,"αο":903,"αβ":3590,"αδ":5509,"αγ":12802,"αζ":1934,"ον ":14807,"αε":1433,"αθ":7116,"αϊ":2364,"βά":3473,"βέ":1564,"αύ":1058,"βί":1262,"βα":6377,"αρ":29289,"ας":38338,"ασ":22621,"ατ":37260,"αυ":7302,"αφ":9354,"αχ":2612,"βρ":7265,"βο":4803,"βλ":1821,"βι":3507,"βη":749,"βε":2725,"γα":7366,"γί":5669,"γέ":2710,"βό":1236,"γή":2815,"γά":3661,"γο":9693,"γρ":8625,"γμ":2369,"γλ":3739,"γν":4085,"γη":1772,"γκ":7566,"γι":14677,"γγ":5019,"γε":9939,"δα":7905,"δά":972,"γό":3291,"δέ":1507,"γύ":735,"δή":3929,"γώ":1054,"δί":4576,"γχ":1165,"γω":3973,"γυ":1102,"ομώ":1007,"ονί":1750,"έτ":5024,"έσ":4850,"ονα":1353,"ές":9695,"έρ":12949,"έπ":1245,"έο":998,"έξ":1325,"έν":21823,"ονδ":706,"ονι":2179,"έω":1309,"έχ":6163,"έφ":948,"έγ":3052,"έδ":1961,"έα":3333,"ομο":3665,"έλ":6166,"έμ":2360,"έι":841,"έκ":2418,"έθ":1065,"ομό":796,"άρ":7787,"άπ":2212,"άσ":7087,"άς":2871,"άν":11519,"άμ":3476,"άο":721,"άξ":842,"άτ":7688,"άχ":1258,"άφ":3485,"άβ":865,"άγ":2736,"ονο":4835,"οντ":6287,"άθ":2400,"άι":984,"άκ":2900,"άλ":9559,"ονό":1460,"άδ":6624,"άζ":2851,"ίς":1393,"ύ ":16375,"ίρ":2411,"ίπ":1897,"ίο":20214,"ίτ":8024,"ίσ":10180,"ίω":4466,"ίχ":2356,"αΐ":1011,"ία":42781,"ίβ":669,"ίε":2902,"ίζ":4719,"ίγ":1307,"ίδ":6660,"ίκ":4798,"ίθ":1008,"ίν":31172,"ίλ":2453,"ίμ":2180,"ήρ":4528,"ήσ":3271,"ής":18133,"ό ":46975,"ήτ":11312,"οπο":11630,"ήθ":4033,"ήκ":2438,"ήλ":1001,"ήμ":8522,"ήν":2806,"οιε":1122,"οιη":754,"οια":988,"φ ":702,"οιό":643,"οκα":975,"οιχ":1283,"οιν":2467,"οικ":4166,"οιο":1378,"ολι":5666,"ολλ":1265,"ολε":1313,"ολη":1127,"ολέ":884,"ω ":2903,"ολή":1110,"ολί":1066,"οκρ":2314,"ομι":2076,"ομη":811,"ομα":4494,"ολό":1136,"ομέ":1196,"ολύ":921,"ομά":4054,"ολυ":875,"ολο":6719,"οδι":937,"οδο":3299,"Υπ":1010,"οει":1399,"Συ":1600,"Στ":5008,"Τα":1846,"Σύ":1280,"Τζ":1148,"Τσ":726,"ς ":240346,"Τρ":1616,"Το":8405,"Χα":1289,"υ ":88180,"Χρ":999,"Φε":912,"Φι":704,"Φρ":703,"οθε":1042,"τ ":3704,"Πό":722,"Πρ":2848,"ξ ":655,"Ρο":774,"Πά":1152,"Ου":930,"ν ":112419,"Ορ":745,"Πο":2485,"Πε":2134,"Πα":4994,"πα ":685,"οβο":653,"Σα":1339,"π ":1661,"Σο":1132,"ογί":3068,"ρ ":3667,"ογέ":1210,"Σε":1940,"Σι":796,"Σκ":862,"ογρ":3223,"Ρω":976,"ογο":1295,"ογι":2141,"ο ":95107,"νός":3015,"νότ":2168,"Νό":654,"νόμ":1784,"λ ":3759,"Ντ":1194,"Νο":1706,"Ολ":1010,"Οκ":750,"Οι":2398,"μ ":2390,"Με":3726,"Μι":1150,"Μέ":678,"Μά":1161,"Μα":4471,"Λο":1279,"ι ":112286,"Νι":687,"νωσ":4336,"Νέ":832,"νων":3168,"Να":926,"Μο":1624,"κ ":2925,"Μπ":2700,"Κα":4969,"Ιω":836,"Κά":943,"Κι":702,"Κε":764,"Ιο":1485,"η ":59406,"Ιτ":907,"Ισ":1161,"Λα":1230,"Κό":910,"Κύ":1401,"Λι":661,"Λε":948,"Κρ":1403,"Κο":2565,"Κω":831,"Κυ":1027,"Θε":1962,"Ηλ":946,"ε ":49298,"Ηρ":654,"νυμ":1332,"Ια":1067,"ντί":2029,"ντα":8117,"Ερ":804,"Επ":1444,"ντε":1807,"Ελ":3849,"Εκ":838,"ντά":1383,"Εθ":920,"ντο":2386,"ντρ":2342,"ντι":5956,"Ευ":1907,"νστ":941,"α ":122436,"Γο":754,"Γε":2955,"Γι":1598,"Γκ":1275,"Δή":1392,"Δε":1218,"Δη":1620,"Δι":2406,"Εί":1505,"Αθ":2048,"νος":3551,"νου":4641,"νοτ":857,"Αγ":2492,"Απ":2382,"νού":1967,"Αν":3971,"Αμ":1723,"Αλ":1805,"Ακ":644,"Αι":969,"Αυ":2140,"Ασ":1614,"Αρ":2646,"ί ":9847,"Βα":2099,"Βι":900,"Βε":785,"Βο":1596,"Βρ":2238,"νοι":1353,"νομ":10454,"νον":1006,"Γα":1202,"νολ":1206,"νορ":724,"έ ":738,"ννή":1417,"ννη":1767,"ή ":39734,"ννο":742,"ά ":28070,"οι ":6175,"Χ ":729,"Ήτ":719,"Έν":837,"Έλ":1540,"Έχ":649,"Άγ":672,"Ο ":12037,"οί ":1669,"νών":1557,"ξύ ":1208,"πόλ":3996,"ρές":813,"ράκ":669,"ράγ":691,"ράσ":941,"ράτ":1685,"ράφ":2049,"ράς":805,"ράμ":655,"ράν":647,"ρίζ":2399,"ρίν":739,"ρία":4134,"ρίδ":772,"ρίω":1265,"ρίπ":1019,"ρίο":5068,"ρίτ":724,"ρίσ":4287,"ρό ":1004,"ρήσ":959,"ραβ":1005,"ραγ":2738,"ραμ":2193,"ραν":1181,"ρακ":3111,"ραφ":4046,"ρατ":4809,"ρασ":2311,"ρας":2953,"ργε":920,"ργι":803,"ργο":1794,"ργό":1216,"ργά":995,"ργί":829,"ργα":2610,"πτι":832,"πτε":965,"πων":724,"πως":2026,"ρμο":1033,"ρνη":961,"ρντ":654,"ρξε":1053,"ροέ":803,"ροκ":927,"ρολ":823,"ρομ":1223,"ρον":3303,"ροβ":944,"ρογ":664,"ροδ":662,"ροε":1475,"ρού":2500,"ροφ":1412,"ρου":6209,"ροτ":807,"ροσ":3339,"ρος":5922,"ροπ":1689,"ρτί":865,"ρτη":992,"ρτο":808,"ρεί":2767,"ρεύ":824,"ρετ":2773,"ρευ":659,"ρεσ":889,"ρες":2082,"ρει":4053,"ρησ":2941,"ρης":1045,"ριά":922,"ριγ":689,"ρια":3527,"ριό":2111,"ρκε":1056,"ριθ":994,"ρικ":7396,"ριλ":1434,"ριμ":904,"ριν":2336,"ριο":5568,"ρισ":7036,"ριφ":871,"ρμα":2357,"ρά ":3405,"πάν":921,"πάρ":1052,"παλ":1326,"παι":1177,"παν":2463,"παγ":893,"παϊ":680,"πατ":824,"παρ":8016,"παί":655,"πίσ":2277,"ούλ":1020,"ούμ":1108,"ούν":3424,"ούσ":2748,"ούς":3386,"πό ":21634,"πήρ":1722,"ούρ":1307,"οτε":3981,"οτι":1757,"οστ":1538,"οσφ":2182,"οσω":886,"οτέ":721,"οτα":918,"οση":738,"οσι":846,"οσπ":775,"ορφ":1231,"ορυ":783,"ορτ":877,"ορι":2946,"ορε":3059,"οργ":1807,"ορο":1078,"οπτ":643,"πο ":1799,"ορα":1218,"ορί":3662,"ορέ":747,"οπό":828,"ορά":1572,"οχή":2609,"οφο":1172,"ουσ":4557,"ους":13764,"ουρ":5299,"ουν":4982,"ουμ":1209,"ουλ":3147,"ουδ":1420,"ουα":1700,"ουά":882,"όγ":2701,"όε":736,"όδ":1693,"όλ":8233,"όκ":1654,"όμ":7862,"όν":10515,"ός":18197,"όσ":5414,"όπ":5405,"όρ":8376,"όφ":825,"όχ":1299,"ότ":13665,"ρι ":2104,"πλα":1198,"ϊκ":1906,"πλε":822,"πλη":1610,"πλο":1278,"ωθ":777,"ωβ":791,"ωδ":719,"ωγ":2280,"ων":32748,"ωπ":2336,"ωμ":4528,"ωρ":6506,"ως":10668,"ωσ":8039,"ωτ":6473,"ρο ":6138,"προ":8229,"πρι":1380,"πρα":1142,"πρώ":2895,"πρό":2160,"πρω":2758,"ώμ":1777,"ών":20079,"ώθ":1069,"ώη":641,"ώδ":730,"ποκ":999,"ποι":5038,"πολ":7906,"πον":1356,"ποί":6780,"ώτ":3447,"ώσ":2701,"ώς":2026,"ώρ":3768,"ποδ":2435,"πογ":674,"ώπ":1387,"ύκ":1365,"ύλ":2704,"ποχ":850,"ύμ":4174,"πού":867,"ύε":938,"ύθ":1852,"πορ":2148,"πος":1087,"ύγ":1143,"ύδ":738,"που":20607,"ποσ":1036,"ποτ":4745,"ύφ":886,"ύχ":810,"ύς":3629,"ύρ":4445,"ύτ":4068,"ύσ":5147,"ύν":5639,"ύπ":2849,"ύο":2732,"τε":30296,"τζ":1331,"τη":93724,"τι":46176,"τλ":1268,"τμ":1495,"πεδ":722,"το":124490,"τρ":19405,"τσ":2719,"στ":76523,"σσ":6194,"σφ":3318,"συ":12181,"σχ":3635,"σω":3204,"τέ":8491,"σό":1919,"τά":12970,"σώ":1166,"τί":8764,"σύ":4398,"τή":11346,"τα":73796,"σε":22382,"σι":15384,"σκ":10283,"ση":23543,"σθ":1011,"σμ":12903,"σο":6917,"σπ":3490,"πει":1514,"πελ":849,"σή":1903,"σέ":940,"περ":10195,"σά":1139,"σα":9280,"σί":8405,"ρα ":9620,"ρφ":1653,"ρυ":3661,"ρχ":9524,"ρρ":1307,"ρτ":5071,"ρσ":1303,"ρώ":6736,"ρύ":1952,"ρω":9925,"ρό":9460,"ρη":8917,"ρθ":1230,"ρε":17142,"ργ":11016,"ρδ":1272,"ρα":38879,"ρβ":958,"ρο":41731,"ρν":3338,"ρξ":1376,"ρλ":780,"ρμ":5151,"ρι":40112,"ρκ":3719,"πυ":748,"πτ":4561,"πρ":20097,"ππ":796,"ρί":22933,"ρή":2864,"ρέ":3880,"πό":28476,"ρά":13738,"πω":3057,"πια":723,"ρη ":2996,"ψε":1003,"ψη":1336,"χω":3038,"χό":665,"χώ":2869,"χρ":6885,"χο":6422,"χτ":889,"χι":3395,"χθ":1552,"χη":2825,"χν":2772,"χα":7239,"χί":2595,"χε":9910,"πισ":2595,"πιτ":871,"φω":2505,"πιο":1239,"χέ":1462,"φό":1995,"χή":3366,"φύ":644,"πικ":1602,"χά":891,"φυ":2356,"φο":8165,"φρ":1732,"φη":1268,"φι":3786,"φθ":1094,"φε":2326,"φή":2402,"φί":1583,"ρε ":822,"φα":6317,"φά":1435,"φέ":4345,"υφ":1198,"υχ":1680,"υψ":1025,"υτ":12113,"υσ":11499,"υς":13842,"υρ":12723,"υπ":8507,"υν":14929,"υμ":7534,"υλ":5896,"υκ":2985,"υθ":4332,"υζ":915,"υγ":5531,"υδ":2390,"υα":2666,"πηρ":828,"υβ":1419,"τώ":3229,"τό":9167,"τύ":1372,"υά":1396,"τω":14910,"ττ":1165,"τυ":2752,"μης":911,"μηχ":778,"μητ":983,"νε ":1648,"μιο":2230,"μισ":919,"νη ":4892,"μια":4477,"μικ":5134,"να ":17430,"μβρ":2160,"μβο":1003,"μερ":4521,"μεσ":1074,"μετ":6749,"μει":655,"μελ":883,"μεν":3875,"μεγ":2940,"μεί":1099,"λώσ":1078,"νή ":1793,"λών":940,"μό ":3080,"λύτ":1526,"μία":2762,"μήμ":1075,"μαχ":648,"μβά":1095,"μαζ":923,"μαν":3924,"ματ":10484,"μασ":1431,"μαί":1647,"λων":1650,"μέτ":1129,"μέσ":1359,"νά ":992,"μέρ":1935,"μέχ":973,"μέλ":884,"μέν":7654,"μέγ":746,"λόγ":1758,"μάτ":1753,"μάδ":1518,"μάζ":1519,"λυμ":1032,"λυτ":817,"λος":3446,"λον":1147,"λογ":7404,"λοί":713,"μο ":3714,"λου":3295,"λού":2344,"λικ":6554,"λια":1551,"λιά":2019,"μη ":2038,"λιό":666,"λιο":1726,"λιτ":3281,"λισ":1155,"λλο":3357,"λλι":1915,"λλε":843,"λλη":7119,"λλα":1712,"λλά":3329,"λλί":726,"νισ":2798,"νιο":1219,"ξη ":1696,"νθρ":1131,"νικ":14169,"νια":1586,"νημ":1520,"νης":3311,"νησ":3074,"νητ":1569,"ξε ":1387,"νει":4020,"νετ":1530,"νεπ":771,"νερ":896,"νες":2492,"νδι":887,"νδρ":1754,"νεί":692,"νδί":1002,"νγκ":862,"ναφ":1731,"νατ":2689,"ναυ":689,"νασ":1113,"νας":6220,"ναν":1504,"νακ":1377,"ναι":23633,"ναγ":847,"νώ ":1108,"νίδ":909,"μών":1634,"νίκ":973,"νίο":894,"νής":1328,"νό ":1732,"νήσ":732,"νία":4805,"νήθ":2044,"νήκ":1169,"μός":2661,"μόν":1144,"νάμ":808,"μων":716,"νω ":758,"μυθ":2305,"ντ ":1585,"μφω":1019,"μον":2292,"μοπ":1626,"μορ":1296,"μος":2596,"μοι":670,"μοκ":1030,"μπο":2312,"νο ":5296,"μπε":1085,"μπι":1180,"μού":4831,"μπα":642,"μου":4833,"μοτ":850,"μοσ":1084,"νι ":660,"μμα":1876,"λή ":1370,"ιών":3452,"κίν":1235,"κία":1185,"κής":8061,"κό ":13722,"καρ":1054,"κας":811,"κασ":794,"κατ":10049,"καθ":2426,"και":39436,"καλ":3288,"καν":3494,"λα ":2059," Ma":1020," O ":728,"κεν":791,"κετ":3212,"κευ":1338,"κεί":1744,"κει":2368,"κεκ":645,"ιφέ":650,"ιχε":1339," Co":711,"ιωτ":1177,"κέν":650,"ιός":767,"λά ":1854,"κές":3367,"ιότ":2001,"κάθ":781,"κάν":679,"κάπ":806,"κάτ":989,"ινο":2651,"ινη":1172,"ινε":1173,"ινι":1101,"ινή":1455,"ινί":997,"ινα":787,"ινό":2461,"ινω":851,"ιου":2729,"ιος":4127,"ιορ":1283,"ιον":1013,"ιολ":889,"ιοι":954,"ιοδ":1147,"ιογ":776,"κο ":960,"ιού":2201,"ιοχ":1758,"ιρι":1611,"ιρά":1156,"ιρα":723,"ιρε":766,"ισμ":7142,"ιστ":11061,"ισσ":1380,"ιση":1365,"ιτο":998,"ιτα":1283,"ιτι":2704,"ιτε":1108,"ιδρ":1035,"ιεθ":1171,"ιεί":1032,"ιδώ":1125,"ιες":926,"ιερ":1150,"κε ":8838,"ιθμ":885,"κη ":1482," To":646,"ικά":10371,"ικί":910,"ική":22548,"ικέ":3180,"ικα":3219,"ικη":1192,"ικε":1161,"ικι":1228,"ικο":9392,"κι ":739,"ικρ":1864,"ικώ":3521,"ιλί":1034,"ιλα":936,"ικό":19394,"ιλι":2810,"ιλε":728,"ιλο":1028,"ιμέ":1283,"ιμο":2191,"μα ":12255,"λαμ":1653,"λαν":1780,"λαι":1164,"λασ":1322,"λατ":899,"λαδ":919,"λαγ":813,"λαβ":1022,"λαί":667,"λητ":1184,"λην":6429,"λημ":897,"ληρ":1062,"λησ":1042,"λης":1640,"ληθ":1186,"με ":14402,"λεσ":1056,"λες":910,"λευ":2243,"λεκ":1059,"λεμ":1535,"λει":2415,"λεγ":742,"λεί":3987,"κων":656,"λίο":1804,"κών":3899,"μή ":801,"λής":941,"λία":3193,"κόρ":832,"λέξ":905,"λέμ":640,"κόμ":1163,"κόλ":651,"λέγ":681,"κότ":1771,"μά ":961,"λές":766,"κός":6008,"κόσ":1288,"λάδ":2237,"κρι":1532,"κρο":1257,"κρά":1666,"κρα":2747,"κρό":1004,"κολ":1260,"κοι":2432,"κοπ":1299,"κον":2063,"κοσ":762,"κος":1289,"κορ":683,"κογ":1034,"λο ":3553,"κου":2843,"κού":6899,"κυρ":1539,"κυβ":687,"κτω":740,"κτο":1065,"κτρ":885,"κτη":2180,"κτι":1278,"κτή":823,"κτα":758,"λη ":4716,"κιν":1980,"κισ":1099,"κκλ":769,"κην":749,"κητ":870,"κης":1489,"κλο":1123,"κλε":952,"κλη":1528," th":948,"ηχα":829,"ηρο":1562,"ηρι":1012,"ηρε":814,"ηρί":1339,"ησε":2338,"ηση":3739,"ησι":2711,"ησί":1393,"ητο":760,"ητε":799,"ητι":2642,"ητή":1996,"ητέ":684,"ητα":2938,"θήν":1152,"θήκ":739,"θαν":924,"ιά ":3103,"θέτ":764,"θέσ":1185,"ηθο":652,"θε ":885,"ηγό":671,"ηγο":953,"ηνα":1733,"ηνι":4662,"ηνο":892,"ηκα":1019,"ηκε":8651,"ηθυ":973,"ημα":7616,"ημέ":1558,"ημο":3252,"ημι":2310,"ημε":2120,"ηλα":1079,"ηλε":1560,"θυσ":990,"ις ":13118,"κα ":1888,"ιβλ":841,"ιδι":2412,"ιδή":920,"ιαδ":1030,"ιαί":809,"ιατ":1212,"ιαφ":946,"ιας":3279,"ιασ":1512,"ιαμ":1313,"ιαν":1844,"ιακ":4564,"ιό ":1664,"θώς":900,"κή ":16317,"ιάδ":1072,"ιάς":1340,"ιάρ":876,"ιάν":812,"ιάσ":850,"κά ":10264,"θηκ":7617,"θην":731,"θετ":1279,"θεσ":1224,"θερ":1269,"θεω":1121,"θεί":1506,"ια ":20899,"ιο ":9017,"θος":942,"θολ":2157,"ιν ":1082,"θνή":736,"θμό":1010,"θνι":1551,"θλη":1496,"ενε":1043,"ενη":691,"ενα":1016,"εντ":2485,"ενν":2479,"ενο":2214,"ενι":1650,"εξα":953,"ενώ":1366,"ενό":1445,"εξά":752,"επι":5002,"επα":2136,"επί":3082,"επτ":1207,"επο":863,"ερα":4072,"εργ":1600,"ερά":780,"ερί":3339,"ερι":10543,"ερε":1426,"ερη":1880,"ερν":709,"ερμ":2853,"ερο":6623,"ερό":795,"εσί":785,"εσα":886,"εση":1176,"εσσ":1054,"εστ":833,"ετά":1901,"ετέ":733,"ετα":16396,"ετί":895,"ετε":731,"ετι":1741,"ετρ":2017,"ετο":896,"ευτ":1808,"ευσ":1149,"ευρ":1328,"ευκ":741,"ευθ":751,"εφα":751,"εχν":1145,"εωρ":1834,"εων":1309,"εύε":718,"είχ":1649,"είτ":3867,"είς":773,"είο":3068,"είν":22546,"δών":1462,"είμ":673,"δύο":1317,"είδ":966,"εία":3700,"εβρ":814,"εγά":1944,"εγα":1515,"εγκ":737,"εδρ":932,"εδο":1081,"εθο":675,"εθν":2241,"εκε":1191,"εκρ":827,"εκτ":2188,"ειτ":1270,"εκα":1164,"εκδ":780,"ειδ":2526,"ειο":1827,"ειν":862,"εισ":862,"εις":3437,"ειρ":2701,"εια":5347,"εμι":793,"εμπ":762,"εμο":808,"ελφ":670,"εμβ":1975,"ελλ":4425,"ελι":1033,"ελο":1356,"ελέ":801,"ελε":3847,"ζον":1351,"ζου":798,"ης ":54494,"εύο":1107,"εύτ":1065,"ζετ":3914,"ζει":1250,"ην ":28066,"δη ":882,"γεί":984,"γεθ":651,"γει":1005,"γεν":3283,"γερ":916,"γετ":873,"δα ":3858,"γγλ":2042,"γγε":798,"γγρ":1089,"γαλ":2463,"γαν":1627,"γασ":694,"γία":4119,"γής":750,"δή ":1030,"γάλ":2004,"γάν":752,"γέν":1475,"βόρ":789,"γωγ":1517,"γρα":5451,"δο ":1489,"γρά":2441,"γού":1541,"γον":1405,"γος":1565,"γορ":893,"γου":2071,"γνω":3224,"γμα":1795,"γλώ":959,"γλι":810,"γκό":699,"γκο":1093,"γκρ":957,"γκε":929,"γκα":1052,"γισ":983,"γιο":2940,"γιν":873,"γικ":1875,"για":6740,"δηλ":1052,"δημ":2586,"δης":760,"δια":7984,"διά":2910,"διο":3225,"δικ":4263,"διε":2036,"ει ":13053,"δεν":1174,"δεκ":905,"δει":815,"δελ":851,"δες":1552,"δεύ":817,"δία":1566,"δήμ":1730,"γών":991,"εί ":5299,"δας":1990,"γων":2003,"γός":1387,"δων":753,"ες ":14729,"δυν":920,"δυτ":1257,"δου":1522,"δοσ":2455,"δος":1488,"δον":679,"δομ":954,"ερ ":1474,"δρύ":879,"δρυ":713,"δρο":2284,"δρα":2109,"εν ":2162,"αίν":1135,"αία":2533,"αίτ":698,"αίρ":1304,"αίο":2174,"αγι":742,"αγγ":1827,"αγο":1254,"αγκ":1429,"αγμ":1117,"αγν":698,"αδι":1357,"αδε":988,"αγω":2920,"αδή":866,"αβε":1016,"ας ":38230,"αρί":2489,"από":22187,"αρά":1986,"απο":6560,"απα":958,"απε":757,"αξύ":1143,"αξι":781,"ανώ":968,"ανό":2218,"αντ":8056,"ανο":2939,"ανθ":906,"ανι":4409,"ανδ":1912,"ανε":2278,"ανα":6682,"ανά":2554,"ανέ":714,"ανή":1615,"ανί":2957,"ατό":1156,"ατε":1300,"ατι":5266,"ατη":1870,"ατρ":1884,"ατο":9284,"ασσ":883,"αστ":6688,"ατά":4672,"ατέ":1441,"ατί":1716,"ατα":6390,"αση":2971,"ασι":3609,"ασκ":1313,"ασμ":1014,"ασί":3461,"αρτ":1786,"αρχ":6414,"αρα":6192,"αρμ":849,"αρο":1166,"αρι":2077,"αρκ":848,"αθο":890,"αθη":1010,"αθμ":688,"αθλ":1208,"αζί":676,"αερ":700,"αλύ":2369,"αμέ":982,"αμβ":1197,"αμα":698,"αμε":1031,"αμμ":1433,"αμο":749,"αμπ":849,"ακό":2346,"αλά":833,"αλα":2736,"αλί":1668,"αλε":761,"αλι":1989,"αλλ":4951,"αλο":1928,"ακή":1031,"αιό":1091,"αιώ":1483,"ακά":695,"ακε":724,"ακα":1680,"ακο":1635,"ακρ":1212,"ακτ":3182,"αθώ":989,"αιδ":651,"αιο":1032,"αιν":1733,"αιρ":2790,"γή ":1222,"βαν":794,"βασ":2971,"γα ":679,"αυρ":642,"αυτ":5333,"αφί":785,"αφή":1070,"αφέ":2568,"αφε":651,"αφι":1185,"αφο":1697,"αϊκ":1749,"βάν":1252,"βάλ":748,"βέρ":1034,"γο ":1180,"βου":1328,"βολ":1321,"βρο":795,"βρί":4251,"βρα":834,"βιβ":715,"βικ":723,"βιο":702,"γκ ":753,"ήτη":852,"ήτα":9260,"ήσε":1365,"ήσο":649,"ίς ":1391,"ήρξ":1088,"ήρι":880,"ήρε":756,"ίο ":4669,"ίες":2648,"ίζο":1090,"ίζε":3305,"ίδο":723,"ίδε":1013,"ίδη":788,"ίδι":1386,"ίδα":1853,"ίας":15390,"ίοδ":915,"ίος":1746,"ίου":12007,"ίπο":938,"ίνε":1855,"ίνα":24006,"ίνη":1713,"ίνο":1856,"ίλι":696,"ίκη":1461,"ίκο":1574,"ίχε":1140,"ίρι":793,"ίτλ":825,"ίτε":1304,"ίτη":995,"ίστ":2304,"ίτα":3434,"ίσκ":3610,"ίση":1856,"ίων":2775,"ίως":1118,"αι ":81620,"αν ":18884,"άνο":1282,"άνν":919,"άνι":1040,"άνε":1521,"άνδ":657,"άνα":777,"άνω":1396,"άντ":1482,"άμε":1147,"άλι":654,"άλη":999,"άλλ":3199,"άλα":1032,"άλο":1498,"άσε":1019,"άρι":1410,"άρκ":849,"άρτ":1022,"άρχ":1270,"άπο":1033,"άφο":2166,"άτω":1906,"άτι":758,"άτο":2114,"άτα":711,"άτη":871,"ές ":9688,"άστ":2257,"άση":1198,"έγε":1024,"έγι":781,"έδρ":1043,"έας":1468,"έλο":1016,"έλα":1017,"έλε":1428,"έλη":777,"έκτ":1194,"ένα":9814,"ένη":1988,"ένε":1716,"ένο":3647,"ένν":695,"έντ":1717,"ένω":1354,"έπε":703,"έρα":2072,"έργ":1441,"έρο":1656,"έρν":854,"έρε":2865,"έρι":1085,"έρχ":675,"έτο":668,"έτρ":1180,"έτη":1275,"έστ":768,"ής ":18113,"έση":981,"έχε":3074,"έχο":1069,"έχρ":1025,"έως":769,"ία ":26814,"ήθη":3124,"ήκε":1241,"ήμο":3064,"ήμε":1045,"ήμα":3234,"ήνα":1396,"άζε":1809,"άζο":714,"άδα":3349,"άδε":985,"άδο":1280,"άκη":718,"άθε":1012,"έα ":1626,"άς ":2864,"άν ":930,"Του":646," θρ":674," ιδ":2116," ηλ":1023," ημ":735," θέ":1277,"Τα ":1230," θά":727," θα":781," θε":3732," κρ":1753," κο":3790," κλ":1289," κυ":2799," λα":1212," κύ":1020," κό":2579," λέ":1007," λε":1503," ισ":2453," κα":52893," κέ":693," κά":2601," κι":1426," κε":1166," μυ":2558,"Σεπ":721," μο":3409," μπ":1646," νη":980," νε":1091," μό":948," να":5646," λο":894," με":23063," μη":1415," μι":5537," μά":792," λό":896," μέ":5756," μί":2039," μα":2448," ον":2891," ολ":648," ομ":3122," οι":5274," νό":1365," νο":3391," ξε":646," ίδ":940," γα":745," βό":838," βι":1203," βο":1444," βρ":3003," αφ":1044," αυ":4681," ατ":926," ασ":3167," αρ":6507," βα":3334," βά":792," αθ":840," αε":736," αγ":3185," αδ":879," απ":30213," αν":12857," αλ":2584," αμ":1021," αι":1819," ακ":2186," δύ":1562," εί":24110," εγ":909," δυ":1764," δο":1194," δρ":920," δε":3712," δη":3127," δι":13223," δή":1731," δί":798," γυ":721," γν":3012," γλ":1409," γρ":1532," γε":4322," γι":8013," ζω":871," ευ":1283," εφ":760," ετ":975," ερ":1138," επ":11178," εξ":2635," εν":5151," εμ":1144," ελ":4400," εκ":4866," ει":1529," εθ":1094," Χα":1287," Χρ":997,"Συν":780,"Στη":2306," άλ":1949," άν":742," έκ":1202," έλ":791," έδ":1173," έγ":922," έχ":2858," έν":9401," έρ":1085," έτ":734," ήτ":9263," Ολ":1008," Οκ":750," Οι":2387," Πε":2131," Πα":4958," Πο":2479," Ου":928," Ορ":742," Πά":1151," Ρο":774," Πρ":2843," Πό":722," ο ":9144," Ρω":975," Σο":1128," Σι":796," Σκ":861," Σε":1934," Σα":1339," π ":930," Τρ":1615," Τσ":726," Το":8380," Τζ":1148," Τα":1842," Σύ":1275," Στ":4987," Συ":1596," Υπ":1004,"Το ":7170," Φρ":703," Φι":702," Φε":912," Ισ":1154," Ιτ":907," η ":9904," Ιο":1482," Κι":702," Κε":764," Κα":4954," Κά":941," Ιω":835," Ια":1066," Ηρ":653," Ηλ":946," Θε":1961," Ντ":1192," Νο":1695," Νό":654," Μπ":2698," Μο":1622," Να":926," Νέ":832," Νι":686," Λο":1279," Μά":1156," Μέ":676," Μα":4467," Με":3720," Μι":1148," Κο":2560," Κρ":1401," Κυ":1025," Κω":831," Κό":910," Κύ":1399," Λα":1229," Λε":940," Λι":661," Βα":2096," Αυ":2137," Αρ":2641," Ασ":1614," Αν":3964," Απ":2366," Αι":968," Ακ":643," Αλ":1804," Αμ":1723," Αθ":2042," Αγ":2491," ή ":7834," Ευ":1907," Εκ":836," Ελ":3840," Εθ":914," Ερ":803," Επ":1439," Εί":1505," Δι":2396," Δη":1617," Δε":1217," Δή":1387," Γε":2953," Γκ":1274," Γι":1594," Γο":753," Γα":1202," Βε":785," Βι":896," Βρ":2238," Βο":1594," Έχ":649," Έλ":1540," Έν":836," Ήτ":719," Χ ":688," Άγ":671," Ο ":11895," Η ":10438," Β ":692," Α ":894,"Παρ":1018,"Παλ":664,"Παν":1277,"Πρω":677,"Πρό":666,"Προ":732,"Πολ":1465,"Περ":871,"Οκτ":727,"Οι ":2013," φω":763,"Μαρ":1413," χα":1979," χι":822," χρ":4665," υψ":758," φα":980," φι":921," φο":1544," φυ":1533," τω":10299," τό":929," υπ":5803," σχ":2338," συ":11696," στ":39224," τα":7256," σύ":3950," τί":845," τέ":1460," τι":4962," τη":55058," τε":2163," τρ":3378," το":79535," τμ":1047," σή":911," σα":762," σπ":865," σε":9337," ση":3591," σκ":2184," πό":3153," πρ":16846," πέ":917," πά":1081," ου":1649," ορ":3515," οπ":6947," πο":24345," πλ":4421," πι":1545," πε":9563," πα":9674," όρ":2611," όπ":2757," όν":3176," ότ":1627," όλ":952,"Μεσ":722," ως":4538," χώ":2083," χω":2280,"Βρί":1153,"Βασ":1048,"Αμε":923,"Ανα":1441,"Αντ":1044,"Αθή":1140,"Αυγ":651,"Αυτ":975,"Αστ":933,"Απο":822,"Αρχ":657,"Αγγ":839,"Αγί":679,"Δημ":1529,"Δεκ":668,"Δια":869,"Δήμ":1366,"Γερ":1165,"Γεν":1089,"Γαλ":1018,"Ελλ":2950,"Εθν":907,"Είν":1389,"Ευρ":1295,"Θεσ":739,"Ιαν":723,"Κων":707,"Με ":1185,"Ιτα":855,"Ιου":1221,"Καλ":850,"Καρ":959,"Κατ":1044,"al ":791,"and":770,"an ":997,"ati":806,"Έλλ":1427,"Ήτα":715,"ion":1164,"he ":670,"ia ":803,"igh":691,"ing":654,"ht ":652,"hum":677,"er ":1543,"es ":1146,"en ":662,"ght":666,"ng ":653,"on ":1503,"mb ":660,"us ":771,"umb":700,"tio":831,"thu":700,"ter":753},"n_words":[6375777,7261876,4927375],"name":"el"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/eng b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/eng new file mode 100644 index 000000000..4807e957e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/eng @@ -0,0 +1 @@ +{"freq":{"D":662077,"E":559834,"F":608348,"G":582849,"A":1412556,"B":916671,"C":1498503,"L":649564,"M":1059392,"N":665299,"O":394009,"H":682378,"I":978047,"J":471262,"K":369000,"U":380950,"T":1402307,"W":505824,"V":256072,"Q":51938,"P":880443,"S":1630016,"R":708545,"Y":131400,"X":37224,"Z":73521,"f":5238032,"g":4381944,"d":8729953,"e":27848709,"b":3669334,"c":7841280,"a":23418136,"n":19713516,"o":18673929,"l":10669664,"m":6170962,"j":262547,"k":1633239,"h":10134148,"i":20570816,"w":3362380,"v":2275926,"u":6637499,"t":19408712,"s":16004058,"r":16873084,"q":170855,"p":4621926,"z":397471,"y":4124069,"x":440231,"é":58984," l":780297," m":1079276," n":608651," o":3436911," h":813084," i":3938466," j":78084," k":215197," d":941771," e":740834," f":1754540," g":440359," a":5405782," b":1659799," c":1744132," y":83514," u":322099," t":5058192," w":1900306," v":255788," q":29653," p":1560368," s":2415857," r":962057," J":460420," K":336817," H":654413," I":868613," N":607763," O":345142," L":596797," M":988580," B":847481," C":1361375," A":1263874," F":559603," G":550525," D":599768," E":493444," Z":67911," Y":122764," S":1468740," R":648863," Q":47311," P":804972," W":486015," V":212635," U":359652," T":1336813,"A ":159383,"Da":104182,"Cu":44169,"Cl":60734,"Co":426605,"Cr":65402,"Ce":60359,"Ch":258329,"Ci":62395,"Ed":38074,"Ea":55403,"Du":53228,"Do":65822,"Dr":31956,"De":174035,"Di":112559,"Fe":83008,"Fa":58998,"Eu":42215,"En":125985,"Em":27259,"El":44031,"Ge":134248,"Ga":73890,"I ":75735,"Fr":140633,"Fo":106181,"Fl":37525,"Fi":77847,"B ":28902,"C ":86756,"Au":138720,"Ar":132765,"At":36103,"As":94697,"D ":41383,"Ba":186506,"Af":42815,"Ac":49109,"Ad":33381,"Am":167256,"An":117416,"Ap":56752,"Ai":30417,"Al":127646,"Bu":74783,"Br":187559,"Ca":304473,"E ":36124,"Bi":58070,"Be":129264,"Bo":112086,"Bl":40686,"Ko":45338,"Le":127247,"Li":124649,"La":147235,"Lu":31872,"Lo":122679,"Me":130273,"Mi":151239,"O ":29173,"Ma":405967,"Mu":71213,"Mo":145746,"Ni":43349,"Ne":178415,"Na":143656,"P ":44679,"No":180123,"Ol":47193,"On":40436,"Oc":53105,"Gi":29349,"Gr":130751,"Go":73286,"Gu":48214,"Ha":132380,"He":218817,"II":40680,"Hi":92944,"Ho":127334,"Hu":45621,"K ":32711,"In":253915,"Is":60970,"It":340082,"Ir":53269,"Ja":154594,"L ":34197,"Je":52293,"Jo":101484,"Ju":117086,"Ka":74254,"M ":37484,"Ki":74159,"Ke":51086,"Un":220729,"Tu":36890,"Tr":84116,"US":35610,"To":93419,"Th":850306,"Ti":41292,"Te":99569,"Ta":74444,"V ":32754,"Sw":37200,"Sy":30043,"St":291796,"Su":96654,"Wo":87820,"Wi":99188,"Wh":33410,"Wa":135830,"We":94221,"Vi":82206,"Va":46571,"Ve":37939,"Pu":36227,"Pr":165318,"S ":81629,"Pe":109002,"Pa":220340,"Pl":35710,"Po":107653,"Pi":44494,"Ph":43729,"Or":50633,"R ":32772,"Se":177109,"Sc":119654,"Si":88455,"Sh":112206,"Sp":78520,"So":160970,"Ru":53200,"Sa":155395,"Re":186160,"Ri":92732,"Ro":164209,"Qu":37827,"T ":30323,"Ra":101065,"b ":134105,"a ":2991353,"Yo":71760,"i ":355519,"gd":31577,"ge":721279,"ga":370090,"fl":84104,"ff":180681,"fi":526440,"fr":391564,"fu":82822,"ft":147685,"fo":920673,"gy":74018,"he":4842012,"ha":1007728,"gn":127025,"gl":188283,"gi":377563,"gh":367310,"gg":29821,"gu":248240,"gt":38716,"gs":80931,"gr":275281,"go":177983,"du":289181,"dv":26927,"dw":35481,"dy":74747,"g ":1213593,"ea":1274992,"eb":152577,"ec":841985,"ed":2289411,"de":1320778,"dd":64948,"dg":51752,"di":930651,"dm":40343,"dl":51794,"do":273396,"ds":196380,"dr":141993,"ew":250035,"ex":221189,"eu":76879,"ev":357914,"ey":221145,"fa":236961,"h ":1529402,"fe":315742,"eh":48317,"eg":294475,"ef":194847,"ee":528675,"el":1146347,"ek":64162,"ei":272994,"ep":332185,"eo":187165,"en":2427008,"em":679038,"et":814658,"es":2395636,"er":4179896,"eq":41573,"ca":1058365,"e ":8494237,"by":527627,"bs":58904,"br":217191,"bu":297420,"bo":472510,"bl":324534,"bi":213219,"bb":35633,"be":846369,"da":395082,"f ":2316051,"cy":71900,"cu":238303,"ct":817847,"cs":93807,"cr":254963,"co":1252186,"ck":305854,"cl":251999,"ci":687756,"ch":1106571,"ce":1086909,"cc":111912,"c ":457702,"az":72598,"ay":450984,"ba":470554,"d ":4698126,"at":2664116,"as":2180049,"ar":2492347,"ax":35262,"aw":117859,"av":238618,"au":228752,"ak":197752,"al":2475728,"ai":590954,"aj":50310,"ap":330102,"am":913130,"an":4857931,"ac":715176,"ad":654223,"ab":325448,"ag":433896,"ah":83166,"ae":126319,"af":115896,"nu":217006,"nt":1825754,"ns":843426,"nr":30719,"no":643421,"nn":264870,"nz":30433,"ny":179007,"nv":69977,"oe":69809,"of":2379880,"oc":501750,"od":362363,"oa":174782,"ob":174628,"om":1179222,"on":3432632,"ok":132945,"ol":912097,"oi":135962,"og":247625,"oh":71587,"ot":549343,"os":498414,"ov":435331,"ou":1258409,"op":505111,"oo":421044,"or":2962572,"r ":3075136,"ox":44665,"ow":555778,"oy":75842,"pe":765233,"pa":591162,"pl":399253,"po":579386,"ph":211053,"pi":302192,"lo":761247,"lm":115044,"ll":1129598,"ls":295312,"lp":38509,"lw":35880,"lv":66473,"lu":281619,"lt":228186,"ly":725738,"o ":1535371,"ma":968442,"mb":416311,"me":1451345,"mi":591681,"mm":262444,"mp":468344,"mo":504581,"ms":133483,"mu":261893,"my":62036,"p ":307798,"na":1160193,"nb":27967,"nc":750937,"nd":2690580,"ne":1275364,"nf":87191,"ng":1746068,"nh":37213,"ni":1104016,"nk":109355,"nl":88734,"nm":67028,"ju":44053,"jo":70049,"ki":171410,"kh":26225,"ke":323852,"ka":109789,"m ":983735,"ky":30837,"ks":106786,"ko":46397,"kl":33919,"km":32936,"kn":143680,"li":1420180,"lk":42132,"le":1534709,"ld":351541,"lg":35629,"lf":59414,"la":1421955,"lb":105992,"n ":6374219,"hr":171058,"hw":45980,"ht":193546,"hu":172799,"hi":1052052,"hn":92044,"ho":773733,"hl":46194,"hm":30448,"id":496380,"ic":1849130,"ib":159645,"ia":1169835,"ig":507511,"if":219645,"ie":800933,"hy":82019,"k ":515132,"ir":647827,"is":3249081,"it":1893192,"iu":65009,"iv":578092,"ix":50259,"ik":78883,"il":1065515,"im":394260,"in":4877222,"io":1592954,"ip":270764,"je":50702,"iz":128734,"l ":1934675,"ja":50690,"xi":69443,"xp":49241,"xt":57882,"z ":53637,"xa":40308,"xe":33587,"wh":393518,"wi":429474,"wn":279417,"wo":263879,"wr":100589,"ws":68714,"vy":28150,"y ":3097451,"wa":1012808,"we":415691,"vi":599499,"vo":108876,"ve":1210480,"va":267555,"x ":126181,"ui":189592,"uk":33957,"ul":459768,"ue":281220,"uf":33361,"ug":230153,"ur":968763,"us":936891,"ut":635083,"um":403450,"un":943875,"up":204022,"ty":567576,"tu":446554,"tt":322006,"tw":175696,"ub":264839,"ua":340676,"ud":207254,"uc":282987,"w ":304612,"to":1515648,"tm":51220,"tl":201040,"ts":524135,"tr":893262,"te":2648213,"ti":2353666,"th":4782590,"v ":29410,"tb":79573,"tc":66980,"ta":1180046,"su":341240,"ss":646227,"st":2324937,"sy":102577,"sw":27118,"sl":145841,"sk":108573,"sn":41499,"sm":113246,"sp":316999,"so":700411,"sc":280155,"se":1450470,"sh":709009,"si":1101025,"u ":116514,"sa":232414,"sb":34898,"rr":265014,"rs":761380,"rt":886247,"ru":271327,"rv":158410,"rw":40021,"ry":553810,"rp":87486,"ro":1594919,"rn":650417,"rm":435749,"rl":279627,"rk":261286,"ri":2008460,"rh":32041,"rg":276649,"rf":65494,"re":2611877,"rd":466156,"rc":300833,"rb":95933,"ra":1639206,"t ":3468815,"qu":157005,"s ":7219728,"pt":158295,"pu":265747,"pp":173102,"pr":683558,"ps":94491,"zi":58211,"ze":102677,"za":82368,"zo":27033,"ye":187250,"yc":42157,"yd":28943,"ya":95795,"yt":30002,"ys":153061,"yr":36606,"yp":60686,"yo":54105,"yn":59856,"ym":80995,"yl":75727,"yi":42920,"一":42790," Ga":73074," Ge":133297," Fo":105500," Fr":140138," Fi":76403," Fl":37253," Ha":131725," He":218212," Go":72637," Gr":129383," Gu":47617," Gi":28529," Hu":45416," Ho":126780," II":28541," Hi":92512," Je":52048," Ja":154158," Ir":53197," Is":59983," It":339895," In":252514," Ka":73450," Ke":49770," Ki":73234," Jo":100944," Ju":116938," La":145853," Le":125799," Li":123371," Ko":45184," Ma":403673," Mi":150289," Me":129337," Lo":122023," Lu":31698," Ne":176925," Na":142533," Ni":43042," Mo":144948," Mu":70352," A ":81995," Ap":56659," Am":166952," An":116734," Al":126650," Ai":30214," Af":42668," Ac":48855," Ad":33141," Ba":185398," Au":138482," At":35966," As":93159," Ar":131824," Be":128479," Bi":57574," Bl":40368," Bo":111176," Br":186728," Bu":74408," Ca":300905," Ce":60031," Ci":62055," Ch":257143," Cl":59706," Cr":64523," Co":423247," Cu":43407," Da":103400," Di":111836," De":173171," Dr":31720," Do":63383," Du":52940," Ea":55250," Ed":37865," El":43749," En":125075," Em":27148," Eu":42050," Fe":82594," Fa":58222," Wo":87042," Wi":98480," Wh":33053," We":93550," Wa":135146," Yo":71619," a ":1606658," Or":50217," Po":106745," Pl":35261," Pi":44206," Ph":42887," Pe":108520," Pa":218936," No":179642," Ol":47101," On":40029," Oc":53053," Ra":100251," Qu":37258," Ro":163370," Re":185467," Ri":92437," Pr":164608," Pu":36045," Sy":29848," Sw":37042," Su":96395," St":289114," Ta":73883," Th":847432," Ti":40916," Te":98615," Tr":83585," US":33813," To":92734," Ru":52977," Sa":154637," Sh":111397," Si":87885," Sc":118544," Se":176317," So":160018," Sp":77680," Va":46297," Ve":37650," Vi":81481," Tu":35914," Un":220424," im":47481," in":2124350," is":1535535," it":174191," ki":30820," jo":31616," ju":31891," ha":241917," he":193790," gi":28626," gr":121630," go":63783," gu":29424," hi":208416," ho":110982," hu":32878," ne":121038," na":174050," mu":147201," mo":231837," on":505803," of":2275616," nu":46047," no":232717," le":140717," li":204448," la":217455," kn":129366," km":28301," me":218768," mi":119142," ma":335287," lo":197009," af":58077," ag":45613," ab":70854," ac":136746," ad":69502," am":31088," an":1904322," ap":69597," ai":40857," al":285645," au":57146," ar":316462," at":262226," as":400242," ba":223899," bi":52056," be":361253," bo":296458," bl":27386," by":488337," bu":118496," br":85339," ca":237167," es":49439," en":130005," em":28882," el":86812," fe":73621," fa":169421," ev":56247," ex":119951," fu":49639," fr":341564," fo":746598," fl":49512," fi":320292," ge":92358," ga":85124," cl":107340," co":825577," cr":113302," ce":122706," ch":161778," ci":78624," da":76510," cu":74858," do":65310," dr":48010," de":365522," di":285811," ed":47217," ea":97123," du":78958," ye":60017," ru":58222," sa":63365," se":417230," sc":118543," si":220940," sh":125764," sn":27188," sm":42001," sp":191590," so":270927," qu":28948," ra":127133," re":580460," ri":81201," ro":102378," pu":110299," pr":488102," s ":285424," ot":53672," ou":36365," ov":43302," op":81547," or":335005," ow":28576," pe":132888," pa":238807," pl":194868," po":256546," pi":40433," ph":50321," wa":774642," we":177231," wr":78668," wo":147411," wi":321826," wh":387560," va":54528," ve":51196," vo":40129," vi":105281," ty":26790," tw":69959," us":113343," up":41302," un":149473," ta":60356," sy":54778," st":354336," su":191136," tr":168050," to":791933," th":3629714," ti":77241," te":209958,"Feb":38336,"Eur":34468,"Eng":96944,"Ger":62713,"Geo":33733,"Gen":26192,"Fra":61982,"Fre":54323,"For":54660,"II ":31692,"His":27636,"Hig":26895,"He ":118997,"Her":26981,"Har":34188,"Gre":62525,"Gra":36710,"Int":46918,"Ind":83336,"In ":64014,"Hou":31497,"Arm":26565,"Apr":40277,"Ass":43311,"Aus":73786,"Aug":44651,"Bar":42165,"Afr":28749,"Ame":138898,"Cal":50030,"Car":57990,"Cat":29319,"Can":84273,"Ber":26471,"Bra":33017,"Bro":31697,"Bri":93113,"Dec":45892,"Chr":35874,"Chi":73091,"Cit":38778,"Cen":43272,"Cha":89919,"Cor":34743,"Com":89536,"Col":68792,"Con":74902,"Cou":101975,"Eas":34019,"Dis":41703,"Nat":69269,"New":118080,"Nov":49796,"Nor":97601,"Oct":42904,"Oly":28739,"Pla":26686,"Per":28472,"Pen":27579,"Par":98820,"Pro":69398,"Pri":36739,"Pre":41911,"Pol":34263,"Ita":30913,"Isl":36514,"It ":288844,"Jap":37112,"Jan":53046,"Joh":48960,"Jul":46542,"Jun":47295,"Kin":45793,"Lea":42060,"Lan":29809,"Lin":26493,"Lon":35381,"Man":49459,"Mar":140591,"May":50344,"Mon":37435,"Mic":30191,"Min":35884,"Mus":28824,"Wor":61067,"Wil":46697,"Wes":53739,"War":53697,"Wal":33670,"Yor":47584,"Str":31655,"Sta":170783,"Ste":27246,"She":47105,"Sha":26436,"Ser":32863,"Sep":45219,"Spa":35346,"Sou":76587,"Rus":29193,"Sco":37321,"Sch":55225,"San":42456,"Riv":36843,"Rep":36734,"Rom":34841,"Uni":206527,"The":741033,"Thi":55958,"Tra":32863,"bit":27600,"bil":34265,"bin":32338,"bly":27084,"ble":108674,"bli":153281,"boo":43455,"bor":211694,"bot":33326,"bou":74106,"be ":86424,"ban":103832,"bal":111539,"bac":27179,"bas":116354,"bee":53796,"bec":41647,"ber":372832,"bel":55314,"bes":39082,"bet":76601,"bia":36531,"ca ":71415,"car":71337,"cas":54417,"cat":224104,"can":218593,"cap":33144,"cad":26654,"cam":39022,"cal":268647,"ce ":489631,"bri":35233,"bro":46239,"bra":53964,"bre":38618,"bru":40872,"bur":52830,"bum":61942,"bui":38535,"but":82424,"bus":32037,"by ":517575,"am ":158006,"ake":79597,"aki":36034,"ajo":27606,"al ":1032287,"ail":109529,"ain":263108,"air":75684,"agu":57502,"ago":34773,"anu":71865,"any":116307,"ano":50033,"ann":83296,"ant":217929,"ans":132995,"ane":74984,"ang":153929,"ani":212965,"ank":54539,"ana":169898,"anc":203858,"and":1922995,"amm":33827,"amo":43526,"amp":91990,"ams":33255,"ami":135603,"ame":296400,"amb":32800,"ama":60146,"aly":26784,"alt":66067,"als":156873,"alo":44306,"all":466989,"ali":291050,"ale":104464,"ala":82861,"alb":63960,"an ":1345264,"aba":26164,"abe":27729,"abi":43800,"abl":95465,"abo":73249,"ae ":67161,"ad ":136134,"aft":64376,"aff":27842,"ai ":26417,"aga":52212,"age":211927,"ael":26991,"ado":32963,"adi":130468,"ade":130763,"ack":93180,"aci":48413,"ach":115898,"ace":139311,"acc":38863,"ada":60436,"act":176914,"azi":34919,"ays":38857,"aye":87163,"at ":514237,"arg":65842,"are":299717,"ard":199526,"arc":122863,"ara":130356,"aro":62443,"arn":35663,"arm":40703,"arl":119272,"ark":89799,"ari":222546,"arr":82306,"ars":76523,"art":349130,"ary":226746,"asi":41320,"ash":45659,"ase":201692,"aso":57197,"ask":29635,"ar ":287761,"apa":53686,"ape":43062,"aph":44106,"app":80291,"as ":1288188,"ava":37165,"aut":60210,"avi":60667,"ave":94995,"ay ":243951,"awa":44906,"ata":58365,"ast":279617,"ass":158911,"atr":35326,"ato":75056,"ate":773247,"ati":841381,"ath":123599,"aw ":33098,"att":81527,"atu":81250,"aus":27235,"jec":34085,"jor":28420,"itl":30516,"ito":44622,"itu":81601,"itt":81137,"its":101906,"ity":314774,"ism":33565,"isl":34570,"iso":38810,"iss":83951,"ist":561559,"ita":125707,"ite":286513,"ith":287933,"iti":312557,"ium":39769,"iva":48200,"ix ":27697,"ivi":104219,"ive":414501,"is ":1834908,"ion":1320795,"ior":32367,"iou":46819,"ipa":66227,"ir ":124191,"irs":127746,"isi":109243,"ish":348637,"ise":68787,"isc":59122,"ire":165519,"ird":33893,"irc":26906,"it ":178657,"ize":56700,"iza":46289,"kin":80796,"ker":49025,"ket":62341,"key":30606,"ke ":83682,"ks ":77920,"kno":134011,"ka ":41749,"ha ":26541,"ham":91101,"han":137177,"hai":28881,"hal":42170,"hav":58023,"har":141850,"has":120534,"hat":219394,"had":38461,"he ":3774627,"hel":72126,"hei":75673,"hed":104387,"hea":95197,"hey":47349,"hes":81158,"her":373103,"heo":27238,"hen":82591,"hem":53106,"hig":49277,"hie":27426,"hic":185273,"hip":92853,"hin":140164,"hil":96538,"his":233818,"hit":44255,"hir":71717,"hn ":39410,"ho ":150031,"go ":38352,"gle":57486,"gli":56142,"gn ":28550,"gla":57467,"gne":39182,"gs ":62491,"gov":34838,"gro":78380,"gra":130928,"gre":50553,"gui":30022,"gua":43805,"gue":71236,"gy ":58853,"gus":48388,"iam":54702,"ial":191889,"ian":404233,"iat":85021,"ic ":400287,"ibl":26901,"ibu":29254,"id ":86767,"ibe":47065,"ia ":367003,"iet":50527,"iel":55976,"ien":102314,"ier":62637,"ies":307456,"ied":65179,"ifo":38546,"iff":31829,"ife":37449,"ifi":68240,"ics":90231,"ict":157327,"icu":32368,"ico":35459,"ick":77376,"ici":172909,"ich":222330,"ice":143792,"ie ":67990,"ica":469571,"idi":26260,"ide":209151,"ida":78657,"il ":176048,"im ":36451,"iga":31696,"igh":217420,"igi":75927,"ign":93132,"imp":47812,"ime":121995,"imi":41657,"ip ":77179,"inc":218718,"ind":114260,"ina":201512,"inn":50515,"ino":47946,"int":230917,"ins":127823,"inf":38004,"ine":357110,"ing":1178957,"ini":149339,"inv":30106,"ike":31715,"ila":50860,"in ":2015240,"ilo":31568,"ill":253039,"ilm":70454,"ili":107918,"ild":57179,"ile":87652,"ima":76627,"io ":93766,"ilw":27998,"ily":104441,"ilt":33467,"how":39080,"hol":72031,"hom":45604,"hon":34484,"hos":48768,"hou":71727,"hoo":99559,"hor":109022,"hro":61086,"hre":44973,"hri":42093,"ht ":111042,"hy ":31885,"hum":60594,"hur":46747,"ffe":52374,"ffi":65666,"fes":54841,"fer":101678,"fea":31829,"fam":97344,"fac":45076,"ff ":28943,"fe ":33600,"ext":42471,"exa":34847,"ews":32501,"exp":39847,"exi":35172,"eta":52929,"ete":109151,"eti":91823,"eth":57374,"esp":36940,"est":416254,"ess":250577,"etr":52595,"ett":68152,"etw":81955,"ety":27383,"ew ":152274,"eve":202090,"evi":96051,"ex ":29419,"ey ":184413,"epe":34508,"er ":1640997,"epa":43995,"eor":48705,"eop":40243,"es ":1236398,"ept":72575,"epu":31828,"epr":49381,"erl":52014,"eri":370698,"erg":54150,"ere":274035,"erf":42571,"erc":40232,"era":262856,"erb":34102,"et ":183510,"equ":41108,"esi":112993,"esc":38776,"ese":189976,"ery":53481,"erv":128955,"err":75913,"ert":119791,"ers":454490,"ern":296552,"erm":132045,"ero":60052,"en ":515700,"ela":94480,"eld":88206,"ele":239396,"eli":77371,"ell":173610,"elo":78428,"els":41004,"ely":58392,"emb":232607,"ema":57740,"eme":113005,"emo":49872,"emi":71126,"emp":43662,"ene":128335,"eng":56090,"ena":53361,"end":141343,"enc":194004,"eno":33355,"enn":56995,"eni":62631,"enu":41299,"ens":118987,"ent":917089,"ege":50969,"egi":112559,"ek ":35390,"eir":69644,"ein":59892,"eig":51339,"el ":184102,"em ":65326,"gis":39618,"gin":123942,"gio":71590,"gic":30033,"gia":32230,"ght":158712,"gen":144495,"ger":93467,"ges":68825,"gh ":114066,"ged":27606,"gdo":27360,"ge ":289041,"gas":27663,"gar":46583,"gat":28511,"gam":47831,"gal":29045,"gan":93331,"fte":73646,"ful":30197,"ft ":41960,"fre":30903,"fri":38796,"fro":298934,"fou":123314,"for":682161,"foo":52751,"fol":40754,"fic":131579,"fie":53477,"fil":79707,"fin":56926,"fir":119031,"da ":86635,"de ":228034,"dal":30100,"dae":42405,"dat":50729,"dar":41780,"dan":30719,"day":44277,"cul":69156,"ctu":58584,"cts":42767,"ctr":37744,"cto":137353,"cti":262008,"cte":91935,"cy ":49469,"cus":28281,"cur":73843,"cla":60174,"cle":56340,"clu":89562,"clo":27081,"co ":51753,"coa":30142,"con":327550,"col":81553,"com":369257,"cor":122655,"cov":34759,"cot":39747,"cou":101684,"cs ":92018,"ct ":169935,"cre":89454,"cra":42776,"cri":68130,"cro":41753,"cco":29437,"cce":37436,"cea":26454,"ch ":441284,"cer":71180,"ces":153825,"cen":136988,"cem":49322,"cel":32556,"ced":67120,"cha":166560,"chu":28019,"cia":202890,"ck ":147449,"cie":145817,"che":138582,"chi":112580,"cho":124613,"chn":32667,"cil":38009,"cis":28214,"cit":63842,"cin":40251,"cip":75068,"cke":66684,"ed ":1971122,"ebr":59143,"eac":57373,"eag":49669,"ead":94691,"ean":92098,"eal":72020,"eam":67571,"ear":238611,"eas":225475,"eat":190659,"ea ":97410,"efo":27942,"efe":67003,"ega":48293,"eek":39188,"een":176170,"eed":37937,"eer":50775,"eet":39266,"edi":120330,"ede":54090,"edu":36419,"ech":57443,"eci":121874,"ece":81981,"eca":34537,"ee ":109231,"ecu":34646,"ect":304913,"eco":150097,"dy ":58601,"dur":62131,"don":63380,"dom":45245,"ds ":164811,"duc":125723,"dra":35355,"dre":38221,"dge":45767,"dic":54056,"dia":144125,"der":278249,"des":154773,"dev":51103,"dea":34588,"ded":141601,"def":26810,"del":51924,"den":154840,"dem":42344,"dep":50458,"dle":29935,"do ":34660,"div":36865,"din":170282,"dio":57931,"dir":47066,"dis":162456,"dit":74391,"die":65117,"dif":26218,"rga":62829,"ri ":41893,"rgi":33226,"rge":101036,"ret":62986,"res":357790,"rev":42186,"rfo":28887,"rds":61017,"rg ":35933,"rea":244476,"ree":171216,"ref":62077,"rec":149809,"red":206208,"reg":86193,"rem":55031,"ren":193932,"rel":146404,"rep":68957,"rdi":57659,"rde":80880,"re ":634483,"rch":164110,"rce":59020,"rd ":218199,"rap":56827,"rar":34987,"ras":43044,"rat":260279,"rai":83507,"rag":34608,"ran":265077,"ram":80300,"ral":264928,"rab":26255,"rad":103893,"rac":129420,"rpo":42976,"rs ":371607,"ros":58364,"rot":58999,"rom":337721,"ron":118148,"roo":26751,"rop":109260,"rou":191436,"rov":99028,"row":41881,"roa":55237,"rod":87645,"roc":66994,"rol":65046,"rof":62861,"rog":49055,"rnm":34849,"rna":118629,"rne":61259,"rni":62594,"ro ":47142,"rma":145311,"rme":117007,"rmi":32749,"rly":65353,"rli":51474,"rld":75350,"rle":27840,"rn ":330287,"rks":33396,"rke":46561,"rm ":73619,"rio":79616,"rit":248352,"ris":163763,"riv":53880,"rig":116494,"ril":65623,"rin":255678,"rim":52709,"ria":159780,"rib":60454,"ric":377068,"rid":60669,"rie":181610,"rk ":140894,"ruc":35769,"run":39647,"rum":30319,"rus":32542,"rva":27044,"rvi":62552,"rve":65133,"ry ":509562,"rsi":95891,"rso":35794,"rsh":28300,"rse":60300,"rta":48186,"rst":132558,"rtm":26912,"rte":66419,"rth":190521,"rti":127728,"rua":38894,"rts":59598,"rty":55015,"rt ":230530,"rro":33066,"rri":69478,"rre":97252,"rra":30166,"san":29214,"sha":36063,"sho":85008,"she":117943,"shi":166608,"sid":90354,"sic":111518,"sia":80711,"sit":152904,"sis":68592,"sin":187018,"sio":187210,"sim":26375,"sig":69827,"scr":41549,"se ":323378,"sci":38993,"sch":76599,"sco":58271,"sev":36211,"ser":204330,"ses":72706,"set":56749,"sh ":261718,"sea":111064,"sed":251715,"sec":65010,"sen":110589,"sem":35416,"sel":52566,"spo":60807,"spe":154402,"spi":31807,"spa":33041,"sou":97501,"sol":40004,"som":46889,"son":213206,"sor":49003,"soc":65715,"st ":788491,"ss ":186657,"sla":91489,"sm ":27910,"sna":26235,"so ":118506,"sma":61408,"sys":38243,"sse":101933,"ssa":44414,"sso":82323,"ssi":178639,"ste":308026,"sta":321451,"sto":159447,"sti":202749,"stl":26896,"stu":53381,"str":353511,"sts":54520,"sub":56163,"suc":48817,"sul":26601,"sup":33543,"sus":37393,"sur":52388,"tai":93008,"tak":29757,"tal":158887,"tag":31026,"tab":60969,"tba":73096,"tat":294451,"tar":154358,"tan":148320,"tch":55824,"te ":378459,"ta ":92521,"pe ":62967,"par":214065,"pat":33109,"pac":31182,"pal":68434,"pai":39322,"pan":124559,"phe":35230,"pho":33690,"phi":46768,"pea":63524,"pec":127586,"ped":38131,"pen":76105,"peo":27260,"per":254210,"pet":53680,"pla":213772,"pli":36447,"ple":105992,"plo":26352,"phy":39410,"pic":63629,"pin":46550,"pio":41668,"pit":34080,"por":147134,"pop":69835,"pos":94042,"pon":41677,"pol":103325,"ps ":57068,"ppo":34542,"ppe":56579,"pub":101611,"pte":60939,"pti":34138,"pri":140547,"pre":169814,"pro":351896,"pur":26601,"put":38175,"pul":69919,"qua":54197,"que":60004,"qui":38739,"ra ":108610,"ngi":45147,"ngl":153748,"ngu":51932,"ngt":37246,"ngs":65275,"ni ":33062,"nge":128219,"nga":40074,"ngd":28313,"nel":35766,"nen":30704,"ner":137621,"net":62476,"nes":167423,"ng ":1115424,"nea":48684,"ned":116572,"nee":30138,"nfo":27425,"ney":30714,"new":36703,"nct":31942,"nco":45249,"nci":91672,"ncl":65296,"nce":360792,"nch":88213,"ne ":474805,"ndu":39629,"ndr":33212,"nds":71457,"ndo":66887,"ndi":147835,"nde":264119,"nda":82618,"ncy":32567,"nal":361592,"nam":140852,"nan":41261,"nar":46225,"nad":72347,"nag":33449,"nai":32626,"nd ":1932876,"nat":199905,"na ":142173,"ny ":146188,"nve":33106,"num":41405,"nus":46108,"nua":61979,"nty":82414,"nto":84185,"ntu":58438,"nts":118194,"ntr":155494,"nti":190207,"nth":52495,"ntl":47080,"nta":166897,"nte":282517,"nsu":48967,"nst":113470,"nse":49755,"nsh":53144,"nsi":90541,"nt ":574346,"ns ":352877,"nol":27739,"nom":44734,"non":40510,"not":75828,"nor":109034,"now":162156,"nov":41537,"nne":95671,"nna":27532,"nni":61016,"nme":53495,"nly":54407,"no ":47600,"nic":132031,"nia":137970,"nk ":44974,"niz":43878,"niv":81629,"nis":146601,"nit":215552,"nio":55312,"nin":128702,"ogr":72732,"ogi":44598,"ohn":44056,"ogy":47192,"oin":47463,"ok ":58105,"ol ":109628,"oce":39082,"oci":84252,"ock":92930,"oca":158968,"occ":29313,"ode":77618,"of ":2204484,"odu":81510,"oft":39655,"off":67447,"ofe":46203,"oad":59707,"od ":90721,"obe":66424,"ows":30274,"own":272385,"owi":30580,"ow ":104160,"oti":37576,"oth":132550,"ote":72682,"ott":42106,"oto":39358,"ost":134462,"ota":47221,"otb":59122,"osi":37738,"ose":115458,"oss":51862,"owe":69263,"ovi":113638,"ove":271311,"oug":99629,"oul":30838,"oun":383251,"oup":67359,"ous":158478,"our":185741,"out":265981,"opo":44332,"opi":26584,"opl":40248,"ope":150764,"oph":34738,"os ":57513,"opu":63831,"ool":97648,"ook":83743,"ood":64494,"or ":897485,"oot":80611,"ork":137621,"orl":77957,"orm":213505,"orn":233282,"oro":42745,"orp":39756,"orr":27698,"orc":40804,"ord":187024,"ore":161271,"org":83794,"ori":179394,"ort":324283,"ors":65851,"ory":92826,"ot ":75528,"ora":99397,"ola":48347,"old":74258,"on ":1693252,"oli":168296,"oll":152650,"ole":57272,"olo":130918,"olu":51650,"om ":355568,"ona":295881,"ond":125458,"onc":37498,"onf":27843,"one":226758,"ong":180887,"oni":86395,"onl":50368,"onn":32769,"ono":57151,"ons":362489,"ont":151478,"ony":30391,"oma":89149,"ome":169344,"omb":33063,"omi":82283,"omm":164677,"omp":213665,"omo":39559,"op ":54660,"la ":85626,"le ":464484,"lf ":36467,"lde":36942,"ldi":28865,"lab":36068,"lac":84352,"lag":63397,"lai":31387,"lan":374156,"lar":145329,"lat":207187,"las":100146,"law":29496,"lay":143764,"ld ":226258,"lbu":63795,"ls ":147230,"lon":87604,"lop":54959,"lor":52442,"loc":148176,"log":104122,"los":46581,"low":85754,"lth":30060,"lti":36200,"lud":61069,"lub":38036,"lue":31016,"lso":110778,"lt ":61158,"li ":29468,"ley":50488,"lev":69397,"les":177287,"let":59346,"ler":75366,"lem":45662,"len":64181,"leg":67495,"led":96172,"lec":118736,"lea":145235,"lls":32993,"llu":31038,"lly":155319,"lo ":32182,"lla":120635,"lle":228951,"lli":124524,"llo":71927,"lm ":62508,"ll ":345769,"lit":221318,"lis":254417,"lin":196823,"liz":27437,"liv":42501,"lic":149255,"lia":177899,"lig":44454,"lie":64153,"lif":67751,"ma ":56941,"mb ":40338,"mai":57333,"mad":33441,"mag":32391,"mar":102764,"mas":36713,"mal":90910,"man":305273,"mat":146584,"mbl":26607,"mbi":34922,"mbe":250295,"me ":304088,"med":139063,"mea":33106,"met":85213,"mes":108882,"mer":308315,"mem":71604,"men":353373,"lve":34044,"lum":34502,"lus":42702,"ly ":633235,"lwa":32178,"lym":34483,"mpi":86987,"mpe":67319,"mpo":59756,"mpl":65250,"mpu":32461,"ms ":108315,"mod":36169,"mon":129400,"mol":27569,"mov":30527,"mor":62243,"mos":67786,"mot":45357,"mou":50940,"mpa":78503,"my ":44622,"mus":79882,"mul":30159,"mun":115137,"min":162859,"mil":151172,"mis":47781,"mit":48071,"mic":78126,"mmu":68704,"mmi":37447,"mmo":49689,"mma":30077,"mme":66787,"zed":29181,"zat":36341,"yst":59562,"ysi":32556,"ys ":46066,"ype":26271,"yea":55238,"yed":50493,"yer":52194,"ymp":36974,"yin":35501,"wo ":61016,"wn ":223496,"ws ":47661,"wri":85490,"wor":132758,"wes":66741,"wer":121358,"wel":48031,"wed":28630,"wee":76113,"whe":65586,"whi":161339,"who":156434,"wit":254528,"win":75777,"way":79562,"war":108109,"was":721522,"via":29199,"vil":95978,"vin":109107,"vic":63884,"vid":74216,"vie":42322,"vis":102225,"vol":39542,"ver":416461,"ves":68869,"ven":139602,"vem":57889,"vel":128051,"ved":73656,"ve ":294814,"val":55056,"van":50667,"var":47368,"vat":46841,"usi":127657,"use":190347,"ust":198208,"uss":43860,"uth":195687,"uti":76065,"ute":88005,"us ":269807,"ut ":151960,"ura":72791,"urc":49405,"ure":175159,"urg":39826,"uri":124329,"urn":72450,"uro":43771,"urr":69334,"urs":30553,"urt":42019,"ury":47606,"ur ":96286,"upp":28633,"umm":33986,"uma":31954,"umb":94738,"ume":46174,"uly":40527,"unt":202586,"uni":169488,"unc":71870,"und":253741,"ung":45523,"une":67239,"up ":99562,"um ":146010,"ult":82523,"ull":33469,"ule":32343,"ula":137681,"un ":32424,"uil":50329,"uis":33184,"uit":37221,"ul ":41234,"ugh":110128,"ugu":55721,"uct":69612,"ude":66964,"udi":73540,"uca":35169,"ue ":120838,"uce":56991,"uch":53880,"ues":42067,"uen":42045,"ub ":41295,"uat":42205,"uar":119614,"ual":88610,"ubl":124785,"uag":32210,"typ":31249,"ty ":506251,"tur":219279,"tut":36373,"tua":41791,"tud":63876,"two":81070,"twe":71315,"ts ":465295,"tre":115840,"tra":308513,"tri":221592,"tru":53183,"tro":123988,"try":66671,"tta":29674,"tte":122526,"tti":34349,"ttl":41524,"tme":35635,"to ":731436,"tly":63791,"tob":48945,"tow":72085,"tom":29936,"ton":150493,"tor":304450,"too":27044,"top":29122,"til":53505,"tie":69965,"tit":108778,"tis":139521,"tin":255051,"tim":81225,"tio":971575,"thu":55673,"tia":79923,"tic":276929,"tiv":181662,"tla":29767,"tle":95143,"tem":124758,"ten":154275,"tel":93554,"tee":36958,"tea":71475,"tec":49230,"ted":637757,"th ":648546,"tes":193644,"ter":809390,"ti ":33930,"tho":134583,"thr":87801,"the":3415279,"thi":110969,"tha":240340},"n_words":[260942223,308553243,224934017],"name":"en"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/est b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/est new file mode 100644 index 000000000..2bdb2a607 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/est @@ -0,0 +1 @@ +{"freq":{"D":3604,"E":9114,"F":3428,"G":4270,"A":13995,"B":6049,"C":4433,"L":9649,"M":10132,"N":6533,"O":2986,"H":6531,"I":5403,"J":4779,"K":13384,"U":2720,"T":11888,"W":2107,"V":9682,"Q":266,"P":11422,"S":15988,"R":6826,"Y":596,"X":461,"Z":653,"f":12728,"g":77107,"d":141364,"e":425996,"b":40246,"c":10761,"a":496421,"n":259681,"o":223900,"l":256122,"m":147242,"j":63354,"k":181311,"h":68975,"i":428108,"w":2663,"v":88215,"u":213745,"t":258531,"s":344443,"r":180124,"q":542,"p":61630,"z":3134,"y":5816,"x":1328,"²":200,"Å":72,"Ä":128,"Á":51,"Ü":1682,"ß":76,"Õ":259,"Ö":167,"í":335,"ì":56,"ë":66,"é":703,"è":77,"ç":89,"æ":123,"å":190,"ä":42375,"ã":61,"á":537,"à":86,"ü":30512,"ú":88,"ø":326,"ö":8126,"ô":78,"õ":40539,"ó":356,"ð":63,"ñ":47,"ē":125,"ė":44,"Ā":44,"ā":654,"č":90,"ı":50,"ī":336,"ş":74,"ń":54,"ł":96,"ō":306,"Ž":57,"ž":1084,"Š":453,"š":2423,"ū":213,"ǎ":46,"ə":85,"́":52,"μ":94,"ν":197,"ο":232,"ι":145,"κ":95,"λ":130,"δ":59,"ε":108,"η":90,"α":274,"γ":53,"ά":69,"ί":80,"ω":53,"ό":79,"σ":105,"ς":232,"ρ":156,"π":59,"υ":62,"τ":124," l":23928,"ь":570," m":38337,"э":66,"ю":76," n":13986," o":51528,"я":590," h":8823,"ш":180," i":10696," j":29617," k":61170,"ы":415,"ф":166," d":4378," e":23050,"х":292,"ц":201," f":3289," g":1891,"ч":785,"р":2377," a":29616,"с":1744,"т":1384," b":2333," c":602,"у":739," y":132," x":127," z":161," u":3277," t":29638," w":134," v":33321,"і":130,"ё":86," q":53," p":29550," s":33963," r":13644,"И":192,"Л":141,"К":318,"Н":192,"М":293,"П":266,"О":115,"Б":203,"А":448,"Г":287,"В":339,"Е":66,"Д":138,"З":71," J":4764," K":12980," H":6494,"Ш":75," I":5378,"Ю":47," N":6511,"Я":49," O":2964," L":9614," M":10069,"Э":79," B":6003,"Т":143," C":4377,"У":66,"Р":154," A":13953,"С":395," F":3376," G":4219,"Ч":60,"Ф":101," D":3559," E":9045,"Х":61,"л":1746," Z":652,"к":1535," Y":594,"й":835," X":432,"и":3293,"п":426,"о":3362,"н":2533,"м":786,"г":616," S":15877," R":6777,"в":1990," Q":264,"б":447," P":11356,"а":3415," W":2074,"з":300," V":9645,"ж":145," U":2711,"е":2779," T":11830,"д":957," ä":1217," õ":2318," ö":381," ü":7159," Ā":44," Á":51," Å":72," Ä":128," Ö":164," Õ":255," Ü":1674," ž":64," Ž":57," Š":453," š":125,"ն":64,"ա":118,"ו":53,"י":74,"ר":53,"و":125,"ي":278,"ف":48,"ل":301,"م":185,"ن":161,"ه":60,"د":159,"ح":106,"ت":46,"ب":196,"ة":66,"ا":449,"ع":100,"ش":48,"س":100,"ر":186," А":444," Б":203," В":336," Г":277," Д":137," Е":66," З":71," И":192," К":315," Л":139," М":291," Н":191," О":113,"A ":1491," П":265,"F ":209,"Da":636,"Cu":143,"Cl":241,"Co":1022,"Cr":170,"Ce":161,"Ch":852,"Ci":177,"G ":207,"Ec":84,"Ed":303,"Ea":53,"Du":151,"Do":581,"Dr":153,"De":809,"Di":576,"Fe":322,"H ":271,"Fa":384,"Eu":1055,"Ev":105,"Ex":60,"Er":534,"Et":156,"Es":507,"En":458,"Em":268,"Ep":67,"Ei":131,"El":689,"Ek":108,"Ee":3423,"Eh":79,"Eg":183,"Ge":880,"Ga":592,"I ":1170,"Fu":158,"Fr":833,"Fo":411,"Fl":194,"Fj":45,"Fi":490," б":52," г":58," в":53," д":53," и":51," к":97," н":58," м":69," п":140,"B ":254," о":107," Р":152," С":394," Т":143," У":64," Ф":99," Х":61," Ч":60," Ш":75," Э":77," Ю":47," Я":48,"C ":532," с":79,"Av":172,"Au":837,"Ar":1361,"At":438,"As":1550,"D ":280,"Ba":1524,"Az":50,"Ae":128,"Af":163,"Ag":213,"Ah":170,"Aa":1076,"Ab":517,"Ac":135,"Ad":407,"Am":1404,"An":1589,"Ap":221,"Ai":278,"Aj":171,"Ak":327,"Al":2030,"Bu":590,"Br":896,"Ca":1008,"E ":421,"Bi":534,"Be":1094,"Bo":722,"Bl":189,"Kv":67,"Ku":1642,"Gö":61,"Ky":76,"Kn":47,"Kl":321,"Kr":1260,"Ko":2411,"Le":1403,"Hä":127,"Li":2750,"N ":331,"Gü":52,"La":1509,"Lu":547,"Ly":58,"Hõ":54,"Lo":1151,"Me":1361,"Dž":49,"Mi":1243,"O ":457,"Ma":3890,"Hü":108,"Mc":62,"My":97,"Mu":881,"Mo":1371,"Jä":515,"Ni":728,"Ne":1120,"Na":1009,"P ":412,"Ny":45,"Jõ":269,"Nu":172,"No":1468,"Ok":125,"Ol":339,"Om":123,"On":147,"Oh":110,"Kä":196,"Oi":46,"Od":88,"Of":51,"Jü":111,"Ob":154,"Gi":310,"Gl":141,"Gr":855,"Go":370,"Gu":494,"Gy":49,"J ":73,"Ha":1920,"He":1336,"Hi":1244,"Ho":963,"Hu":297,"Hy":59,"K ":351,"Dü":69,"Id":463,"Ig":87,"Io":55,"Im":143,"In":1490,"Il":192,"Ii":222,"Iv":146,"Is":449,"It":383,"Ir":247,"Ja":1273,"L ":301,"Ji":117,"Je":477,"Jo":991,"Ju":835,"Fü":63,"Ka":3521,"Fö":134,"M ":228,"Kh":87,"Ki":1209,"Ke":1467,"Us":124,"Ut":61,"Ur":136,"Um":60,"Un":420,"Uk":201,"Ul":110,"Ud":58,"Pü":264,"W ":104,"Pö":45,"Ty":76,"Põ":1331,"Tv":68,"Tu":682,"Tr":728,"Ts":169,"To":953,"Pä":660,"Th":747,"Ti":538,"Te":1883,"Ta":4354,"V ":865,"Sy":110,"St":1249,"Sv":158,"Su":1472,"Wo":216,"Wi":599,"Wh":48,"Sä":63,"Rü":62,"Wa":532,"We":428,"Rõ":64,"Vo":452,"Vu":47,"Rä":65,"Vi":1892,"Vl":115,"X ":185,"Va":3312,"Ve":2352,"Uu":347,"Mä":340,"Lü":129,"Pt":77,"Pu":606," م":56,"Pr":1526,"Ps":58,"S ":641,"Lõ":671,"Py":58,"Pe":1263,"Pa":2287,"Kü":279,"Pl":289,"Po":1247," ع":51,"Pi":1126,"Ph":224,"Lä":1080,"Os":432,"Ot":174,"Ou":77," ا":173,"Oo":46,"Op":127,"Or":500,"R ":183," ب":58,"Kõ":416,"Kö":81,"Se":3048,"Sc":514,"Si":1380,"Sh":515,"Sm":85,"Sl":182,"Sk":219,"Sp":264,"So":1693,"Ru":426,"Nõ":704,"U ":154,"Sa":3549,"Nü":46,"Re":985,"Ri":1129,"Nä":146,"Rh":72,"Ro":1769,"Qu":132,"Mõ":229,"T ":213,"Ra":1769,"Mü":121,"Tš":407,"b ":14100,"a ":101956,"Tõ":185,"Tö":129,"Tü":236,"Ya":114,"Yo":251,"Yu":48,"Z ":57,"Sõ":312,"Sö":54,"Sü":198,"Xi":96,"Tä":315,"Tō":50,"Za":127,"Ze":122,"Zh":62,"Vä":634,"Zi":61,"Zo":49,"Zu":94,"Võ":414,"bö":50,"i ":67391,"gd":177,"ge":11091,"ga":17189,"bü":159,"fj":156,"fl":261,"fg":90,"ff":336,"fi":3834,"bä":233,"fs":80,"fr":799,"fu":505,"ft":358,"fo":2004,"j ":178,"gy":115,"he":15992,"ha":9696,"gn":1067,"gm":312,"gl":3003,"gk":631,"gj":169,"gi":15351,"gh":514,"gg":188,"gv":123,"gu":12657,"gt":248,"gs":906,"gr":3204,"gp":765,"go":1593,"dt":600,"du":15412,"dv":357,"dw":178,"dy":147,"dz":76,"g ":7339,"ea":10628,"eb":4711,"ec":855,"ed":12410,"de":25494,"dd":200,"dg":178,"di":20365,"dh":181,"dk":488,"dj":432,"eK":296,"dm":1746,"dl":1518,"do":2346,"dn":649,"dp":77,"ds":1055,"dr":3163,"ew":508,"ex":366,"eu":1294,"ev":10732,"ey":521,"aõ":117,"ez":242,"fa":820,"aü":201,"h ":1684,"fe":1177,"eh":9506,"eg":11045,"ef":1060,"ee":30805,"el":44868,"ek":15889,"ej":1876,"ei":11617,"ep":3591,"eo":4613,"en":30509,"em":17859,"et":21350,"es":49834,"er":30979,"eq":50,"ca":1187,"e ":97234,"by":175,"bs":372,"br":3541,"bu":2050,"bt":50,"bn":97,"bo":1301,"bj":462,"bk":63,"bl":1788,"bh":62,"bi":4858,"bb":142,"bd":109,"be":5461,"db":83,"da":21215,"f ":1128,"cz":59,"cy":123,"cu":367,"ct":474,"cs":86,"cr":248,"co":978,"cm":60,"ck":1210,"cl":163,"ci":834,"ch":3094,"ce":1021,"cc":199,"c ":475,"az":442,"ay":578,"ba":4886,"d ":44215,"at":32525,"as":52565,"ar":30297,"aq":50,"ax":179,"aw":265,"av":11952,"au":7185,"ak":18860,"al":53791,"ai":13608,"aj":8772,"ao":2265,"ap":5317,"am":18369,"an":38127,"ac":1403,"ad":21341,"aa":42535,"ab":9670,"ag":6434,"ah":11107,"ae":3739,"af":1986,"nu":11347,"nt":12596,"ns":4828,"nr":469,"np":151,"no":4692,"nn":17075,"q ":46,"nz":355,"jö":51,"ny":360,"jõ":2814,"nw":57,"nv":314,"oe":1975,"of":1882,"oc":974,"od":6416,"oa":902,"ob":2993,"om":10938,"on":61110,"ok":4533,"ol":25486,"oi":2595,"oj":1236,"og":7246,"kä":1444,"oh":4211,"ot":7307,"hō":45,"m²":200,"os":13528,"ov":3905,"ou":1255,"op":3770,"oo":36377,"or":18504,"r ":11002,"ox":103,"ow":446,"kö":136,"oz":161,"oy":237,"kõ":3255,"pe":8582,"pf":53,"kü":2678,"pa":9082,"pl":1823,"pm":182,"lé":50,"pn":209,"po":8371,"lä":2964,"ph":615,"pi":8736,"pk":178,"lo":11129,"ln":1607,"lm":6318,"ll":19635,"ls":3471,"lr":311,"lp":708,"lv":1889,"lu":12030,"lt":11142,"lz":55,"ly":347,"hõ":638,"o ":5439,"hü":580,"ma":35693,"mb":5069,"mg":52,"dž":411,"mh":80,"me":23829,"mf":109,"hā":79,"mk":376,"ml":264,"mi":40706,"eš":58,"mj":183,"mn":780,"mm":2852,"mp":2268,"mo":4294,"mr":80,"mt":306,"ms":1112,"mv":97,"mu":8559,"iõ":260,"my":155,"p ":1639,"na":27821,"iü":173,"nb":439,"nc":950,"nd":30717,"ne":35835,"nf":748,"ež":190,"ng":16763,"nh":382,"jä":4035,"ni":36973,"nj":320,"nk":2416,"nl":419,"nm":235,"jt":102,"ju":8195,"jn":184,"jo":2230,"jm":158,"kj":201,"ki":13463,"kh":323,"kf":60,"ke":20124,"kd":44,"kb":60,"fü":589,"ka":27697,"m ":10376,"fö":145,"ky":200,"gõ":66,"gö":54,"ks":20790,"kt":6626,"ku":25416,"kv":1230,"ko":25420,"kp":298,"kr":3838,"kk":4692,"kl":3700,"km":2283,"kn":633,"li":57000,"hä":827,"lh":474,"lk":2832,"lj":4573,"le":37295,"ld":8105,"lg":4950,"lf":372,"gü":68,"la":31670,"lc":95,"lb":823,"n ":49802,"hr":621,"hs":195,"hv":2638,"hw":103,"ht":6604,"hu":4453,"hj":2882,"hk":5994,"hh":1052,"hi":9059,"hn":1001,"ho":2898,"hl":335,"hm":902,"dé":47,"id":25348,"ic":2524,"ib":3313,"dü":272,"ia":15748,"ih":2638,"ig":11090,"if":1034,"ie":3981,"hy":186,"dõ":82,"k ":16382,"iq":93,"ir":11061,"is":67525,"it":26582,"iu":2821,"iv":6458,"iw":71,"ix":158,"ii":25093,"aš":218,"ij":1535,"ik":35922,"il":29934,"im":19741,"in":53773,"io":9587,"ip":3170,"je":2855,"až":108,"ji":256,"fä":213,"iz":330,"iy":72,"eõ":59,"l ":31660,"eü":118,"ja":41991,"tä":3641,"xi":267,"té":49,"xt":76,"sö":241,"sõ":3307,"ww":59,"z ":542,"sü":7550,"xa":160,"xe":69,"sä":382,"oš":66,"wi":436,"sé":45,"wn":69,"wo":143,"ws":111,"vv":89,"rõ":329,"vy":59,"rö":278,"y ":2468,"rø":55,"wa":716,"rü":1335,"rā":49,"we":364,"vl":251,"vm":177,"ré":93,"vj":46,"vk":322,"rä":668,"vi":9510,"vg":104,"vt":88,"vu":4481,"vr":127,"vs":891,"vp":221,"rí":55,"vn":468,"vo":2748,"uz":144,"uy":48,"ux":121,"uv":4464,"uu":16971,"ve":10196,"vd":60,"va":34297,"x ":556,"ui":3667,"uj":2076,"uk":5480,"ul":16978,"ue":1272,"uf":259,"ug":4237,"uh":3669,"ur":13993,"us":50648,"ut":13872,"um":10739,"un":13735,"uo":494,"up":1948,"ty":350,"põ":3410,"tz":299,"pö":275,"tu":27878,"tt":4340,"tw":94,"tv":618,"ub":5783,"pü":734,"ua":3006,"ud":21571,"uc":397,"w ":514,"to":11780,"tn":1099,"tm":2505,"tl":5476,"ts":21273,"tr":8177,"tp":259,"tg":91,"tf":183,"te":48864,"tk":949,"tj":657,"ti":30264,"pä":3196,"th":1862,"v ":7055,"tb":129,"tc":91,"ta":41990,"su":20276,"sv":2315,"ss":8143,"st":67054,"sy":172,"sz":75,"sw":139,"sl":2942,"sk":10212,"sn":1521,"sm":4289,"sp":2885,"so":5912,"sr":794,"sd":174,"sc":930,"sf":485,"se":62785,"sh":1322,"sg":140,"sj":1063,"kš":54,"si":30745,"rz":159,"u ":17617,"sa":24031,"nü":262,"sb":374,"rr":3973,"rs":3109,"rt":7363,"ru":7114,"rv":5729,"rw":105,"ry":602,"nõ":791,"rp":648,"ro":11751,"rn":3712,"rm":4085,"né":46,"rl":1539,"rk":3920,"nç":57,"rj":4639,"ri":41739,"rh":803,"nä":2052,"iž":51,"rg":9073,"mā":44,"rf":347,"re":19761,"rd":6093,"rc":505,"rb":1857,"mü":731,"ra":27209,"t ":40235,"mõ":3716,"mö":208,"qu":338,"iš":133,"lā":51,"mä":4794,"lü":1913,"s ":83808,"px":82,"lõ":2040,"py":45,"lö":179,"pt":1489,"pu":3682,"pp":2089,"pr":5736,"hū":50,"ps":1178,"yō":62,"uš":116,"tš":984,"vö":298,"zz":105,"vü":141,"vä":6112,"zh":68,"zi":492,"ze":455,"uü":74,"za":431,"uõ":62,"zy":50,"võ":10296,"zs":86,"zu":144,"zo":270,"zn":53,"zm":49,"yg":56,"ye":201,"yc":105,"yd":131,"tü":1113,"ya":457,"yb":52,"tö":1641,"tõ":1288,"yt":138,"ys":416,"yr":185,"yp":88,"yo":142,"yn":260,"ym":152,"yl":325,"yk":76,"yi":121,"რ":63,"ო":50,"ნ":45,"ი":145,"ლ":57,"ე":73,"ა":150,"² ":198,"án":134,"ä ":222,"ár":59,"äb":871,"Üh":852,"Ül":582,"á ":83,"Ü ":171,"Õi":103,"Õh":47,"Õp":48,"Ök":67,"アアア":314,"ö ":312,"õ ":118,"ón":116,"ín":74,"ía":57,"í ":51,"én":82,"és":48,"ér":80,"ää":6210,"é ":189,"ät":739,"äv":318,"äm":341,"äl":3418,"äo":127,"än":4791,"äp":377,"äs":977,"är":10885,"äe":2551,"äd":252,"äg":1326,"äi":4721,"äh":3974,"äk":203,"üü":2774,"ān":168,"ār":63,"õš":48,"ā ":58,"öö":3301,"ể":72,"üo":89,"ün":5015,"üm":1677,"ül":5410,"üs":2571,"ür":1208,"üp":727,"üv":138,"üt":1243,"üb":167,"üa":118,"üf":48,"üg":358,"üd":830,"ük":2636,"üh":5389,"øy":105,"õõ":933,"öv":135,"ør":74,"øn":53,"õr":3591,"õs":403,"õt":1896,"õm":351,"õn":2300,"õo":45,"õp":1548,"õi":12796,"õj":1645,"õk":165,"õl":2454,"õe":2011,"õg":861,"õh":4577,"õb":159,"õd":527,"öt":705,"ör":689,"ös":334,"öp":203,"ön":372,"öl":253,"öm":99,"ök":454,"öi":89,"ög":138,"öe":80,"öd":707,"öb":82,"ḩ":72,"õz":69,"õv":176,"õu":3856,"ī ":118,"īn":58,"š ":464,"še":571,"ša":283,"šo":109,"šk":120,"ši":439,"šu":129,"št":112,"Ša":47,"Šo":91,"Šv":165,"ōk":47,"ō ":113,"žu":64,"žo":59,"že":84,"ža":274,"ži":342,"ž ":81,"ū ":64,"ი ":59,"あ":71,"ア":442,"가가 ":46," ア":53,"乙":67,"之":249,"丹":47,"临":68,"並":138,"丘":83,"专":99,"三":373,"丁":204," 三":86," 丁":77,"倉":51," 之":80,"ああ":46,"ος":107,"ος ":107,"ς ":231,"α ":91,"アア":377,"ян":79,"ый":89,"ье":98,"ьс":48,"ьн":72,"ха":91,"ци":80,"че":89,"ск":479,"сл":56,"со":89,"се":96,"си":145,"рь":62,"са":149,"рс":87,"рт":59,"ру":71,"тр":186,"то":214,"те":148,"тв":71,"ти":150,"та":205,"сс":83,"ст":346,"ур":101,"ус":74,"ул":50,"ун":50,"уд":52,"уб":58,"ть":45,"фо":51," Ga":590," Ge":860," I ":313," Fo":396," Fu":156," Fr":828," Fi":477," Fl":192," Fj":45," Ha":1914," He":1326," Gy":49," Go":366," Gr":850," Gu":492," Gi":307," Gl":139," Ig":87," Id":463," Dü":69," Hy":59," Hu":297," Ho":962," Hi":1244," Ji":117," Je":475," L ":50," Ja":1269," Iv":146," Ir":247," Is":445," It":383," Im":143," In":1484," Io":55," Ii":222," Il":189," M ":95," Fö":134," Fü":63," Ka":3502," Ke":1459," Ki":1200," Kh":87," Jo":986," Ju":831," N ":212," Gü":52," La":1495," Le":1398," Hä":127," Li":2733," Kl":320," Kn":46," Ko":2402," Kr":947," Kv":67," Ku":1637," Gö":60," Ky":76," Mc":62," Ma":3863," Hü":108," O ":93," Mi":1232," Dž":49," Me":1354," Lo":1146," Ly":58," Hõ":54," Lu":546," Ne":1115," P ":83,"а ":653," Na":1003," Jä":515," Ni":722," Mo":1366," My":96," Mu":873," A ":257," B ":117," C ":205," Ap":221," Am":1400," An":1581," Ak":327," Al":2024," Ai":275," Aj":171," Ag":212," Ah":170," Ae":126," Af":163," Ac":133," Ad":404," Aa":1075," Ab":516," Ba":1515," D ":91," Az":50," Av":171," Au":835," At":438," As":1512," Ar":1360," Be":1090," Bi":531," Bl":186," Bo":717," Br":891," Bu":586," E ":253," Ca":996," Ce":158," Ci":166," Ch":848," Cl":225," Cr":170," Co":1011," Cu":137," F ":65," Da":635," Di":564," De":805," Dr":153," Do":564," Du":150," Ea":51," Ec":83," Ed":300," G ":69," El":689," Ek":107," Ei":131," Eh":78," Eg":183," Ee":3409," Et":156," Es":505," Er":526," Ep":67," En":453," Em":267," Ex":60," Eu":1052," Ev":105," Fe":322," Fa":376," H ":102," Xi":80," Tä":312," Sü":194,"к ":130," Sõ":311," Sö":54,"Ив":73," Wo":210," Wi":583," Wh":45," Sä":63," We":424," Rü":62," Wa":532,"й ":637," Rõ":64," Zu":94,"Ле":48," Võ":412," Zo":49,"Ку":52," Ze":122," Zh":62," Vä":632," Zi":58,"Ко":96,"м ":90," Za":127," Yu":48,"Ка":72," Yo":250," Tü":235," Ya":113," Tö":129," Tõ":184,"л ":110,"Ни":84,"Мо":47,"о ":255," Tš":404,"Ма":85,"Ми":98," Tō":50,"н ":434,"Па":47,"Пе":79,"По":48," a ":162,"с ":91,"р ":253," R ":62,"в ":424,"Ан":87," Kõ":416," Kö":81,"Ал":161," Ou":77," Os":431," Ot":172," Or":497," Oo":46,"Аб":44," Op":127," Po":1235," Pl":283," Pi":1123," Ph":212," Lä":1080," Pe":1250," Pa":2281," Kü":278," Ny":45," Jõ":269," Nu":172," No":1462," Ol":339," Ok":124," On":146," Om":122," Oh":110," Kä":196," Oi":46," Od":87," Of":45," Ob":154," Jü":111," Mõ":229,"Вл":51," Ra":1755," Mü":121," T ":66,"д ":86,"Ви":55," Qu":130," Ro":1766," Re":978," Ri":1126," Nä":145," Rh":72," Lõ":669," Py":57," S ":141,"Бо":74,"г ":58," Pr":1513," Ps":52," Pt":76," Pu":606,"Ва":94," Lü":129," Mä":338," Sy":110," Sv":156," Su":1464," St":1223," Ta":4345," V ":98," Pä":659," Th":744," Ti":535," Te":1863," Tr":722," Ts":168," To":951," Nõ":702," Ru":426,"Ге":81,"Гр":45," Sa":3543," Nü":45,"е ":239," Sh":511," Si":1350," Sc":495," Se":3040," So":1682," Sp":263," Sk":219," Sl":182," Sm":84," Uu":347," Va":3308," X ":95,"и ":220," Ve":2347," Rä":65," Vi":1878," Vl":115," Vo":452," Vu":47," Tu":679," Tv":68," Ty":76," Põ":1331," Pö":45," W ":53," Pü":263," Ud":58," Uk":200," Ul":110," Um":60," Un":417," Ur":135," Us":122," Ut":61," ja":20477," l ":68,"ь ":130," io":82," im":299," in":4488," il":865," ii":156," is":1859," it":246," fü":370," ka":13902," fö":77," m ":441," ki":4980," ke":11286," jn":167," jo":514," jm":152," jt":94," ju":2953," ha":2640," he":1467," gl":111," gr":524," go":49," k ":146,"ы ":90," ib":56," dü":205," id":1072," ig":443," hi":1143," ho":971," hu":967," jä":3184," ni":6713," nd":118," ne":1909," na":1142," p ":48," mu":3133," mo":1838," mm":67," ok":758," ol":7096," om":1854," on":34245," oh":172," kä":1164," oj":83," of":466," ob":937," jõ":1996," nu":369," nt":126," no":1262," nn":71," le":1944," lk":65," hä":549," li":6989," n ":104," la":5115," kv":246," ku":9586," km":1544," kl":989," kr":1633," ko":10755," me":3580," dž":65," mi":14942,"я ":380," hü":385," ma":7824," lu":810," hõ":577," lo":3309," ae":363," af":69," ag":306," ah":192," aa":4258,"Ст":49," ab":842," ac":46," ad":192," am":855," an":2331," ap":575," ai":1079," aj":1910," ak":483," al":5568," av":698," au":1797," ar":3514," at":197," as":4137," d ":153," ba":664," 가가":46," bi":566," be":162," bo":152," bl":78," bu":241," br":141," ca":117," e ":147,"х ":65," b ":66,"т ":156,"Ро":57,"Се":84,"Со":64," er":2077," et":1438," es":2246," en":2378," em":344," ep":75," ei":852," el":2672," ek":498," ef":88," ee":3011," eh":5575," eg":105," fe":136," fa":280," eu":119," ev":98," fu":315," fr":185," fo":525," fl":88," fj":44," fi":1214," bä":181," ge":720," ga":319," i ":993," cm":54," co":181," ch":69," da":137," do":440," dr":125," de":2173," eK":291," di":908,"ч ":585," ed":721," eb":183," du":101,"ль":338,"ма":140,"ме":79,"ми":161," vö":80,"лл":50,"ло":200," vü":80,"ла":291," zo":50," zu":50,"ле":285," võ":8473,"ли":217,"кс":169,"ко":414," vä":4759,"ка":276,"ки":323," tõ":919," tö":1012," tü":520,"йс":53,"ия":126," tä":3294,"им":129,"ин":324,"ик":203," sõ":2172,"ил":197," sö":81,"ии":45,"ий":374,"ич":632,"их":108,"ит":98,"ир":115,"ис":145," sü":5410,"ри":296,"рк":48,"рн":83,"ро":406,"ра":317,"рг":121,"рд":63,"ре":208,"пр":87,"по":93,"па":67,"пе":55,"ос":221,"ор":399,"оп":51,"от":68,"ок":58,"ол":330,"ом":142,"он":240,"ой":87,"ов":918,"ог":103,"од":117,"ое":100,"об":67,"ны":111,"нт":92,"нс":154,"но":345,"нн":108,"нк":74,"ни":279,"не":99,"нг":60,"нд":193,"на":391," tš":115,"мо":119,"ге":109," ru":423," nõ":449,"ги":57," u ":56,"го":156," sa":6645," nü":110," se":7005,"гу":45," sc":47," si":2589," sh":125," sl":105," sk":246," sp":570," so":1701,"да":103,"ве":150,"ви":646," mõ":2887," mö":122,"вн":105,"во":155," t ":61," mü":545," ra":5080,"вс":81," re":2103," ri":3272," nä":1534,"га":89," ro":1241,"бе":93," pu":1946," pr":4024," ps":246,"бо":55," s ":402," lö":96," px":82," lõ":1781," mä":2882," lü":990,"ва":236," os":2510,"ад":144," ot":471,"ае":61,"аз":52," oo":592," op":302,"аб":45,"ав":150," or":1834,"аг":45,"ам":81,"ан":559,"ай":127," kõ":2868,"ак":68,"ал":255," kö":73," pe":3640," kü":1892," pa":3723,"ас":154,"ар":332,"ат":153," pl":542," po":5154,"ая":206,"ба":89," pi":4298," lä":2715," rü":649," rõ":177," y ":67," rö":76,"ив":76,"иг":52,"ид":49,"ие":98," sä":314," x ":107," va":12420," ve":4280," uu":1024," vo":1317,"за":70," vu":102," rä":537," vi":1606," vk":47," vm":99,"ет":178," pü":607,"ес":139,"ер":394,"ео":53,"ен":381,"ем":79,"ел":192," pö":222," põ":3044,"ек":180,"ей":122," tu":3292,"ее":74," us":346," um":867," un":274," uk":117," ul":323," uj":60," ta":4816,"др":169,"до":115,"ди":121," sy":46," st":1273,"де":141," su":5118,"ев":407," tr":1088," ts":358,"ед":85," to":2603," pä":1847," th":387," ti":918," te":10216," Õp":48," Õh":47," Õi":101," Ök":64," Ü ":59," Ül":578," Üh":851," är":293," ää":835," öe":60," ök":219," õl":119," õi":938," õh":408," õp":648," õn":74," öö":76," ür":128," ül":2321," üm":508," ük":1493," üh":2633," 가":51,"가":148,"ōky":44," Šv":165," Šo":91," Ša":47," ža":50,"د ":87,"ة ":66,"ان":46,"ال":176,"ر ":45,"ي ":68,"ن ":97," アア":51,"AS ":102," ко":46,"BA ":64," по":46," Ро":57," Пе":79," Па":47," По":48,"가가":97," Ст":49," Се":84," Со":64,"AO ":53," Ан":87," Ал":161," Аб":44," Ва":94," Бо":74," Ви":55," Вл":50," Ге":81," Гр":45," Ка":71," Ив":73," Мо":47," Ни":84," Ко":95," Ку":52," Ле":47," Ма":83," Ми":98,"Fel":59,"Fer":121,"Fil":156,"Fin":145,"Fir":68,"Fan":92,"Fal":44,"Fai":50,"Era":62,"Eri":232,"Est":182,"Ern":93,"Esi":185,"Eur":956,"Eva":52,"Ehi":44,"Ele":225,"Ela":50,"Eks":56,"End":51,"Ena":97,"Eng":50,"Ene":66,"Emm":77,"Ema":72,"Eli":126,"Ell":63,"Ent":53,"Ger":95,"Geo":499,"Gen":130,"Gio":51,"Gil":46,"Ива":71,"Öko":66,"Gan":54,"Gal":104,"Gam":62,"Gar":101,"Gab":56,"Flo":75,"Fla":65,"Fra":377,"Fri":218,"Fre":186,"Foo":47,"Fon":48,"For":124,"IP ":48,"II ":579,"His":301,"Hii":583,"Hil":89,"Hin":100,"Hel":430,"Hei":240,"Hea":65,"Hen":145,"Her":270,"Haa":140,"Hab":68,"Hal":209,"Hai":81,"Han":256,"Ham":105,"Har":682,"Hau":60,"Gus":86,"Gua":87,"Gui":119,"Grö":69,"Gre":178,"Gri":80,"Gra":216,"Gru":170,"Gro":104,"Gol":71,"Got":58,"Gor":73,"Ing":355,"Inf":74,"Ini":62,"Int":306,"Ins":151,"Ill":72,"Ind":377,"Imp":71,"Iis":118,"Iir":94,"Ida":408,"Hum":47,"IV ":90,"Hor":121,"Hoo":71,"Hom":80,"Hon":86,"Hol":356,"Arg":115,"Arh":59,"Are":119,"Arc":52,"Ara":180,"Arm":142,"Arn":51,"Ark":65,"Ari":84,"App":49,"Apo":82,"Ate":50,"Atl":232,"Asu":1049,"Ast":103,"Ass":139,"Ase":89,"Art":168,"Arv":91,"Aru":68,"Ava":88,"Aut":116,"Aus":402,"Aug":149,"Bai":96,"Bak":55,"Bal":343,"Ban":110,"Bab":69,"Bad":75,"Bar":269,"Bat":57,"Bas":115,"Bau":47," пр":54,"Aar":73,"Aas":446,"Aaf":295,"Aad":67,"Abr":47,"Abe":61,"Aba":83,"Abd":79,"Abi":49,"Ada":90,"Adv":74,"Ado":56,"Ade":47,"Aer":49,"Aeg":46,"Age":54,"Afg":70,"Ain":50,"Air":92,"Al ":56,"Aja":140,"Aka":119,"Akt":63,"Ala":283,"Alb":201,"Alg":178,"Ali":85,"Ale":472,"Alf":50,"Alu":59,"Alt":115,"All":206,"Alp":102,"Ame":1051,"Amb":81,"Ama":69,"Ang":173,"Ani":70,"Ana":136,"And":351,"Ans":55,"Ant":450,"Ann":191,"Bus":55,"Bul":94,"Bur":160,"Bud":75,"Мих":58,"Bru":68,"Cal":198,"Cam":87,"Cas":93,"Car":284,"Cat":48,"Can":91,"Bea":78,"CH ":77,"Ber":414,"Ben":187,"Bel":194,"Bil":84,"Bis":73,"Bir":85,"Bio":136,"CO ":51,"Bla":86,"Bre":116,"Bra":266,"Bro":108,"Bri":271,"Ник":72,"Bol":76,"Bon":63,"Bor":154,"Bos":66,"Bou":71,"Õig":83,"EE ":44,"Det":56,"Des":76,"Dev":50,"Del":63,"Dem":159,"Den":66,"Dep":48,"ан ":122,"Dan":112,"Dar":75,"Dav":137,"ай ":47,"Chr":190,"Che":117,"Chi":112,"Cit":59,"Cla":86,"Cen":74,"Cha":324,"Cri":46,"DV ":45,"Clu":51,"Cor":172,"Com":152,"Col":177,"Con":247,"Cou":57,"FA ":50,"ади":61,"аев":60,"Ege":46,"Egi":118,"али":51,"аль":66,"ано":90,"Ees":3340,"анд":117,"ани":46,"Edu":80,"Edw":63,"Ede":52,"FC ":88,"Dia":62,"Dis":117,"Dio":47,"Dig":58,"Die":54,"Div":45,"ая ":201,"Dre":44,"Dra":54,"Пет":51,"Doy":59,"Don":122,"Dom":77,"Doo":55,"Dor":65,"Nee":123,"Nen":81,"Nel":76,"Nei":118,"Nev":47,"Neu":75,"Net":49,"Nat":157,"Nii":60,"Nig":95,"Nic":90,"Nim":92,"Nik":161,"Jär":285,"New":291,"Nap":53,"Nar":263,"Nan":47,"Nag":44,"Nad":109,"Jõe":111,"Jõg":96,"Jää":129,"OS ":46,"Nov":157,"Nor":978,"Noo":108,"Але":136,"Kär":84,"Obe":69,"Jür":85,"Ott":71,"Ote":47,"Kõi":90,"Kõr":209,"Oli":46,"Ole":65,"On ":49,"Oma":92,"Olü":53,"Ope":62,"Ora":58,"Osc":88,"Osa":64,"Ord":51,"Ori":67,"Org":113,"Ost":56,"Osl":81,"Oss":50,"Lää":780,"Ple":51,"Pla":187,"Pin":124,"Pil":73,"Pik":86,"Pii":306,"Pir":78,"Pih":114,"Pie":94,"Pho":46,"Phi":103,"Läh":64,"Lät":200,"Pea":138,"Ped":50,"Per":283,"Pet":350,"Pen":99,"Pel":65,"Pee":136,"Pat":127,"Pas":71,"Par":721,"Pav":48,"Pau":155,"Paa":107,"Pad":62,"Pan":241,"Pai":107,"Pal":313,"Kül":163,"Pak":101,"Lõu":592,"Pto":68,"Pun":149,"Pur":44,"Pue":49,"Puh":59,"Puu":79,"Pro":404,"Pri":219,"Pre":257,"Pra":604,"Pol":248,"Pom":45,"Poh":46,"Pot":67,"Pos":114,"Poo":305,"Por":187,"RO ":68,"Mär":85," ال":145,"Män":102,"Вла":51,"SA ":770,"Вас":49,"Raa":184,"Rad":71,"Rai":65,"Rah":536,"Ram":65,"Mün":49,"Ran":128,"Rak":98,"SD ":47,"Mõn":60,"Mõi":70,"Isa":72,"Ise":51,"Ita":340,"Isl":190,"Ira":139,"Iva":115,"Jac":79,"Jaa":509,"Jar":46,"Jan":141,"Jam":143,"Jal":74,"Jak":74,"Jen":64,"Jer":96,"Jea":76,"Jee":58,"KP ":62,"Jos":138,"Jor":57,"Joo":51,"Jon":103,"Joh":467,"Joa":63,"Jug":45,"Juh":63,"Juu":106,"Jur":60,"Jul":218,"Jum":146,"Föd":118,"Kaa":255,"Kad":123,"Kab":68,"Kai":254,"Kah":71,"Kag":66,"Kam":188,"Kal":368,"Kak":46,"Kap":63,"Kan":466,"Kau":239,"Kat":178,"Kas":307,"Kar":687,"Ker":134,"Kes":554,"Ket":49,"Ken":126,"Kel":51,"Kem":44,"Kei":251,"Keh":55,"Kee":118,"Kir":431,"Kit":75,"Kin":160,"Kiv":96,"Kil":83,"Kih":48,"Kii":162,"Klo":53,"Kli":49,"Kle":53,"Kla":98,"Klu":55,"Koo":227,"Kon":442,"Kom":339,"Kol":258,"Kos":162,"Kor":274,"Kop":81,"Kog":69,"Kod":97,"Kok":46,"Koi":60,"Koh":156,"Kr ":310,"Kot":63,"Kre":312,"Kra":186,"Kri":267,"Kro":87,"Kru":51,"Kui":148,"Kul":317,"Kun":277,"Kur":369,"Kuu":241,"Kva":53,"Lev":81,"Les":48,"Lep":73,"Leo":109,"Len":251,"Lem":45,"Lei":135,"Leh":50,"Lee":284,"Lea":56,"Lau":185,"Le ":49,"Lak":57,"Lai":145,"Lag":77,"Lah":103,"Lae":57,"Las":93,"Lar":49,"Lap":96,"Lam":60,"Lan":154,"Lad":56,"Laa":70,"La ":89,"ML ":59,"Lib":76,"Lie":81,"Lih":74,"Lig":47,"Lii":1363,"Lil":58,"Lim":58,"Lin":573,"Lip":63,"Lis":111,"Lit":56,"Liv":63,"Lut":62,"Luu":51,"Luk":48,"Lui":44,"Lud":75,"Luc":57,"Lou":126,"Los":88,"Lot":49,"Loh":45,"Lor":56,"Loo":276,"Lon":195,"Lom":53,"Lok":47,"NA ":78,"Mei":81,"Meh":138,"Men":72,"Mel":110,"Mes":92,"Mer":322,"Met":201,"Med":80,"Mee":102,"Man":356,"Mal":230,"Mar":1023,"Mas":191,"Mag":212,"Hüd":45,"Mad":279,"Maj":106,"Mak":124,"Mah":61,"Mai":109,"Mac":68,"Maa":607,"Max":73,"Mau":82,"Mat":240,"Mod":67,"Moh":45,"Mol":99,"Mon":346,"Moo":103,"Mos":352,"Mor":136,"Mot":44,"Mih":126,"Mik":120,"Mic":227,"Mit":88,"Mis":98,"Mil":150,"Min":245,"Mul":70,"Muh":59,"Muu":174,"Mur":95,"Mus":281,"Tän":126,"Täh":115,"лав":45,"лад":53,"ль ":49,"TÜ ":47,"ääm":126,"ääl":395,"ään":2004,"ääk":111,"ääd":51,"ääg":344,"ääb":251,"äät":82,"ääv":158,"äär":2288,"ääs":242,"ää ":101,"Sõn":78,"кса":105,"Sõj":66,"Sõr":64,"ков":99,"кол":81,"кий":216,"Wor":93,"Wol":71,"Wil":257,"Win":131,"кая":100,"Wei":45,"Weh":50,"Wes":117,"Was":59,"War":74,"Wat":77,"Wal":182,"йск":48,"ко ":58,"Vor":103,"Voo":53,"Vol":205,"Vis":61,"Vit":59,"Vla":113,"ная":59,"ое ":83,"ндр":145,"ой ":73,"Väl":103,"Väi":301,"Väs":46,"Vär":64,"ов ":254,"мир":58,"мов":45,"ман":65,"Yor":178,"You":47,"Töö":118,"Tür":179,"льн":72,"на ":209,"льс":44,"三三":54,"Tõn":45,"лов":104,"лив":45,"лен":58,"лек":145,"ра ":49,"Sve":99,"Suu":805,"Sur":85,"Sul":92,"Sup":46,"Sun":86,"Sud":52,"Str":229,"Stu":106,"Sto":184,"Sta":395,"Ste":226,"Tee":206,"Teh":108,"Teg":101,"Tea":178,"Ted":50,"Ten":61,"Tem":174,"Teo":71,"Tei":326,"Tel":114,"Tam":134,"Tan":148,"Tat":66,"Tar":920,"Tav":135,"Tai":140,"Tal":1376,"Tag":78,"Taa":310,"Tab":46,"Tad":48,"Ta ":667,"ори":54,"оро":72,"Ska":93,"Shi":143,"She":124,"Sha":138,"Sim":113,"Sil":212,"Sii":184,"Sih":45,"Sig":69,"Sis":180,"Sir":66,"ост":84,"Sin":138,"Sie":46,"Sib":150,"оль":64,"Ser":245,"Sev":74,"оло":46,"оли":53,"ола":72,"Sep":56,"Sen":68,"Sel":786,"Sem":74,"Sei":87,"Sed":193,"See":1098,"Sea":119,"TV ":56,"äb ":221,"Spa":44,"Spe":59,"Spo":69,"Sof":45,"Soc":51,"Sot":162,"Sou":50,"Sol":103,"Som":77,"Son":96,"Soo":896,"TO ":49,"Slo":106,"äga":245,"äev":922,"ова":78,"äet":56,"äes":339,"äea":55,"äed":62,"äel":380,"äht":1060,"äid":319,"äib":55,"Nõu":525,"ähe":2126,"ähk":56,"ähi":637,"Nõm":138,"äge":296,"ägi":746,"äe ":449,"äbi":596,"ный":73,"SV ":478,"Rus":63,"äda":144,"Rum":92,"äde":48,"änn":112,"änu":150,"Sag":67,"Sai":131,"Sah":102,"Sak":1209,"Sam":213,"Sal":247,"Saa":614,"Sab":44,"Sad":48,"ämm":58,"äna":797,"äni":236,"äng":1228,"äne":1640,"änd":528,"äpp":49,"äps":237,"Sco":47,"Sch":374,"äol":71,"Sav":86,"Sau":94,"Sar":178,"San":281,"är ":134,"äit":1511,"äis":253,"äir":146,"äin":438,"äil":189,"äik":1090,"äij":45,"äig":275,"äie":224,"äiv":81,"ове":46,"älu":94,"ält":126,"ови":380,"äli":683,"älj":1874,"овн":48,"овс":48,"äme":148,"ого":52,"äki":100,"TA ":65,"älg":52,"äld":112,"äle":277,"ävi":138,"SI ":60,"Res":61,"äva":99,"Rev":69,"Näi":96,"нов":187,"ор ":52,"Ris":101,"Rii":508,"Rin":80,"Ric":153,"Rid":55,"ärg":1735,"äri":1473,"ärj":460,"ärk":656,"ärm":139,"ära":1650,"ärd":69,"äre":1128,"Ras":57,"Rau":107,"Rap":154,"äsi":369,"äsk":115,"äse":53,"нко":46,"он ":72,"ärv":1633,"ärn":371,"äru":76,"ärt":890,"ärs":325,"ärr":78,"ätm":48,"äti":288,"ätk":94,"äst":200,"äss":64,"äsu":88,"Rec":53,"Rei":185,"Reg":77,"Ren":63,"Rel":79,"Rep":45,"ätt":141,"äts":56,"Rea":67,"Roh":92,"Rob":131,"Roc":60,"Ros":150,"Rom":120,"Roo":904,"SS ":97,"SO ":46,"нск":92,"сан":105,"Vab":795,"Vaa":45,"Vai":341,"Vah":167,"Vel":86,"Ven":1754,"Vee":94,"сил":46,"ски":218,"ска":112,"ско":106,"Vas":243,"Van":479,"Val":835,"Var":232,"Vih":45,"Vig":101,"Vii":222,"Vid":54,"Vic":79,"Vie":71,"Vir":448,"Vil":366,"Vik":195,"Vin":105,"сов":48,"Ver":155,"Ves":127,"Ukr":194,"Ung":127,"Uni":210,"VR ":44,"Uus":233,"Uur":54,"Uue":46,"Tve":67,"Põl":225,"Põh":1046,"Püh":181,"рий":44,"рис":45,"Pür":45,"ров":215,"VI ":61,"Ter":274,"Tes":65,"The":470,"Päi":111,"Tho":103,"Pär":428,"Tih":59,"Tii":133,"Tim":77,"Pää":51,"Too":201,"Tor":167,"Tol":64,"Tom":75,"Ton":64,"Toi":63,"Tru":76,"Tro":136,"Tri":130,"Tre":108,"Tra":219,"Tur":159,"Tuu":92,"Tul":130,"Tun":106,"ši ":155,"šet":55,"šev":66,"šel":50,"šer":71,"šee":52,"ван":86,"šeh":151,"ša ":68,"šat":45,"Šve":145,"вск":69,"вна":76,"вич":569,"šii":58,"ва ":83,"аси":52,"ато":47,"во ":47,"bje":380,"bja":66,"bis":218,"bit":234,"biv":187,"bio":537,"bip":80,"bir":67,"bik":204,"bil":578,"bim":157,"bin":301,"bii":222,"bij":70,"bo ":72,"blo":54,"ble":274,"bli":550,"bn ":58,"bla":847,"ев ":82,"bod":50,"bok":45,"bol":236,"ей ":78,"bon":137,"boo":67,"bor":247,"bot":147,"bos":56,"bou":65,"be ":205,"bam":130,"ban":365,"bak":284,"bal":373,"bai":111,"baj":47,"bah":73,"bac":66,"bad":310,"baa":286,"án ":48,"bav":70,"bat":316,"bas":493,"bar":1055,"bi ":1023,"bee":78,"bed":61,"bec":51,"ber":2586,"ben":167,"bem":51,"bel":642,"bek":156,"bes":968,"bet":314,"bia":533,"bib":89,"bid":126,"bie":117,"bha":48,"дро":45,"ет ":44,"ca ":308,"car":187,"cas":78,"cat":96,"can":142,"cal":161,"ce ":506,"bri":2225,"bro":86,"bra":389,"bre":198,"bu ":80,"bru":574,"bso":114,"bse":67,"bst":74,"дим":49,"bub":112,"bur":697,"bul":127,"bun":75,"bum":298,"bud":140,"but":54,"bus":333,"дор":45,"by ":122,"aka":1199,"am ":1037,"ake":1191,"aki":1056,"ajo":642,"aju":375,"al ":9437,"aja":7056,"aje":136,"aaž":50,"aik":874,"ail":2117,"aim":1277,"ain":2391,"aio":97,"air":125,"ais":922,"ait":1457,"aiu":220,"aiv":79,"ak ":324,"aig":556,"aie":299,"aid":1846,"aia":317,"ahn":114,"ahk":234,"ahl":63,"ahi":395,"ahj":153,"ahh":236,"ahu":752,"ahv":2279,"ahs":82,"aht":765,"ahr":54,"aho":103,"ahe":4825,"aha":671,"agi":522,"agr":165,"agu":1145,"agn":333,"ago":338,"akä":47,"aol":220,"aok":108,"anu":1617,"anz":132,"ajõ":234,"any":60,"ano":601,"ann":2713,"anm":52,"ant":3838,"ans":1284,"anr":93,"ane":2890,"ang":1938,"ajä":246,"ani":8218,"anj":107,"ank":687,"anl":132,"ap ":65,"ana":2831,"anc":369,"and":7769,"amu":491,"amt":68,"amm":1132,"aml":63,"amo":227,"amp":318,"ams":141,"amj":57,"ami":6164,"adž":93,"ame":2122,"amb":788,"ama":4891,"ao ":126,"alv":587,"alu":1954,"alt":2286,"als":1219,"alr":157,"alp":242,"alo":1054,"aln":583,"alm":1124,"all":6989,"alk":711,"alg":2752,"alh":218,"ahä":77,"ali":9008,"alj":729,"ald":4688,"ale":3211,"alf":70,"ala":5975,"alb":322,"an ":2385,"akv":79,"aks":8379,"akr":533,"aku":957,"akt":1317,"ako":2809,"akp":79,"akk":543,"akl":109,"aba":1901,"abe":658,"abi":1296,"abl":140,"abo":165,"abr":186,"abs":170,"abu":92,"ae ":265,"aca":68,"aab":988,"aaf":943,"aag":470,"aad":3122,"aae":152,"aaj":148,"aak":2014,"aai":1233,"aan":4143,"aal":7268,"aam":1949,"aas":6140,"aar":5151,"aap":765,"aav":886,"aau":47,"aat":3358,"ad ":6207,"ac ":51,"aa ":3615,"ab ":4871,"afo":83,"afr":355,"aft":134,"aff":76,"afe":44,"afi":983,"ai ":831,"aga":2664,"agd":52,"age":905,"aen":249,"ael":441,"aes":76,"aer":147,"aeg":1173,"aee":54,"aed":90,"aek":78,"aeh":45,"ah ":172,"afa":57,"aev":851,"aet":163,"ado":272,"adr":398,"adl":409,"adm":484,"adj":65,"adi":3217,"ade":4451,"ag ":78,"ads":103,"adu":2361,"adv":107,"aco":80,"ack":227,"aci":112,"ach":400,"ace":151,"acc":48,"ada":2882,"af ":128,"act":96,"azo":46,"azi":122,"гор":67,"Šot":73,"avä":555,"aza":97,"др ":56,"avõ":220,"avö":76,"azz":52,"atä":55,"axi":69,"asõ":365,"asü":91,"atõ":66,"atö":93,"atü":106,"aya":58,"aye":71,"ba ":651,"atš":101,"at ":2216,"amõ":135,"arh":476,"anä":68,"arg":455,"arf":44,"are":3776,"ard":1446,"arc":202,"arb":519,"ara":2982,"amü":61,"arp":144,"aro":486,"arn":587,"arm":512,"arl":676,"ark":1022,"anç":55,"arj":940,"ari":5535,"aru":930,"arv":2193,"arr":543,"ars":766,"art":3541,"au ":240,"asa":1531,"anõ":84,"ary":130,"asi":2682,"ash":208,"asc":73,"ase":3414,"aso":395,"asn":174,"asp":282,"ask":962,"asj":302,"asm":178,"asl":169,"aot":356,"aor":55,"aos":1245,"ar ":2000,"akü":111,"apa":845,"ape":400,"api":685,"aph":50,"apn":98,"apl":208,"apo":517,"app":368,"apr":632,"aps":286,"apt":144,"apu":179,"alõ":58,"as ":16624,"alü":198,"amä":398,"ava":6484,"ax ":62,"aut":985,"avs":163,"avo":221,"avl":84,"avi":977,"ave":501,"ay ":224,"arü":99,"awa":117,"arö":60,"avy":49,"arõ":46,"avu":364,"av ":2085,"ata":5828,"asu":6462,"ast":15872,"ass":1978,"asr":56,"asv":597,"atm":137,"atn":57,"atk":174,"atl":435,"atr":525,"ato":1488,"ate":6661,"ati":3865,"ath":254,"apä":659,"aua":310,"aub":254,"att":452,"ats":3184,"atv":82,"atu":6581,"apõ":81,"aul":1069,"aum":65,"aun":225,"aup":177,"aur":292,"aus":715,"aud":1021,"aue":64,"auf":46,"aug":1111,"auh":299,"auk":196,"Tōk":46,"Tšu":55,"Tši":63,"Tše":232,"Ühi":101,"Ühe":728,"Võr":202,"Või":74,"еев":71,"Üli":294,"Üld":58,"Üle":201,"еви":205,"ени":90,"енн":63,"ерн":50,"ерг":55,"екс":141,"ель":84,"етр":46,"ико":106,"ина":63,"ими":56,"иль":70,"ист":52,"иха":59,"ка ":82,"ив ":46,"ие ":51,"ий ":339,"ин ":106,"ич ":575,"ия ":116,"jee":65,"jer":66,"jek":711,"jel":510,"jem":199,"jen":398,"jes":189,"jet":51,"jev":327,"ji ":46,"jad":794,"jaa":1553,"jab":52,"jat":1299,"jas":1811,"jav":659,"jap":328,"jao":620,"jar":182,"jal":3824,"eük":52,"jak":1121,"jan":2708,"jam":517,"jah":222,"jag":412,"jaj":121,"jai":178,"jaz":54,"je ":209,"jms":73,"jne":167,"jok":49,"joo":1404,"jon":315,"jor":223,"jia":91,"jm ":66,"fää":209,"itn":116,"itm":881,"itl":1066,"itr":232,"ito":1263,"itu":2865,"itt":840,"its":4841,"itz":125,"ity":156,"ipõ":57,"iud":60,"isk":1562,"isj":238,"ism":2164,"isl":320,"iso":452,"isn":380,"üdr":236,"isp":759,"iss":1297,"isr":458,"isu":1149,"üdn":80,"ist":16111,"üdi":214,"isv":570,"iv ":471,"ita":4226,"ite":4040,"ith":114,"ipä":225,"iti":2606,"itj":280,"ivs":528,"ivo":234,"ivn":346,"ivu":91,"ühe":2500,"irü":49,"iwa":47,"ühh":198,"ühi":1384,"üha":330,"iup":58,"ius":891,"ium":1351,"iul":72,"iut":86,"iva":1768,"ix ":96,"ügi":120,"ivi":1653,"ive":618,"üga":160,"ipr":172,"ipo":148,"ipp":426,"ipu":354,"ips":94,"ipt":204,"ipi":209,"ipl":275,"ilõ":45,"is ":17934,"ion":1904,"ioo":5170,"iop":63,"ior":225,"ios":453,"iot":121,"iog":121,"iok":89,"iol":466,"iom":85,"ipa":243,"ikü":95,"ipe":504,"iov":51,"ikõ":47,"ir ":371,"iru":697,"irv":50,"irs":78,"irt":114,"iro":264,"irm":315,"irn":410,"irk":973,"irl":76,"iri":2513,"irj":2489,"isi":2505,"ish":182,"ise":17961,"isc":260,"isa":2662,"üda":146,"iu ":159,"inõ":65,"iqu":72,"übi":94,"imä":330,"ire":897,"inä":160,"irg":342,"ira":660,"ird":488,"irc":67,"it ":2043,"imõ":379,"ünn":379,"üno":56,"ünk":61,"üng":61,"ünd":3848,"üp ":170,"üna":270,"ümp":310,"ümm":93,"ümn":303,"itš":421,"ümi":74,"üme":56,"ümf":54,"ümb":638,"ülr":51,"üpo":95,"üpp":83,"üpe":67,"üpi":189,"ünt":213,"ja ":25408,"ül ":45,"itü":46,"itõ":50,"itö":136,"isü":229,"ühr":50,"isõ":144,"ühm":571,"üht":317,"üla":1693,"üle":1718,"üld":476,"ülg":296,"üli":561,"가가가":51,"ülj":132,"ülm":94,"üll":158,"ülo":65,"üks":2052,"ivõ":345,"ivä":146,"üki":160,"ize":56,"ükl":190,"ükk":136,"iza":126,"üm ":72,"kii":670,"kih":644,"kik":66,"kij":101,"kim":281,"kil":445,"kk ":305,"kia":138,"kib":147,"kie":46,"kid":1460,"kiv":697,"kin":1384,"kip":117,"kir":3701,"kis":700,"kit":731,"kiu":59,"kja":72,"km ":1345,"ki ":1992,"kha":79,"kj ":53,"kho":116,"kea":512,"ked":219,"kee":6776,"keh":762,"kei":247,"kek":94,"kej":56,"kem":268,"kel":1252,"ken":530,"kep":122,"kes":5621,"ker":962,"ket":387,"kev":86,"füü":427,"ke ":2101,"kra":1232,"kre":1046,"kt ":481,"ksa":2425,"kse":4827,"ku ":4118,"kro":695,"kru":92,"kri":683,"kpa":66,"kr ":45,"kov":236,"km²":193,"kot":103,"kos":501,"kor":2423,"kop":353,"koo":4137,"kon":8471,"kom":1331,"kol":1558,"kok":400,"koj":93,"koh":2395,"kog":2107,"koe":132,"kod":636,"ööp":158,"öör":516,"öös":287,"ööt":635,"ks ":9327,"ööv":121,"ööb":59,"ööd":419,"öög":123,"kpo":74,"kpi":89,"öök":163,"ööm":71,"ööl":141,"öön":269,"kme":409,"kmi":180,"koa":59,"kob":69,"kne":492,"öö ":232,"kku":1792,"kke":775,"kka":353,"kko":768,"kki":577,"klu":516,"ko ":325,"kma":69,"kle":259,"kla":1096,"klo":288,"kli":1510,"jut":1345,"jus":656,"juv":119,"juu":1477,"jul":461,"juk":80,"jun":529,"jum":545,"jur":167,"jub":134,"juh":1325,"jug":89,"jud":292,"ju ":890,"jt ":90,"kav":342,"kat":1523,"kau":1221,"kar":907,"füs":56,"kas":4782,"kap":253,"kan":1568,"kao":86,"kal":1965,"kam":275,"kaj":243,"kak":404,"kah":1019,"kai":1321,"kag":415,"kae":301,"kad":579,"kab":194,"kaa":1822,"ka ":8332,"föd":110,"ha ":1068,"ham":380,"han":1084,"hap":399,"hai":439,"haj":90,"hak":332,"hal":1865,"hau":155,"hav":82,"har":1689,"has":829,"hat":244,"haf":57,"hae":123,"hag":90,"hab":58,"haa":386,"had":171,"he ":2035,"hek":639,"hel":4104,"hei":379,"heg":134,"hee":149,"hed":836,"hea":267,"hev":124,"het":632,"hes":861,"her":737,"hep":112,"heo":122,"hen":4035,"hem":646,"hi ":803,"hhi":366,"hho":288,"hha":319,"hk ":5071,"hig":50,"hie":100,"hid":172,"hic":69,"hib":91,"hia":196,"hip":104,"hio":120,"hin":1818,"him":313,"hil":853,"hik":677,"hii":392,"hiv":50,"his":1677,"hit":1195,"hir":223,"hja":2408,"hje":45,"hju":407,"hka":48,"hm ":244,"hke":354,"hkl":54,"õõd":171,"hkr":47,"hku":160,"hkv":87,"hn ":212,"õõt":409,"õõr":156,"õõs":83,"hla":75,"hle":125,"hli":44,"ho ":78,"hma":426,"gma":96,"go ":269,"gme":81,"glu":61,"glo":135,"gle":108,"gli":2195,"gla":352,"gko":571,"gno":68,"gni":103,"gne":544,"gna":249,"gmi":89,"glü":44,"gs ":53,"gpa":728,"gol":120,"goo":292,"gon":121,"gos":166,"gor":359,"got":49,"gov":53,"ый ":88,"gu ":2469,"gse":607,"gro":161,"gru":407,"gra":1940,"gt ":50,"gri":373,"gre":257,"gto":66,"gug":104,"gui":112,"guk":582,"gum":403,"gul":521,"gua":174,"gub":77,"gue":138,"gud":1131,"gy ":51,"guv":167,"gut":1041,"guu":62,"gur":250,"gus":4478,"gup":144,"gun":555,"guo":121,"gvi":72,"iai":81,"iah":71,"iak":307,"iaj":141,"iam":367,"ial":852,"iao":48,"dün":222,"ian":848,"iap":68,"ias":2407,"iar":200,"iau":97,"iat":663,"iav":133,"ic ":272,"iaa":1098,"iab":61,"iac":55,"iad":147,"iae":81,"iag":258,"ibl":123,"ibi":192,"ibo":94,"ibn":54,"ibr":97,"ibu":187,"id ":9461,"iba":199,"ibe":483,"ia ":7687,"ib ":1767,"iet":453,"iev":106,"iel":576,"iem":193,"ien":617,"ier":409,"ies":329,"iee":79,"ied":249,"iek":65,"ig ":195,"iec":79,"ifu":44,"ifo":208,"ife":183,"ifi":363,"ifa":59,"icr":74,"ics":57,"ict":114,"icu":98,"ico":150,"ick":168,"ici":96,"ich":758,"ice":186,"ie ":546,"ica":492,"idu":2141,"ids":89,"idr":54,"ido":139,"idm":73,"idn":61,"idl":140,"idi":1042,"idg":52,"ide":8097,"ida":3662,"iib":405,"iia":256,"iif":48,"iig":4040,"iid":2067,"iie":248,"iik":3861,"aši":75,"iin":2367,"iil":963,"iim":756,"iis":1521,"iir":3180,"iip":91,"iiv":1986,"iiu":178,"iit":2428,"il ":6055,"ija":1055,"ije":50,"ijo":86,"iju":112,"im ":1389,"ika":6374,"ige":1448,"iga":2716,"ii ":657,"igl":90,"igm":62,"igh":187,"igi":4211,"igu":1608,"igr":133,"igo":112,"ign":238,"ihe":679,"iha":299,"ihk":182,"ihm":65,"ihh":111,"ihi":253,"iht":687,"ihu":144,"iho":52,"ik ":7328,"imo":225,"imn":64,"imm":144,"iml":60,"ims":252,"imp":192,"idž":109,"ime":7025,"imk":210,"imi":4107,"ip ":128,"inc":157,"ind":2723,"ina":4896,"inb":48,"imt":70,"imu":1850,"inn":6824,"ino":606,"inr":85,"int":1835,"ins":667,"inf":422,"ine":12596,"ijä":97,"inh":82,"ing":10735,"inj":49,"ini":4649,"inl":74,"ink":241,"ioa":102,"inu":4443,"inv":62,"iny":57,"ьев":85,"iko":1851,"ikn":407,"ikm":345,"ikl":1543,"ikk":1983,"iki":2101,"ikh":52,"ike":2715,"ila":1146,"ilb":76,"in ":2156,"ikv":103,"ikt":211,"iku":8444,"ikr":276,"iks":1858,"ilp":103,"ilo":1161,"ill":5963,"ilk":54,"iln":65,"ilm":2925,"ilh":117,"ilj":833,"ili":8126,"ild":409,"ile":1595,"ima":3230,"imb":81,"io ":525,"ils":210,"ilt":420,"ilu":306,"ilv":181,"hol":538,"hom":193,"hon":119,"hoi":327,"hos":103,"hot":60,"hou":76,"hov":70,"hoo":630,"hop":48,"hor":259,"hob":86,"hof":75,"hoe":47,"hod":56,"hni":355,"hno":248,"hnu":57,"hna":53,"hiü":45,"hme":82,"hmi":96,"øya":60,"huk":196,"hul":1525,"hua":81,"htu":834,"htt":114,"hts":526,"htr":54,"htp":46,"htn":93,"htm":114,"htl":468,"hti":872,"htk":120,"hte":1012,"hta":927,"hv ":86,"hst":88,"hu ":482,"hrm":49,"hro":62,"hre":114,"hri":254,"ht ":1267,"hra":59,"hvu":1043,"hwa":51,"hum":318,"hun":86,"hus":694,"hut":421,"hur":174,"huu":56,"huv":197,"hva":963,"hve":131,"hvi":258,"hvk":76,"fi ":130,"ffe":80,"ffi":97,"fes":255,"fer":227,"fen":116,"fek":256,"fel":93,"fia":527,"bän":220,"fga":88,"far":57,"fan":78,"fak":63,"aül":78,"fal":91,"fai":103,"aüh":102,"fac":50,"faa":159,"ff ":69,"fe ":58,"etš":80,"fa ":46,"etü":153,"etö":63,"etõ":90,"eys":46,"esü":78,"exa":132,"ez ":79,"esõ":110,"etä":142,"exi":65,"evõ":561,"evä":227,"ezi":53,"eta":4185,"ete":3476,"eti":2019,"eth":183,"epä":212,"etn":244,"etl":824,"etk":122,"esp":119,"esn":50,"eso":307,"est":15172,"esu":447,"esr":46,"ess":2291,"esw":67,"ev ":1881,"eud":58,"euk":45,"eum":209,"eto":650,"etr":1191,"ets":1555,"ett":1369,"etu":2430,"etv":60,"epõ":75,"ew ":294,"eve":552,"eva":4542,"evo":358,"evk":55,"evi":1332,"eut":162,"eur":217,"eus":372,"ex ":72,"evu":1013,"ey ":327,"erü":78,"epe":305,"epi":674,"elä":86,"eph":149,"er ":4533,"ekü":242,"epa":593,"eot":431,"eos":1290,"eor":477,"eom":115,"eol":658,"eok":113,"eop":87,"eoo":298,"eon":217,"emä":170,"es ":19178,"ept":722,"eps":46,"epu":101,"epl":50,"epp":174,"epo":236,"epr":147,"erk":288,"erl":431,"eri":8620,"erj":357,"erg":1464,"enä":125,"erh":103,"ere":3347,"erf":89,"erc":92,"erd":390,"era":2994,"erb":550,"et ":2344,"emõ":84,"esk":3814,"esl":149,"esm":728,"esh":61,"esi":3721,"esc":105,"ese":2495,"esa":695,"erz":44,"enõ":60,"ery":69,"erv":749,"eru":688,"err":901,"ert":1083,"ers":969,"ern":1144,"erm":1039,"erp":165,"ero":598,"eki":846,"ekk":441,"ekl":132,"eko":1441,"ekr":148,"eks":6278,"ekt":2822,"eku":1116,"ekv":84,"en ":1782,"elb":55,"ela":2671,"eld":1386,"elf":47,"ele":10866,"eli":5612,"elj":466,"elg":374,"elm":278,"eln":482,"elk":721,"ell":3694,"elo":690,"elp":87,"elu":1130,"elv":392,"els":698,"elt":4591,"eo ":141,"emb":1631,"ema":5853,"eme":1702,"emm":105,"emn":126,"emo":658,"emi":4057,"emj":89,"emk":49,"emu":471,"emp":531,"ems":73,"ep ":59,"enf":67,"ene":6080,"enh":138,"ejä":142,"eng":640,"enb":279,"ena":1669,"end":9301,"enc":218,"eno":318,"enn":1302,"enk":163,"enl":78,"eni":2414,"enj":57,"enu":916,"ens":876,"ent":3483,"enr":170,"enz":141,"ejõ":394,"eny":49,"eog":500,"eod":99,"eob":44,"egl":195,"ego":223,"egn":128,"ege":2106,"egi":861,"eha":1078,"egr":208,"egs":221,"egu":1523,"ehn":541,"ehm":64,"ehk":5017,"ehr":86,"eho":88,"ehe":590,"ehi":903,"ehh":383,"ek ":209,"eib":48,"eic":64,"eia":95,"eht":613,"eip":60,"eis":4050,"eir":116,"eim":514,"eil":387,"ein":1247,"eii":45,"eik":96,"eie":63,"eid":2255,"eig":71,"eja":948,"el ":10310,"eit":602,"eiu":148,"eiv":45,"ejo":57,"eje":77,"eke":406,"eka":1625,"em ":2077,"eju":213,"gjo":58,"öta":380,"ötl":187,"ötm":68,"gji":57,"gl ":95,"öst":232,"git":756,"gis":1905,"gir":78,"giv":225,"gil":1090,"gim":411,"gij":262,"gik":642,"gip":428,"gin":524,"gio":325,"gid":469,"gie":61,"gib":455,"gih":62,"gii":53,"gig":185,"örl":72,"gia":2005,"örs":50,"ght":152,"öra":67,"örd":139,"gha":121,"öri":170,"ös ":62,"gga":46,"gi ":5321,"öpm":55,"ör ":108,"gen":1194,"geo":730,"get":321,"geu":170,"ger":573,"ges":288,"gev":1367,"gh ":77,"gee":427,"ged":631,"geb":241,"gei":271,"gem":670,"gel":1762,"gek":61,"gej":286,"öni":115,"gda":70,"önd":159,"gde":51,"ömi":48,"ge ":1988,"gaz":58,"öli":74,"gab":187,"gad":306,"gai":51,"gaa":657,"gas":1340,"gar":467,"bür":50,"gat":540,"gav":357,"gak":106,"gaj":153,"gam":272,"gal":712,"gan":2019,"öko":300,"gap":72,"ga ":9681,"öid":47,"ögi":100,"öel":65,"fur":44,"fta":81,"fti":45,"fun":331,"ft ":139,"fra":194,"fre":107,"fri":412,"fro":53,"for":851,"fos":114,"fot":258,"fon":233,"foo":243,"fol":120,"fla":75,"fli":57,"fo ":79,"fid":70,"fic":72,"fie":44,"fii":98,"fil":1891,"fik":301,"fin":213,"fir":227,"fis":69,"fit":113,"fjo":141,"õla":152,"õle":240,"õlg":110,"õli":251,"õlk":134,"õll":298,"õlm":435,"õlt":294,"õlu":48,"õlv":413,"õju":446,"õkk":88,"õne":668,"õng":76,"õna":926,"õnd":49,"õnn":136,"õni":203,"õnk":86,"õnu":108,"da ":7682,"õmb":51,"õmm":206,"õpe":513,"õpi":263,"õpu":202,"de ":10486,"õpp":472,"dad":930,"daa":286,"dab":1585,"dak":424,"dal":2308,"dai":94,"daj":449,"dag":307,"dae":79,"dat":1521,"das":1349,"dar":435,"dap":141,"dao":265,"dan":602,"dam":1690,"dav":923,"õri":60,"õrj":81,"õrk":196,"dde":47,"õrg":1625,"õra":75,"õrb":100,"õrd":333,"õt ":51,"õrv":475,"õru":187,"õrr":267,"õrm":46,"õda":213,"õde":121,"cul":68,"ctu":66,"õe ":1023,"cto":118,"cti":143,"cy ":83,"õet":187,"ões":152,"õel":416,"õen":137,"õdu":141,"cus":131,"cur":49,"õhk":139,"õhe":49,"õhj":2576,"õhi":1112,"õge":171,"õgi":631,"õi ":5148,"õja":1187,"õiv":218,"õit":583,"õis":2033,"õim":1468,"õik":622,"õie":258,"õid":332,"õig":1596,"õib":513,"õhu":552,"cks":55,"cki":151,"ckh":122,"cla":52,"cle":64,"co ":192,"con":154,"col":137,"com":86,"cor":129,"cos":67,"cot":61,"cs ":57,"öd ":110,"ct ":57,"cra":52,"cro":105,"ödi":95,"öda":96,"öde":377,"õst":108,"cci":47,"õu ":118,"õsa":163,"õtu":46,"õtt":671,"cea":61,"õte":379,"õta":58,"õtm":273,"õtl":100,"õtj":101,"õus":427,"õut":47,"ch ":578,"ces":126,"õua":73,"cen":106,"õue":77,"õud":589,"õug":83,"cel":80,"õuk":759,"õul":55,"õun":1596,"ci ":105,"õva":82,"õve":54,"cha":386,"chw":86,"õtü":68,"chu":131,"cia":158,"ck ":487,"cie":98,"che":615,"chl":138,"chi":411,"cho":153,"chm":45,"chn":57,"chs":85,"cht":224,"chr":50,"cis":100,"cin":92,"cm ":52,"cke":185,"cka":54,"õzs":53,"ed ":5646,"eba":352,"ebe":121,"ebi":253,"ebl":44,"ebo":77,"ebr":684,"ebu":73,"eab":210,"eaa":424,"eag":132,"eae":122,"ead":2747,"eak":483,"eaj":63,"eai":99,"eah":87,"ean":733,"eao":48,"eal":1914,"eam":934,"ear":190,"eas":399,"eap":99,"eav":225,"eat":919,"eau":103,"eb ":2987,"ea ":655,"efi":173,"efo":256,"efa":50,"efe":291,"eff":54,"ei ":1558,"ega":4991,"eft":49,"eej":166,"eek":1260,"eeh":72,"een":1833,"eel":7467,"eem":2642,"eeb":812,"eea":50,"eeg":511,"eed":1212,"ees":3817,"eer":4899,"eep":225,"eev":114,"eet":2444,"edi":900,"ede":2096,"eda":2449,"eg ":436,"edu":707,"edo":157,"edr":231,"eck":136,"ech":210,"eci":98,"ee ":3170,"ef ":57,"ect":151,"eco":81,"dwi":78,"dvu":88,"dwa":83,"dy ":101,"dve":99,"duv":409,"duu":64,"dur":309,"dut":208,"dus":9107,"dva":107,"dor":276,"doo":134,"don":412,"dom":146,"dol":150,"dok":340,"dow":80,"dov":88,"dot":70,"dos":91,"dr ":97,"ds ":128,"dmi":448,"dmu":204,"dne":328,"dni":181,"dnu":82,"dsu":120,"dso":79,"dte":403,"dun":212,"dum":683,"dul":361,"duk":455,"õbe":86,"dub":375,"dua":181,"dud":1109,"dri":1541,"drh":50,"dra":532,"dt ":79,"dre":399,"du ":1711,"dro":385,"dru":114,"dsi":69,"dsa":56,"dse":425,"dha":80,"dge":90,"dgl":50,"dic":84,"did":1413,"dia":1187,"der":1254,"des":3846,"det":1487,"dev":307,"deb":74,"dea":150,"ded":103,"def":181,"dee":433,"deg":743,"dei":268,"del":2624,"dek":762,"den":1386,"dem":499,"dep":286,"deo":437,"di ":4266,"dle":97,"dla":684,"dko":283,"dki":67,"dme":789,"dma":248,"do ":334,"dlu":270,"dli":419,"dja":309,"div":260,"diu":154,"dim":305,"din":5058,"dio":737,"dip":162,"dir":107,"dis":3167,"dit":1143,"die":158,"dif":137,"dig":325,"dii":121,"dik":678,"dil":754,"dka":57,"dju":74,"eKr":290,"rgu":1208,"rhe":141,"näd":70,"rha":144,"näg":90,"näh":356,"näi":1177,"rhi":386,"när":92,"rho":51,"näo":109,"rga":2008,"ri ":5455,"rgk":63,"rgl":133,"rgi":2791,"rgh":68,"rge":1513,"rgs":57,"rgr":60,"rgo":122,"rgm":113,"rgn":141,"ret":637,"res":3334,"rev":282,"reu":99,"müü":230,"rfa":51,"rfe":44,"rfi":65,"rfo":51,"rdu":636,"rds":305,"rdr":70,"rg ":613,"reb":76,"rea":973,"ree":2061,"ref":247,"rec":94,"red":566,"rei":666,"reg":889,"rem":1488,"ren":1721,"rek":855,"rel":1476,"rer":134,"reo":148,"rep":269,"rda":591,"rcu":58,"rdo":137,"rdn":203,"rdk":56,"rdm":90,"rdl":149,"rdi":1642,"rde":1014,"re ":3338,"rbu":230,"rbr":301,"rch":187,"rce":98,"rd ":981,"rao":70,"rap":222,"mür":81,"rar":113,"ras":2388,"müt":281,"rat":2331,"rau":610,"rav":669,"rbi":388,"rbl":48,"rbo":167,"rba":241,"rbe":348,"raj":969,"rai":575,"rah":2331,"rag":255,"ran":3582,"mün":66,"ram":1127,"ral":1912,"rak":1264,"rab":296,"raa":4053,"raf":126,"rae":588,"rad":970,"rac":160,"rpu":103,"rpr":48,"rpo":141,"rs ":316,"rpe":48,"rpa":108,"rr ":55,"rpi":60,"ror":118,"ros":627,"rot":969,"rom":675,"ron":932,"roo":2596,"rop":430,"rou":140,"rov":1089,"row":56,"rob":239,"roa":117,"rod":447,"roc":250,"roj":238,"roi":109,"rol":630,"rok":255,"rof":315,"roe":51,"roh":391,"rog":576,"rno":131,"rns":89,"rnu":569,"rna":702,"riü":55,"rež":141,"rne":1143,"rni":528,"rjä":49,"rmo":236,"rms":58,"rmu":175,"ro ":398,"rma":1727,"rme":627,"rmi":820,"rlo":160,"nää":74,"rli":332,"rld":67,"rle":265,"rla":365,"rn ":318,"rgõ":53,"rkv":211,"rku":265,"rkt":136,"rks":128,"rkm":44,"rko":1059,"rki":431,"rkk":66,"rke":333,"rka":216,"rm ":305,"rju":905,"rjo":50,"rja":2847,"rje":754,"riz":44,"rl ":207,"rip":347,"rio":550,"rir":293,"rit":4861,"ris":3546,"riv":668,"riu":963,"rih":61,"rig":747,"rij":404,"rii":5626,"ril":3640,"rik":3181,"rin":3123,"rim":2490,"ria":2118,"rib":484,"ric":609,"rid":1612,"rie":633,"rif":87,"rk ":868,"rtü":56,"rug":66,"rue":78,"rud":172,"ruc":52,"rup":396,"run":460,"rum":712,"rul":170,"ruk":513,"ruu":777,"ruv":117,"rus":1487,"rut":261,"rva":1548,"rvi":795,"rve":1159,"rvp":144,"rvl":46,"rvu":1089,"rwa":50,"ry ":413,"rsk":243,"rsi":519,"rso":171,"rsc":53,"rsa":171,"rsh":62,"rse":561,"rta":274,"rv ":755,"rst":515,"rss":168,"rsu":190,"rtl":107,"rtm":58,"rtn":92,"rto":217,"rte":1543,"rth":281,"rti":1255,"rub":87,"rua":490,"rts":1053,"rtr":65,"rtu":1315,"rtt":57,"rt ":810,"rro":167,"rri":784,"rre":476,"rra":2127,"ru ":1080,"rry":114,"rru":164,"saa":4775,"sab":140,"sad":632,"sae":148,"sag":380,"sah":226,"sai":500,"saj":656,"sak":2002,"sal":1925,"sam":2292,"sbe":92,"sap":131,"óni":51,"san":1221,"sau":105,"sat":1244,"sas":2183,"sar":1496,"sav":213,"sa ":3636,"ón ":53,"rze":44,"nõu":458,"nõr":64,"nõl":71,"nõi":66,"rvü":53,"sha":261,"sho":138,"she":80,"shi":370,"si ":5360,"sgr":60,"sja":511,"siv":324,"sju":179,"sjo":145,"sfä":198,"sie":142,"sid":2303,"sic":71,"sib":74,"sia":2206,"sk ":538,"shu":57,"sit":1318,"siu":225,"sir":212,"sis":2918,"sip":251,"sin":1981,"sio":5046,"sil":1686,"sim":1606,"sij":144,"sik":2762,"sih":204,"sii":1362,"sif":138,"sig":349,"sda":47,"sdo":45,"sbo":51,"sbu":115,"se ":21232,"sca":191,"sci":49,"sch":453,"sco":130,"sev":717,"sey":55,"ser":1068,"ses":5796,"set":1978,"seu":254,"nüü":243,"sh ":174,"sfi":86,"sfo":68,"sea":1804,"sei":2222,"seh":77,"seg":1695,"see":2074,"sed":3928,"seb":254,"sep":903,"seo":645,"sen":2101,"sem":2170,"sel":10065,"sek":3272,"sej":332,"spu":121,"spo":772,"spr":203,"spe":493,"spi":353,"spa":687,"skü":66,"sot":518,"sou":51,"sov":164,"skõ":91,"sol":473,"som":95,"son":907,"soo":2060,"sop":124,"sor":585,"sos":135,"sog":196,"sof":91,"skä":80,"soa":50,"soc":67,"sob":104,"su ":776,"sri":388,"sre":70,"sra":250,"st ":19438,"smõ":57,"smä":672,"ss ":961,"sli":1453,"slo":247,"slu":141,"sla":864,"sle":179,"ski":1330,"skk":688,"skj":46,"skm":251,"skl":222,"sko":1611,"skn":98,"skp":86,"sks":70,"skr":240,"sku":1933,"skv":335,"sm ":509,"ska":1203,"ske":1189,"sno":114,"sjõ":49,"snu":95,"sna":125,"sni":235,"sjä":141,"sne":888,"smo":245,"smu":122,"so ":126,"sma":1250,"smi":1155,"sme":256,"swi":78,"ssü":155,"ssö":85,"ssõ":135,"stõ":73,"stö":240,"svä":103,"svõ":164,"svö":80,"sse":2400,"ssa":886,"sso":712,"ssk":48,"ssi":2279,"ssu":260,"sst":65,"ste":12441,"stf":123,"spä":99,"sta":12430,"stm":389,"stn":305,"sto":736,"sti":11558,"stj":94,"stk":190,"stl":1467,"stv":203,"stu":4098,"str":2584,"sts":374,"sua":230,"sud":110,"sub":2124,"suh":654,"sug":926,"sul":1089,"sum":385,"suk":274,"sup":112,"sun":473,"suu":3246,"sut":3768,"sus":4456,"sur":769,"suv":746,"sva":1352,"sve":77,"svi":156,"svo":72,"svu":249,"sy ":64,"tai":1177,"taj":1586,"tak":4223,"tal":2877,"tae":166,"taf":74,"tag":732,"tah":420,"taa":2158,"tab":1730,"tac":49,"tad":1273,"tba":65,"tav":3721,"tau":131,"tat":7322,"tas":2453,"tar":1636,"tap":159,"tao":157,"tan":2647,"tam":2975,"tch":74,"te ":12807,"ta ":4265,"сто":56,"стр":66,"ств":57,"pa ":804,"ста":51,"pe ":459,"par":1885,"küt":108,"pat":370,"küs":137,"pas":347,"pau":44,"pad":102,"paa":872,"pab":98,"pag":125,"pae":47,"pak":331,"kül":2089,"pal":1654,"pai":924,"paj":61,"pap":44,"küm":165,"pan":1223,"kün":49,"phe":92,"läb":569,"pha":122,"lät":92,"pho":86,"phi":121,"läh":1032,"pi ":489,"küü":67,"ph ":74,"lä ":65,"pea":2994,"peb":54,"pec":50,"ped":165,"pen":309,"per":2019,"pet":866,"pes":209,"pee":735,"pej":56,"pei":56,"pel":221,"pek":193,"pla":985,"pli":241,"lää":1062,"ple":335,"plo":204,"pko":106,"тан":48,"phy":67,"pia":480,"pid":668,"pie":55,"pig":83,"pii":2460,"pik":984,"pil":982,"pim":106,"pin":1660,"pio":63,"pir":110,"pis":249,"pit":216,"por":922,"pop":279,"poo":3433,"pot":178,"pos":489,"poi":69,"poj":56,"pom":75,"pon":250,"pok":78,"pol":2011,"poe":314,"ps ":115,"ppu":86,"ppi":265,"ppl":73,"ppo":76,"ppa":134,"ppe":738,"тер":49,"pme":107,"po ":62,"pni":140,"pne":50,"pp ":583,"psu":187,"pta":45,"pse":289,"psi":131,"pso":44,"ptu":183,"pub":112,"pud":66,"pte":686,"pti":246,"pto":149,"pts":116,"pra":973,"pru":93,"psa":102,"pu ":143,"pri":927,"pre":785,"pro":2923,"psü":231,"lõh":137,"pur":257,"pus":270,"put":156,"pun":658,"pui":197,"pul":391,"puh":552,"px ":81,"тов":47,"puu":696,"тор":53,"lõp":469,"lõi":316,"lõu":988,"тро":97,"löö":149,"lüm":359,"lül":150,"lük":99,"lüh":844,"lüü":275,"mäe":703,"mäg":380,"män":1220,"mäl":265,"mär":1565,"mää":557,"qua":76,"que":158,"qui":88,"mõe":265,"mõi":1422,"mõj":443,"mõl":89,"mõn":454,"mõr":58,"mõt":400,"mõõ":559,"ra ":2421,"möö":180,"rb ":55,"ngo":283,"ngj":112,"eži":152,"ngi":2407,"ngl":2197,"ngk":485,"ngv":53,"ngu":1971,"ngr":466,"ngt":111,"ngs":158,"ni ":8348,"nge":1413,"ngh":131,"nga":1383,"ngd":44,"nho":71,"jäl":102,"jät":125,"jär":2920,"nha":193,"jäi":81,"nhe":51,"neg":216,"nei":559,"nel":854,"nek":392,"nen":1253,"nem":2691,"nep":231,"neo":254,"ner":1383,"net":1372,"nes":1547,"nev":1928,"neu":153,"ndv":49,"ng ":5293,"nea":209,"neb":1735,"ned":454,"nee":1283,"nfi":63,"nfo":399,"nfl":72,"ney":104,"nez":55,"nfe":71,"nco":82,"nci":160,"nce":327,"nch":174,"ne ":18973,"nbu":170,"ndt":47,"ndu":3781,"ndr":1767,"nds":245,"ndn":73,"ndo":567,"ndl":703,"ndm":736,"ndj":199,"ndk":76,"ndi":9574,"nde":2285,"nda":5981,"ncy":54,"nak":847,"nal":1444,"iül":54,"nam":1141,"nan":791,"nao":524,"nap":666,"nar":696,"nac":71,"nad":869,"nae":164,"naf":95,"nag":661,"nah":165,"iüh":71,"nai":421,"naj":121,"nab":249,"naa":1844,"nbe":157,"nd ":4383,"nba":54,"nav":684,"nau":173,"nat":1014,"nas":5608,"na ":9461,"iõp":167,"가 ":51,"nya":69,"jõe":1151,"nyi":68,"jõg":658,"nz ":90,"nsü":49,"ny ":159,"nux":47,"nve":213,"nuk":391,"nul":392,"num":581,"nun":66,"nui":73,"nuj":150,"nus":1407,"nut":211,"nuv":56,"nur":279,"nua":567,"nud":6307,"nto":594,"ntn":44,"ntu":1152,"nts":3190,"ntr":629,"nti":1551,"nth":107,"ntl":53,"nta":1333,"nte":1954,"nsu":194,"nsp":183,"nso":192,"nst":1654,"nss":87,"nse":418,"nsh":72,"nsi":398,"nsk":423,"nsa":519,"nsb":47,"nu ":581,"nri":214,"nra":73,"nt ":1663,"npr":44,"ns ":389,"nod":52,"nob":45,"nog":106,"nof":50,"nok":61,"nol":406,"noi":73,"noo":957,"nop":56,"nom":241,"non":176,"not":137,"nos":276,"nor":508,"nov":777,"nr ":71,"nne":1409,"nna":9091,"nnm":60,"nno":142,"nni":2211,"nnu":1256,"nns":51,"nme":49,"nma":125,"ndž":60,"nli":99,"jää":730,"nn ":2722,"nla":220,"no ":545,"nke":134,"nkl":53,"nki":267,"nka":177,"nku":165,"nko":182,"nks":69,"nkt":721,"nkr":123,"nji":51,"nja":120,"njo":51,"nij":103,"nii":935,"nih":114,"nig":327,"nif":70,"nie":199,"nid":1206,"nic":153,"nib":61,"nia":1970,"nk ":386,"nix":49,"niu":138,"niv":309,"nis":5167,"nit":1025,"nir":49,"nio":206,"nip":222,"nim":5797,"nin":5067,"nik":3655,"nil":1691,"ogs":64,"ogr":1310,"ogu":2080,"ogt":71,"ogi":2325,"ogl":51,"ogo":115,"ogn":110,"oga":201,"oge":329,"oi ":80,"oht":1247,"kät":121,"käs":428,"kär":67,"ohv":181,"ohu":379,"ohk":157,"ohj":63,"käi":618,"ohi":105,"oho":123,"ohn":161,"oha":1453,"käe":74,"ohe":234,"ois":197,"oir":72,"oiu":71,"oit":264,"oin":102,"oik":52,"oim":998,"oil":59,"oid":535,"ok ":100,"oia":64,"oju":137,"oje":372,"oja":659,"ol ":1399,"oce":44,"och":80,"oci":105,"ock":501,"oco":61,"obs":62,"obu":202,"oe ":109,"ode":1123,"odk":64,"odi":1047,"odo":182,"odn":64,"ods":77,"odr":58,"of ":621,"oda":609,"oel":103,"oeg":287,"oer":126,"oes":47,"oet":688,"oen":399,"odu":2480,"oee":44,"og ":463,"ofi":557,"oft":95,"ofo":118,"off":59,"ofe":202,"oa ":93,"ob ":139,"oan":65,"oam":51,"oal":156,"oak":80,"oaj":111,"oba":165,"od ":481,"oar":70,"oas":64,"obo":116,"obr":390,"obl":782,"obj":309,"obi":400,"obe":361,"jõk":47,"jõu":952,"nza":48,"nze":88,"nzi":54,"kõi":997,"otü":52,"oya":45,"osü":192,"ows":73,"own":56,"kõr":1655,"kõv":81,"oyl":61,"kõl":116,"kõn":322,"otu":561,"ow ":114,"otl":94,"otk":48,"otj":93,"oti":581,"oth":115,"ote":630,"ott":288,"ots":2879,"otr":134,"oto":793,"otm":209,"ost":1657,"osu":161,"ota":435,"otb":45,"ov ":391,"osi":662,"osh":53,"osk":556,"ose":1045,"osf":200,"osp":69,"oss":687,"osm":201,"osl":192,"oso":739,"osn":672,"oy ":48,"owa":44,"owe":70,"ovi":1506,"ovg":80,"ovn":57,"ovo":225,"ovu":110,"ovs":142,"ox ":49,"ova":496,"ove":767,"oug":79,"oui":114,"oul":81,"oun":169,"oup":53,"ous":121,"our":234,"out":116,"opo":355,"opp":88,"opi":377,"opk":103,"opl":127,"ope":659,"oph":152,"opa":1002,"os ":1676,"olü":473,"opu":229,"opr":90,"opt":153,"ops":80,"oon":7646,"ool":6457,"oom":3730,"ooj":448,"ook":1060,"oof":591,"oog":2684,"ood":3903,"oob":808,"ooa":118,"or ":1504,"oov":321,"oot":2071,"oos":2409,"oor":2416,"oop":1217,"ork":293,"orl":106,"orm":1403,"orn":581,"oro":441,"orp":251,"orr":1904,"orc":46,"ord":2640,"ore":923,"orf":173,"org":2150,"ori":3030,"orj":99,"ou ":125,"osa":4585,"onü":106,"ort":1076,"ors":316,"orv":260,"oru":308,"ory":79,"omä":44,"ot ":233,"m² ":198,"omö":62,"orb":147,"ora":643,"ola":1318,"old":420,"on ":39161,"olj":64,"oli":8483,"oll":1578,"olk":349,"olf":126,"ole":2988,"kää":76,"olg":132,"ols":1007,"olt":1144,"olm":1122,"oln":368,"olo":2600,"olu":1563,"olv":65,"ofü":93,"oka":297,"om ":370,"okk":531,"oki":231,"oke":623,"okr":399,"oks":957,"oko":247,"okl":55,"okt":664,"oku":340,"ona":1303,"ond":3491,"onf":139,"one":1232,"ong":640,"oni":6425,"onl":72,"onk":273,"onn":4600,"ono":803,"onp":75,"onr":44,"ons":816,"ont":1242,"onu":172,"onv":154,"ony":92,"oma":3656,"oo ":462,"ome":2088,"omb":266,"omi":1618,"omm":613,"omp":670,"omn":106,"omo":342,"omt":108,"omu":606,"oms":246,"op ":270,"la ":5991,"le ":12620,"lf ":96,"ldg":52,"lde":484,"lda":2949,"ldo":95,"ldn":65,"ldm":61,"ldk":243,"ldj":62,"ldi":712,"ldu":1916,"ldt":53,"lds":102,"ldr":58,"laa":1373,"lab":404,"lac":145,"lad":1522,"lae":732,"lah":1640,"lag":388,"laj":204,"lai":1062,"lal":666,"lak":450,"lan":3578,"güm":58,"lam":1233,"lap":307,"lao":158,"lar":440,"kyō":50,"lat":2238,"las":6761,"lau":1302,"lav":840,"lay":76,"lba":164,"ld ":1107,"lbe":196,"lbi":58,"lbo":45,"lbu":264,"lbr":50,"kvi":101,"kve":117,"kva":933,"kuv":271,"kuu":2381,"kut":1032,"kus":4511,"kur":510,"kup":256,"kun":2636,"kum":1199,"kul":2990,"kuk":399,"kuj":1401,"ky ":44,"kta":184,"kte":370,"ksp":172,"ksu":1368,"kst":539,"ksk":77,"ksj":60,"ksi":1286,"ksh":44,"kso":186,"ksn":51,"ksm":52,"ksl":97,"kub":299,"kud":842,"kug":145,"kuh":220,"kui":2011,"kua":93,"ktr":1077,"kts":955,"ktu":547,"kti":1734,"kto":1139,"gõz":53,"ksü":131,"kyl":45,"lpo":71,"lpe":157,"lpi":167,"lph":47,"ls ":120,"llü":71,"lpt":60,"lol":75,"lok":121,"lon":328,"lom":526,"lop":192,"loo":6341,"lor":264,"lod":57,"loc":108,"loe":826,"loh":62,"log":273,"loi":81,"los":787,"lot":130,"lov":353,"lkõ":156,"lni":82,"lne":1147,"lob":91,"lnu":266,"lmn":103,"lmi":1561,"lme":771,"lma":2491,"liõ":138,"lmu":534,"lms":87,"lti":513,"lto":103,"ltr":71,"lts":498,"ltu":933,"lud":201,"lub":1064,"lua":79,"lug":367,"lue":62,"lsi":290,"lsk":106,"lso":81,"lss":61,"lst":139,"lsu":210,"lv ":77,"lta":252,"lte":588,"lri":102,"lu ":1464,"lse":1684,"lsa":658,"ía ":44,"lt ":7949,"lra":58,"lhu":155,"häv":119,"lho":73,"här":83,"lhe":124,"häi":143,"lha":82,"lgu":794,"lgs":300,"lgn":56,"lgl":54,"lgr":91,"lgo":86,"lgp":735,"lge":1193,"lgi":247,"li ":8571,"lga":1157,"lfr":46,"lfi":78,"lfa":51,"ley":127,"lex":145,"leu":72,"lev":2102,"les":6911,"let":1229,"ler":467,"leo":191,"lep":522,"lem":2382,"len":1713,"lek":2924,"lel":939,"lei":662,"lej":650,"leh":741,"leg":615,"lef":123,"lee":784,"led":276,"lec":56,"leb":814,"lea":143,"lg ":112,"llp":58,"lls":97,"llu":829,"lly":101,"lo ":301,"lla":3994,"lle":7577,"hää":354,"lli":4723,"llk":46,"llo":330,"lko":770,"lku":106,"lka":667,"lke":205,"lki":380,"lkl":73,"lju":697,"ljo":186,"lm ":614,"lje":847,"ll ":1528,"lja":2809,"lit":3006,"lis":12972,"lir":127,"lip":448,"lio":191,"lin":10479,"lim":654,"liz":82,"liv":165,"liu":274,"lic":156,"lid":1460,"lia":1378,"lib":211,"lk ":259,"lik":8420,"lil":1193,"lii":5503,"lij":133,"lig":496,"lih":443,"lie":227,"lif":188,"hõõ":63,"ma ":4860,"mb ":129,"maa":11983,"mac":100,"mab":268,"mah":237,"чес":55,"mai":1139,"maj":980,"mak":919,"hüd":167,"mad":1582,"mae":114,"maf":51,"mag":417,"hüp":189,"map":146,"mar":885,"mas":3246,"mal":2280,"hüm":55,"mam":324,"man":2399,"mav":524,"mat":3086,"mba":251,"mbl":329,"mbi":269,"mbe":2044,"mbr":1530,"mbo":263,"me ":2925,"mbu":182,"med":1125,"mee":3676,"meg":594,"mea":100,"met":4426,"mev":67,"mep":72,"mes":2849,"mer":2169,"mem":157,"mel":1042,"men":2636,"mei":782,"meh":405,"mek":592,"hüü":97,"lva":713,"lve":678,"lvi":208,"lul":347,"luk":457,"lup":150,"luo":49,"lun":505,"lum":505,"lut":683,"lus":3490,"lur":311,"luv":1330,"luu":781,"ly ":163,"lrü":75,"lvk":62,"hõb":45,"hõi":206,"hõl":310,"mpi":452,"mph":51,"mpe":554,"mpr":66,"mpo":299,"mpl":310,"mpu":89,"mps":61,"ms ":217,"mog":59,"mob":84,"moe":58,"mod":191,"moo":1204,"mon":658,"mok":297,"mom":61,"mol":409,"mov":44,"mor":367,"mos":365,"mot":173,"mpa":252,"msa":75,"mu ":287,"mse":406,"mtu":96,"mud":268,"mub":235,"mst":77,"msu":90,"mso":47,"msi":100,"mte":76,"my ":109,"mur":342,"mus":2450,"mut":357,"muu":2318,"muv":182,"mui":212,"muj":55,"muk":66,"mul":772,"mum":89,"mun":762,"džu":46,"dža":146,"mi ":3313,"dži":112,"mjo":107,"min":5859,"mio":159,"mil":5861,"mim":121,"mir":250,"mis":17764,"mip":65,"miv":72,"mit":2152,"mic":74,"mia":602,"mig":164,"mie":74,"mid":2544,"mik":1090,"mii":356,"mo ":151,"mli":87,"mle":44,"mla":87,"mn ":55,"mko":173,"mka":66,"mm ":329,"mnu":50,"mni":67,"mna":105,"mne":450,"mmy":82,"mp ":57,"mmu":480,"mmi":519,"mmo":72,"mma":633,"mme":654,"tš ":386,"tše":222,"tši":133,"tša":111,"zst":65,"võt":836,"võs":96,"võr":892,"võn":91,"võl":153,"või":7974,"võe":178,"vöö":291,"võõ":64,"vür":134,"zi ":155,"väl":2397,"väh":435,"väi":1090,"väg":389,"väe":751,"zen":74,"zer":96,"ze ":109,"zab":50,"uüh":53,"zan":66,"zar":62,"zon":61,"zo ":48,"vää":478,"vär":503,"väs":44,"zia":44,"zin":86,"yst":121,"ysi":65,"ys ":119,"ylä":47,"za ":111,"tüü":554,"yer":56,"ya ":162,"töö":1589,"tüt":130,"tür":79,"yan":90,"tük":102,"tüh":106,"yn ":51,"yle":91,"ylo":45,"yne":47,"yin":76,"tõe":238,"tõm":70,"tõl":200,"tõk":57,"tõu":195,"tõs":109,"tõt":177,"tõr":100,"tän":706,"täh":1822,"täi":727,"xi ":91,"süü":243,"xim":52,"tär":60,"täp":255,"söö":193,"süs":1324,"süt":71,"sük":585,"sül":70,"süm":231,"sün":4272,"xan":102,"süd":144,"süh":336,"süg":181,"sõl":377,"sõj":1120,"sõp":113,"sõn":939,"sõd":233,"sõi":351,"sää":83,"ws ":61,"wor":58,"rüü":199,"wer":86,"wen":48,"säi":178,"wit":44,"wig":128,"wic":50,"win":68,"rõh":178,"röö":217,"wa ":114,"wan":110,"rün":141,"rüo":64,"wal":97,"rük":165,"way":55,"rüt":71,"war":196,"rüh":567,"vri":47,"vsu":116,"vst":161,"vse":403,"vsk":184,"vu ":181,"vut":793,"vus":2887,"vud":63,"vum":73,"vuk":112,"vul":243,"vy ":55,"vib":72,"via":291,"vio":50,"vip":54,"vir":136,"vik":721,"vil":657,"vim":530,"vin":1205,"vig":116,"vih":89,"vii":1360,"vic":51,"vid":522,"vie":84,"viv":99,"vit":1084,"vis":990,"vka":64,"vko":169,"vkj":47,"vla":98,"rää":402,"vli":75,"vo ":249,"vms":66,"vne":367,"vna":66,"voj":65,"vol":333,"vok":90,"von":554,"voo":711,"vor":540,"vos":69,"vpa":151,"rän":173,"vi ":1273,"vgo":75,"veo":115,"ver":1595,"ves":902,"vet":333,"vei":261,"veg":47,"ven":2478,"vem":547,"vel":383,"vek":127,"vea":44,"vee":1876,"ved":504,"ve ":854,"val":8945,"vak":669,"van":2026,"vam":407,"vap":226,"var":1747,"vat":2727,"vas":3460,"vav":166,"vaa":1097,"vab":718,"vae":151,"vad":3860,"vai":1190,"vaj":399,"vag":98,"vah":2967,"va ":3296,"uvõ":268,"uvä":105,"usõ":228,"usü":545,"uuk":89,"uun":1174,"uul":3063,"uum":754,"uub":214,"uua":104,"uug":75,"uud":1301,"uue":262,"ux ":63,"uus":2149,"uur":5973,"uup":59,"uuv":44,"uut":1103,"uvi":326,"uvo":58,"uva":2014,"uve":246,"uvu":186,"usl":1435,"usm":668,"usj":225,"usk":1361,"ush":270,"usi":2532,"usf":104,"usg":54,"usd":49,"use":12729,"usc":44,"usa":1306,"uu ":547,"uv ":1217,"usv":989,"usu":604,"ust":10829,"uss":984,"usr":193,"usp":536,"uso":240,"usn":79,"utk":47,"utl":151,"utm":97,"utn":50,"uth":113,"upä":61,"uti":1297,"ute":1328,"uta":4946,"utz":51,"upõ":82,"utt":121,"uts":1366,"utv":93,"utu":2313,"uto":959,"utr":121,"us ":14520,"umä":125,"ut ":606,"urb":400,"ura":699,"urd":430,"ure":1850,"urg":757,"urj":163,"uri":3709,"url":67,"urk":267,"urm":383,"urn":372,"uro":1163,"urr":134,"urs":299,"urt":336,"uru":948,"urv":239,"uol":59,"uot":45,"uor":83,"uos":126,"ukü":84,"upa":311,"ur ":1500,"upi":356,"upe":239,"upo":146,"upp":283,"upr":65,"upl":50,"upu":118,"ump":59,"umu":239,"umi":3810,"umm":293,"umo":96,"uma":2384,"umb":1389,"ume":800,"unt":871,"uns":729,"unu":969,"unk":808,"uni":2914,"uno":48,"unn":618,"unc":54,"und":1856,"una":2903,"ung":491,"ujä":52,"une":1105,"up ":125,"uks":640,"ukr":117,"uku":265,"ukt":617,"uko":1820,"ukk":131,"ukl":81,"uki":384,"uke":268,"um ":1368,"uka":800,"uju":1494,"ulu":2649,"ult":2105,"uls":130,"ulp":70,"ulo":139,"uln":45,"ulm":184,"ull":465,"ulk":645,"ulj":361,"uli":2783,"ulg":972,"ule":2072,"uld":337,"ula":1652,"un ":198,"uid":849,"uie":51,"uig":91,"uil":85,"uim":112,"uin":284,"uis":365,"uht":1356,"uhu":769,"uk ":199,"uiv":119,"uit":151,"ul ":2180,"uja":426,"ugh":62,"ugi":162,"uge":590,"ugo":56,"ugl":46,"ui ":1419,"uga":910,"uhi":560,"uhe":222,"uho":49,"uhk":168,"ugu":2195,"ugr":50,"uha":362,"uct":46,"uda":566,"ude":2760,"udi":687,"udm":209,"ubu":163,"uca":46,"ue ":313,"uci":50,"uch":100,"uck":66,"uet":68,"uer":113,"ues":193,"püü":159,"ufo":48,"ufi":80,"udu":959,"uds":80,"udt":385,"udo":126,"ug ":76,"udw":51,"uee":109,"uen":148,"uel":155,"pöö":270,"ub ":3808,"põõ":56,"ua ":229,"uat":112,"uas":207,"püs":236,"uar":1172,"pür":52,"uam":44,"ual":222,"uan":196,"ubi":508,"ubj":82,"ubl":189,"ube":338,"uba":529,"ud ":15469,"uak":53,"püh":249,"uai":64,"uad":62,"uaa":347,"tvõ":44,"tvä":73,"tzi":57,"tze":47,"põh":2641,"põi":53,"põl":539,"põr":58,"ty ":254,"trü":150,"tvu":92,"tvo":55,"tve":93,"tva":221,"tur":775,"tus":7900,"tut":545,"tuu":2287,"tuv":618,"tuj":83,"tui":121,"tul":1640,"tuk":346,"tun":1878,"tum":1084,"tup":139,"tub":376,"tua":183,"tud":7345,"tuh":72,"tug":512,"tsü":333,"tz ":121,"tsõ":45,"ts ":1169,"tre":529,"tt ":402,"tra":1815,"tri":3128,"tru":752,"tro":1685,"tu ":1887,"tsa":1214,"tse":5653,"tsc":70,"tsi":9068,"tsj":165,"tsm":159,"tsk":220,"tsl":83,"tso":358,"tsu":2329,"tst":212,"tta":440,"tte":2371,"tti":343,"ttl":46,"tto":143,"ttp":55,"tts":70,"ttu":276,"tme":1276,"tma":236,"to ":641,"tmu":55,"tmo":97,"tmi":756,"tni":437,"tne":300,"tp ":49,"tna":202,"tnu":77,"tno":51,"tof":48,"toe":213,"tod":315,"toc":161,"toi":1340,"toh":46,"tog":150,"toa":50,"tov":120,"tos":269,"tot":150,"tom":456,"ton":1159,"tok":224,"tol":1335,"tor":2218,"too":2528,"top":205,"tkü":52,"tij":48,"tii":1991,"til":2148,"tik":5067,"tif":152,"tie":142,"tih":290,"tig":255,"tir":123,"tit":780,"tis":3212,"tin":1198,"tim":859,"tip":427,"tio":925,"thu":237,"tia":704,"tic":223,"tid":1567,"tiu":100,"tiv":496,"tja":582,"tki":109,"tko":214,"tku":135,"tka":199,"tke":169,"tli":1813,"pää":190,"tlu":1138,"tla":898,"tle":1553,"tem":2042,"ten":994,"teo":974,"tep":235,"tei":2648,"tej":88,"tek":2590,"tel":4094,"tee":4577,"tef":53,"teg":3418,"teh":952,"tea":2198,"tec":57,"ted":509,"tfo":51,"tfa":78,"th ":373,"tev":754,"tet":709,"tes":4048,"ter":4969,"ti ":9417,"tho":135,"thr":60,"pär":1925,"päe":892,"the":496,"thi":183,"päi":92,"tha":245,"ān ":65,"üüp":380,"üür":188,"üüs":557,"üüt":421,"üüa":70,"üüb":92,"üüd":395,"üüg":68,"üüh":62,"üüm":176,"üül":234,"üün":56,"並 ":57,"žik":69,"žis":93,"三 ":165,"žii":61,"žan":88,"丁 ":49,"žaa":84,"ži ":55,"üve":65,"ürs":166,"ürt":60,"üro":72,"ürk":57,"ürg":241,"üri":378,"üre":55,"üra":58,"üs ":51,"ütt":66,"ütu":70,"üti":151,"ütl":183,"ütm":69,"üto":339,"üta":158,"üte":90,"üss":79,"üst":1343,"üsi":1015,"之 ":88},"n_words":[4341644,4941492,4175920],"name":"et"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fas b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fas new file mode 100644 index 000000000..87dddc1b1 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fas @@ -0,0 +1 @@ +{"freq":{"٬":970,"پ":57795,"و":425936,"ي":735907,"ً":1698,"َ":4564,"ُ":2202,"ف":144242,"ق":86257,"ك":2176,"ل":186547,"م":383367,"ن":505254,"ه":501741,"ّ":1083,"ِ":3108,"ٔ":10105,"خ":65646,"د":475980,"ج":87595,"ح":43181,"ت":373990,"ث":6476,"ب":289206,"ة":899,"ئ":9436,"ا":1111531,"آ":65724,"أ":1456,"ء":1000,"غ":15714,"ع":91539,"ظ":7379,"ط":45348,"ض":9683,"ص":43813,"ش":310066,"س":370480,"ز":155766,"ر":687985,"ذ":11817,"،":43281,"؛":1040,"۲":32624,"۳":25683,"۰":28783,"۱":63091,"۶":17216,"۷":19045,"۴":17256,"۵":18080,"۸":24510,"۹":42744,"گ":80261,"ک":285107,"چ":25230,"ژ":11180," ،":7698," گ":30777," ک":148021," ۸":2786," ۹":2591," ۱":47632," ۲":17985," ۳":5368," ۴":3375," ۵":3167," ۶":2742," ۷":2925," ن":61607," ه":83469," ل":8629," م":155700," ق":22376," ك":1185," ف":28537," ي":42307," و":134423," ص":10068," ش":162851," ط":22340," ض":1200," ر":51088," ذ":1128," س":118308," ز":19079," ع":23850," غ":6362," ا":284499," آ":62929," ج":29359," ح":15097," خ":24724," د":158860," ب":152331," ت":57718," ژ":5441," چ":17369," پ":40145,"کا ":2349,"کت ":2257,"ژوئ":1909,"ژي ":877,"ژه ":1588,"ژان":2068,"گيت":1091,"گير":2604,"کلا":1036,"کلي":1793,"کوچ":1236,"کيل":3244,"کمي":2269,"کنا":990,"کند":3501,"کنو":1241,"کنن":2076,"کوم":883,"کوه":1843,"کرا":939,"کشف":46287,"کشو":4351,"کست":856,"کزي":3453,"کرد":5509,"کار":7408,"کات":897,"کان":3075,"کاي":1649,"کام":1480,"کال":1004,"کبي":947,"کتر":1843,"کتا":2868,"کتب":2985,"کم ":997,"کل ":1774,"که ":49534,"کن ":1159,"کي ":15027,"کز ":2384,"کس ":931,"گور":1227,"گون":2525,"گوي":1532,"گلي":2047,"گفت":2210,"گست":862,"گري":2038,"گرو":2216,"گزا":1135,"گرد":3447,"گرا":2354,"گرف":2543,"گذش":1619,"گذا":1619,"گار":1384,"گاه":8669,"گان":3798,"گي ":4154,"گر ":3440,"ا، ":2188,"پان":3222,"پاد":1299,"پار":1859,"۹۹ ":1855,"۹۸ ":1731,"۹۷ ":955,"۹۶ ":844,"۹۲ ":854,"۹۱ ":894,"ئي ":825,"ات ":10939,"اح ":1044,"اج ":937,"۹۰ ":940,"پرا":1102,"پرد":1609,"پرو":1607,"اب ":5407,"ئن ":919,"پاي":4002,"پتا":3629,"پنج":5682,"۸۹ ":864,"۸۸ ":992,"۸۳ ":1400,"۸۵ ":947,"۸۰ ":846,"۸۱ ":878,"اي ":55848,"بت ":1678,"اه ":14391,"او ":4256,"با ":13059,"ان ":92173,"اً ":1671,"اف ":1676,"پيو":992,"پيش":2404,"پير":873,"ام ":15467,"ال ":24240,"اق ":2509,"اع ":1667,"اط ":832,"ار ":39983,"اد ":13676,"اش ":1063,"از ":51085,"اس ":3550,"اسک":971,"بي ":8868,"ت، ":2631,"اضي":879,"ارگ":1672,"اصل":2729,"اسپ":971,"اعا":905,"اعت":1127,"اطل":2273,"اعي":1202,"۹۹۹":1558,"۹۹۸":1457,"ادا":1809,"احي":1808,"اخت":6534,"احم":966,"احت":888,"ارب":1131,"ارا":5657,"ادي":8285,"اده":8465,"ادب":902,"بق ":16057,"ادر":1545,"ادش":1271,"ازي":4465,"است":105076,"ازه":1433,"ازن":1098,"اسا":2986,"ازم":1894,"ازد":2915,"اري":13153,"اره":35608,"ازا":956,"ارن":1623,"ارو":2419,"ارم":2814,"ارز":893,"ارس":5553,"ارش":1311,"ارص":1726,"بل ":1849,"ارد":9154,"ارت":4139,"اشن":1730,"ارک":47474,"اشي":1130,"اشد":5423,"به ":41777,"اسم":943,"اسل":2665,"اشا":865,"اشت":3533,"اسي":5578,"بن ":2042,"اسر":1003,"بع ":2965,"ائي":1624,"ابا":1519,"ابت":1082,"ابر":3253,"ابع":2818,"ابي":1834,"ابل":1424,"ابق":1003,"ابو":1132,"اتر":1045,"اثر":1056,"اتي":2176,"اتو":1748,"اجر":1089,"ئيه":1089,"بر ":33260,"آب ":1128,"آثا":830,"آبا":1911,"آزا":908,"آذر":4073,"آن ":10516,"آما":970,"آلم":1164,"آمر":3443,"آمد":1740,"آمو":1076,"آنه":16519,"آور":2786,"آهن":945,"آغا":1416,"چه ":1398,"جزي":1617,"خت ":2202,"حل ":927,"جرا":1045,"جري":3087,"جار":1185,"جاد":1192,"جان":5597,"جام":2439,"جاه":2146,"جاي":1843,"حال":1317,"جنو":3614,"جها":2193,"جمي":1716,"جمع":1997,"جمه":2045,"جمو":2028,"خش ":8012,"حي ":1372,"د، ":4587,"خي ":1696,"دا ":1969,"خه ":1063,"حسي":842,"حزب":975,"حرم":1392,"حده":1001,"حدو":1445,"جنگ":1615,"جوا":942,"جود":1945,"ختر":883,"خان":4015,"خار":1012,"خاب":828,"حمد":2876,"در ":87864,"دد ":1157,"دن ":19684,"تگا":1213,"خست":1155,"ده ":55594,"دو ":4399,"ر، ":2027,"دي ":13399,"خته":2886,"ختل":1697,"خدا":1090,"دل ":1012,"دم ":1329,"خلي":855,"دان":9861,"دام":1683,"دال":1294,"داي":1703,"دار":14265,"داز":1707,"داس":1080,"داش":2836,"داخ":1028,"داد":4687,"خوا":3065,"خود":3802,"خور":1687,"دبي":1292,"رج ":831,"درگ":1116,"رت ":5024,"رد ":14918,"را ":12544,"دست":3550,"دسا":1658,"رب ":1902,"دشا":1262,"درس":984,"درج":847,"درا":1451,"دري":2646,"درو":1489,"دول":1633,"دون":991,"دوم":3136,"دوي":2445,"دهم":3138,"دوا":1480,"دود":1919,"دور":3332,"دهٔ":2250,"دها":1941,"دهد":1019,"دني":1772,"دهس":4371,"دمي":947,"دند":2383,"ذار":1352,"رف ":16580,"ديو":1392,"ديم":1100,"دين":2614,"ديا":931,"ديد":3091,"دير":977,"رش ":1790,"رس ":3514,"رز ":943,"دما":1034,"دلب":839,"اقي":1204,"افي":974,"اقع":6290,"الل":1166,"ان،":3374,"الي":6506,"الن":1060,"اما":3065,"الم":2177,"اله":1801,"امب":7272,"امر":1231,"الت":2172,"الب":1010,"الا":3840,"الد":1099,"الع":862,"افز":1059,"افر":840,"افت":2627,"اين":37088,"ايل":1631,"ايي":11337,"ايه":1592,"ايس":842,"انگ":3856,"ايش":2420,"ايا":4829,"ايت":2340,"ايج":4814,"انک":896,"ايد":1943,"ايز":1142,"اير":12515,"، ":41769,"بخش":8437,"اپ ":1341,"اهر":1198,"اهش":1637,"اني":16598,"باي":4838,"انه":7584,"انو":5568,"اهد":836,"انق":1002,"اها":4950,"بان":6032,"انن":2230,"بال":3191,"اند":8054,"باد":2479,"باز":4359,"انز":1366,"بار":4430,"انش":5048,"باش":6504,"انس":4593,"باس":1834,"انص":1766,"امن":1026,"انا":2522,"امه":4047,"امو":1040,"انت":3295,"بات":1162,"امي":5640,"انج":1903,"امل":2517,"اوي":1440,"اول":3794,"اور":2685,"الک":1567,"اوت":2392,"اهي":3496,"اوا":1252,"امپ":1281,"تا ":5488,"بسي":1565,"برگ":2294,"ايگ":1002,"بدا":1231,"برا":9676,"برد":2157,"برخ":1084,"برو":884,"برن":1758,"بري":2753,"بزر":3175,"بست":2397,"تر ":6150,"بعد":1118,"بني":1199,"بنا":1507,"بند":1464,"ا ":87899,"ب ":20308,"ح ":3843,"خ ":4523,"د ":139796,"بين":3092,"بيم":902,"بيس":5590,"بيش":2092,"ت ":137024,"بيا":1448,"بير":1134,"ث ":1238,"بور":941,"ج ":5421,"بود":10929,"تي ":8134,"اک ":1290,"تن ":2136,"ته ":15461,"تم ":2196,"ثر ":1178,"؛ ":940,"تبر":18681,"تال":1624,"تبا":2109,"تان":31858,"تام":3922,"تاه":3675,"تاي":3199,"تاد":4918,"تاش":890,"تار":5154,"تاب":4019,"تخا":898,"تحد":1114,"تري":7869,"ترو":1889,"ترا":2202,"ترن":839,"جا ":15939,"تصا":1521,"تشر":878,"ترک":1945,"تصد":3250,"تشک":1423,"تعد":829,"تغي":867,"اژه":1048,"تفا":3357,"تقا":902,"تقو":993,"تهر":2967,"تها":877,"ثار":853,"تند":2837,"تمي":4044,"تلف":1376,"تما":2359,"تلا":1147,"تيم":1139,"تين":1737,"تيا":863,"تون":1309,"تول":2859,"تور":2332,"توس":3860,"توا":4394,"پس ":2219,"تيک":1005,"اکن":1376,"اکت":3167,"اکس":936,"جه ":2283,"جي ":1241,"حت ":897,"پت":4019,"پا":14295,"پس":3568,"پد":1266,"پر":7121,"گ ":9285,"پو":2856,"په":1230,"پن":7042,"پي":8594,"پل":1723,"ک ":69398,"مک":3060,"ي،":6981,"وي":29381,"وو":995,"يب":4572,"يا":96279,"يع":3352,"يز":10370,"نگ":14413,"يس":23115,"يش":9793,"يص":2081,"يخ":3819,"يد":17899,"ير":33847,"يت":13742,"يج":6291,"يح":1015,"نک":2007,"يه":14576,"ين":90729,"وچ":1800,"يو":11558,"يق":4160,"يم":13074,"يل":23315,"يف":3191,"وپ":2022,"يي":14011,"وژ":952,"وک":2822,"پ ":2440,"وگ":1347,"يچ":1842,"يپ":878,"يژ":1013,"يک":36397,"يگ":5574,"فع":2000,"فض":915,"فز":1100,"فر":14718,"فس":1042,"فد":1178,"فت":17008,"فا":9831,"قع":6601,"قط":1598,"قش":1281,"قس":1226,"قر":7195,"قد":3410,"قت":1605,"في":8057,"قب":1853,"فه":2747,"فو":4734,"فن":1501,"قا":9232,"فل":2016,"فق":1179,"ل،":834,"قي":10959,"قل":3288,"قم":3612,"قه":3627,"قو":3406,"لق":1885,"لف":2767,"لط":1095,"لع":1660,"لد":3211,"لح":1516,"لز":963,"لس":4361,"لر":1340,"لا":28241,"لت":4427,"م،":1074,"لب":3816,"مع":25874,"مغ":887,"مص":1370,"مط":1157,"مف":852,"مق":2922,"مل":8979,"مت":12979,"لو":11064,"مج":4572,"ن،":5004,"لي":31085,"لم":9307,"لل":2270,"له":9135,"مب":9205,"لن":3401,"ما":76186,"مز":2088,"مر":23149,"مش":4307,"مس":6882,"مخ":2590,"مح":8770,"مد":9936,"نظ":3887,"نع":1089,"نط":1891,"نم":4839,"نق":3830,"نف":2887,"نج":25669,"ه،":2861,"مي":78888,"نت":9394,"مو":18704,"مه":13616,"نب":2742,"نا":34982,"من":11960,"نص":3159,"نش":8281,"نس":7940,"نز":3319,"نر":3727,"ند":45085,"نخ":1510,"مپ":1882,"هف":7528,"هل":3945,"هم":15355,"وئ":3203,"وا":39119,"هن":8401,"نه":35756,"هب":1561,"ها":75779,"نن":4681,"هت":1153,"نو":29290,"هج":3131,"ني":39040,"هد":4476,"هز":15706,"هر":26999,"هش":9098,"هس":7389,"هص":1630,"وع":5118,"وق":2152,"وف":3392,"ون":20803,"وه":7280,"ول":18645,"وم":15237,"هي":7368,"وت":7324,"مچ":1311,"هو":6697,"هه":1141,"وب":8255,"ود":37999,"وح":978,"لک":3276,"وج":4297,"وس":20717,"لگ":942,"وز":11168,"ور":41200,"وط":1483,"وض":931,"وص":985,"هٔ":10019,"وش":6987,"چ ":1702,"خو":10471,"دت":1296,"دا":45095,"خه":1201,"دب":2008,"دخ":1393,"خي":3813,"خل":2639,"خط":1338,"خر":3213,"خد":1570,"خص":2448,"خش":9472,"خس":1563,"تگ":2018,"ده":71326,"دو":21727,"ر،":2098,"دي":30900,"دف":1399,"دق":1055,"دل":3645,"دم":4441,"دن":24729,"ذا":2266,"دد":1619,"در":101792,"دش":2498,"دس":6715,"جي":2986,"جو":5371,"حت":1860,"حا":5566,"جن":6990,"جه":5500,"حب":830,"جل":2106,"جم":10111,"جس":1114,"جز":2725,"جر":5927,"جد":2691,"بک":2261,"خت":10589,"حي":3848,"د،":4720,"تک":1874,"حم":4596,"خا":9456,"حو":1605,"حق":1478,"حل":2638,"حص":1359,"حز":1102,"حر":3367,"حس":2640,"حد":3791,"اژ":1490,"تغ":1106,"تف":4099,"تم":9655,"تل":4375,"تق":4035,"تو":18858,"ته":20979,"تن":7644,"ثا":1467,"تج":1247,"تح":3912,"تر":24685,"تخ":2986,"تد":1435,"تش":4284,"تص":5949,"تس":1020,"تع":2873,"جا":32040,"جب":888,"جت":900,"تي":16351,"اک":9717,"ثر":1600,"اگ":2405,"بع":5160,"به":44819,"بن":6697,"بل":4961,"بق":17149,"بخ":9337,"بد":4503,"اً":1680,"بت":3170,"اي":143043,"اه":29729,"او":19244,"بط":1115,"بش":1384,"بز":4117,"بس":4538,"بر":58307,"اپ":4030,"تا":68031,"تب":22518,"بو":16880,"بي":27336,"ت،":2720,"ا،":2256,"ائ":3170,"از":65740,"ار":177821,"اد":40749,"اض":1760,"اص":6315,"اش":15541,"اس":126776,"ات":19285,"ئو":1601,"اب":23054,"ئن":1012,"اخ":9486,"اح":6972,"اج":4954,"ئي":4511,"اث":1612,"اف":9698,"اق":12353,"ام":46608,"ان":164721,"با":53255,"ال":53226,"اع":7941,"اغ":1903,"اط":5875,"اظ":989,"آب":4072,"آث":840,"ٔ ":10096,"آذ":4112,"آر":1739,"آس":1327,"آز":1293,"آغ":1527,"آف":915,"آل":2867,"آم":7747,"آو":3278,"آن":29292,"آه":1034,"آي":2113,"غي":2298,"عي":7120,"غر":4096,"عل":6634,"عم":5201,"غا":3393,"عن":4842,"عه":5570,"عت":3100,"عد":3656,"عر":22149,"عض":1560,"عا":7561,"عب":3193,"ظا":1618,"طل":3586,"طق":2226,"شگ":3723,"ظر":2221,"شک":5793,"طي":2187,"طه":1305,"طو":2844,"طر":3523,"ضي":1604,"سک":2829,"طا":2296,"طب":17352,"ضو":1678,"سپ":5713,"صل":3684,"صف":2604,"ضر":876,"زگ":1068,"صو":4924,"صن":1205,"ضا":2719,"صي":2649,"شف":46579,"شص":3397,"شش":4939,"شع":1023,"رک":59526,"صد":15627,"صر":2425,"رگ":10959,"شم":40834,"شن":7520,"صا":3027,"شه":20211,"شو":16524,"صت":1929,"شي":10582,"سع":1222,"سط":4899,"دگ":4253,"سف":2299,"رپ":863,"سي":82351,"شت":20229,"رچ":966,"سو":9339,"شب":2714,"سه":5822,"شا":14113,"سن":5406,"سم":5040,"سل":6428,"شر":11318,"شد":71050,"شخ":1686,"زش":2575,"زه":4419,"سب":3293,"زن":6220,"سا":40397,"ست":157670,"زو":2068,"زم":7708,"سد":1583,"سر":10053,"زي":19577,"سخ":1157,"دک":1541,"رس":21469,"رش":6643,"رر":874,"رز":5465,"رص":2328,"رض":1657,"رع":995,"رل":1461,"رق":7164,"رف":22038,"رو":41463,"ره":48555,"زب":4854,"زا":26314,"رن":9102,"رم":13248,"ري":64671,"زر":4516,"زد":7554,"ذر":4784,"ذش":1625,"رآ":1627,"رب":15211,"را":79279,"رت":10552,"رج":4101,"ذي":851,"رخ":3587,"رح":1384,"حک":1290,"رد":33206,"ف ":71140,"ع ":15503,"غ ":1398,"ص ":2346,"ط ":7167,"ظ ":1176,"ر ":213685,"ز ":65089,"س ":20728,"ش ":24544,"ً ":1683,"ي ":278753,"ه ":289561,"ن ":207616,"و ":126016,"ق ":24581,"م ":45325,"ل ":55421,"۳۰":2261,"۳۱":1756,"۳۲":1475,"۲۷":1672,"۲۶":1845,"۲۹":1827,"۲۸":1810,"۲۳":1837,"۲۲":2072,"۲۵":2015,"۲۴":2310,"۴۲":932,"۴۳":828,"۴۰":1179,"۴۱":851,"۳۹":874,"۳۸":3317,"۳۷":1442,"۳۶":1469,"۳۵":1620,"۳۴":1319,"۳۳":1412,"۱۰":3498,"۰۱":1251,"۰۰":7262,"۰۳":960,"۰۲":955,"۰۵":991,"۰۴":954,"۰۷":971,"۰۶":1030,"۰۹":925,"۰۸":1126,"۲۰":6610,"۲۱":2252,"۱۴":2656,"۱۳":8246,"۱۲":3243,"۱۱":2760,"۱۸":4100,"۱۷":2716,"۱۶":2670,"۱۵":2740,"۱۹":21618,"۷۴":853,"۷۳":1099,"۷۶":1037,"۷۵":996,"۷۰":1130,"۷۲":902,"۷۱":971,"۶۸":828,"۶۹":864,"۸۷":1462,"۸۶":1335,"۸۵":1706,"۸۴":1157,"۸۳":1867,"۸۲":1238,"۸۱":1392,"۸۰":1426,"۷۹":1133,"۷۷":1205,"۷۸":1210,"۵۰":1455,"۵۲":836,"۵۱":867,"۵۴":849,"۵۳":863,"۴۴":839,"۴۵":921,"۴۸":900,"۴۹":832,"۶۱":861,"۶۰":1533,"۶۵":892,"۵۷":978,"۵۸":881,"۵۵":896,"۵۶":829,"۵۹":829,"۸۹":1660,"۸۸":1649,"۹۰":1972,"۹۳":2257,"۹۴":1978,"۹۱":1915,"۹۲":1938,"۹۷":3928,"۹۸":5762,"۹۵":1920,"۹۶":2485,"۹۹":9457,"۸ ":9234,"۷ ":8195,"۹ ":8815,"کي":21693,"کس":3863,"کش":52864,"کر":10838,"کز":5951,"کد":1167,"کت":10947,"کو":9889,"که":50638,"کن":11029,"کم":5441,"کل":6076,"کب":1527,"کا":21352,"گف":2232,"گل":4014,"گن":1256,"گه":1120,"گو":7699,"گي":9941,"گذ":3598,"گز":1726,"گر":18517,"گش":860,"گس":1433,"گا":16359,"۵ ":8279,"۶ ":7892,"۳ ":8356,"۴ ":8000,"۱ ":8359,"۲ ":7902,"۰ ":11742,"چي":2258,"چن":2891,"چه":10435,"چو":1224,"چک":1330,"چا":2573,"ژا":3316,"ژه":1974,"ژي":1330,"ژو":2750,"چين":1123,"چني":1160,"چها":6583,"چهل":2101,"چند":1391,"چار":831," ، ":7275," خ ":829," و ":107907," حا":2893," جن":6563," جه":2834," جل":883," جم":4408," جو":1700," جد":1121," جز":2226," جر":1081," جا":5217," تي":2383," اک":4067," خل":1477," خي":1014," خو":9064," دا":22315," خر":1716," خد":1173," خط":1264," حق":954," تک":1140," حم":1000," خا":5629," حو":858," حز":987," حر":1265," حس":1494," حد":1443," به":41159," بن":5266," بل":1919," بع":1479," بز":3261," بس":2873," بر":23110," اي":60506," اه":1491," او":12009," بخ":8934," بد":2040," اق":1653," اف":3495," ال":9180," با":32041," ان":13519," ام":5995," اط":2539," اع":2096," اد":2220," ار":5819," از":47219," اس":93321," اش":2136," اص":3471," اب":2944," ات":1821," اث":1151," اج":1670," اح":1812," اخ":1959," تو":11109," ته":3565," تن":2119," تم":1148," تل":1644," تق":2105," تع":1944," تش":1637," تص":1087," تر":7158," تخ":1066," تج":1001," تح":1857," تا":10536," تب":1758," بو":12627," بي":13492," آم":7369," آل":2819," آو":2892," آه":1013," آن":28846," آي":1817," آذ":4109," آر":1633," آث":831," آب":3531," آغ":1486," آس":1300," آز":1278," شک":1757," طو":1797," عض":849," عر":3450," عا":1962," عب":2630," غر":3490," عل":4955," عم":2914," عن":2426," غي":1131," سط":837," سف":999," سي":58158," شب":2526," سه":2789," سو":5501," سم":1003," سن":2452," شا":6389," سل":2036," شر":8538," شخ":981," شد":64662," شص":1903," شش":4604," شو":11010," شي":3635," شم":35388," شن":2904," شه":16707," صد":3342," سپ":4409," صف":1164," صو":2043," صن":981," طب":16842," طر":1891," دس":4487," در":93973," دي":6271," دو":15789," ده":8568," دن":1430," دل":1101," حک":1033," را":15933," رس":3186," رش":1541," ري":3051," رف":1064," رو":19239," زب":3421," زا":2852," رم":1079," زي":3601," سد":907," سر":6965," زم":4334," سب":1207," زن":2927," سا":27260," ست":1210," ۲۱":1529," ۲۰":5779," ۱۹":20860," ۱۵":1981," ۱۶":1865," ۱۷":1946," ۱۸":3370," ۱۱":2053," ۱۲":2491," ۱۳":7504," ۱۴":1848," ۳۰":1169," ۲۸":971," ۲۹":1004," ۲۶":1106," ۲۷":943," ۲۴":1600," ۲۵":1220," ۲۲":1386," ۲۳":1186," ۱۰":2514," ۷ ":1034," ۶ ":835," ۹ ":923," ۸ ":918," پل":1189," پن":6100," پو":1775," پي":6231," پا":11101," پر":5507," پد":1204," پس":3103," لا":2038," مل":2782," مق":2722," مع":22757," مط":1111," مص":1331," مس":5314," مش":3603," مر":12704," مد":3474," مح":8486," مخ":2396," لي":1375," مج":4247," لو":1161," مت":6834," ما":10891," مب":1057," نف":1957," نق":2575," نم":3573," نظ":2990," نخ":1392," نر":962," نز":1060," نس":1428," نش":1872," نص":1002," نا":13232," من":6720," مه":4441," مو":8861," مي":39390," هف":7486," هن":3049," وا":10473," هم":7875," هر":3177," هز":15471," هس":2372," هش":6627," نو":12914," ها":28631," نه":5384," ني":6690," هج":2983," فر":9595," فع":1613," فا":3850," فل":1560," قا":3036," فو":3446," قب":1076," في":4001," قد":1747," قر":6081," قم":3484," قل":1179," قو":1126," يک":22683," وج":1401," هي":1336," هو":2401," وس":1484," وز":1216," ور":1520," ول":1293," مک":1516," وي":5201," يا":14595," نگ":1352," يو":1770," ۱ ":999," ۵ ":990," ۴ ":1026," ۳ ":1037," ۲ ":1134," کت":2907," کر":7960," کش":52338," کل":3525," کن":7370," کم":2467," کو":5973," که":48270," کي":3060," کب":1107," کا":11187," گا":3551," گل":1221," گف":2153," گي":3912," گو":4533," گر":10421," گذ":2142," ژا":2692," ژو":2172," چا":2040," چي":1498," چن":1727," چه":9110,"۶۰ ":1024,"۲۰۰":3965,"۳۸۳":931,"۲۸ ":1132,"۲۹ ":1101,"۲۶ ":1164,"۲۷ ":991,"۲۴ ":1524,"۲۵ ":1126,"۰۰۰":1569,"۲۳ ":1040,"۲۲ ":1199,"۲۱ ":1215,"۲۰ ":1572,"۳۱ ":837,"۱۹۸":3784,"۱۹۹":7313,"۱۹۳":1178,"۱۹۲":829,"۱۹۵":879,"۱۹۴":946,"۱۹۷":2720,"۱۹۶":1373,"۱۳۸":2507,"۳۰ ":1283,"۰۰ ":2532,"۱۲ ":1158,"۱۱ ":1041,"۱۳ ":1130,"۱۴ ":1282,"۱۵ ":1270,"۱۶ ":1284,"۱۷ ":1225,"۱۸ ":1153,"۱۹ ":1122,"۱۰ ":1507,"فر ":1868,"فت ":4170,"قع ":6048,"فار":2458,"فاد":2141,"فاع":864,"فتا":2708,"فته":4673,"فتم":1892,"فتص":1637,"فه ":1283,"في ":1976,"عرو":1419,"عرف":15753,"عرب":2186,"عرا":897,"عدا":1093,"عبد":885,"عات":1421,"عال":2039,"عبا":1366,"عاد":1232,"غرب":3482,"عيت":1749,"عمل":1014,"عنا":1018,"عمو":1947,"عنو":2161,"غان":879,"عني":1446,"غاز":1437,"علا":887,"علي":2182,"علو":970,"عما":1036,"علم":1702,"غير":1279,"صي ":884,"شما":36739,"شهر":16753,"شنا":4807,"صاد":1085,"شمي":1876,"رکت":2292,"رکز":5506,"رکي":1378,"شور":5763,"شود":8535,"شهو":994,"شون":1223,"شير":1302,"شيد":1499,"شين":1156,"ضي ":873,"رگا":1053,"رگذ":955,"رگر":1703,"رگز":904,"سپت":3558,"سپا":1035,"صول":885,"صور":2307,"ضاي":1046,"صلي":1295,"طي ":1075,"طه ":1047,"ظر ":999,"طبق":15902,"طرا":958,"عت ":1441,"عد ":843,"طلس":913,"طلا":2183,"طقه":1497,"طور":1362,"ظام":977,"شکي":1859,"شکل":1326,"شگا":3095,"عه ":4310,"عي ":3265,"زد ":1250,"ري ":28175,"رن ":1348,"ذشت":1620,"زب ":861,"ره ":40871,"رو ":1622,"ديگ":2478,"ديک":1038,"رق ":1211,"ذرب":3735,"رم ":3802,"رجه":899,"ردم":1119,"رده":3960,"ردن":2001,"ردي":2386,"ردا":4731,"رتب":927,"ربي":3967,"رتي":854,"راک":1311,"ران":23644,"ربا":5086,"راه":2985,"راو":1025,"راي":12001,"ربر":1171,"راف":1247,"رام":1664,"رال":1192,"راب":3402,"رائ":1115,"راح":1002,"رات":2813,"رار":4645,"راد":1759,"راز":1040,"راس":2348,"زش ":1033,"رفت":3769,"سر ":1698,"زي ":8767,"رصد":2148,"رشي":1128,"ست ":82115,"رسا":1284,"رست":10190,"رشت":1369,"رسم":1031,"رسي":3685,"زه ":3212,"رزش":844,"سم ":1194,"زدي":1099,"زده":4341,"ريک":4778,"روپ":963,"ريه":3010,"ريو":908,"رين":6859,"ريل":1861,"ريق":887,"ريا":4939,"ريخ":2752,"ريت":1617,"ريز":1529,"رنگ":1040,"ريس":1451,"روه":2711,"روي":3959,"ري،":1064,"روف":1550,"رون":2388,"روم":1326,"رور":969,"روز":5199,"رود":4045,"رهٔ":1083,"روس":7942,"روش":1626,"رهن":1422,"روا":2639,"زاي":1000,"زان":1010,"رها":4101,"زبا":3526,"زار":18512,"رند":2708,"زاد":3573,"رمي":2432,"رنا":1487,"رما":3636,"رمز":959,"سط ":3314,"رقي":4879,"شد ":26077,"شر ":1296,"شش ":1401,"سن ":1047,"سه ":5126,"زرگ":3314,"شت ":4426,"سي ":13405,"ستگ":1285,"شف ":46304,"زيک":1213,"سري":988,"سرو":889,"سرا":2106,"دگي":1827,"شه ":1221,"دگا":1978,"زما":4471,"سام":2387,"سال":16867,"سان":4639,"ساي":1790,"زند":3098,"ساخ":3059,"ساس":1619,"ساز":3943,"زنا":1261,"زمي":2413,"ساب":1251,"ستا":39209,"ستب":15399,"ستر":2167,"ست،":1386,"ستف":2194,"ستن":2498,"زيا":1067,"ستم":1666,"ستي":2717,"سته":2853,"ستو":1258,"زيس":843,"زير":3410,"رگ ":3861,"صر ":1320,"سلا":2748,"سمت":1146,"شي ":3088,"صت ":1755,"صد ":14363,"رک ":48005,"شرق":5570,"صل ":1169,"شده":27411,"شدن":16377,"شصت":1903,"شرک":1669,"شصد":1494,"ششم":1955,"ششص":1494,"شتا":2276,"سوم":2657,"سوي":1270,"شتر":2340,"شتص":1588,"شبه":953,"شاه":3881,"شان":2849,"شام":1210,"شار":1758,"سند":1687,"شاخ":862,"سمي":1232,"شخص":1423,"سيل":1493,"سين":2125,"سيم":1189,"سيق":1188,"سيو":851,"شتم":2005,"سيص":1797,"سنگ":854,"سيس":2418,"سير":939,"سيد":2026,"شتي":869,"سيا":50847,"شته":5322,"يکا":4258,"يکم":1999,"يکي":12431,"يگر":3114,"يگا":1094,"يچ ":1170,"وچک":1078,"يقي":1448,"يلا":5819,"يلي":2362,"يلم":2163,"يما":2897,"يله":1142,"يلو":2447,"يند":2629,"ينج":15434,"ينا":1201,"يمن":836,"ينت":984,"يمي":2048,"ينو":1227,"يني":2869,"ينه":1667,"يهٔ":843,"يوس":866,"يوا":1011,"يون":3682,"ينگ":934,"وپا":979,"يصد":1797,"يشه":906,"يشت":1412,"يسي":2944,"نگي":1776,"نگل":2493,"يسه":1037,"يسن":1399,"يزي":2379,"يست":11437,"يزه":870,"يسا":894,"نگا":2016,"يره":2645,"يرو":2532,"يري":2723,"يزد":1123,"يعي":880,"يجا":4729,"يتا":2607,"يتي":884,"يده":2751,"يدن":1012,"يدي":1302,"يرا":13163,"يرد":1088,"يخي":912,"يدا":2030,"يدل":878,"ياف":1602,"يال":2762,"يان":11075,"يبا":1219,"يام":955,"ياه":1109,"ياي":3214,"ياس":2249,"يار":48948,"ياز":1404,"ياد":1729,"يات":2044,"ياب":1358,"يک ":14180,"وز ":3949,"ور ":11858,"ود ":25900,"نقش":885,"هٔ ":10011,"نفر":1610,"وش ":1865,"وس ":2204,"نمو":979,"نند":4531,"هاس":15525,"هار":8046,"نما":2997,"ها،":830,"وع ":1666,"نقل":1074,"وط ":936,"نيز":2529,"نيس":1397,"نير":1331,"نيا":4775,"ني،":840,"نوي":5351,"نون":2065,"نور":1647,"نود":1940,"نوب":3858,"نهم":1851,"نوا":6754,"نوع":1934,"نوش":1776,"نوز":853,"هاي":33269,"هان":4405,"نها":19728,"نهص":1628,"هدا":927,"وف ":1708,"نيک":1404,"نين":1804,"نيم":949,"نيو":887,"هجر":2343,"هست":7247,"وم ":4571,"هري":1954,"هشت":6878,"ون ":8984,"هرا":3739,"هرم":1056,"هره":1437,"هزا":15536,"هرس":8280,"ول ":5820,"وي ":9400,"ي، ":6814,"وه ":3934,"هشم":1388,"هصد":1629,"معي":1766,"معم":1600,"معن":1773,"معر":16933,"معا":1278,"هد ":1760,"هر ":8315,"مقا":1363,"منا":1581,"ناب":867,"مند":1285,"ناخ":1262,"منت":1332,"منط":1759,"ناس":3745,"نار":1067,"ملل":1010,"مله":1083,"ملي":2015,"مهم":1073,"مهو":1618,"موا":1351,"موج":939,"مور":2297,"موز":1395,"مود":1287,"موس":2124,"موع":2058,"نام":12986,"نان":3607,"ناي":2070,"نتش":1291,"نتر":1378,"مون":1614,"مول":1953,"ميل":5431,"ميد":1645,"مير":1559,"ميا":3140,"نتي":1863,"نجم":2428,"نجا":19529,"مين":23588,"ندا":3431,"ند،":1301,"نخس":1148,"ندو":1099,"نده":6796,"ندر":1455,"ندس":875,"ندي":2668,"هل ":2462,"نزد":2165,"هم ":4541,"نسا":1177,"نست":1454,"ندگ":2266,"نسو":981,"نشا":1366,"وب ":4521,"نصد":1688,"وت ":2984,"هي ":3587,"نطق":1746,"نظا":1022,"نظر":1892,"نشگ":2179,"ونا":1554,"ومي":5536,"وند":2535,"ولي":4939,"ومت":2798,"يع ":1026,"ولت":1350,"ولا":2437,"ولد":1454,"يش ":4417,"يس ":3929,"نگ ":4653,"يق ":1173,"ويژ":863,"يف ":1505,"ويچ":897,"مکا":1239,"ويي":925,"وين":2044,"ويه":2289,"ويم":1400,"ويز":853,"ويس":4678,"وير":1085,"وني":3417,"ونه":1782,"وها":1116,"يي ":11355,"يه ":12282,"يو ":1257,"يم ":5175,"ين ":61177,"يل ":7962,"هفت":6908,"هنگ":2686,"واژ":1094,"مچن":1005,"وتب":889,"وجو":2093,"لکت":1073,"هنر":1330,"وار":3450,"واز":2127,"هند":2551,"واد":2014,"همي":4888,"وئي":1673,"واب":2536,"وئن":956,"هما":980,"هور":2961,"وبي":1735,"همچ":1222,"هوا":1704,"واه":871,"واي":1826,"واق":6339,"وال":1232,"وان":9374,"وام":2251,"وري":9228,"وست":8309,"وزه":1349,"وزن":1058,"وزي":1584,"يا ":15452,"وسط":3323,"وسي":3688,"وشت":1878,"يب ":1599,"ود،":1062,"ودر":855,"ودن":1173,"ودي":1606,"وده":3280,"ورا":3355,"ورز":1216,"ورش":1426,"ورد":3566,"ورت":2597,"وره":2981,"ورو":1136,"يد ":7931,"ير ":7783,"يز ":4213,"يت ":7713,"يج ":845,"يخ ":2265,"وعي":1123,"وعه":1942,"لد ":1738,"لس ":1850,"لت ":2709,"لا ":1918,"لب ":937,"م، ":1039,"لف ":1009,"له ":6963,"ما ":2248,"لم ":2584,"قمر":3187,"قلا":1065,"قيق":1249,"قوي":1155,"فعا":1470,"فرد":869,"فرا":3846,"فرو":1305,"فري":1360,"فرم":1232,"فره":1581,"فزا":918,"قه ":2804,"قي ":7279,"فيز":835,"فيل":2814,"قدي":1049,"قرن":906,"قرا":4415,"قال":936,"قاب":1236,"فوت":1061,"فور":2032,"قان":1259,"لله":1097,"لما":2054,"ماع":870,"لمي":1688,"مات":1140,"مار":39512,"لند":1567,"ماد":1634,"لمل":950,"نس ":921,"نش ":1280,"ند ":23182,"ه، ":2793,"مي ":37976,"نج ":1914,"ني ":21211,"مشه":1314,"مرک":5626,"نو ":876,"نه ":11112,"مسي":1271,"ها ":10366,"مست":1149,"مسا":1677,"مري":7089,"مرو":1152,"مرد":2093,"مرا":2087,"مرب":1215,"مدي":1420,"مدر":931,"مخت":1330,"مدا":1385,"محر":1442,"محل":1270,"محم":2301,"ليو":834,"لين":2134,"مجم":2201,"مجل":977,"ليت":1597,"ليا":2311,"متو":1555,"ليس":3144,"ليد":1495,"ليل":1108,"لوي":1612,"لوم":2898,"متر":3763,"متح":1213,"مال":4589,"مام":1588,"مان":14800,"ماه":2044,"ماي":4595,"مبر":7239,"مد ":3240,"لو ":1092,"مت ":2632,"ن، ":4905,"لي ":12663,"مه ":7560,"نا ":1758,"من ":2003,"نت ":1363,"مل ":2783,"لاح":1096,"لاد":4785,"لار":867,"لاب":1067,"لات":2844,"لاق":1169,"لاف":888,"لاس":997,"لاع":939,"لبر":1058,"لاي":1580,"لام":3536,"لان":2170,"لال":908},"n_words":[8069793,10004435,6796528],"name":"fa"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fin b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fin new file mode 100644 index 000000000..fdb41748e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fin @@ -0,0 +1 @@ +{"freq":{"D":15745,"E":23140,"F":13820,"G":13964,"A":40046,"B":22964,"C":22892,"L":28771,"M":37698,"N":19249,"O":13807,"H":28813,"I":21256,"J":16698,"K":43440,"U":7805,"T":36899,"W":9333,"V":24290,"P":38188,"S":77764,"R":24157,"Y":10043,"X":1821,"Z":1858,"f":29615,"g":68514,"d":158713,"e":1194104,"b":43435,"c":44492,"a":1814181,"n":1349748,"o":934203,"l":885783,"m":433706,"j":314669,"k":691662,"h":239330,"i":1579260,"w":11494,"v":295575,"u":751889,"t":1169051,"s":1099978,"r":475344,"q":1633,"p":248621,"z":7860,"y":250687,"x":8131,"é":2342,"ä":426790,"ö":56679,"š":2606," l":70812," m":89685," n":43615," o":180629," h":39470," i":21438," j":161666," k":172428," d":8045," e":69090," f":6572," g":3193," a":72510," b":5870," c":2712," y":39165," u":13744," t":117334," v":98965," p":89643," s":126171," r":34331," J":16375," K":41900," H":27293," I":17045," N":17648," O":11538," L":26471," M":33953," B":21331," C":19265," A":36093," F":12406," G":12952," D":13481," E":21275," Z":1697," Y":9517," S":71766," R":22636," P":35182," W":8721," V":22294," U":6908," T":34378," ä":2798,"A ":2604,"Da":2655,"Co":4892,"Ch":3205,"Do":1694,"De":2688,"Di":2497,"Fa":1585,"Eu":3024,"Et":2349,"Es":2046,"En":2950,"El":2967,"Ge":2029,"Ga":2319,"I ":2891,"Fr":2159,"Fo":2415,"Fi":2245,"C ":2932,"Au":2202,"Ar":3564,"As":1696,"D ":1819,"Ba":4270,"Am":2679,"An":4463,"Al":7577,"Bu":1605,"Br":4547,"Ca":3954,"Bi":1625,"Be":3488,"Bo":2874,"Ku":5528,"Ky":1627,"Kr":2024,"Ko":6559,"Le":5504,"Hä":4384,"Li":5491,"La":6972,"Lu":2444,"Lo":3355,"Me":4707,"Mi":5018,"Ma":12276,"Mu":3221,"Mo":4384,"Ni":3815,"Ne":4302,"Na":2575,"P ":1899,"No":3154,"Gr":2750,"Ha":6094,"He":6887,"II":1871,"Hi":2221,"Ho":2925,"In":4312,"Is":2133,"It":2586,"Ja":4546,"Jo":4525,"Ju":3085,"Ka":13363,"M ":1871,"Ki":5554,"Ke":4172,"Un":1530,"Tu":4391,"Tr":2204,"To":3873,"Th":5318,"Ti":2566,"Te":3907,"Ta":5984,"St":4721,"Su":13153,"Wi":2315,"Wa":2313,"Vu":2187,"Vi":4932,"Va":6002,"Ve":5654,"Pu":2910,"Pr":3317,"S ":3929,"Pe":5861,"Pa":6975,"Po":6867,"Pi":3820,"Se":20320,"Si":6786,"Sh":1709,"So":3993,"Ru":2993,"Sa":10443,"Re":3883,"Ri":2393,"Ro":4731,"Ra":6455,"b ":4269,"a ":521046,"Yh":4604,"Tä":2310,"i ":187878,"ge":9008,"ga":10572,"fi":6772,"fr":2666,"fo":3746,"hd":23028,"he":38383,"ha":33064,"gn":1824,"gl":5520,"gi":17723,"gh":2779,"gu":2320,"gr":3324,"go":5014,"du":5956,"dy":8630,"g ":5897,"ea":17917,"eb":2211,"ec":3419,"ed":14005,"de":60149,"di":25899,"do":15043,"ds":2160,"dr":3184,"ew":1828,"eu":16676,"ev":21342,"ey":5808,"fa":2058,"h ":5313,"fe":3904,"eh":18148,"eg":3976,"ef":1593,"ee":73047,"el":141223,"ek":30007,"ej":4585,"ei":64027,"ep":7092,"eo":9816,"en":311708,"em":29073,"et":103119,"es":102393,"er":103228,"ca":4693,"e ":102313,"br":3098,"bu":11145,"bo":3540,"bl":1718,"bi":4927,"be":5208,"da":16197,"f ":4183,"cu":1883,"ct":2366,"co":5044,"ck":6770,"ci":3249,"ch":7835,"ce":5416,"c ":2562,"az":1738,"ay":3699,"ba":5388,"d ":12256,"at":82974,"as":103098,"ar":90264,"av":32524,"au":43994,"ak":51088,"al":188447,"ai":159817,"aj":32823,"ao":2348,"ap":28311,"am":44148,"an":226249,"ac":6773,"ad":13018,"aa":139980,"ab":3846,"ag":5956,"ah":19189,"ae":6848,"af":2453,"nu":19006,"nt":79878,"ns":48167,"nr":2630,"np":4065,"no":34422,"nn":76172,"ny":10224,"nv":4829,"oe":6505,"of":6585,"oc":5124,"od":21394,"oa":12733,"ob":3163,"om":49202,"on":220535,"ok":63100,"ol":88347,"oi":101083,"oj":13195,"og":7134,"oh":26450,"kä":31248,"ot":48882,"os":73162,"ov":18707,"ou":20507,"op":25063,"oo":22586,"or":48012,"r ":15286,"ow":2927,"kö":4127,"oy":1883,"pe":39610,"pa":50151,"pl":2749,"po":19855,"lä":49440,"ph":2309,"pi":40558,"lo":48127,"lm":34905,"ll":141072,"ls":4754,"lp":5969,"lv":6764,"lu":74348,"lt":40738,"ly":10157,"o ":46103,"ma":107323,"mb":5971,"iä":11662,"me":68275,"mi":93628,"mm":26269,"mp":15152,"mo":20189,"mu":39868,"iö":6377,"my":13711,"p ":3699,"na":88104,"nc":4077,"nd":15417,"ne":115628,"nf":1558,"ng":26517,"nh":5001,"jä":31523,"ni":80364,"nj":4418,"nk":37841,"nl":4563,"nm":4904,"ju":18610,"jo":83376,"ki":95289,"ke":65747,"ka":163517,"m ":8821,"ky":14212,"ks":65607,"kt":5970,"ku":90075,"ko":85957,"kr":5885,"kk":48142,"kl":2002,"kn":1816,"li":159675,"hä":6582,"lk":30410,"lj":7180,"le":81668,"ld":2991,"la":154382,"lb":9921,"n ":656910,"hr":2420,"ht":42173,"hu":10726,"hj":14036,"hk":3966,"dä":2655,"hi":25267,"hn":1754,"ho":13688,"hl":1555,"hm":8011,"id":26485,"ic":10236,"ib":2776,"ia":70345,"eä":2738,"ih":17748,"ig":6859,"if":2884,"ie":58968,"hy":6074,"k ":7419,"ir":40208,"is":262822,"it":142893,"iu":5141,"iv":30487,"ii":85125,"ij":23513,"ik":78594,"il":97254,"im":65870,"in":288307,"io":39520,"ip":11864,"je":25016,"ji":8870,"l ":13054,"ja":144917,"tä":77533,"sä":41776,"vy":5926,"y ":23865,"wa":2667,"rä":7609,"vi":49369,"vu":43029,"vo":19782,"uv":30695,"uu":71208,"ve":29647,"va":118391,"x ":5327,"ui":22148,"uj":5727,"uk":45990,"ul":59174,"ue":19283,"ug":2138,"uh":10868,"ur":38607,"us":87239,"ut":63413,"um":30283,"un":78305,"uo":96118,"up":18134,"ty":54901,"tu":95699,"tt":139450,"ub":2312,"ua":10701,"ud":16569,"uc":1658,"w ":2157,"to":89637,"tl":2100,"ts":24815,"tr":16390,"te":142275,"tk":13593,"ti":135644,"th":11168,"pä":16825,"ta":258052,"su":49746,"sv":13201,"ss":117492,"st":215124,"sy":12228,"sl":7481,"sk":39138,"sn":1670,"sm":5723,"sp":7200,"so":30621,"sr":2112,"sc":2341,"se":139811,"sh":5275,"sj":2476,"si":171906,"nö":1934,"u ":38729,"sa":155918,"rr":9979,"rs":10921,"rt":23316,"ru":25282,"rv":12255,"ry":7951,"rp":3591,"ro":37223,"rn":7182,"rm":9935,"rl":3938,"rk":30938,"rj":32055,"ri":107434,"rh":7195,"nä":20276,"rg":6568,"re":35490,"rd":7095,"rc":2086,"rb":1938,"ra":66068,"t ":86930,"mä":30120,"s ":74921,"px":2388,"py":4209,"lö":4854,"pt":2602,"pu":33575,"pp":18507,"pr":6312,"ps":3220,"yä":2288,"yö":17077,"vä":26642,"yy":14572,"yh":29899,"ye":9120,"yd":4538,"ya":1921,"tö":12963,"yv":6669,"yt":27603,"ys":23779,"yr":6697,"yp":4560,"yn":15218,"ym":10818,"yl":20580,"yk":18251,"yi":8456,"ä ":141477,"äa":1925,"ö ":8048,"ää":49135,"ät":13038,"äv":12353,"äy":16618,"äm":13914,"äl":20535,"äo":2938,"än":46392,"äp":3824,"äs":18046,"är":23375,"äe":2662,"äi":25110,"äh":12610,"äk":13701,"äj":7869,"öö":1835,"öy":2134,"öt":2960,"ör":2049,"ös":12022,"ön":8537,"öl":2694,"öm":1579,"ök":3180,"öh":1825,"öi":4386," Ga":2281," Ge":2007," Fo":2388," Fr":2153," Fi":2200," Ha":6075," He":6845," Gr":2717," Ho":2907," Hi":2219," Ja":4528," Is":2125," It":2580," In":4291," Ka":13310," Ke":4144," Ki":5524," Jo":4519," Ju":3077," La":6921," Le":5486," Hä":4383," Li":5091," Ko":6537," Kr":2018," Ku":5494," Ky":1626," Ma":12197," Mi":4965," Me":4668," Lo":3341," Lu":2432," Ne":4266," Na":2563," Ni":3790," Mo":4358," Mu":3189," Am":2670," An":4363," Al":7546," Ba":4234," Au":2195," As":1683," Ar":3519," Be":3463," Bi":1601," Bo":2840," Br":4522," Bu":1591," Ca":3824," Ch":3183," Co":4800," Da":2631," Di":2463," De":2676," Do":1656," El":2955," Et":2345," Es":2034," En":2918," Eu":3021," Fa":1558," Tä":2303," Wi":2296," Wa":2289," Yh":4598," Po":6838," Pi":3788," Pe":5834," Pa":6894," No":3136," Ra":6410," Ro":4711," Re":3856," Ri":2382," Pr":3297," Pu":2902," Su":13126," St":4422," Ta":5960," Th":5301," Ti":2528," Te":3868," Tr":2184," To":3832," Ru":2990," Sa":10406," Sh":1689," Si":6699," Se":20290," So":3959," Va":5984," Ve":5638," Vi":4890," Vu":2183," Tu":4371," ja":74622," in":3365," il":6233," is":1907," it":4582," ka":41758," ki":21829," ke":20426," jo":60523," ju":13868," ha":11651," he":10326," hy":3213," ih":2463," hi":4639," ho":2199," hu":2999," jä":12144," ni":12782," ne":5502," na":3130," my":11678," mu":27269," mo":4701," ol":30354," om":3788," on":110013," kä":15552," oh":5375," oi":2526," of":2700," ny":2745," nu":2351," no":7612," le":7943," hä":3832," li":11414," n ":4861," la":17994," ku":35062," ky":5412," kr":3070," ko":26681," me":12340," mi":8054," ma":22033," lu":14733," ly":2009," lo":4509," am":2608," an":4850," ai":10388," aj":3176," al":26047," av":3055," au":2714," ar":5107," as":8761," er":7980," et":8124," es":9200," en":13349," ei":4106," el":17426," fi":2104," de":3555," di":1711," ed":3633," vä":7263," ym":1774," yl":9242," yk":6097," yh":19431," tä":4808," ru":4569," ry":2522," sa":23518," se":22713," si":27049," so":8389," ra":14800," re":3082," ri":4303," nä":4180," ro":4580," pu":9566," pr":4112," s ":2297," px":2387," py":2739," mä":2284," os":9956," ot":1666," ov":7670," op":3466," or":1769," pe":20224," pa":14359," po":10381," pi":14437," lä":10166," sä":4588," va":34158," ve":7508," uu":2456," vo":6724," vu":30542," vi":12396," ty":5276," tu":19858," us":4512," ur":1664," ul":2520," ta":38855," sy":5905," st":3683," su":25086," to":18439," th":5224," pä":9746," ti":8862," te":13642," ää":2036,"Ete":1912,"Eur":2720,"For":1614,"Hel":2818,"Int":2022,"Alb":1684,"Bri":2185,"Nor":1531,"Per":1731,"Par":1783,"Poh":2941,"Ran":1941,"Kal":1586,"Kan":2320,"Kau":1621,"Kar":2566,"Kir":1567,"Kun":1618,"Hän":3486,"Mar":3439,"ään":18825,"ääk":4426,"äät":2724,"äär":4190,"ääs":2129,"ää ":10320,"Vuo":2097,"Yhd":3250,"Suo":9477,"Sta":1658,"Sen":4830,"äht":3405,"ähd":1555,"ähe":3536,"ähi":1621,"Ruo":1578,"änn":2773,"äns":2545,"änt":2999,"Sak":1930,"ämi":2674,"äni":2131,"äjä":6711,"äne":3700,"Se ":11672,"äs ":1575,"ämä":7782,"äos":2009,"äka":1964,"äis":10749,"äin":8551,"äiv":1941,"ält":2814,"äli":6173,"älk":2158,"äll":6310,"äks":2395,"äki":2767,"än ":27597,"äve":2052,"ävi":2773,"ärä":1957,"äyt":13595,"äri":6126,"ärj":7258,"ät ":5667,"äsi":4968,"äse":2119,"ärv":3216,"äst":3327,"äss":3767,"ätt":2038,"ävä":6336,"Ven":3558,"Val":1869,"The":3947,"Tur":1761,"ber":2683,"ce ":2305,"bri":1634,"bum":8758,"aka":6269,"ake":7201,"aki":5604,"aji":6912,"ajo":3036,"al ":4672,"aja":18366,"aje":2029,"aih":3713,"aik":14735,"ail":13159,"aim":1862,"ain":38398,"ais":49469,"ait":14001,"aiv":4010,"aid":2730,"ahm":1834,"aht":3966,"ahd":4670,"aha":3293,"anu":4220,"ano":5725,"ann":13433,"anm":2516,"ant":14494,"ans":18785,"ane":3551,"ang":3334,"anh":3197,"ani":13808,"anj":1817,"ank":6571,"ana":14302,"anc":1814,"and":6936,"amm":4533,"amo":2056,"amp":3132,"ami":8254,"ame":4479,"ama":17130,"alv":4153,"alu":15472,"alt":16363,"alo":7802,"alm":6123,"all":43431,"alk":10647,"ali":18156,"ale":9704,"ala":40225,"alb":7609,"an ":106763,"aks":12179,"aku":8003,"akt":1737,"ako":3232,"akk":5053,"ae ":1542,"aaj":5209,"aak":5208,"aai":4807,"aan":46070,"aal":13155,"aam":4542,"aas":4039,"aar":7457,"aav":4444,"aat":11110,"aa ":30258,"ai ":13611,"ael":1895,"adi":4196,"ack":1788,"ada":3189,"at ":26536,"arh":2305,"are":4235,"ard":3175,"ara":7612,"arp":1607,"aro":2059,"arm":2145,"arl":1651,"ark":11086,"arj":11397,"ari":15453,"aru":3626,"arv":4834,"arr":3315,"ars":2606,"art":6849,"asa":4886,"asi":8287,"ase":5553,"aso":1854,"ask":4888,"ar ":2391,"apa":10451,"ape":2308,"api":2097,"app":6574,"apu":2355,"as ":6418,"ava":19468,"aut":8391,"avo":2634,"avi":5086,"avu":2827,"ata":7640,"asu":5324,"ast":26494,"ass":30398,"asv":4804,"atk":3390,"ato":4227,"ate":6056,"ati":12192,"att":13242,"ats":1884,"atu":3704,"aul":4866,"aup":10709,"aur":1674,"aus":6854,"aud":2731,"auh":2050,"auk":3794,"jel":4529,"jen":8431,"jes":7295,"jet":1556,"ji ":2297,"jaa":5054,"jat":4403,"jas":4641,"jal":7569,"jak":4713,"jan":11104,"jai":10124,"jou":4303,"joh":4795,"joe":2427,"jol":3356,"jok":24849,"joi":16729,"jon":9520,"jot":6559,"jos":6649,"jia":1786,"itk":2090,"ito":6246,"itu":9149,"itt":43813,"its":13426,"ity":9715,"isk":6128,"ism":2973,"isl":1855,"iso":4721,"isp":1964,"iss":30541,"isu":9410,"ist":90841,"isy":1690,"ita":17408,"ite":16460,"iti":5058,"ivo":1659,"ivu":2547,"isä":6664,"iva":11789,"ivi":6748,"ive":3576,"ipp":2283,"ipu":1889,"ilä":2764,"ilö":2966,"is ":8294,"ion":10934,"iop":2837,"ios":4401,"iot":1986,"ikä":1979,"ioi":3973,"iol":2452,"ipa":1808,"ipe":1630,"irt":2993,"iro":1572,"irk":4448,"iri":6484,"irj":10801,"isi":26753,"ise":59209,"isa":5742,"ire":2058,"inä":3666,"ira":5520,"it ":5916,"ja ":90836,"itä":10709,"ivä":3912,"kii":3407,"kik":3240,"kij":2090,"kim":2775,"kil":12288,"kia":4204,"kie":9439,"kiv":2180,"kin":14280,"kio":1639,"kir":13427,"kis":5163,"kit":6283,"ki ":12342,"kea":4096,"kee":4463,"keh":4191,"kei":5212,"kem":2757,"kel":5236,"ken":9401,"kes":10316,"ker":7027,"keu":3655,"ket":2834,"kev":1653,"ke ":2125,"kre":1700,"ksa":4741,"kse":20115,"ku ":3951,"kot":3952,"kou":3762,"kos":5488,"kor":5268,"koo":4082,"kon":11074,"kom":3392,"kol":7289,"kok":7259,"koj":1821,"koi":14746,"koh":3422,"koe":1980,"kku":3944,"kke":3841,"kka":15414,"kko":10268,"kki":11721,"ko ":7803,"jul":11521,"kat":4283,"kau":16540,"kar":4289,"kas":12031,"kap":6608,"kan":20757,"kal":9712,"kam":1710,"kak":4624,"kah":2946,"kai":21386,"kaa":14665,"ka ":40830,"ha ":1581,"han":4990,"hai":2275,"hal":6945,"har":4587,"hah":1631,"haa":1766,"he ":6389,"hdo":2167,"hdy":6548,"hde":8081,"hdi":4168,"hel":4032,"hei":7575,"hee":1552,"het":1965,"her":2750,"hen":6953,"hem":2103,"hin":8148,"his":2803,"hit":5065,"hja":5248,"hje":3366,"hjo":5005,"gle":2192,"gla":2321,"gra":1797,"ial":8370,"ian":13283,"ias":7499,"ic ":1670,"iaa":4991,"ia ":28344,"iet":9042,"iel":9758,"iem":2939,"ien":20960,"ier":2897,"ies":3794,"ied":2257,"ieh":1857,"iek":1604,"eä ":1619,"ich":1751,"ie ":2310,"ica":1971,"idi":2094,"ide":16311,"ida":3705,"iid":1915,"iik":12079,"iih":2036,"iin":34905,"iil":1871,"iim":1601,"iis":3357,"iir":7370,"iip":1650,"iiv":3159,"iit":11463,"ija":15115,"ijo":3212,"ika":17282,"ii ":2634,"igh":2049,"ihe":3769,"iha":1816,"ihm":2273,"ihi":4976,"iht":1902,"imo":4420,"imm":10403,"imp":1982,"ime":14110,"imi":21669,"ind":1904,"ina":17571,"imu":3688,"inn":9244,"ino":7309,"int":21117,"ins":3814,"ine":62207,"ijä":3525,"ing":10847,"ini":7961,"ink":6694,"ioa":2138,"inu":2993,"inv":2235,"iko":8699,"ikk":20680,"iki":6034,"ike":7607,"ila":13660,"in ":123439,"iku":7225,"iks":5910,"ilp":4235,"ilo":6040,"ill":27290,"ilm":11405,"ilj":1888,"ili":8485,"ile":2304,"ima":7267,"io ":5938,"ilt":4359,"ilu":7728,"hmä":2450,"hol":1937,"hon":2485,"hoi":2109,"hmi":2965,"hmo":1850,"hty":9392,"htu":3085,"hto":2163,"hti":9794,"hte":8765,"hta":4518,"htä":1902,"huo":1796,"hum":3543,"hyv":1693,"etä":4989,"evä":1690,"eta":9667,"ete":9398,"eti":3164,"est":38413,"ess":23541,"eud":1841,"eto":4814,"etr":5809,"ets":2385,"ett":36313,"etu":5501,"ety":2077,"erä":4263,"eve":1697,"eva":7898,"evi":4106,"euv":2196,"eut":3244,"eur":5135,"eus":2033,"esä":2111,"ey ":1541,"evy":4434,"elä":9755,"er ":8358,"eor":2097,"eol":1627,"emä":1894,"es ":8151,"erk":7307,"eri":25262,"erg":2239,"erh":1625,"enä":7730,"ere":5494,"era":4710,"et ":16346,"esk":9110,"esi":14483,"ese":2664,"erv":1561,"eru":10609,"err":4242,"ert":7186,"ers":4983,"ern":2916,"erm":2674,"ero":5460,"eki":2975,"ekk":1967,"ekn":1637,"eko":1843,"eks":9087,"ekt":2330,"en ":216998,"ela":5301,"ele":9915,"eli":28185,"elj":2641,"elm":10985,"ell":36182,"elo":8595,"elu":6803,"els":2931,"elt":10887,"ely":1692,"ema":7235,"eme":2562,"emm":5417,"emo":1546,"emi":5347,"emp":2813,"ene":8165,"eng":2981,"ena":5955,"end":1729,"enn":9973,"enk":6752,"eni":7989,"ens":15471,"ent":18077,"ekä":5887,"ehd":2924,"ehi":4544,"eht":6057,"eis":18168,"eim":3841,"eil":7078,"ein":8482,"eik":4720,"eid":4335,"eja":2716,"el ":2656,"eit":8348,"öss":1852,"gis":3146,"gin":6890,"gia":4299,"ght":1865,"ös ":7736,"gen":2252,"ger":1575,"ön ":5342,"gas":2278,"gan":2134,"fri":1576,"for":2137,"fil":1743,"da ":1964,"de ":3246,"daa":2346,"dal":1725,"das":2350,"dan":3795,"ck ":3175,"ed ":1799,"ean":1991,"eal":1781,"eat":2428,"ea ":2811,"ei ":3830,"een":37770,"eel":9070,"ees":6176,"eet":6503,"edi":2493,"ede":4270,"edu":2200,"edo":1603,"ee ":9590,"dys":6375,"dus":2698,"don":2736,"dol":2034,"dos":3976,"dia":2516,"der":2863,"des":8657,"det":3714,"del":8280,"dek":2312,"den":24947,"dem":1603,"di ":1662,"din":5138,"dio":5021,"dis":6234,"rhe":3181,"rha":2376,"näj":3467,"näk":2091,"näi":1855,"ri ":14183,"rgi":2577,"ret":2238,"res":3703,"nä ":7166,"rea":2509,"ree":2885,"rei":4803,"ren":6049,"rel":2990,"rdi":1756,"re ":2848,"rd ":1882,"ras":4899,"rat":4668,"rau":3008,"raj":2533,"rai":2122,"ran":13051,"ral":4384,"rak":6377,"raa":6078,"rad":3325,"rs ":1794,"ros":3755,"rot":3070,"rom":2805,"ron":4039,"roo":4243,"rov":1686,"roc":2312,"roi":1996,"rna":1810,"rne":1656,"rni":2033,"ro ":2723,"rma":3198,"rme":1785,"riä":3343,"rmi":2119,"rko":8356,"rki":6693,"rkk":7003,"rke":4145,"rka":1913,"rjo":6361,"rja":16764,"rje":7814,"rio":2073,"rit":12816,"ris":12311,"rii":3347,"ril":5111,"rik":9617,"rin":19152,"rim":2324,"ria":8783,"ric":1741,"rie":2399,"näy":2474,"ruo":2205,"run":2801,"ruu":3504,"rus":12209,"rva":2385,"rvi":3707,"rve":3560,"rvo":2466,"ry ":2410,"rsi":3925,"rta":4520,"rto":3696,"rte":2990,"rti":3436,"rtt":1850,"rt ":1812,"rro":1797,"rre":2394,"rra":3831,"saa":11689,"sai":4605,"sak":3935,"sal":8568,"sam":4120,"san":10417,"sat":2386,"sas":5453,"sar":9940,"sav":3217,"sa ":88364,"ryh":2885,"si ":33316,"siv":2877,"sie":3768,"sia":14727,"sit":13812,"sis":15595,"sin":22898,"sio":5975,"sil":7537,"sim":10671,"sij":10631,"sik":6439,"sii":15427,"se ":7339,"sev":3309,"ser":1954,"ses":19353,"set":8009,"seu":4708,"sei":5713,"see":16044,"sen":44413,"sem":6469,"sel":8992,"sek":9571,"spa":2113,"sot":3315,"sol":2285,"son":3580,"sop":1591,"sos":3124,"sod":2739,"sof":1780,"soi":4463,"st ":1959,"sli":1829,"sla":3001,"ski":7594,"sko":4863,"sku":10246,"ska":6718,"ske":7078,"sma":1538,"siä":2875,"smi":2339,"ssä":20775,"stä":20839,"stö":6003,"syn":3354,"syy":2751,"sse":2037,"ssa":81782,"sso":2391,"ssi":7227,"ste":34759,"sta":74007,"sto":18448,"sti":27582,"stu":19044,"str":3547,"sty":7941,"suk":6559,"suo":12490,"suu":15921,"sut":2418,"sva":8410,"svi":2330,"tai":23079,"taj":9294,"tak":4197,"tal":15729,"taa":33105,"tav":11283,"tau":2602,"tat":3910,"tas":5911,"tar":15686,"tap":4732,"tan":13725,"tam":13647,"te ":4200,"ta ":96137,"pa ":1685,"par":4524,"paa":2641,"pah":2670,"pak":1785,"pal":14678,"pai":9231,"pan":6844,"läp":1604,"län":3940,"läm":2523,"läi":5398,"läh":6121,"pi ":2782,"lä ":21592,"per":21853,"pet":1794,"pel":8616,"lää":3392,"pia":3590,"pid":1828,"pie":3232,"pii":5873,"pil":2184,"pin":5017,"pis":5110,"pit":5090,"por":1632,"poi":2560,"poh":4180,"pol":4180,"ppu":2417,"ppi":4768,"ppa":7267,"ppe":1921,"pro":3960,"pur":1783,"pus":1680,"pun":10901,"puo":7107,"pul":1657,"puh":2589,"px ":2372,"puu":2017,"mä ":7257,"mäi":6703,"män":3876,"mäs":1650,"mää":5076,"ra ":5712,"ngi":7939,"ngl":4558,"ni ":6341,"nge":2486,"nga":3203,"jän":3177,"jäl":4462,"jäs":2729,"jär":9906,"nha":2067,"nei":4215,"nel":5383,"nen":63104,"ner":2732,"net":11819,"nes":5079,"neu":1692,"ng ":3916,"nee":7398,"jä ":5912,"nce":1684,"ne ":6951,"ndo":1777,"ndi":2475,"nde":2171,"nda":1665,"nak":1691,"nal":6875,"nan":9972,"nai":6761,"naa":4824,"nd ":4059,"nat":3023,"nas":6250,"na ":39872,"myö":9305,"iö ":2528,"ntä":3484,"nsä":4958,"nva":1615,"num":1758,"nus":3629,"nut":8387,"nty":5978,"nto":10581,"ntu":4377,"ntt":4440,"nti":13349,"nta":21023,"nte":11336,"nso":2855,"nss":4946,"nse":1616,"nsi":11891,"nsk":3706,"nsa":12409,"nnä":1593,"nt ":1924,"ns ":1897,"nol":2730,"noi":8508,"nom":2361,"non":3636,"not":1919,"nos":4123,"nne":16039,"nna":31714,"nno":6361,"nni":12231,"nnu":4777,"nme":1667,"nma":1873,"jää":2989,"nla":2791,"no ":2124,"nke":2631,"nki":13461,"nka":13056,"nko":2285,"nja":2100,"nii":4930,"nie":2772,"nia":6492,"nis":11071,"nit":5273,"nim":13793,"nin":16562,"nik":3354,"nil":2835,"ogi":4118,"oi ":3679,"oht":5278,"käs":5110,"kär":1779,"ohj":13237,"oho":2246,"oiv":1619,"ois":23808,"oir":1655,"oit":25419,"oin":13137,"oik":5181,"oim":14211,"oil":4642,"oih":1702,"oid":5498,"käy":11169,"oje":6434,"oja":5307,"ock":3160,"ode":9371,"odi":1977,"odo":4669,"of ":2718,"oda":3354,"oel":2434,"oen":2647,"ofi":1682,"kä ":7989,"oa ":4765,"oal":3299,"nyk":2547,"nyt":4401,"nvä":1760,"otu":2486,"otk":3192,"oti":5562,"ote":5798,"ott":10457,"ots":2991,"oto":4571,"ost":14630,"ota":8496,"osi":11836,"osk":3907,"ose":3031,"oss":12304,"oso":3047,"ovi":3135,"ova":10956,"ove":2498,"ouk":4542,"oul":4682,"oun":1887,"ous":2951,"out":1762,"opp":4159,"opi":5727,"ope":4607,"opa":3651,"os ":5287,"opu":2089,"oon":7289,"ool":1601,"oom":1672,"or ":1961,"oot":2091,"oos":2166,"oop":3454,"ork":3647,"orm":3104,"orn":1628,"oro":2190,"ord":2513,"ore":3159,"org":2171,"ori":12794,"osa":15087,"ort":3782,"ot ":3256,"ora":3303,"ola":6203,"on ":146201,"oli":32153,"oll":16426,"ole":10977,"kää":1980,"olt":1744,"olm":4749,"olo":5842,"oly":2026,"olu":4176,"oka":27584,"okk":2554,"oki":3937,"oke":2183,"oks":6588,"oko":8846,"oku":9166,"ona":6281,"one":7607,"ong":1915,"oni":10795,"onk":9689,"onn":20892,"ono":2022,"ons":4191,"ont":4754,"oma":18393,"ome":15724,"omi":7452,"omu":1601,"la ":45674,"le ":23672,"laa":8510,"lah":2594,"laj":7083,"lai":41589,"lal":1802,"lak":2624,"lan":15670,"lam":1915,"lat":4073,"las":9219,"lau":6037,"lbu":8824,"kuv":12915,"kuu":20315,"kut":5564,"kus":5968,"kup":2448,"kuo":2056,"kun":18716,"kul":5464,"kuk":1991,"ksi":34515,"kso":2000,"kue":1696,"kui":3945,"kti":3367,"kyi":1827,"kyl":5052,"llä":17871,"lok":9030,"lon":3666,"lom":4409,"lop":2359,"log":4285,"loi":6423,"lpa":4160,"los":4127,"lot":1540,"lou":2403,"ljä":2124,"lmi":8971,"lme":5378,"lma":14737,"lti":5458,"ltt":2378,"lue":13574,"lsi":2865,"lta":20774,"lu ":5034,"lmä":3813,"hän":3427,"li ":38792,"lev":10595,"les":3513,"let":2489,"ler":1630,"lem":3429,"len":7655,"lek":2031,"lel":2977,"lei":7201,"leh":3152,"lee":7823,"llu":3725,"lo ":3012,"lla":45545,"lle":23098,"lli":38165,"llo":8003,"lko":3906,"lku":3582,"lka":14232,"lke":3142,"lki":3385,"ljo":1577,"lje":1833,"ll ":2046,"lit":6604,"lis":35039,"lip":2086,"lio":3340,"lin":25643,"lim":2511,"liv":3460,"lia":6855,"lik":3266,"lil":3081,"lii":12989,"lij":5839,"lie":2208,"ma ":15016,"mb ":3008,"maa":25280,"mah":1595,"mai":6076,"mak":3049,"mar":3413,"mas":6492,"mal":15003,"man":17338,"mat":9985,"me ":2801,"mee":1671,"met":10390,"mes":9381,"mer":13701,"mel":4799,"men":18334,"mei":2490,"iä ":10723,"lve":3316,"lvi":1540,"luk":6577,"lui":2536,"luo":7753,"lun":5262,"lut":6301,"lus":6284,"luv":9141,"luu":4990,"ltä":6950,"lyh":1732,"lym":1752,"mpi":5319,"moo":2276,"mon":6257,"mpa":1715,"mmä":7757,"mpä":2564,"mua":1679,"mus":7282,"mut":3853,"muu":6734,"mui":3639,"muk":6397,"muo":5752,"mi ":13252,"min":18710,"mil":5082,"mis":25017,"mit":6945,"mia":4076,"mie":6732,"mik":3016,"mii":3025,"mo ":3241,"mmi":7415,"mma":5671,"mme":2557,"väl":6253,"vä ":5493,"vää":1811,"vän":2110,"vät":4019,"yvi":1744,"yty":2014,"ytt":9230,"yte":5446,"ysv":6099,"yst":4193,"ysi":1754,"yri":2968,"yt ":5088,"ymä":1567,"ys ":5219,"ylä":5863,"yny":2515,"yvä":4334,"yyl":1824,"yys":2076,"yyp":2141,"yyt":1690,"yy ":2993,"ye ":3730,"yde":2513,"yee":3728,"yks":11428,"yky":3192,"yn ":4172,"yle":4657,"yli":5834,"yll":2070,"ymi":2202,"ymp":3885,"yne":1918,"ynt":3210,"yi ":2699,"yhm":2893,"yhd":7827,"yht":15566,"yis":3850,"tön":2023,"tös":1710,"tö ":2585,"täm":6823,"tän":1885,"täh":1876,"täj":3398,"tä ":34022,"tää":13926,"täy":1596,"tär":1635,"täv":7438,"sää":2844,"sä ":25127,"säl":3359,"säk":2119,"säv":1927,"vuo":32425,"vun":2514,"vul":3123,"vy ":2051,"via":2642,"vio":1556,"vir":4221,"vil":2731,"vin":6040,"vii":6538,"vie":4226,"vit":3912,"vis":7340,"voi":10127,"von":1808,"vos":2863,"räi":2223,"vi ":2985,"ver":6645,"ves":2270,"ven":5385,"vel":7217,"ve ":1928,"val":26751,"vak":1862,"van":11048,"vap":1548,"var":8953,"vat":20575,"vas":8886,"vaa":7863,"vai":7839,"va ":18614,"uuk":1525,"uun":9740,"uul":10457,"uud":5759,"uus":11398,"uur":9061,"uut":11944,"uvi":3760,"uvo":2424,"uva":18498,"uvu":5385,"usl":2474,"usk":5912,"usi":8604,"use":5829,"usa":2048,"uu ":9094,"ust":26922,"uss":6964,"utk":3663,"uti":2698,"ute":5204,"uta":9377,"utt":14676,"uts":1830,"utu":7065,"uto":3590,"us ":19751,"ut ":13926,"ura":6710,"ure":2812,"urh":2266,"uri":10072,"uro":4160,"uru":1961,"uod":11474,"uon":20919,"uol":10441,"uom":19569,"uok":4826,"uot":13021,"uor":5597,"uos":6389,"upe":2549,"upu":10042,"umi":12508,"uma":5258,"umb":3567,"ume":3010,"unt":10189,"unu":3435,"unk":6506,"uni":5890,"unn":17239,"und":1617,"una":4707,"ung":5391,"une":2125,"uks":15716,"uku":7377,"uko":2518,"ukk":6046,"uki":2552,"uke":1610,"um ":2055,"uka":8994,"ulu":17346,"ult":3742,"ulo":2329,"ull":6128,"ulk":14188,"uli":3634,"ule":2174,"ula":6501,"un ":17537,"uin":4870,"uis":6404,"uht":1985,"uhu":1855,"uje":1776,"uit":1991,"uja":2763,"ui ":2881,"uha":2389,"ude":10287,"udi":3267,"ue ":4574,"uet":2172,"uee":7376,"työ":3659,"ua ":4041,"uas":1855,"tyv":3209,"tyy":6164,"tye":7861,"tyi":5279,"tyk":3846,"tym":2979,"tyn":4512,"tys":6857,"ty ":6437,"tur":3509,"tus":10527,"tut":5144,"tuu":8595,"tuv":3012,"tuj":1880,"tui":4969,"tul":5059,"tuk":7469,"tun":13048,"tum":4274,"tuo":5296,"tua":2491,"tud":2510,"ttö":2890,"ttä":18426,"tra":3772,"tri":7061,"tro":3179,"tu ":15401,"tsa":2112,"tse":11636,"tsi":5021,"tsu":1775,"tta":37250,"tte":15326,"tti":29985,"tto":7420,"ttu":17456,"tty":9077,"to ":10851,"tiö":3363,"toj":3671,"toi":21414,"tkä":1786,"toa":3897,"tos":4171,"tot":2445,"tom":3430,"ton":10160,"tok":5162,"tol":5536,"tor":8049,"too":2936,"top":1727,"tii":20914,"til":10225,"tik":4482,"tie":14185,"tit":2814,"tis":9101,"tin":13829,"tim":2695,"tio":13178,"thu":3317,"tia":5511,"tiv":2672,"tki":4098,"tka":4817,"pää":9932,"tem":2906,"ten":19694,"teo":3855,"tei":13515,"tek":5492,"tel":25974,"tee":16061,"teh":4545,"th ":1573,"tet":23609,"tes":1638,"ter":13778,"ti ":27214,"pär":2295,"the":3039,"päi":2568,"yön":1725,"yös":8569,"yöh":1625,"yä ":1547},"n_words":[15184556,16912812,13033049],"name":"fi"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fra b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fra new file mode 100644 index 000000000..1d6d3baa0 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/fra @@ -0,0 +1 @@ +{"freq":{"D":116102,"E":120408,"F":121384,"G":111406,"A":238769,"B":169565,"C":285959,"L":345504,"M":204991,"N":98243,"O":65813,"H":89479,"I":164982,"J":77783,"K":45111,"U":61602,"T":117987,"W":42348,"V":73826,"Q":14589,"P":196230,"S":238878,"R":128546,"Y":18365,"X":15982,"Z":13917,"f":625832,"g":841835,"d":2804209,"e":9206578,"b":583197,"c":1872040,"a":5160230,"n":5070939,"o":3525396,"l":3535844,"m":1717377,"j":148113,"k":150020,"h":692514,"i":4746975,"w":64787,"v":659313,"u":3519294,"t":4403208,"s":4479915,"r":4208721,"q":428703,"p":1557910,"z":87206,"y":309342,"x":204437,"É":44421,"ï":13787,"î":22540,"ê":38749,"é":1751958,"è":218696,"ç":101170,"â":19710,"à":277569,"û":11801,"ù":7682,"ô":30698,"œ":8733," l":1232220," m":320276," n":242807," o":228420," h":94558," i":171950," j":98827," k":16664," d":1997342," e":1227865," f":345437," g":129922," a":696872," b":124278," c":594010," y":7295," u":524523," t":219372," w":8382," v":133967," q":138426," p":728591," s":616330," r":286749," J":75893," K":42648," H":85423," I":133876," N":84973," O":54606," L":335414," M":194304," B":161567," C":266111," A":214898," F":109790," G":105282," D":105238," E":106937," Z":13187," Y":17633," X":12755," S":214333," R":117248," Q":13527," P":183259," W":40332," V":62074," U":57563," T":104796," à":274935," î":9932," é":209998," ê":8160," É":44088,"A ":15041,"Da":22440,"Cl":11868,"Co":65041,"Cr":12941,"Ce":29429,"Ch":51129,"Ci":6652,"Du":7894,"Do":13538,"De":21502,"Di":17162,"Fe":8715,"Fa":10235,"Eu":11691,"Es":11694,"En":18617,"El":32899,"Ge":14692,"Ga":20211,"I ":15646,"Fr":44421,"Fo":14809,"Fl":7090,"Fi":9942,"C ":21532,"Au":19631,"Ar":26711,"At":6889,"As":11086,"D ":7702,"Ba":35723,"Am":14264,"An":31376,"Al":37486,"Bu":10594,"Br":27743,"Ca":55063,"Bi":10547,"Be":29116,"Bo":31176,"Bl":7237,"Le":129356,"Li":24542,"La":91448,"Lu":9746,"Lo":35045,"Me":21247,"Mi":27542,"Ma":80328,"Mu":9199,"Mo":39904,"Ni":11148,"Ne":15700,"Na":15519,"No":31277,"On":6946,"Gi":8289,"Gr":22075,"Go":10803,"Gu":15739,"Ha":29460,"He":19781,"II":12760,"Hi":8034,"Ho":13597,"In":22404,"Il":64459,"Is":6832,"It":7525,"Ja":19690,"L ":40055,"Je":19939,"Jo":19144,"Ju":9216,"Ka":11065,"Un":43594,"Tr":15916,"To":17150,"Th":22226,"Ti":6718,"Te":13283,"Ta":12863,"V ":9181,"St":21014,"Su":20295,"Wi":11355,"Wa":11101,"We":6825,"Vi":21333,"Ré":14676,"Va":15441,"Ve":10793,"Pr":25219,"S ":10997,"Pe":15558,"Pa":62058,"Pl":7693,"Po":24431,"Pi":18433,"Ph":7701,"Ou":6784,"Or":12154,"Se":26414,"Sc":10127,"Si":15134,"Sh":8197,"Sp":6886,"So":23717,"Ru":6655,"Sa":56793,"Re":19635,"Ri":11472,"Ro":36071,"Qu":12001,"Ra":14786,"b ":23149,"a ":715548,"Yo":8948,"i ":246446,"ge":153192,"ga":79217,"bé":13640,"fl":14307,"ff":44067,"fi":98156,"fr":118819,"fu":33433,"fo":104257,"he":135815,"ha":144005,"gn":87721,"cé":45974,"cè":9053,"gl":38751,"gi":139568,"gh":16776,"gu":62416,"gr":93539,"go":42919,"du":266692,"g ":46447,"ea":84524,"eb":15026,"ec":142148,"ed":28114,"de":1288806,"di":214915,"dm":11618,"do":95110,"ds":13995,"dr":52545,"ew":13282,"ex":53989,"eu":311458,"ev":34640,"ey":24158,"ez":12097,"fa":75922,"h ":43257,"fe":44423,"eg":22246,"ef":23663,"ee":14949,"el":261273,"ei":65911,"ep":62933,"eo":13735,"en":1013332,"em":298038,"et":487438,"aï":8404,"es":1468583,"aî":9959,"er":561408,"ca":174843,"e ":4165476,"by":10945,"bs":8710,"br":109877,"bu":41947,"bo":48835,"bl":80107,"bi":56922,"be":65791,"da":250547,"f ":44719,"cy":11950,"cu":58711,"ct":159489,"cs":7871,"cq":7986,"cr":84742,"co":398094,"ck":30588,"cl":49217,"ci":192973,"ch":228563,"ce":285004,"cc":27518,"c ":86602,"az":14616,"ay":48306,"ba":99079,"d ":356687,"at":402587,"as":164469,"ar":580946,"aq":13150,"ax":8225,"av":102326,"au":313806,"ak":16011,"al":437033,"ai":491839,"aj":9782,"ao":15479,"ap":112014,"am":169689,"an":984305,"ac":155600,"ad":94574,"ab":78438,"ag":129146,"ah":12966,"ae":24602,"af":19038,"nu":48492,"nt":781378,"ns":405957,"nr":20379,"nq":10241,"no":177623,"nn":194465,"nz":7383,"ny":16039,"nv":29268,"oe":7051,"of":34594,"oc":112798,"od":60253,"oa":9189,"ob":47107,"om":320717,"on":978231,"ok":8561,"ol":182032,"oi":182944,"og":68867,"oh":10520,"ot":93297,"os":119510,"ov":56208,"ou":495961,"op":94277,"oo":30133,"or":397296,"oq":6742,"r ":618020,"ox":6981,"ow":11940,"oy":26184,"pe":191299,"pa":336824,"lè":14938,"pl":106081,"lé":66665,"po":236682,"ph":72167,"pi":70246,"lo":174519,"hé":40769,"lm":23015,"hè":8383,"ll":348027,"ls":35163,"lp":13659,"lv":7890,"lu":105730,"lt":35681,"ly":20798,"o ":123736,"ma":245390,"mb":101583,"me":421982,"iè":67396,"mi":181182,"mm":149391,"ié":40043,"mp":121199,"mo":139179,"mt":11044,"ms":10324,"mu":103041,"my":7264,"p ":21047,"na":254840,"nc":212957,"nd":247872,"ne":645258,"nf":26140,"ng":123325,"ni":252369,"nk":9186,"ju":35235,"jo":42449,"fé":31064,"ki":18400,"ke":23430,"ka":17710,"m ":101180,"ko":10158,"gé":41926,"li":366432,"le":1033424,"ld":17364,"lg":18291,"lf":6672,"la":653743,"lb":19702,"n ":1301691,"hr":18002,"ht":13842,"hu":32067,"hi":111052,"hn":14386,"ho":82392,"hl":7215,"dé":209539,"id":89273,"ic":228813,"ib":37956,"ia":126735,"ig":111904,"if":68146,"ie":498651,"hy":15296,"k ":41221,"iq":189141,"ir":210609,"is":657338,"it":513778,"iu":11403,"iv":116504,"ix":21397,"ik":10626,"il":316521,"im":87035,"in":595401,"io":414857,"ip":60451,"je":33885,"iz":8646,"l ":543603,"ja":25992,"xi":22025,"tè":15940,"té":190035,"xp":12895,"xt":10929,"z ":20913,"xa":6853,"xe":16992,"wi":9300,"sé":88528,"rô":7192,"y ":99277,"wa":16319,"we":7882,"rè":35139,"ré":242093,"vi":188474,"vu":6788,"vr":43893,"rê":8320,"vo":57579,"ux":99749,"uv":71595,"ve":234012,"va":93360,"x ":120860,"ui":230155,"uj":8246,"ul":117513,"ue":407659,"uf":8137,"ug":28998,"ur":515467,"us":227928,"ut":191898,"um":73719,"un":620155,"up":64955,"ty":19621,"tu":167178,"tt":77237,"ub":50581,"ua":51699,"ud":59261,"uc":57765,"w ":13938,"to":173702,"pé":53976,"tl":8663,"pè":21910,"ts":102393,"tr":321129,"te":602785,"ti":612679,"th":96741,"v ":6801,"où":7384,"tb":13422,"tc":11543,"oû":9564,"ta":328001,"su":146804,"ss":210582,"st":753670,"sy":23798,"sl":12189,"sk":12848,"sn":9845,"sm":19680,"sp":78469,"so":222811,"sq":17522,"sc":60065,"se":403227,"sh":19364,"si":325826,"u ":509520,"sa":131590,"rr":83294,"rs":168244,"rt":289803,"ru":65582,"rv":27573,"ry":20802,"rq":9625,"rp":15297,"ro":341033,"rn":84154,"né":177701,"rm":89580,"rl":33141,"rk":16207,"nç":94772,"ri":487470,"rg":66626,"rf":12647,"re":763207,"rd":96680,"rc":70956,"rb":28741,"ra":505286,"t ":1634972,"qu":422607,"mê":10277,"mé":91911,"mè":10378,"s ":1913426,"pt":48826,"pu":65796,"pp":68088,"pr":230460,"ps":19103,"zi":10741,"ze":10497,"za":12596,"zo":10854,"vé":17663,"ye":16656,"yc":12861,"ya":27740,"yt":7956,"ys":37929,"yr":15599,"yp":14150,"yo":8853,"yn":14467,"ué":92385,"ym":16691,"yl":12792,"Ét":26242,"ât":11174,"à ":276969,"éé":15388,"îl":9937,"êm":12225,"êt":20220,"él":51000,"éo":28234,"ép":86639,"ém":44293,"én":55491,"és":107336,"ét":140932,"éq":14455,"ér":173640,"év":51715,"éb":22743,"éa":37956,"éd":70000,"éc":110985,"éf":19719,"ée":230327,"ég":99948,"èm":27722,"èn":11542,"èr":67257,"ès":34878,"èt":16045,"èv":6684,"èg":9962,"èc":26515,"ço":8440,"ça":89329,"é ":372600,"ût":9917,"ù ":7557,"ôt":12300,"œu":7751,"一":9376," Ga":20103," Ge":14539," Fo":14685," Fr":44293," Fi":9743," Fl":7048," Ha":29378," He":19697," Go":10717," Gr":21904," Gu":15637," Gi":8161," Ho":13528," Hi":7850," Je":19786," L ":35977," Ja":19604," Is":6751," It":7499," In":22151," Il":64299," Ka":10962," Jo":19013," Ju":9181," La":90821," Le":128061," Li":24245," Ma":79831," Mi":27364," Me":21128," Lo":34906," Lu":9698," Ne":15538," Na":15371," Ni":11097," Mo":39732," Mu":9105," C ":11416," Am":14164," An":31164," Al":37253," Ba":35535," Au":19508," At":6802," As":10968," Ar":26331," Be":28995," Bi":10366," Bl":7174," Bo":30964," Br":27614," Bu":10535," Ca":54551," Ce":29219," Ch":50964," Cl":11738," Cr":12852," Co":64524," Da":22266," Di":16958," De":21321," Do":13217," Du":7843," El":32823," Es":11656," En":18307," Eu":11642," Fe":8673," Fa":10157," Wi":11260," We":6753," Wa":11001," Yo":8931," a ":54049," Ou":6671," Or":12055," Po":24205," Pl":7593," Pi":18345," Ph":7574," Pe":15479," Pa":61683," No":30970," On":6799," Ra":14631," Qu":11878," Ro":35894," Re":19473," Ri":11439," Pr":25007," Su":20225," St":20131," Ta":12776," Th":22049," Te":13049," Tr":15810," To":17022," Sa":56588," Sh":8106," Si":14799," Sc":9966," Se":26149," So":23336," Sp":6786," Va":15389," Ve":10579," Vi":21221," Ré":14605," Un":43425," ja":19099," l ":229130," je":16653," im":17160," in":90112," il":33523," is":6946," it":13099," jo":28748," fé":16770," ju":33224," ha":21033," gr":51361," go":9168," gu":9190," hi":17321," dé":147001," ho":26370," hu":11315," ne":11993," na":26573," mu":26866," mo":87695," on":19443," oc":20805," of":17687," ob":10074," no":93418," le":471758," li":50278," n ":10043," la":426807," gé":20899," me":31539," mi":31668," ma":94790," lu":10283," lo":32481," af":11272," ag":11352," ab":10657," ac":41475," ad":17435," am":34528," an":80768," ao":8597," ap":47388," ai":15942," al":42510," av":56190," au":168550," ar":49629," at":13572," as":18267," d ":197071," ba":44107," bi":13538," be":11213," bo":15457," bl":6713," bu":7813," br":18993," ca":62413," et":342046," es":474914," en":328723," em":8216," el":14313," fe":12823," fa":58915," eu":10657," ex":33671," fu":26386," fr":103021," fo":71702," fl":7457," fi":46439," ge":16870," ga":14369," cl":20052," co":290856," cr":32388," ce":54595," ch":72895," ci":26401," da":165596," cu":9192," cy":6653," do":48107," dr":11453," de":1120211," di":79077," du":223778," té":10776," ru":15648," sa":43475," se":95411," sc":20238," si":97963," sp":20322," so":138476," qu":138128," ra":22818," re":79730," ri":12843," né":88113," ro":35414," pu":26022," pr":170981," s ":23984," mê":10232," mé":23004," ou":87553," op":9623," or":44807," pe":62711," pa":204808," lé":7304," pl":62779," po":141674," pi":14858," ph":17219," sé":19742," va":14483," ve":21390," vo":19720," vi":65672," ré":111803," ut":13716," un":501687," ta":13187," où":7340," sy":15329," st":19632," su":114473," tr":64495," pé":8718," to":29268," th":29162," ti":14570," te":41930," Ét":26213," à ":274908," êt":8158," év":15420," éq":11336," ét":84332," ép":12565," él":18021," éd":13385," éc":33500," ég":11829," îl":9913,"Eur":7732,"En ":11566,"Ell":27452,"Fra":34835,"For":6793,"II ":8125,"Her":7505,"Hau":10362,"Gra":11197,"Ind":7362,"Il ":58031,"Bar":7002,"Bas":7999,"All":7697,"Ang":8461,"Cal":11943,"Car":9781,"Can":10563,"Ber":8508,"Bel":7820,"Bou":9492,"Dan":8952,"Chi":7925,"Cen":6692,"Cet":9727,"Cha":27535,"Cor":8959,"Com":17296,"Col":7940,"Con":15750,"Cou":6779,"New":7835,"Nor":17044,"Pie":8398,"Par":29868,"Pro":9444,"Ita":6863,"Jea":13129,"Les":29698,"Le ":85946,"Lan":7053,"La ":64716,"Lou":8888,"Loi":7362,"Man":8487,"Mar":33987,"Mon":17275,"Mic":7917,"Sud":6967,"Sta":7499,"Son":7414,"Sai":21598,"San":8752,"Val":6713,"Uni":28327,"Un ":8531,"The":11621,"bit":13396,"bil":9380,"ble":36471,"bli":30327,"bor":11093,"bou":14756,"be ":11661,"ban":14082,"bal":23571,"bat":8684,"bas":21924,"bar":8519,"bec":7102,"ber":20504,"bel":11445,"bie":9676,"ca ":7169,"car":22613,"cat":26927,"can":25116,"cap":8531,"cad":7391,"cal":21842,"cai":32564,"ce ":152975,"bri":16551,"bra":7577,"bre":74429,"bum":11288,"but":12601,"by ":8395,"am ":12290,"al ":83242,"ail":20993,"ain":126816,"air":72297,"ais":165056,"ait":69408,"aie":8332,"acé":7099,"agi":9624,"agn":32293,"ago":7536,"anv":10025,"ano":12803,"ann":37434,"ant":198270,"ans":198981,"ane":14041,"ang":47054,"ani":45704,"ana":30499,"anc":97402,"and":98722,"amm":17042,"amp":23230,"ami":37168,"ame":15452,"amb":9570,"ama":14537,"alt":7552,"alo":12342,"all":56591,"ali":100273,"ale":107350,"ala":20659,"alb":12381,"an ":76640,"abe":9364,"abi":15595,"abl":19961,"abo":9408,"abr":8483,"ae ":16557,"ac ":8751,"aff":8179,"ai ":16674,"aga":7441,"age":55470,"ado":7415,"adm":9823,"adi":21924,"ade":15733,"aci":10019,"ach":16602,"ace":28163,"acc":10028,"ada":13056,"act":43926,"até":6761,"ays":15243,"aya":8788,"aqu":12595,"at ":36684,"arg":12036,"are":21800,"ard":35646,"arc":26378,"arb":8126,"ara":32792,"aro":14440,"arn":8384,"arm":11551,"arl":15187,"anç":91515,"ari":62241,"aru":7211,"arq":6770,"arr":20556,"ars":16927,"art":134713,"au ":118568,"asi":7486,"ase":11574,"ar ":120208,"api":10314,"aph":15548,"apo":12040,"app":42097,"apr":9346,"as ":37163,"amé":27799,"ava":24401,"aux":51164,"aut":60224,"avr":9575,"avo":10413,"avi":13083,"ave":40354,"ay ":10427,"ata":13379,"aoû":8368,"ast":22288,"ass":51465,"atr":15439,"ato":12284,"ate":44406,"ati":192812,"ath":17738,"auc":6672,"att":16852,"ats":23409,"atu":15332,"aul":9810,"aum":7753,"aur":11354,"aus":19732,"aud":9105,"jet":8119,"jeu":19460,"jan":10693,"fév":8788,"fér":12432,"jou":35022,"itr":12118,"ito":10908,"itu":87676,"itt":10859,"its":10569,"ism":13926,"iso":19540,"isp":7420,"iss":50166,"ist":125656,"ita":62348,"ite":57973,"ith":6663,"iti":60924,"isé":36821,"iva":20746,"ix ":16528,"ivi":25932,"ive":55895,"is ":216454,"ion":363871,"iol":6761,"ipa":18735,"ipe":13929,"ir ":34075,"iro":12325,"iné":18867,"iri":8297,"isi":28415,"ise":101298,"isc":8611,"isa":28074,"iqu":188846,"ire":120253,"ira":8690,"irc":8347,"it ":122098,"ité":60635,"gén":18856,"jus":7076,"jui":19529,"ham":23355,"han":29050,"hau":9292,"har":26334,"hab":12359,"he ":52407,"hel":8715,"hef":7684,"hes":11848,"her":19826,"hie":13715,"hin":15050,"hil":13377,"his":19375,"hiq":6944,"dé ":18734,"déb":7151,"déc":35759,"go ":7689,"cée":7075,"céd":16748,"gle":10717,"gli":6716,"gla":15951,"gno":9326,"gni":10059,"gne":50271,"gna":8886,"gou":8451,"gro":28558,"gra":41927,"gre":10583,"gui":7723,"gue":37672,"ial":35445,"ian":23438,"iat":15622,"ic ":12032,"ibl":8749,"ibu":7144,"ia ":21961,"ieu":43579,"iel":22526,"ien":138676,"ier":92906,"ies":16655,"iff":14012,"ifi":22387,"ict":17983,"icu":12669,"ico":11245,"ick":6729,"ici":37411,"ich":23588,"ice":26902,"ie ":169464,"ica":66266,"idi":10544,"ide":31414,"ida":13896,"if ":16206,"il ":58832,"ige":6657,"igh":9785,"igi":21897,"igu":11721,"ign":41717,"idé":15214,"imp":16150,"ime":18408,"imi":12406,"inc":41459,"ind":21942,"ina":36398,"ino":12991,"int":75915,"ins":44722,"inf":11189,"ine":105011,"ing":34736,"ini":40626,"ila":9244,"in ":120797,"ilo":10879,"ill":136561,"ilm":14297,"ili":45030,"ile":18930,"ima":15975,"io ":17855,"ils":11236,"hol":10188,"hom":18219,"hon":13352,"hor":8438,"dév":10462,"dée":10321,"déf":8940,"dém":9364,"dép":53945,"dér":20431,"dés":15740,"ht ":8492,"hum":15199,"ffe":7771,"ffi":11627,"fes":12569,"fer":7877,"fam":26250,"fai":22917,"fac":6862,"ext":9480,"ez ":9334,"exp":11699,"exi":10548,"eta":8136,"ete":7713,"eti":12647,"esp":33176,"est":489584,"ess":57266,"eul":7484,"ett":36757,"ew ":8505,"eve":10111,"eva":7495,"evi":7979,"euv":6803,"eut":10699,"eur":177418,"eus":14865,"eux":38960,"ey ":17748,"er ":177809,"es ":856843,"ept":19543,"epu":14012,"elé":11860,"epr":16261,"erl":8779,"eri":17387,"erg":13600,"ere":10113,"erc":19130,"era":14672,"erb":9918,"et ":392437,"esc":6799,"eu ":31850,"erv":19978,"err":46160,"ert":38461,"ers":78150,"ern":42947,"erm":29874,"ero":7440,"en ":352124,"ela":11282,"ele":8299,"eli":13751,"elg":9644,"ell":93604,"elo":21097,"els":10727,"emb":53506,"ema":21014,"eme":149235,"emi":31587,"emp":25298,"ene":6850,"ena":20675,"end":38663,"enc":42120,"enn":54421,"eni":9389,"enu":8876,"env":9265,"ens":48323,"ent":371396,"enr":18661,"eil":18380,"ein":23896,"eig":7921,"el ":58534,"gis":10364,"giq":10802,"gin":20723,"gio":57044,"gie":22112,"ght":8779,"gen":26739,"ger":14731,"ges":19429,"ge ":72294,"gar":9985,"gal":16426,"gan":17016,"ga ":6882,"fus":7249,"fut":21703,"fra":95189,"fri":7633,"for":45771,"fon":27020,"foo":11436,"foi":12370,"fic":24328,"fil":25221,"fin":20051,"ffé":6845,"da ":14864,"de ":945562,"dai":12767,"dae":8896,"dat":11688,"dan":177922,"cul":27372,"ctu":20091,"ctr":11700,"cto":18088,"cti":59878,"cte":30379,"cré":24660,"cla":14396,"cle":15005,"clu":9348,"ché":8767,"co ":9868,"cié":10273,"con":120854,"col":28490,"com":148564,"cor":20969,"cou":37141,"cs ":7503,"cqu":7392,"ct ":7934,"cra":8267,"cri":32184,"cro":10112,"cci":7074,"cea":6989,"ch ":14828,"cer":17030,"ces":36299,"cet":8987,"cen":24433,"cem":11283,"cel":14093,"cha":54442,"cia":30366,"ck ":14947,"cie":55297,"cid":7429,"che":76684,"chi":31813,"cho":10460,"chn":7132,"cir":7170,"cis":7169,"cit":9428,"cin":16999,"cip":23717,"cke":8035,"ed ":9999,"ec ":39615,"ean":16858,"eau":41781,"eff":6903,"ech":13667,"ef ":8454,"ect":52251,"eco":14578,"dur":7123,"don":36748,"dom":8813,"dou":8007,"ds ":11646,"dmi":10099,"doc":6954,"dui":12311,"duc":16031,"dri":6694,"dra":6827,"dre":21768,"du ":216503,"dro":13106,"dic":10492,"dia":18227,"der":20812,"des":229646,"deu":19332,"dev":7361,"del":7755,"den":24656,"dep":13089,"di ":9657,"do ":8222,"div":14424,"din":10138,"dio":11927,"dir":13444,"dis":29420,"dit":31296,"die":29137,"dif":14101,"rga":14359,"ri ":10992,"rgi":6778,"rge":19992,"ret":19172,"res":111968,"reu":15390,"rg ":10612,"rea":7335,"rec":29178,"reg":9663,"rem":41279,"ren":49926,"rel":19572,"rer":6909,"rep":18635,"rdi":12299,"rde":11104,"re ":401675,"rco":8273,"rch":25796,"rce":14227,"rd ":49795,"rap":22951,"ras":10406,"rat":61280,"rav":14677,"rbe":7330,"rai":37514,"rag":12671,"ran":191224,"ram":14978,"ral":42593,"rab":8579,"rad":17757,"rac":18041,"rs ":108005,"ros":12152,"rot":13239,"rom":20207,"ron":45128,"rop":30358,"rou":56658,"rov":25371,"rod":19072,"roc":18144,"roi":33087,"rol":7836,"rof":11414,"rog":8618,"rna":26829,"rne":26551,"rni":14539,"riè":7237,"nér":15715,"ro ":12314,"rma":27965,"née":51678,"rme":33077,"rmi":8879,"rle":10727,"rla":9260,"nça":87637,"né ":83238,"rip":8171,"rio":12752,"riq":23356,"rit":49518,"ris":61412,"riv":19174,"rig":30515,"ril":14567,"rin":32694,"rim":9133,"ria":17879,"rib":8141,"ric":64397,"rid":9964,"rie":84165,"rk ":9714,"ruc":9646,"rus":10779,"rvi":9893,"rve":7324,"ry ":13884,"rsi":16639,"rso":15966,"rse":12239,"rta":21499,"rto":8213,"rte":72339,"rth":9356,"rti":82832,"rts":8395,"rtu":7199,"rmé":10475,"rt ":67054,"rqu":9541,"rro":9520,"rri":15769,"rre":35748,"rra":13162,"sac":6821,"sai":15869,"san":31853,"sat":19662,"sa ":20364,"si ":23508,"sie":23358,"sid":13927,"sic":8539,"sit":96579,"sis":11253,"siq":13014,"sin":20761,"sio":46892,"sil":9278,"sig":20886,"scr":8195,"se ":185840,"sca":7156,"sci":11470,"sco":9152,"ser":33436,"ses":32384,"seu":18614,"sea":8788,"sei":15724,"sec":11236,"sep":15495,"sen":31564,"sem":23920,"sel":11350,"spo":15398,"spe":6813,"spa":15911,"sou":38682,"sol":8864,"son":104745,"sor":19583,"soi":7516,"soc":22585,"st ":465410,"squ":17455,"sla":8458,"siè":10850,"sme":14217,"stè":10526,"sys":7499,"où ":7381,"sse":73979,"ssa":25709,"sso":20070,"ssi":65158,"ssu":9524,"ste":86262,"sta":32395,"spé":11204,"sto":25947,"sti":51286,"spè":18097,"str":64918,"sud":12096,"sui":13416,"sul":7775,"sup":9440,"sur":74845,"tai":73243,"tal":50318,"tag":11022,"tab":9930,"oût":9507,"tba":12570,"tat":51850,"tar":13094,"tan":65935,"tam":9043,"tch":9033,"te ":229351,"ta ":14870,"pe ":50543,"par":234438,"pat":9116,"pas":16097,"pay":9300,"pag":21493,"pal":18293,"pan":7834,"phe":9797,"pha":8008,"pho":13907,"phi":21732,"peu":15687,"pen":18365,"per":42656,"pet":8398,"pes":12928,"pel":20669,"pla":26028,"pli":9068,"ple":16401,"plo":8634,"plu":41224,"lé ":12711,"phy":6923,"pio":10675,"pir":7633,"pit":8267,"por":43095,"pop":8694,"pou":69236,"pos":40507,"poi":8423,"pon":18257,"pol":30878,"ps ":10703,"ppo":8721,"ppa":15829,"ppe":26475,"lév":6751,"lég":7457,"lée":13954,"pub":20867,"pte":18796,"pti":14976,"pri":39208,"pre":41906,"pro":84520,"pui":23064,"pul":10006,"prè":17131,"pré":40058,"mé ":9595,"mêm":9754,"mée":9397,"méd":12609,"mét":11009,"mér":37720,"qu ":18907,"qua":24258,"que":267169,"qui":99689,"qué":9551,"ra ":22507,"ngl":20995,"ngu":17741,"ni ":11818,"nge":18618,"nga":7486,"ndé":17148,"nel":18137,"nen":6872,"nem":17361,"ner":14652,"net":8307,"nes":51020,"neu":14088,"ng ":26468,"nfo":8493,"nct":9124,"nco":15938,"nci":43333,"nce":105515,"nch":14886,"ne ":496030,"ndu":10752,"ndr":20713,"ndo":10176,"ndi":34156,"nde":56096,"nda":37414,"nal":54750,"nan":26247,"nar":12696,"nad":12377,"nag":10703,"nai":30209,"nd ":51106,"nau":12991,"nat":48959,"na ":18193,"nté":16371,"ny ":7135,"nvi":18890,"nve":7658,"nue":12712,"nto":18893,"nts":41197,"ntr":72123,"nti":46425,"nta":41915,"nte":98733,"nsu":6773,"nso":9167,"nst":29806,"nse":30814,"nsi":22894,"nsc":6653,"nu ":15262,"nné":23464,"nre":13930,"nt ":427954,"nqu":6929,"ns ":274209,"nol":9967,"noi":11530,"nom":60135,"non":15485,"not":12329,"nor":18442,"nov":11258,"nou":9106,"nne":96393,"nna":28812,"nni":16118,"nnu":18917,"no ":11795,"nif":7747,"nie":43637,"nic":15379,"niv":18250,"nis":60898,"nit":15799,"niq":25898,"nio":9717,"nim":8520,"nin":8256,"ogr":17742,"ogi":23895,"ogn":7673,"oi ":11549,"ois":67090,"oir":45748,"oit":23632,"oin":16797,"ol ":10751,"och":11107,"oci":26047,"ock":12402,"oca":13060,"occ":8851,"ode":18688,"oct":13097,"of ":10906,"odu":17793,"off":9016,"ofe":9519,"obr":10777,"obi":7081,"oye":7463,"oya":11498,"osé":9652,"oue":24956,"ouc":7361,"oti":7550,"ote":10769,"oto":12004,"opé":11013,"ost":16493,"ota":13987,"otb":12106,"osi":13992,"ose":15543,"oss":13431,"ovi":29641,"ouv":52919,"ove":15893,"oug":6908,"oui":10077,"oul":19390,"oup":35466,"ous":44108,"our":142367,"out":30934,"opo":10738,"opp":14092,"ope":8783,"oph":15160,"os ":20357,"opu":8920,"or ":16010,"oot":13483,"ork":6806,"orm":40453,"orn":11249,"orr":9505,"orc":7615,"ord":43495,"ore":17630,"org":20050,"ori":52286,"ou ":81997,"ort":98537,"ors":17665,"omé":6755,"ot ":11871,"ora":19855,"ola":10628,"on ":413868,"oli":37368,"oll":18132,"ole":20481,"olo":39631,"olu":16814,"om ":32719,"ona":46449,"ond":64776,"onc":25758,"onf":7947,"one":18885,"ong":21441,"oni":23679,"onn":93395,"ono":18517,"ons":103783,"ont":114426,"ony":7110,"oma":27935,"ome":15382,"omb":20959,"omi":18767,"omm":120540,"omp":47351,"omo":9810,"omt":10618,"la ":409873,"le ":650000,"lab":8668,"lac":18171,"lag":11480,"lai":40035,"lan":67550,"lam":6667,"lar":10935,"lat":30778,"las":17285,"ld ":8004,"lbu":11677,"llé":6984,"ls ":27190,"lon":33452,"lom":9149,"lop":13744,"lor":20550,"loc":9951,"log":34746,"loi":10734,"los":7562,"lié":10397,"héo":7867,"lti":6832,"lub":8118,"lue":8111,"li ":8120,"leu":30125,"les":193810,"let":24641,"ler":15063,"lem":54863,"len":12174,"lec":18621,"lo ":9843,"lla":30932,"lle":228673,"lli":25721,"llo":13913,"lm ":12927,"ll ":25434,"lit":56867,"lis":75238,"liq":19529,"lio":7237,"lin":24717,"lim":6784,"liv":7668,"lic":17589,"lia":14317,"lib":8142,"lig":13313,"lie":66363,"lif":7647,"ma ":11524,"mb ":9981,"mai":41522,"mag":14210,"mar":34078,"mas":7661,"mal":10704,"man":59224,"mat":42658,"mba":7370,"mbl":12331,"mbr":52251,"mbo":7187,"me ":138747,"met":15733,"mes":29770,"mer":17959,"mem":10190,"men":192406,"lui":7872,"lut":8740,"lus":46191,"mpi":17291,"mpr":7983,"mpo":28665,"mpl":18530,"mps":7384,"mpt":6961,"ms ":7519,"moi":10596,"mod":8999,"mon":39570,"mor":34638,"mot":9918,"mou":10824,"mpa":13773,"mmé":6819,"mus":17057,"mul":7053,"mun":72605,"mi ":7506,"min":39720,"mil":42847,"mis":18157,"miq":9951,"mit":10387,"mie":22944,"ièr":39842,"ièm":14714,"ié ":12315,"mmu":65417,"iét":13514,"miè":11922,"mma":8876,"mme":60859,"yst":10800,"ys ":16246,"yen":7179,"yan":8923,"ué ":23787,"uéb":10376,"uée":52636,"tér":21675,"tés":15841,"tél":10092,"tée":11073,"tèr":7376,"tèm":7268,"té ":120644,"sée":25892,"sér":11984,"sé ":33254,"réé":15299,"vri":19364,"vre":15576,"vra":7557,"vir":10748,"vil":38576,"vin":28833,"vic":9378,"vid":11495,"vie":25896,"vit":11987,"vis":24817,"ré ":18385,"rès":23870,"réc":11353,"rée":15149,"réf":7765,"réa":27396,"rén":7293,"rég":60534,"rét":7637,"rés":42404,"rép":7979,"voi":21769,"vol":18467,"ver":63394,"ves":12081,"ven":32893,"vem":17149,"vel":23577,"vea":6695,"vec":28438,"ve ":39545,"val":17132,"van":23469,"var":6981,"vai":21124,"uté":12504,"ux ":89405,"uve":48851,"uvr":11649,"usi":30125,"use":23041,"ust":23088,"uss":29122,"uti":33117,"ute":37011,"uto":14655,"utr":16881,"us ":97767,"ut ":58626,"ura":21007,"ure":61643,"urg":15629,"uri":18044,"urn":17785,"uro":15520,"urs":51288,"urt":11255,"ur ":263487,"upe":34564,"uma":8198,"umb":11805,"ume":16466,"uni":34130,"una":10830,"une":273015,"um ":21626,"ult":20316,"uli":14760,"ule":23978,"ula":21824,"un ":279711,"uil":20013,"uin":15450,"uip":9137,"uis":42982,"uit":34639,"ul ":11106,"ui ":87556,"uct":19646,"ude":13798,"udi":11213,"ue ":252733,"uch":11064,"ueu":15091,"uer":16125,"ues":65033,"uen":9815,"uel":31495,"ub ":7072,"uat":10437,"uar":8894,"uan":14849,"ubl":25725,"ud ":22607,"tué":65263,"typ":6932,"ty ":7203,"tré":9963,"tur":39432,"tut":8273,"tud":13647,"tue":18585,"ts ":96064,"tre":117480,"tra":79361,"tri":46224,"tru":15862,"tro":41105,"tta":10904,"tte":35818,"ttr":6953,"pée":8023,"péc":10887,"to ":12714,"pér":17722,"tiè":7263,"toi":21756,"tob":11135,"tou":31577,"tom":9528,"ton":34164,"tor":25952,"til":20545,"tif":22436,"tie":47885,"tir":8477,"tiq":62118,"tit":40283,"tis":20099,"tin":33045,"tim":9651,"tio":235114,"thu":11875,"tia":8957,"tic":25452,"tiv":30333,"thé":16932,"pèc":18042,"tem":70682,"ten":37907,"tel":13125,"tec":11914,"th ":10711,"teu":75009,"tes":56728,"ter":82954,"ti ":26511,"tho":14369,"the":16191,"Éta":23397,"ège":6746,"èce":21913,"ère":67047,"ète":9916,"ène":11368,"ème":27688,"ès ":31596,"édé":24476,"éga":13682,"égi":62907,"écé":13741,"édi":27690,"éce":13512,"éci":16144,"ée ":173192,"écu":7487,"écr":22748,"éco":23770,"éfi":6764,"ées":42716,"éen":8156,"ébe":6903,"éal":20524,"éve":11864,"évi":9923,"éré":8391,"évo":13471,"évr":9038,"éta":51936,"éti":16412,"éte":7748,"étr":10893,"étu":6864,"été":39872,"éme":8284,"émi":12731,"émo":10213,"éna":8958,"éni":9260,"éli":8934,"éle":12690,"éma":11177,"éo ":6991,"équ":14445,"éra":46783,"ére":13799,"éri":83768,"éro":16442,"éné":26266,"ése":23781,"ési":28918,"épa":51263,"épu":10400,"épo":7454,"élé":15180,"és ":45990,"ême":12159,"êtr":10139,"çai":86644,"ût ":9033,"ôte":8179,"île":9715,"éé ":7606},"n_words":[66338594,78580813,56850284],"name":"fr"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/guj b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/guj new file mode 100644 index 000000000..5ab783f82 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/guj @@ -0,0 +1 @@ +{"freq":{"ૈદિ":382,"g":235,"d":312,"e":960,"c":304,"a":1076,"n":720,"o":584,"l":382,"m":289,"h":369,"i":764,"u":324,"t":728,"s":517,"r":627,"ોટ ":345,"ેસા":764,"ોલ ":730,"ોર ":574,"ોદ ":1827,"ેત્":227,"ેતી":2222,"ેતમ":2186,"ેતપ":357,"ેડબ":253,"ેડા":1366,"ેડી":300,"ેગા":229,"ેગો":375,"ેઘર":242,"ૈકી":6300,"ેશમ":527,"ેશન":12436,"ેવી":831,"ેવા":710,"ઇડર":265,"ેરા":387,"ેરી":718,"આહવ":288,"ેલા":24917,"ેલી":519,"ેલુ":9935,"ેલો":381,"ોઇ ":458,"ેન્":278,"ેપુ":457,"આવે":34862,"ા":337683,"િ":47127,"સ":31472,"હ":20294,"શ":32541,"ષ":5409,"વ":91695,"લ":111041,"ળ":3931,"ર":102867,"ય":39143,"મ":113670,"ભ":35403,"બ":10569,"ફ":1198,"પ":49237,"ન":84304,"ધ":9131,"દ":38743,"થ":6321,"ત":89107,"ણ":9770,"ઢ":1233,"ડ":18443,"ઠ":3507,"જ":54268,"ઝ":1439,"ટ":6287,"ઘ":2525,"ચ":20557,"છ":25106,"ક":72592,"ખ":14557,"ગ":61691,"ઓ":8101,"એ":23599,"ઉ":5095,"ઈ":409,"અ":6168,"ઇ":1975,"આ":43598,"ં":82987,"૫":1391,"૪":875,"૩":2115,"૨":1146,"૯":1054,"૮":946,"૭":1034,"૬":461,"૧":5611,"૦":1269,"ૈ":7159,"ો":34921,"્":89060,"ૌ":562,"ુ":82336,"ી":42473,"ૃ":539,"ૂ":4236,"ે":108368,"આણં":435,"આદિ":1564,"ેશ ":483,"અને":1581,"અન્":344,"e ":271,"અમદ":630,"ેમ ":2812,"ેર ":1681,"ેલ ":1022," ૧":4255," ૩":409," ૨":679," ૫":978," ૪":492," ૭":700," ૯":551," ૮":625,"અગિ":1051," વ":14987," શ":3197," ર":16267," લ":5654," સ":11956," હ":3244," થ":1672," ત":31864," ધ":1718," દ":21808," ડ":1738," ઠ":222," ભ":34182," બ":4095," ય":383," મ":24848," ન":6795," ફ":765," પ":35455," છ":24245," ચ":2656," ઘ":628," ટ":479," ઝ":829," જ":21642," ઓ":682," ગ":30845," ખ":8068," ક":14981," ઉ":4757," એ":23366," આ":43205," ઇ":661," અ":6143,"આંગ":703,"્ચિ":11645,"્ટ્":549,"ોતર":377,"ોદર":1858,"ોનગ":236,"ોટા":473,"ોટી":225,"ોડા":794,"આઠ ":685,"ોની":800,"ોનો":2167,"ોરી":514,"ોળી":244,"ોલી":442,"ંવત":748,"ંબા":470,"ંબુ":281,"ંમત":254,"ંઠા":1406,"ંડવ":256,"ંદુ":455,"્ધ ":712,"ંદો":312,"ંધી":504,"ંતર":406,"ંચા":1418,"ંચમ":1337,"ંગા":221,"્ર ":966,"ોકો":3591,"્ય ":7092,"ંગણ":713,"ંખે":303,"ંગર":288,"્ષ ":789,"્વ ":2508,"એવા":6093,"્ષન":1137,"્ષિ":1509,"્વા":430,"્વે":772,"્વન":6820,"્વર":251,"્યન":12109,"્યત":720,"્યમ":432,"્યપ":428,"્યવ":2272,"્યા":2476,"્યુ":248,"્મદ":563,"્મા":375,"્લો":1068,"્લા":13052,"્રો":432,"્રે":602,"્રમ":649,"્રદ":871,"્રા":2175,"્રિ":476,"્રી":593,"્રહ":375,"્દ્":258,"્થા":288,"્તા":298,"્તી":856,"્તર":2535,"એક ":15869,"ઉદે":246,"ઉપલ":606,"ઉપર":392,"ઉત્":2557,"ઉમર":329,"િત":853,"િણ":1494,"વિજ":359,"ીં":343,"િમ":11976,"િપ":550,"િન":1570,"વાય":500,"િવ":4622,"વાર":525,"િશ":322,"ીક":534,"વામ":999,"િલ":14752,"ીઓ":697,"િય":2671,"િર":803,"વાસ":1799,"ીજ":386,"િહ":232,"વિક":492,"િસ":578,"વાલ":357,"ીત":406,"ીદ":281,"ું":22062,"વાદ":862,"વાન":404,"ીય":2619,"ીમ":860,"ીન":8731,"વાડ":2612,"ીપ":459,"ુક":18441,"ીવ":394,"ુખ":4304,"ીર":426,"ીલ":229,"વાગ":247,"વાઘ":254,"ીસ":510,"ુચ":222,"ુજ":13015,"ાં":48849,"ાઉ":298,"ાઇ":474,"ાક":921,"ાઓ":6449,"ાઘ":283,"ાખ":279,"ાગ":19994,"ાજ":13842,"ાચ":245,"ાટ":1064,"ાડ":4936,"િં":1255,"ાણ":2500,"ાથ":1359,"ાત":14028,"ાદ":2250,"ાન":14000,"ાપ":2091,"ાબ":1765,"ામ":34603,"ાય":4603,"ાર":20818,"ાલ":24953,"ાળ":1774,"વિર":286,"િક":2870,"ાવ":3657,"ાષ":849,"ાસ":4564,"ાહ":1263,"િજ":517,"વિસ":266,"હત":7478,"સી":2165,"સુ":1962,"સે":1528,"સા":8757,"સિ":770,"હવ":567,"સો":764,"હર":240,"સ્":3025,"સૌ":277,"હુ":529,"સા ":522,"હે":3680,"હા":2824,"હિ":2043,"હી":349,"હો":1278,"હ્":385,"શ્":12458,"ષન":1142,"સગ":988,"સર ":276,"શહ":485,"શિ":374,"શા":1696,"શુ":2253,"શી":262,"સં":2001,"ષ્":864,"સમ":828,"સન":417,"સવ":569,"સર":997,"ષા":458,"સદ":328,"સત":251,"સણ":439,"ષિ":1579,"વદ":549,"વન":7118,"વર":2659,"વલ":1055,"શક":498,"વગ":256,"વસા":2722,"વડ":3280,"વત":1294,"વણ":314,"વે":36512,"શન":12531,"વૈ":520,"શમ":627,"વ્":2839,"વસ":7405,"વી":2081,"વિ":2302,"વા":17902,"લો":6663,"લ્":14395,"લે":641,"લા":40018,"લિ":942,"લી":2736,"લુ":28591,"લસ":736,"લવ":315,"વસ્":826,"વસે":1125,"ળી":539,"વં":274,"ળા":1514,"રો":1975,"ર્":7275,"રુ":979,"રી":7304,"રૂ":908,"રે":1966,"રસ":718,"વાં":660,"રહ":1839,"રા":36128,"રિ":1193,"રવ":1135,"લબ":632,"લપ":735,"લય":580,"લન":2427,"લક":304,"લગ":215,"રક":1797,"રગ":229,"રખ":218,"યવ":2310,"રજ":562,"યા":7096,"રડ":414,"યુ":510,"રણ":534,"રત":14232,"રથ":239,"રદ":1032,"શમા":566,"યે":847,"રન":646,"રપ":682,"યો":569,"રબ":221,"રમ":2425,"મર":703,"મમ":2823,"મલ":319,"મહ":10705,"રં":397,"મી":561,"યડ":242,"મુ":6197,"મા":44661,"મિ":1415,"યત":1490,"યપ":480,"યન":12830,"મે":837,"યમ":548,"મ્":803,"મો":2623,"બ્":1122,"ભર":899,"મજ":2296,"મગ":222,"મખ":281,"મણ":336,"મત":581,"મથ":816,"ભા":32622,"ભિ":388,"મપ":589,"ભો":320,"મદ":1417,"મધ":3415,"મન":2890,"બર":1834,"બહ":293,"મં":287,"બી":424,"બુ":465,"બા":2768,"બિ":244,"બો":581,"બે":417,"પો":705,"પ્":4053,"બન":257,"પલ":826,"પહ":227,"પશ":13852,"પર":1594,"પૂ":2675,"પૈ":6312,"પે":306,"પુ":5227,"પી":742,"પિ":245,"પા":6287,"ન્":1623,"નો":5861,"પણ":494,"પત":282,"પટ":291,"પડ":321,"પછ":431,"નવ":1459,"નર":658,"ધ્":3586,"ધો":283,"નપ":579,"નન":237,"ને":4269,"નુ":10812,"પં":2789,"ની":3990,"નિ":691,"ના":45180,"નસ":606,"ધા":1073,"ધુ":315,"ધી":641,"દે":14545,"ધન":837,"દ્":1191,"દો":459,"ધર":916,"સી ":1244,"નગ":2570,"દશ":215,"દસ":731,"દહ":218,"દા":3639,"દિ":5058,"દી":575,"દુ":1289,"દર":3345,"થવ":580,"વેલ":34942,"શના":12337,"થી":1041,"થા":882,"તો":531,"વૈદ":382,"તે":6014,"દક":1517,"થય":782,"ત્":12219,"થમ":1093,"થક":777,"તી":4432,"તુ":553,"તા":26724,"તિ":1123,"તન":712,"ણે":327,"તપ":511,"તર":3967,"તલ":356,"તમ":2718,"ણા":2366,"ણી":846,"ણવ":795,"તઘ":640,"ડો":2767,"ડુ":286,"ડે":1027,"ણં":571,"ડી":3535,"ડિ":410,"ડા":5615,"ડવ":598,"ડર":315,"ડભ":218,"ડબ":277,"ઠા":1831,"ટ્":673,"ટે":774,"વ્ય":2778,"ટિ":249,"સે ":1144,"ટી":761,"છે":23574,"જન":365,"છી":486,"ઝઘ":245,"જય":244,"છો":305,"જબ":1127,"જર":11973,"જે":2020,"જો":465,"જિ":13950,"જા":1399,"જુ":2555,"જી":794,"જ્":13119,"ઝર":271,"શુપ":2187,"ઝા":567,"સંવ":756,"ટક":225,"સંત":320,"સંખ":325,"ટા":840,"ટલ":348,"ગા":17980,"ગુ":12125,"ગિ":1160,"ઘડ":264,"ગી":427,"૯ ":627,"ગ્":891,"ગો":1143,"ઘર":948,"ઘો":548,"ચર":560,"ચમ":1383,"ચા":2321,"ચિ":12038,"ચી":259,"જં":215,"ચો":437,"ચ્":251,"જક":251,"શહે":470,"૫ ":1091,"કર":2446,"કમ":270,"કલ":513,"કપ":478,"ખં":251,"કડ":644,"ખલ":227,"ક્":3347,"કો":5466,"કે":1500,"૭ ":792,"કુ":6686,"કૃ":229,"કા":21625,"કી":6922,"કિ":350,"કહ":564,"કવ":583,"ગવ":1115,"ગલ":272,"ગર":2876,"ગમ":18397,"ખ્":4351,"૮ ":673,"ખે":6309,"ગન":575,"ગણ":1117,"ગઢ":779,"ખા":2071,"૧ ":1168,"શાળ":1055,"શાસ":252,"એવ":6158,"૨ ":320,"૩ ":1541,"૪ ":593,"ઓન":283,"એક":16184,"૦ ":810,"ઉદ":317,"ઉત":2595,"ઉપ":1216,"સગવ":904,"ઉમ":378,"આં":1102,"અગ":1187,"અં":436,"ઇડ":287,"ષના":751,"આહ":296,"ષનો":362,"આવ":35199,"આદ":1695,"આઠ":804,"આણ":440,"અમ":826,"અર":256,"અન":2071,"ંવ":912,"ંસ":486,"ંત":1429,"ંથ":310,"ંદ":2195,"ંધ":939,"ંબ":1038,"ંભ":281,"ંમ":287,"ંક":540,"શ્ચ":11655,"ંગ":2855,"ંખ":377,"ંચ":4016,"ંજ":464,"ંટ":564,"ંડ":982,"ંઠ":1433,"હે ":1152,"શ્ર":320,"શ્વ":348,"૧૩":1467,"૧૧":1091,"૧૯":283,"૧૦":694,"વડો":2345,"ોટ":1277,"ોડ":1517,"ોજ":373,"વલી":267,"ોન":3584,"ોધ":322,"ોત":616,"ોદ":3809,"ોગ":284,"ોક":3826,"ોઇ":523,"્ટ":1147,"્ત":4385,"્ણ":325,"્દ":602,"્થ":651,"્ધ":1001,"્પ":336,"્બ":262,"વર્":2136,"્ક":609,"્ગ":267,"્ચ":11827,"ોમ":362,"ોલ":1612,"ોય":246,"ોર":2045,"ોવ":257,"વલસ":582,"ોળ":645,"્સ":302,"્ષ":3855,"્વ":11263,"્લ":14321,"્ર":8621,"્ય":26212,"્મ":1641,"ૂર":2771,"ુદ":699,"ુધ":815,"ુન":510,"ુણ":524,"ુત":213,"ુમ":369,"ુર":8763,"ુપ":2377,"ુવ":804,"ુસ":354,"ુલ":6351,"ૂચ":717,"વનો":376,"વનુ":6376,"ૃત":300,"ેક":249,"ેત":5179,"ેડ":2071,"ેટ":618,"ેઠ":219,"ેજ":326,"ેગ":653,"ેઘ":271,"ષા ":222,"વતા":228,"ેર":3345,"ેલ":37195,"ૈક":6315,"ેશ":13804,"ેવ":2024,"ેન":1094,"ેપ":540,"ેમ":3602,"ૈદ":389,"ેસ":990,"હિં":776,"હાલ":1485,"હાર":571,"હિન":919,"ઇ ":1018,"આ ":2702,"ાં ":41350,"ઓ ":7041,"હેર":525,"હેલ":239,"હેવ":536,"હેસ":730,"એ ":663,"ાઇ ":270,"હોદ":867,"હ્મ":326,"ાઓ ":6349,"ં ":62940,"ાગ ":214,"ાડ ":990,"ાદ ":1109,"ાણ ":231,"ાત ":12086,"ાન ":979,"ામ ":12051,"ાલ ":1653,"ાર ":2510,"ાય ":3046,"ાવ ":357,"િક ":1785,"ાસ ":1162,"ષિણ":1462,"ે ":34827,"ો ":11870,"સણા":264,"ષ ":917,"સ ":4627,"સમો":292,"વ ":3614,"શ ":598,"સરા":281,"ષ્ટ":602,"િ ":698,"ુ ":1292,"ી ":24520,"ા ":103799,"સવા":466,"સુર":1060,"દ ":4991,"થ ":242,"સીઓ":544,"ન ":4557,"સુદ":463,"ધ ":850,"સાડ":665,"સાત":801,"સાણ":973,"સાગ":213,"પ ":563,"સાય":2235,"સામ":236,"સાર":662,"સાવ":281,"સાબ":1406,"બ ":1292,"મ ":27791,"સોન":293,"ર ":16908,"ય ":11483,"લ ":10111,"હતા":268,"હત્":6808,"ળ ":723,"ક ":19636,"ગ ":1433,"સ્વ":268,"સ્થ":430,"ચ ":2010,"સ્ટ":235,"સ્ત":1316,"સ્ક":359,"જ ":4325,"ટ ":1263,"ડ ":2185,"ઠ ":958,"ઢ ":645,"હવે":238,"ણ ":3405,"હવા":327,"ત ":27700,"ૂચ ":710,"િત્":251,"ાસા":294,"ાસિ":270,"ાસી":1732,"ાહો":869,"ાષા":325,"ાસણ":337,"ુલ ":6018,"ાસર":237,"ાષ્":514,"ાલન":2232,"ાલપ":364,"ાલય":562,"ંગ ":904,"ારે":564,"ાર્":428,"ારો":350,"ારી":908,"ારા":1301,"ારત":13028,"ારમ":342,"ારડ":261,"ાયત":689,"ાયડ":229,"ામા":16128,"ુર ":3220,"ાવી":500,"ાવા":1445,"ાવલ":274,"િકે":222,"િક્":471,"ંચ ":1075,"ાવત":219,"ાળા":1219,"ાલો":667,"ાલુ":18139,"ાલી":427,"ાલિ":223,"ાલા":242,"ાનો":1081,"ંટ ":317,"ાનપ":429,"ાના":6337,"ાનુ":3493,"ાની":787,"ંજ ":235,"ાદર":601,"ામપ":347,"ંત ":433,"ામન":2336,"ામમ":2770,"ાબર":1409,"ાપ્":387,"ુદ ":457,"ાપી":523,"ાપુ":503,"ાપા":321,"ંદ ":612,"ીદા":229,"ીનગ":468,"ીના":6429,"ીને":1070,"ીની":270,"ીનો":264,"િસ્":315,"િલ્":13910,"િલો":366,"િવસ":2730,"િવા":1650,"િનો":226,"િના":989,"િયા":2403,"ાંટ":436,"ાંઠ":1422,"ાંડ":461,"ાંગ":1094,"ાંચ":1295,"ાંત":590,"ાંધ":547,"ાંદ":419,"ાંસ":263,"ીઓ ":502,"િમ ":11653,"િપ ":367,"િત ":360,"િણ ":1447,"ાણા":1231,"ાણી":404,"ાતી":550,"ાત્":264,"ાથમ":992,"ાતે":354,"ાટી":295,"ાટે":280,"િંમ":251,"િંદ":527,"ાડી":1596,"ાડા":2060,"ાજક":237,"ાજી":257,"ાજ્":12491,"ીય ":442,"ાકી":371,"ાગમ":18270,"ાગન":475,"ાઉદ":238,"ું ":21442,"ૂર્":2560,"ેટ ":236,"ુણા":437,"ુજબ":1107,"ુજર":11840,"ુપા":2208,"ુધન":587,"ીયન":389,"ીમા":379,"ીયા":1731,"ીમખ":262,"ીસમ":292,"ુકા":17641,"ુકો":529,"ુખ્":4233,"ુરી":2300,"ુરુ":440,"ુરા":1358,"ુરત":829,"ુવા":696,"તઘર":640,"ણવા":740,"દસ ":512,"ણાવ":406,"દા ":938,"તપુ":465,"તનગ":252,"દી ":294,"તના":216,"દુ ":479,"તમજ":2184,"તમા":321,"તરી":269,"તરા":350,"તો ":423,"થા ":316,"થી ":996,"નવ ":475,"થવા":574,"ના ":41544,"ને ":3899,"ની ":3744,"નો ":5537,"દરા":2352,"દરમ":423,"તું":277,"તાલ":18057,"તાર":306,"તાપ":566,"તાન":302,"ધા ":271,"તેમ":3056,"તેર":1418,"તેન":315,"દક્":1484,"ત્ત":2727,"થમિ":987,"ત્વ":7552,"ત્ય":281,"ત્ર":1452,"થયે":642,"નપુ":541,"પી ":564,"ધીન":468,"ધાર":249,"ધાન":290,"નવસ":483,"નસવ":370,"ધ્ય":3481,"નર્":560,"દુધ":605,"દેપ":250,"દેશ":13431,"દેવ":535,"ધની":595,"દાવ":797,"દિક":394,"દાર":330,"દાદ":262,"દિવ":4303,"દાહ":863,"નગર":2214,"નગઢ":247,"પર ":286,"પણ ":420,"દોદ":293,"દ્વ":331,"દ્ર":524,"ધરા":484,"બા ":381,"પટે":233,"પાવ":384,"પાર":273,"પાલ":2355,"પાટ":403,"પાડ":735,"પાં":1274,"પશ્":11653,"પશુ":2197,"પલબ":596,"પરા":655,"પંચ":2575,"નું":10559,"નાં":923,"નાર":240,"નામ":306,"નાન":1138,"પછી":428,"ન્ય":559,"ન્દ":395,"બહુ":235,"બાક":373,"બાર":800,"બાય":217,"રજ ":269,"મા ":715,"મી ":253,"યડ ":217,"યન ":455,"બરક":1386,"મો ":1343,"પૂર":2616,"પુર":4959,"પૈક":6303," આ ":2656,"પોર":340," એ ":485,"પ્ર":3459,"પ્ય":389,"માં":41157,"માટ":294,"માન":402,"માણ":276,"માત":359,"માલ":325,"માર":263,"મિક":1063,"મહત":6802,"મહા":1848,"મહિ":850,"મહુ":233,"મહે":917,"યત્":701,"મેઘ":271,"મુખ":4261,"મુજ":1125,"મુવ":353,"યતઘ":640,"મપુ":552,"રે ":767,"મમા":2808,"મધ્":3365,"મદા":1324,"રી ":4562,"મના":2419,"રો ":232,"મજુ":2185,"મખે":264,"રા ":5544,"મતન":247,"મથક":765,"ભિલ":318,"ભાર":12956,"ભાગ":18607,"ભાષ":335,"બોર":287,"રત ":13401,"યા ":2563,"રમ ":485,"યો ":254,"ભરૂ":710,"બ્ર":421,"બ્ધ":597,"ળા ":1138,"રેગ":384,"ળી ":385,"રોત":365,"રાં":597,"રાય":238,"રામ":591,"રાવ":421,"રિક":325,"રાષ":510,"રાડ":230,"રાણ":287,"રાત":11870,"રાથ":991,"રાપ":541,"રાજ":13365,"રીય":783,"રીન":986,"રું":396,"રીક":260,"રિય":414,"રૂચ":710,"રવા":911,"રહવ":219,"રહે":1153,"રહ્":327,"રપુ":361,"રમ્":382,"રમા":804,"લો ":1417,"લા ":25318,"રના":235,"યેલ":764,"લી ":1812,"રદે":816,"રડી":227,"યાલ":588,"યાર":1934,"યાન":576,"યાપ":305,"રકા":1582,"લય ":553,"યવસ":2216,"યપૂ":410,"મોડ":217,"મોટ":454,"યનો":326,"યના":11717,"મ્ય":415,"યમા":407,"લન ":2219,"મ્બ":232,"લ્લ":14131,"વે ":1140,"લોલ":465,"લોડ":396,"લોદ":449,"લોક":3642,"વા ":7780,"વી ":1602,"લુક":18002,"લીમ":321,"લુણ":389,"લિય":312,"લું":9913,"વસ ":2535,"લાન":6932,"લિપ":369,"લાસ":286,"લાવ":223,"લાલ":307,"લામ":5764,"લસા":677,"શક ":371,"વર ":236,"લબ્":597,"વદ ":505,"લપુ":412,"વત ":759,"વડ ":417,"ર્ષ":1963,"ર્વ":2626,"ર્ય":411,"ર્મ":900,"કી ":503,"કા ":605,"કે ":834,"કો ":1354," ૧૦":680,"૧૦ ":535,"૧૧ ":1036,"૧૩ ":1412,"ગઢ ":538," ૧૩":1456," ૧૧":1079," ૧૯":274,"ગર ":1959,"કડી":283,"કડા":244,"કરવ":314,"કરી":1162,"કવા":445," હો":303," હિ":944," હા":540," સો":475," સૌ":273," સ્":714," સિ":322," સા":3562," સુ":1717," હત":654," સમ":395," સર":370," સત":226,"કાલ":238,"કામ":9196,"કાર":676,"કીન":6304,"કુલ":6004," લુ":420," લી":386," લિ":414," લા":253,"કહે":527," લો":3728,"કાં":1539," રહ":1203," રા":13805,"કાન":2517,"કાઓ":6055," સં":1919," શા":1268," શિ":264," શહ":475," સગ":922,"ઘર ":662," શ્":290," વા":1551," વિ":1924," વસ":1926," વ્":2581," વૈ":515," વે":236," વડ":2142," વર":2148," શક":474," વલ":624," વદ":498," પછ":431," પટ":261," પણ":391," નો":313," પા":2926," પુ":759," પૂ":2113," પૈ":6312," પર":651," પશ":13847," પહ":226," ધા":386," દ્":305," દે":13156," નગ":894," ધર":567," ના":1491," નિ":408," નસ":380," ને":386," પં":2780," ધો":248," નવ":1299," નર":628," મધ":3389," ભિ":335," ભા":32144," મથ":749," ભર":862," મે":521," મો":1041," મા":2519," મુ":5993," મહ":9472," પ્":3289," પો":348," બો":476," બે":295," મં":217," બી":247," બા":1559," બહ":292," ડા":372,"કોન":2841," ડે":860,"કોળ":215,"કોટ":356,"ક્ષ":1887,"ક્ર":890," ત્":349," થય":778," દક":1478," તે":5306," થવ":379," દર":551," દુ":722," દિ":2858," દા":1294,"કેટ":221," દસ":704," તર":348," તિ":233," તા":24717," ૯ ":497," ગો":553," ગ્":552," ગુ":12029,"ખેડ":1595,"ખેત":4414," ગા":16841,"ગના":399," ૮ ":570," ખે":5659," ખા":1675," ગણ":237," ચર":392," ઘો":266," છો":266,"ગણવ":693," ઝઘ":243," છે":23548," ચો":383," જં":214," ચા":714," ચિ":300," ઝા":412," જ્":480," જુ":259," જા":631," જિ":13843," જો":332," જે":1921,"ખાસ":931," એવ":6158,"ખાન":217," એક":16184,"ખાત":404," ૫ ":907," ૪ ":431," કહ":562," કવ":319," કુ":6308," કા":1279," કો":831," ૭ ":640," કે":929," ક્":383," કડ":504," કપ":373," કલ":240," કર":2121," ઇડ":271," આહ":296," આવ":35196," આદ":1582," ઉત":2589," ઉપ":1212," ઉમ":372,"ગવડ":906,"ગરહ":219,"ગમા":18349,"ખ્ય":4323," અં":432," અગ":1187," આં":1036," અન":2069," અર":252," અમ":825," આઠ":804," આણ":440,"ગાં":635,"ગામ":16798,"ગિય":1057,"ગુજ":11824,"ઘડી":254,"ગોર":435,"ગોધ":222,"ગ્ર":743,"ઘરજ":242,"છી ":438,"ઘોડ":335," જ ":2898,"છે ":23415,"જબ ":1105,"ચરો":362,"ચાર":560,"ચાય":582,"ચિમ":11652,"ચાં":471,"ચાગ":369,"જી ":285,"જા ":331,"ચમહ":1210,"જે ":397,"જકો":214,"ઝઘડ":245,"જિલ":13824,"જુર":2204,"છોટ":245,"જરા":11822,"ઝાલ":270,"ઠા ":1548,"ટી ":375,"ટા ":336,"જેવ":714,"જેત":374,"જ્ય":12917,"ટે ":225,"ડી ":2334,"ડા ":4375,"ડર ":279,"ટેલ":254,"ટાઉ":239,"ડો ":637,"ણી ":405,"ણા ":1630,"ટ્ર":578,"ડેર":603,"ડેડ":232,"તી ":3871,"ડોદ":1844,"તે ":714,"ડિય":272,"ડાસ":222,"ણંદ":569,"ડીય":740,"તિ ":370,"તા ":7106,"તર ":2912,"થક ":760,"ડાં":355,"ડબ્":254,"ણે ":229},"n_words":[2118540,2468202,1874859],"name":"gu"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/heb b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/heb new file mode 100644 index 000000000..38a8c9d47 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/heb @@ -0,0 +1 @@ +{"freq":{"D":3214,"E":2525,"F":2735,"G":2624,"A":5600,"B":4044,"C":5446,"L":2999,"M":4837,"N":2358,"O":1895,"H":2508,"I":3050,"J":1816,"K":1288,"U":823,"T":4063,"W":1765,"V":1278,"P":3992,"S":6051,"R":3127,"f":3967,"g":6300,"d":10934,"e":38551,"b":4292,"c":11175,"a":34025,"n":25648,"o":25621,"l":18280,"m":9009,"k":3209,"h":10406,"i":28660,"w":2312,"v":3224,"u":12118,"t":20514,"s":19158,"r":26616,"p":7557,"z":1550,"y":5684,"x":3018," o":1293," d":1423,"р":1134," a":1241,"с":1017," c":818," t":1122," p":2507," s":1080," J":1761," K":1182," H":2237," I":2087," N":1804," O":1286," L":2498," M":4152," B":3287," C":4445," A":4293," F":2284," G":2345," D":2725," E":1939,"л":851,"к":858,"и":1731,"о":1736,"н":1202," S":4832," R":2670,"в":941," P":3269,"а":1783," W":1618," V":962,"е":1219," T":3332,"ז":63772,"ח":143673,"ה":590284,"ו":795043,"ג":118718,"ד":182547,"א":355837,"ב":395285,"מ":381378,"ן":91462,"ל":422282,"ם":165990,"ך":21160,"כ":123771,"ט":120550,"י":838057,"ץ":10248,"פ":163464,"ק":174715,"צ":88276,"ס":156906,"נ":265593,"ף":12208,"ע":168037,"ש":294877,"ר":442678,"ת":390314,"ְ":2319,"ִ":1697,"ֵ":751,"ֶ":1684,"ַ":1974,"ָ":1859,"ֹ":1678,"ּ":3241,"ي":1156,"ل":1891,"م":1083,"ن":836,"ب":960,"ا":2457,"ر":948,"A ":1146,"Co":1139,"Ch":747,"Ca":914," ט":10158," י":46710," כ":41422," ל":87440," מ":140680," א":111429," ב":199095," ג":26594," ד":18598," ה":315869,"Ma":1436," ו":76633," ז":14443," ח":27536," ת":26310," ש":120088," ר":28151," ק":30023," צ":12233," פ":33679," ע":48214," ס":29027," נ":37369,"Th":1329,"St":822,"Pa":795," ا":1195,"a ":5141,"i ":1770,"ge":1176,"he":2979,"ha":1572,"g ":1420,"ea":1448,"ec":949,"ed":1174,"de":2377,"di":1239,"do":869,"h ":1424,"el":2456,"ei":783,"en":3848,"em":940,"et":1553,"es":3076,"er":6931,"ca":1297,"e ":9963,"be":993,"da":916,"f ":1405,"ct":774,"co":1157,"ci":1010,"ch":2176,"ce":1369,"c ":854,"d ":3184,"at":3174,"as":1657,"ar":4336,"au":801,"al":3282,"ai":824,"am":1581,"an":5294,"ac":1575,"ad":954,"nt":2386,"ns":1298,"no":898,"nn":849,"of":1227,"oc":763,"om":1498,"on":5076,"ol":1724,"ot":992,"os":1322,"ou":1121,"op":789,"or":3356,"r ":4009,"pe":961,"ph":746,"lo":1342,"ll":2162,"o ":2412,"ma":1706,"me":1669,"mi":920,"mo":751,"na":1919,"nc":982,"nd":2342,"ne":2187,"ng":1840,"ni":1853,"m ":1750,"li":2362,"le":2918,"la":2312,"n ":6713,"hi":1088,"ho":885,"id":1119,"ic":2833,"ia":1960,"ig":907,"ie":1690,"k ":1105,"ir":937,"is":2730,"it":1899,"il":1849,"in":4459,"io":2236,"l ":3308,"y ":3108,"vi":786,"ve":1332,"x ":2437,"ul":958,"ur":1480,"us":2545,"um":935,"un":962,"tu":790,"tt":809,"to":1696,"tr":1218,"te":3049,"ti":3191,"th":2015,"ta":1915,"ss":1070,"st":2602,"so":786,"se":1404,"si":1360,"rs":966,"rt":1408,"ry":760,"ro":2308,"rn":818,"ri":3441,"re":2927,"rd":1160,"ra":3300,"t ":3529,"s ":8103,"px":1778,"一":845," Ma":1422," Ca":896," Co":1129," Pa":776," St":815," Th":1324," of":1007," de":821," px":1777,"זר":6935,"זק":1127,"חב":10029,"חז":2980,"חו":22900,"חה":3687,"חד":8305,"זי":12406,"זל":838,"זם":1284,"זכ":3534,"זנ":886,"זמ":4439,"זע":2250,"חר":11087,"חק":7976,"חת":6995,"חש":6932,"טב":2858,"טא":3408,"טו":20425,"טה":4110,"טח":2065,"חי":19519,"חל":11067,"חם":835,"חמ":5926,"חנ":2382,"חס":4114,"חצ":1267,"הת":16129,"הש":20373,"הר":18303,"הק":13593,"הצ":7002,"הפ":12266,"וה":16855,"וד":26125,"וג":17753,"וב":35986,"וא":44658,"וּ":1323,"הכ":8371,"וֹ":1575,"הט":3770,"הי":51622,"הז":2998,"הח":11926,"הה":6606,"הו":49027,"הע":15156,"הנ":11770,"הס":11464,"המ":50070,"הן":3379,"הל":10568,"הם":6285,"ות":101531,"וש":17323,"וצ":14838,"וץ":2534,"ור":67093,"וק":18906,"זו":10251,"זה":6566,"זא":1585,"וי":25913,"וך":3767,"וכ":13432,"ול":56167,"וו":21707,"וז":11389,"וח":11917,"וט":7960,"וס":26165,"וע":21211,"וף":4260,"ופ":26005,"ום":16031,"ומ":32989,"ון":31711,"ונ":45275,"גת":2080,"דב":1971,"דג":1438,"דא":1968,"גע":907,"גר":12191,"גש":1319,"גם":5839,"גל":15851,"גנ":4603,"גן":1862,"גמ":1889,"גו":18230,"גה":2711,"גד":7511,"גי":15377,"גז":1369,"הא":24412,"הב":13059,"הג":10416,"הד":6369,"דפ":866,"דצ":1312,"דק":1275,"דר":19078,"דש":2624,"דת":5288,"דל":3528,"דמ":4712,"דם":3790,"דנ":1611,"דן":1253,"דע":6022,"דס":1191,"דה":10078,"דד":1385,"דו":30532,"די":39839,"בא":28974,"את":18469,"אר":23727,"אש":17310,"אצ":2077,"אק":3488,"אפ":6737,"אף":1142,"אנ":19673,"אס":5720,"אן":3277,"אמ":12397,"אם":2757,"אל":31779,"אכ":1022,"אך":1814,"אי":39448,"אט":3314,"אח":13816,"אז":5466,"או":54111,"אה":8465,"אד":6606,"אג":2909,"אב":7150,"גא":2681,"גב":4647,"בש":16669,"בת":15296,"בצ":5367,"בק":6122,"בר":44457,"בס":9775,"בע":20054,"בפ":5660,"במ":24479,"בנ":12394,"בן":3469,"בי":60852,"בל":12579,"בכ":5400,"בז":1800,"בו":37124,"בט":3788,"בח":6845,"בג":4476,"בב":4468,"בה":14562,"בד":9533,"ממ":12115,"מן":5860,"מנ":16156,"מס":13321,"מע":13284,"מפ":8474,"מצ":11869,"מק":11494,"מר":20980,"מש":30914,"מת":18345,"נד":8678,"נג":16204,"נב":2857,"נא":5195,"נח":5856,"נז":1832,"נו":50382,"נה":26549,"נכ":2770,"ני":73546,"נט":9488,"נן":997,"נמ":4014,"נם":1134,"נל":2549,"לנ":7233,"לס":4718,"לע":5121,"לל":8431,"לם":5118,"למ":14400,"לן":1558,"לר":5001,"לש":7046,"לת":11787,"לפ":7565,"לצ":2285,"לק":11094,"מו":54355,"מה":19324,"מד":15338,"מג":4215,"מב":11717,"מא":19955,"מל":12739,"מכ":7596,"מי":43286,"מט":8749,"מח":12385,"מז":4310,"כד":4207,"כה":6173,"כו":21072,"כז":3111,"כח":1672,"כי":15596,"כך":1583,"כא":3499,"כב":6283,"כג":1009,"כפ":2033,"כת":9752,"כש":2355,"כר":5552,"כמ":4368,"כם":777,"כל":14948,"ככ":754,"כס":2535,"כנ":8682,"כן":3171,"לז":1198,"לח":8146,"לה":26418,"לו":38179,"לך":2679,"לכ":7962,"לט":7328,"לי":67951,"לג":4986,"לד":10370,"לא":20135,"לב":10370,"טק":1116,"טס":846,"טנ":3561,"טע":1653,"טל":6264,"טן":1424,"טמ":2400,"טי":27400,"טכ":861,"יו":59458,"יז":7368,"יח":8678,"יט":18165,"יב":19301,"יג":6611,"יד":26912,"יה":49212,"יא":28186,"טר":15887,"טת":2335,"יר":32678,"יק":28848,"יצ":10768,"יץ":1467,"יפ":9697,"יף":1039,"יע":8301,"יס":16568,"ינ":36790,"ין":20736,"ימ":19188,"ים":101424,"יל":28185,"יכ":8588,"יך":2854,"יי":52949,"יש":24046,"ית":80424,"צמ":5084,"צע":4237,"צפ":3530,"צח":1679,"צי":17340,"צט":759,"צל":2956,"צא":6953,"צב":5471,"צג":1091,"צד":1322,"צה":5120,"צו":14859,"פצ":904,"פק":4972,"פת":9249,"פר":34424,"פש":3647,"רץ":4177,"רפ":7179,"רק":7125,"רצ":5822,"רס":9590,"רנ":6801,"רע":2837,"רם":1942,"רל":4398,"רן":1612,"רמ":9087,"רי":69906,"רט":11059,"רכ":12424,"רך":5453,"רה":18046,"רו":57537,"רז":1504,"רח":8185,"רא":29022,"רב":18351,"רג":11231,"רד":8475,"קר":20408,"קש":3566,"קת":4771,"קצ":3292,"קפ":1285,"קע":1184,"קס":4328,"קנ":4930,"קן":2101,"קמ":2688,"קם":1371,"קל":7255,"קי":22013,"קט":8069,"קו":31546,"קד":4923,"קה":11443,"קב":8684,"קא":6360,"צת":2627,"צר":9786,"עד":7161,"עה":5494,"עו":21588,"עז":1654,"עט":1111,"עי":23608,"על":30126,"עם":5137,"עמ":4465,"ענ":3092,"עס":1118,"סע":1202,"סס":1542,"ספ":16242,"סף":1568,"סר":7306,"סק":6961,"סת":3711,"עב":7995,"סד":6581,"סה":2338,"סב":2454,"סג":2607,"סח":1327,"סט":14456,"סו":21766,"סכ":1718,"סל":4205,"סי":26035,"סנ":2332,"סם":1071,"סמ":4060,"נע":2683,"נס":7827,"ננ":1118,"נק":6861,"נצ":2907,"נפ":4308,"נת":16355,"נש":4892,"נר":4214,"סא":1865,"פט":6029,"פי":27041,"פה":6116,"פו":28843,"פח":3684,"פנ":5942,"פס":4846,"פע":6986,"פל":6474,"פן":2295,"פב":1568,"פא":3156,"פד":1152,"פג":1094,"עש":4774,"ער":15071,"עק":2148,"עצ":4716,"עת":7895,"שת":9019,"שש":1558,"תב":4462,"תא":5204,"תו":25811,"תה":9277,"תג":1436,"תי":25751,"תח":9940,"תל":3463,"תם":2303,"תכ":2023,"תנ":5503,"תמ":4850,"תן":2959,"תפ":5557,"תע":2232,"תר":13462,"תש":2068,"תק":7602,"רש":6651,"רר":1758,"רת":19384,"שא":5518,"שג":2036,"שב":15227,"שה":14417,"שד":1381,"שו":28172,"שט":3529,"שח":6900,"שי":32057,"שך":1218,"שכ":3883,"של":59496,"שם":6738,"שמ":16387,"שנ":26253,"שע":3886,"שפ":9870,"שק":2676,"שר":23791,"תת":1846,"מ ":2663,"ן ":91356,"ס ":23921,"ע ":17848,"ף ":12199,"ִי":1007,"פ ":1749,"ץ ":10234,"צ ":3355,"ק ":22523,"ר ":101491,"ש ":18495,"ת ":251160,"ב ":39174,"א ":61709,"ד ":40754,"ג ":17864,"ו ":72231,"ה ":204656,"ח ":14016,"ז ":8988,"י ":129045,"ט ":20042,"כ ":3096,"ך ":21128,"ם ":165828,"ל ":123422,"ال":1187," יי":2324," יכ":1029," יל":1306," ימ":1454," יע":851," יצ":2302," יר":1739," יש":8585," כג":1001," כב":1385," כא":2275," כו":3554," כד":2689," כך":799," כי":5212," כח":844," חל":3208," חמ":880," חי":4768," חס":883," חר":777," חש":1430," טו":2163," טב":768," טל":1002," טי":1699," טר":1404," יח":2213," יו":7458," יה":3689," יד":8356," מז":2002," מח":5968," מט":3237," מי":10487," מכ":3995," מל":5214," מא":7744," מב":4174," מג":2553," מד":6437," מה":5964," מו":15023," מש":13103," מר":5197," מק":5213," מצ":3521," מת":7226," מס":7731," מנ":4010," מן":1074," ממ":8626," מפ":3253," מע":6426," כר":1353," כת":1870," כש":1438," כפ":1233," כנ":1474," כל":6776," כמ":3311," לט":1128," לי":6245," לכ":2758," לה":9774," לו":4443," לז":853," לח":2914," לא":10716," לב":3660," לג":1530," לד":1145," לת":2908," לש":5145," לר":2977," לק":2667," לצ":1757," לפ":4810," לע":3788," לס":2540," לנ":1953," למ":9220," לל":1387," בפ":5193," בע":12834," בס":7728," בר":10133," בק":4194," בצ":3678," בת":9609," בש":14953," גב":1847," גא":1205," בד":5369," בה":6389," בב":3563," בג":3763," בח":3909," בט":1774," בו":5324," בז":1578," בכ":4321," בל":4682," בי":25678," בן":1774," בנ":6905," במ":21078," גר":3583," דב":749," גד":1588," גו":3424," גי":2015," גל":1445," גם":4780," אפ":2121," אק":1199," אצ":767," אס":1813," אנ":6385," בא":23971," אש":4957," אר":6566," את":12538," או":23084," אז":1939," אח":7629," אב":4176," אג":950," אד":3113," אל":10175," אם":984," אמ":5812," אי":11144," אך":1639," זה":3518," זו":3424," וק":1350," ור":2477," וש":2610," ות":1633," ונ":3060," ומ":9400," ופ":2170," וע":3597," וס":1644," וח":1862," וז":955," וו":1631," ול":4945," וכ":2933," וי":4333," חב":4303," חד":1040," חו":5710," זר":823," זמ":1557," זי":910," זכ":1452," הג":7501," הד":4857," הא":22400," הב":10880," דר":2719," דמ":1254," די":3533," דו":3757," דה":785," וב":8620," וג":1290," וד":892," וה":11812," וא":5274," הר":14413," הש":17912," הת":11571," הפ":9733," הצ":5867," הק":10138," הס":10053," הנ":10137," הע":13912," הם":2069," הל":5334," הן":954," המ":46981," הי":41072," הט":3324," הכ":7288," הו":33156," הה":5396," הח":10762," הז":2732," שה":7711," שב":7588," שח":2817," שט":1041," שו":5579," רש":1366," שא":2492," שפ":2381," שע":1892," שר":1669," שק":787," של":48394," שכ":1941," שי":8345," שנ":9947," שמ":8425," שם":3634," רא":3404," רב":4590," רו":6814," רח":840," קר":4233," קש":1007," רפ":810," רק":1211," רצ":860," רי":2280," רכ":802," תח":2475," תי":1934," תו":4939," תא":1279," שש":1373," שת":1185," תק":2224," תש":1190," תר":2157," תע":967," תפ":1385," תנ":1167," תכ":774," תל":1823," סי":4571," סל":908," סמ":1246," סג":795," סב":864," סד":1598," סו":5658," סט":1619," נש":1719," נת":1130," נע":1238," נפ":2034," נק":2006," נכ":1356," ני":4715," נמ":1957," נג":1220," נב":1056," נא":920," נח":2096," נו":11348," נה":1061," עת":798," עצ":1752," עק":770," ער":2088," עש":1568," ענ":811," עמ":1580," עם":3883," על":19873," עי":2972," עו":4351," עד":2831," עב":2405," סק":894," סר":2435," ספ":4534," פר":8948," פו":6232," פי":5929," פל":1804," פע":2438," פנ":1331," פס":1467," פא":1358," קל":1932," קט":1426," קי":3820," קצ":927," קנ":905," צר":1714," קו":8076," קא":953," קב":2948," צי":2521," צפ":808," צמ":781," צו":1425," צב":1575," ال":1017," ב ":10067," ג ":4498," ד ":1157," ה ":7037," א ":1385," י ":1129," כ ":2336," ל ":2779," ו ":2034," ז ":1154," מ ":2074," ס ":1112," צ ":1288," ר ":1507,"The":1046,"al ":1171,"and":1073,"an ":1270,"ati":1099,"מוז":5024,"מוד":3483,"מוג":886,"מוב":939,"מהל":1373,"מהמ":885,"מדר":908,"מהו":1225,"מדי":5777,"מדו":1516,"מדע":3235,"מגו":862,"מבר":4568,"מגד":820,"מבו":1915,"מבי":1059,"מבנ":1260,"מאת":1015,"מאר":916,"מאפ":1026,"מאנ":883,"מאל":2405,"מאי":3462,"מאז":946,"מאו":3114,"מאה":2706,"מלו":953,"מלא":1080,"מלכ":2095,"מלך":1227,"מלי":1534,"מלח":3450,"מכו":2726,"מכי":1235,"מים":6416,"מיל":2833,"מין":1783,"מינ":3538,"מיש":1371,"מית":4649,"מיק":1216,"מיר":984,"מטר":3264,"מיי":3085,"מיד":2520,"מיה":1218,"מיו":3528,"מחק":931,"מחל":1800,"מחי":970,"מטי":1746,"מחש":1462,"מחו":2697,"מחז":1008,"מזר":2302,"מוע":3080,"מוס":2260,"מונ":5841,"מון":1066,"מוצ":2037,"מופ":1468,"מוי":943,"מוח":898,"מול":1345,"מוכ":1297,"מזו":770,"מוש":3780,"מות":5842,"מוק":2142,"מור":3868,"מפי":1187,"מפל":1393,"נו ":5903,"מפו":1340,"מפר":1910,"מעו":2266,"מעל":1128,"מספ":3471,"נד ":1870,"מעב":969,"מער":4843,"מעש":819,"נה ":21979,"מנה":2231,"מנו":2766,"מנט":976,"מני":6289,"is ":1053,"ion":1503,"מסו":3392,"מסי":756,"מנת":816,"מסג":979,"נג ":1904,"ממל":1294,"ממו":4003,"ממש":2774,"נם ":1133,"מתא":1357,"מתי":1175,"מתח":1378,"מתו":2071,"מתמ":1624,"מתק":1096,"מרו":1617,"מרי":5941,"מרח":1042,"ני ":19093,"מרץ":1409,"מרכ":2955,"משו":2959,"משח":2455,"משך":1130,"משי":1615,"מרת":774,"משפ":4826,"משק":861,"משר":976,"משת":2362,"משל":2762,"משמ":3131,"משנ":2281,"מצו":2210,"מצב":1295,"נח ":1477,"מצא":2270,"מצע":1849,"מצי":1590,"מקו":5589,"מקב":868,"נט ":1605,"מצר":828,"מקר":1322,"נק ":1115,"נס ":1624,"נן ":997,"נר ":886,"נת ":12553,"סט ":2719,"סד ":1188,"סה ":2203,"סם ":1071,"נאי":1779,"סי ":2536,"סל ":766,"נהל":1094,"נהי":761,"נוד":953,"נוב":2639,"נוא":1590,"נהר":1042,"נדי":1685,"נדו":1190,"נהג":967,"נדר":1651,"נגל":9186,"נגד":1024,"סף ":1568,"נגר":1057,"סס ":885,"נבח":833,"נטי":3381,"נטר":1455,"ניו":3890,"ניה":4469,"ניב":1798,"נחש":1738,"נטו":1177,"סר ":1369,"he ":1611,"סק ":1452,"נוי":2975,"נול":6258,"נון":1701,"נונ":778,"נוס":3397,"נוע":4528,"נוצ":1379,"נור":1169,"נות":10949,"נוש":1445,"נלא":901,"נכת":1073,"נית":14496,"סת ":2182,"ניס":1942,"ניק":1685,"ניי":6008,"נימ":1196,"נים":13661,"נסו":805,"נסי":2174,"נמצ":1867,"עו ":882,"נפו":1293,"עד ":4359,"נסת":1066,"עה ":5479,"נער":986,"נקר":1955,"עי ":4052,"נשי":2815,"נצי":1255,"נקו":1045,"נקצ":758,"עם ":5134,"נתי":767,"נתו":1033,"על ":22307,"סבי":1330,"סגר":950,"סגנ":827,"סוג":2713,"סוד":1173,"סוב":810,"סדר":3650,"ia ":834,"סוי":1607,"סוף":1248,"סול":1222,"סון":1399,"סור":2397,"סות":809,"סופ":3199,"סטי":3364,"סיד":979,"סיב":1007,"סיו":1804,"סיה":1411,"סטר":2818,"ער ":2948,"סטו":3180,"סיפ":1197,"סינ":1401,"סיס":1561,"סיל":886,"סים":1765,"סימ":1300,"סיט":1729,"סיי":2145,"סיכ":1356,"עת ":4300,"סית":2310,"סלו":858,"סמו":1244,"ing":1041,"in ":936,"ספט":1488,"ספי":2004,"ספו":1293,"ספר":9874,"סקו":1337,"סקי":1760,"סרט":3915,"סרי":1021,"עבר":4731,"עבו":2091,"עדו":1037,"עוב":1493,"פו ":941,"עסק":909,"פה ":6052,"עני":1193,"עמו":895,"עמי":1194,"עמד":1340,"עלי":4061,"עלה":1199,"עלו":1136,"עלת":1040,"עיק":3105,"עיר":4131,"עית":1602,"עיי":870,"עיל":2019,"עים":3131,"עין":910,"עיו":894,"עור":1459,"עות":4912,"עול":5515,"עונ":916,"עוס":1354,"עוד":1596,"עזר":762,"er ":2469,"es ":1643,"פן ":2293,"en ":849,"עתי":2916,"ent":903,"עשר":1306,"עשי":1214,"עשו":933,"עשה":950,"ערי":962,"ערכ":3489,"ערך":1379,"פי ":4902,"ערב":4397,"ערו":1170,"פט ":1621,"עקב":1399,"עצמ":2020,"עצה":792,"פר ":7389,"פת ":4142,"פונ":2515,"פון":2263,"פול":5205,"פוב":883,"פות":3286,"פור":5443,"פוצ":750,"פופ":985,"פוס":1005,"פוע":1359,"פטמ":1413,"פטי":1246,"פיה":1485,"פטר":1084,"פחה":834,"פחת":1765,"פבר":1306,"פוא":886,"פאר":769,"פעי":1681,"פעל":1386,"פעו":1775,"צה ":4704,"פרט":1640,"פרי":7391,"פרו":4724,"פרנ":1094,"פרס":3792,"פרד":2122,"צי ":1464,"de ":816,"פשי":825,"פרש":1302,"פרק":1005,"פקי":1813,"פלו":847,"פלג":1367,"פלי":1158,"פים":2239,"פינ":1223,"פיע":1348,"פיו":1127,"פיז":1279,"פיי":2109,"פיל":2559,"פיר":2169,"פיק":1363,"פית":1710,"צב ":1365,"פני":3690,"פנה":1015,"פסי":1405,"פסו":1262,"צא ":3406,"צת ":2388,"צר ":2282,"פשר":1288,"פתח":1344,"פתי":2367,"צע ":1320,"קו ":1976,"קט ":953,"קי ":3109,"קל ":917,"קב ":846,"קה ":10128,"צוע":1224,"צות":4135,"צור":3752,"צוו":876,"צוי":1042,"ציא":1461,"ציב":1399,"קר ":5102,"קת ":3999,"ציר":1681,"צים":1036,"ציי":1115,"ציו":2783,"ציה":2306,"צלי":914,"קם ":1371,"צאה":819,"קן ":2098,"צבי":1113,"צבא":1757,"קס ":1455,"צאת":990,"קדמ":1302,"קדו":1269,"קהי":992,"קונ":1555,"קומ":2802,"קופ":3480,"קור":4356,"קות":1519,"קוב":1891,"רץ ":4170,"קוו":1390,"קוד":2387,"קוט":813,"קול":4389,"קום":1590,"רן ":1611,"קאי":4278,"קבל":961,"קבו":5125,"קבי":757,"רס ":2957,"קלא":1049,"קלי":2877,"קלו":814,"קמה":931,"שא ":795,"רק ":2876,"קטי":1305,"קטו":2534,"רר ":986,"קיב":1075,"רש ":946,"קטר":975,"קים":4228,"קיס":929,"קיד":1911,"קיו":786,"קיי":2845,"קית":1359,"רת ":15678,"קיצ":864,"קיר":818,"רה ":17356,"רד ":3185,"צעו":1152,"צעי":1124,"צפו":2771,"רו ":3945,"רא ":2013,"צמב":1291,"צמח":843,"רג ":1850,"רב ":5168,"רל ":1007,"רם ":1940,"רט ":4971,"רח ":1986,"רך ":5443,"צרפ":2865,"רי ":10968,"צרי":2230,"רחש":787,"רחי":1692,"רחב":1963,"רחו":949,"ריא":2270,"רטי":3060,"שר ":8585,"רטו":1441,"רות":11282,"רוש":2596,"רור":832,"רוק":2070,"רופ":3572,"רוע":945,"רוס":3581,"רונ":2892,"רון":3292,"רומ":4126,"רום":2275,"רוי":1525,"רוח":842,"רוט":809,"רוו":1191,"רוז":748,"רוב":4518,"רוא":1983,"רדי":2706,"רבי":6491,"רבע":1063,"ראת":808,"ראש":9879,"רבו":2717,"רבה":870,"רגנ":814,"רגל":1905,"רגי":1770,"רגו":2907,"תב ":1936,"רנס":871,"רנט":865,"רני":2334,"רמו":1109,"רמנ":3395,"רמי":1311,"רכה":807,"רכז":2614,"רכו":1721,"רכי":2246,"רכת":2068,"רלי":1812,"ריו":3530,"ריט":3551,"ריה":4718,"ריד":1253,"רים":13911,"רינ":921,"ריי":3646,"ריל":1756,"ריכ":1158,"ריק":5899,"ריס":1584,"שת ":3670,"רית":8516,"רכב":1910,"קצי":1354,"שו ":1123,"שה ":6000,"שג ":788,"קסי":1168,"קני":2966,"שב ":2846,"ראה":1168,"ראו":1207,"ראל":9123,"ראי":2021,"שם ":6732,"של ":44424,"קשר":1129,"שך ":1218,"קשו":1188,"קרא":3185,"שי ":4651,"קרב":1789,"קרו":2813,"קרי":3474,"שהי":1689,"שהו":2779,"שהת":1193,"שוו":1653,"שוי":825,"שוב":2695,"שות":2730,"שור":3173,"שומ":896,"שון":3078,"שול":846,"שונ":5449,"שחק":4451,"תר ":6554,"שטח":1349,"שיא":1478,"שיב":1320,"שיח":755,"שיו":1010,"שיט":1510,"שיי":2304,"שימ":3122,"שים":3750,"שינ":1048,"שיצ":765,"שית":2397,"שיש":1013,"שיר":3655,"תת ":1033,"שכו":948,"שלת":1194,"שלי":4040,"שלט":1378,"שלו":3513,"שלה":1787,"שמא":2250,"שמה":1020,"שמש":2616,"שמע":1452,"שמו":3471,"שמי":1858,"שנה":2722,"שנו":3666,"שנת":8163,"שני":8407,"תה ":7963,"רסי":2582,"רסם":846,"רעי":965,"רפת":3016,"רפי":1377,"רפו":1781,"תו ":7307,"רקי":1347,"תח ":1273,"רצו":3053,"רצי":1126,"רשו":916,"רשי":915,"תי ":6224,"תל ":1457,"רתו":1195,"רתי":1593,"רשת":1744,"px ":1770,"תם ":2303,"שאי":1679,"תן ":2959,"שבת":1116,"שבי":2213,"שבע":790,"שאר":864,"שבה":1333,"שבו":2486,"תחו":3127,"תחי":1668,"תחת":1243,"תוא":930,"תוך":1588,"תוח":1128,"תונ":1543,"תוכ":2531,"תול":1229,"תות":809,"תור":2674,"תוצ":851,"תופ":747,"תכו":755,"תלמ":974,"תים":1902,"תיי":3333,"תיו":2454,"תיה":1049,"תיב":1533,"תיא":1180,"תית":3825,"תיק":1981,"תנה":885,"תנו":2011,"תמש":815,"תמט":1174,"תמו":1033,"תפי":902,"תפת":844,"תפק":1672,"שפע":1069,"שפו":1080,"שפה":1050,"שפי":949,"שפח":2708,"שפט":1854,"שתמ":820,"שתי":1677,"שרת":856,"שרי":1851,"שרא":9189,"שרו":1075,"שרה":794,"שרד":795,"תאי":785,"תאו":1106,"תהל":1012,"תאר":1331,"ng ":993,"ne ":883,"nd ":899,"תקו":3171,"תקי":1081,"תרח":857,"תרו":1096,"תרג":858,"תרב":1108,"of ":1020,"on ":2345,"le ":936,"אב ":829,"אה ":7609,"או ":12752,"אז ":1578,"אי ":11190,"אך ":1814,"אל ":12893,"אם ":2755,"אן ":3273,"אחד":3813,"אזו":2699,"אות":6901,"אוק":2466,"אור":6849,"איט":1941,"איו":924,"אטר":826,"איס":807,"איר":3360,"איל":857,"איי":2254,"אינ":4275,"אין":766,"אימ":1541,"אים":3388,"בר ":12599,"אחר":6475,"אחת":1793,"אדו":1100,"אדם":2266,"בע ":2728,"אוד":916,"אוג":1935,"אוח":876,"אוט":953,"אוו":1522,"אול":3101,"און":955,"אונ":2600,"אומ":3134,"אופ":3417,"אוס":2423,"אמר":4875,"אמצ":1763,"אמנ":1370,"אמי":1391,"אמו":966,"גד ":977,"אסי":1374,"אסט":928,"אנש":1036,"אנר":800,"אנט":1124,"אני":2535,"אנג":9388,"אנד":988,"אנו":1034,"בת ":4691,"אית":2756,"איש":1805,"אלק":946,"אלג":769,"אלב":2498,"אלו":1949,"אלה":1036,"אלי":7303,"ארד":814,"ארג":2148,"גי ":1572,"ארב":1076,"ארו":1606,"ארץ":2338,"ארצ":2697,"ארק":837,"ארי":2497,"ארכ":746,"אשו":5612,"אשר":5633,"אשי":2353,"גה ":2608,"גו ":887,"אפי":1390,"אפר":2492,"אפש":1248,"באי":3225,"באמ":1587,"באל":995,"באז":1071,"באו":6670,"בבי":1380,"באר":2896,"באנ":6445,"באפ":1580,"בגו":776,"בדי":2083,"בדו":915,"בגר":1359,"גל ":2819,"אתר":938,"גם ":5839,"גן ":1860,"אף ":1141,"אס ":1146,"בא ":1578,"את ":15913,"אש ":2340,"אר ":5565,"בי ":5655,"בה ":7790,"בו ":4295,"בד ":1438,"אבו":828,"אבי":2570,"בן ":3463,"בל ":2984,"גנו":1314,"גני":1049,"הה ":812,"הו ":1555,"גור":2881,"גות":1342,"גוף":967,"דר ":2321,"גיי":929,"גים":1431,"גיל":1327,"גיע":1045,"דש ":1335,"גיה":3078,"דת ":3965,"גית":995,"גלו":929,"גלי":10256,"דבר":1224,"דוב":1184,"דול":3841,"דום":754,"דומ":1571,"דון":1523,"דוג":872,"דוד":964,"דות":4827,"דור":4722,"דוק":822,"דוע":2536,"גרו":886,"גרת":1011,"גרי":1714,"גרפ":891,"גרמ":3486,"הם ":6282,"הל ":908,"הן ":3375,"במח":1274,"במו":1362,"במי":1660,"במא":2636,"במד":1407,"במה":1632,"במב":1705,"במר":2370,"במק":1759,"במש":1939,"במע":1091,"במס":1456,"בלי":2952,"בלו":1708,"בלת":1123,"בעב":1312,"בעו":2020,"בעל":3414,"בעי":5046,"בער":1666,"בעת":1302,"דה ":9750,"בפב":1248,"דו ":2707,"בנו":3853,"בנה":1480,"בני":4749,"בסו":1238,"בסד":891,"בסי":1809,"בספ":2568,"בוצ":4259,"בור":4953,"בות":6458,"בחי":1679,"בחו":1131,"בהם":920,"בהי":972,"בהו":872,"בדצ":1243,"בדר":2390,"בוע":1416,"בוס":1642,"בונ":896,"בום":1558,"בול":2422,"בוי":829,"בוה":789,"בוד":2124,"ביש":3045,"ביר":2459,"בית":7075,"גת ":1847,"בכל":1398,"בכי":1314,"בחר":970,"גר ":827,"בימ":897,"בין":7303,"ביל":1749,"בים":5704,"ביט":1549,"ביי":2219,"ביצ":869,"ביע":1697,"בינ":3973,"ביו":8219,"ביה":1061,"ביד":1090,"ביב":2499,"ביא":912,"גבי":1029,"גבו":1377,"גאו":1715,"דן ":1252,"גוב":1126,"גוד":1622,"גון":2245,"גוס":1728,"גול":1378,"גדר":1056,"גדו":3497,"גבר":964,"דע ":2354,"ברו":5256,"ברה":2480,"די ":14259,"ברא":1602,"בקר":1360,"בקי":1190,"בקו":797,"בצר":1026,"בצע":1020,"בצפ":918,"בצו":754,"בפר":1402,"בפו":753,"בפי":884,"דם ":3784,"דל ":1350,"בתי":1021,"בתק":1270,"בתח":2033,"בתו":2504,"בשי":1378,"בשמ":809,"בשם":1347,"בשל":1420,"בשנ":7415,"ברת":3153,"ברט":849,"ברי":11218,"ברס":1667,"הקב":1121,"הצפ":881,"הצל":875,"הצי":1591,"הרא":4672,"הרב":2013,"זי ":1210,"הקר":1616,"הקש":833,"הקת":1394,"הקל":776,"הקי":1474,"הקה":1071,"הקד":827,"הקו":2620,"השב":876,"הרפ":831,"הרש":823,"הרו":2886,"הרכ":769,"הרי":1168,"התא":1307,"התו":1514,"השת":1139,"השמ":1266,"השם":895,"השנ":4351,"השפ":1366,"השו":2146,"השח":757,"השי":2832,"השל":1958,"העת":967,"הער":1024,"העו":4093,"העב":1724,"העל":1178,"העי":2782,"זה ":4910,"הפע":812,"הפס":746,"הפר":2442,"זו ":2407,"הפו":2450,"הפי":1400,"הצב":868,"המח":2130,"המז":1081,"המי":3193,"המד":2330,"המו":7722,"המב":1301,"המא":3556,"המצ":1978,"המק":2404,"המר":1784,"המש":5759,"המע":1738,"המפ":1404,"הממ":1866,"המנ":1147,"המס":1855,"המכ":1676,"המל":2091,"המת":2867,"הנו":2020,"הנח":758,"הני":1012,"הנפ":766,"הנמ":908,"הסו":2019,"הסי":1362,"הסד":840,"הסר":1363,"הספ":2367,"היש":1505,"היר":1734,"ות ":80938,"הכו":1820,"הכל":1158,"הכי":931,"הכנ":1262,"הלא":944,"הלה":874,"הלו":1160,"הלי":2332,"הלכ":875,"הלך":1189,"ויל":1139,"וים":1245,"וימ":813,"וינ":891,"ויה":1089,"ויו":3873,"ויז":1668,"ויי":2636,"ויד":832,"וטו":1573,"וטי":1439,"זר ":1170,"וחר":794,"וכן":1385,"וכנ":2823,"וכל":1110,"וכי":1321,"וכו":764,"וכה":1041,"וכב":1408,"ויר":1363,"ויק":1124,"ווא":1655,"us ":1690,"ווה":2251,"ווי":6670,"וול":1093,"וון":1540,"והא":894,"והו":1891,"והי":2099,"והמ":1272,"ודע":1169,"ודר":1718,"ודת":964,"וחד":1468,"וחו":1384,"וזע":1797,"וזי":3484,"וונ":2693,"וות":1300,"וור":1036,"ואר":4871,"ואל":1667,"ובה":2620,"ובו":2126,"ובי":4910,"ובד":1206,"ובא":1004,"ואה":1373,"ואו":1083,"ואי":2839,"וגר":1479,"וגמ":793,"ודל":997,"ודי":6497,"ודה":2328,"ודו":2620,"ובר":4203,"ובת":944,"ובע":1673,"ובל":2998,"ובמ":2420,"וגי":5063,"וגו":2244,"וגד":821,"זם ":1283,"התח":1134,"התי":1325,"התמ":749,"התנ":1704,"התפ":1798,"התק":1851,"התר":1227,"וט ":1289,"דצמ":1291,"וי ":5737,"דרה":2116,"וז ":2245,"וח ":3705,"דעי":2475,"וד ":6343,"וה ":2998,"וב ":6671,"וג ":4167,"דמו":2336,"דמי":1260,"וא ":27697,"דלי":756,"דיר":1020,"דית":2578,"הר ":1518,"דיה":1129,"דיו":2800,"דינ":5116,"דין":785,"דים":4959,"דיי":1568,"היי":4423,"היל":1466,"היו":4371,"היח":928,"היס":2192,"הים":937,"הינ":2071,"היג":810,"וש ":3750,"היה":10243,"היד":1593,"היא":15411,"הטו":996,"החש":794,"ור ":18092,"החו":2245,"החי":1691,"החל":2789,"וק ":4196,"החב":1254,"הזמ":843,"הופ":1656,"הור":1218,"הוק":1750,"הוצ":992,"הונ":877,"הול":1454,"הוו":1959,"וץ ":2534,"הוד":5252,"הוא":27359,"ההי":939,"ההו":815,"ופ ":863,"הדר":1419,"הדי":781,"וף ":4256,"הדו":1789,"הגר":1312,"הגי":1488,"הגב":784,"וע ":5599,"הגו":1529,"הגד":2288,"הבר":3864,"האנ":1474,"האמ":2115,"האל":2120,"האר":2435,"tio":1159,"וס ":5753,"הבי":3093,"הבו":902,"האד":1377,"האי":3937,"האו":3742,"האח":1546,"ון ":31676,"ום ":16021,"ול ":7891,"ter":1142,"דרו":3914,"the":876,"דרי":1886,"דרך":2231,"וך ":3767,"דרת":2145,"חבר":6406,"חבי":909,"חות":2707,"חור":1374,"חוק":2664,"חופ":953,"חומ":2243,"חדש":1272,"חוז":2017,"חום":1881,"חול":1611,"חוב":1301,"חוד":1401,"חיר":890,"טת ":2178,"חית":881,"טר ":2558,"חיו":928,"חיד":1965,"חיי":3491,"חיל":2274,"חים":2086,"חינ":1388,"חין":819,"חמה":852,"חמי":1161,"יא ":17223,"חמת":1678,"חלו":1698,"חלל":804,"חלק":3950,"זמר":1390,"זמן":1228,"טו ":1328,"טה ":3869,"זער":1824,"זרח":2887,"טי ":5165,"טח ":798,"טן ":1424,"חס ":1181,"זהו":873,"זור":3460,"חק ":2379,"חר ":3837,"זיה":1878,"זיק":3731,"זית":1113,"חת ":4976,"זכו":1572,"ולר":980,"ולק":1057,"ולת":1183,"ולפ":880,"ולנ":2842,"ולם":4221,"ולמ":1167,"ולל":2126,"ולי":9326,"ולט":1565,"ולו":7007,"ולה":3768,"ולד":6790,"ולא":1327,"וכר":1278,"ומת":1301,"ומש":1030,"ומר":2913,"ומי":8418,"ומנ":2251,"ומה":2366,"ומד":1168,"ומב":746,"ומט":1282,"ומח":813,"ומו":3468,"ומא":1433,"וסס":1023,"וסף":1300,"וספ":1419,"וסק":2400,"וסד":1576,"וסט":3543,"וסי":4415,"וסו":1601,"ונס":965,"ונת":1474,"ונק":1268,"חב ":1144,"ונג":1320,"ונא":1208,"וני":18082,"ונח":1810,"ונט":1231,"ונו":5615,"ונד":1458,"ונה":7200,"חה ":3681,"ועצ":1483,"ועת":846,"ועד":3169,"ועה":1693,"חד ":5298,"ועו":1416,"ועל":2118,"ועי":1952,"וצא":2429,"ופי":5387,"ופה":2721,"ופו":2815,"חו ":753,"ופק":800,"ופר":3436,"ופש":817,"ופת":1896,"ופן":1487,"ופס":1055,"ופע":1474,"וקם":1123,"וקס":776,"וקמ":1227,"וקו":1308,"וקי":1776,"וקט":2107,"חי ":1719,"ורב":1210,"ורג":4279,"ורא":1280,"וקר":2331,"וצי":1905,"וצה":1895,"וצו":1018,"וצת":1866,"וצר":3353,"ושי":1977,"ושה":1203,"ושו":851,"ושל":2823,"ותה":2054,"ורט":1801,"ורי":12062,"ורך":1570,"ורד":1610,"ורה":4165,"ורו":3649,"ורנ":1343,"ורס":1879,"ורכ":1436,"ורמ":1653,"ורר":1139,"ורק":1753,"ורת":4134,"ורש":1062,"ושב":1741,"ושא":1174,"ושג":868,"חם ":833,"ותו":3558,"ותח":851,"ותי":4897,"ותם":860,"ותר":5363,"חל ":1502,"יית":6408,"ייר":2338,"ייש":1691,"ייצ":1194,"ייק":972,"יינ":2765,"ייס":1621,"יכי":851,"יכו":4344,"יחס":2243,"יטי":4701,"יטל":2302,"יטו":2202,"יטה":1667,"יטר":974,"יטת":1710,"יטנ":845,"ייט":1193,"ייך":816,"יים":14831,"ייל":1292,"יין":3012,"יימ":2364,"ייב":892,"ייד":1305,"ייה":4423,"ייח":1458,"יוס":1553,"יונ":4734,"יון":4211,"יומ":966,"יום":4082,"יול":2364,"יות":18525,"יור":2161,"יוצ":1391,"יזי":2803,"יזם":1225,"יחד":770,"יחו":1331,"יחי":2092,"ידע":1040,"ידת":830,"יהו":5488,"יהם":1573,"יהן":839,"יוו":4083,"יוח":1326,"יעי":1794,"יעו":1404,"יעה":1184,"יסר":789,"כה ":5083,"ינס":944,"ינט":1703,"יני":8382,"ינל":1089,"ינא":757,"כב ":1369,"ינג":1937,"ינה":5280,"ינו":10255,"יסי":1267,"יסט":5187,"יסד":879,"יסה":750,"יסו":2347,"ינת":1901,"ימי":5064,"ימו":4842,"ימפ":1867,"ימה":1856,"ימת":1210,"ימש":796,"ילד":1523,"ילה":3661,"ילו":5745,"ילי":5359,"יכר":764,"ילת":1987,"טרי":3898,"טרה":1144,"טרו":3685,"טרת":804,"טרנ":1010,"ידו":5598,"ידה":2025,"ידי":10222,"יגה":763,"יגו":1454,"יבר":2757,"יבת":1107,"יבי":2538,"יבו":5867,"יבה":1458,"יאנ":1337,"יאל":1853,"יאט":1005,"יאה":813,"יאו":2501,"טון":1905,"טונ":1205,"טוס":1037,"טור":5386,"טות":1114,"יק ":3514,"יר ":9468,"טיו":1116,"טיב":1924,"יש ":4075,"טים":3865,"טינ":2155,"טיי":2059,"טבע":1372,"יע ":1962,"יף ":1039,"טוב":2684,"יץ ":1463,"טמב":1415,"טני":1443,"טית":3454,"ית ":68847,"טיס":800,"טיפ":954,"טיק":2311,"טכנ":772,"טלי":1241,"טלו":1568,"טלק":1324,"יז ":756,"יו ":8828,"יט ":1800,"חקי":1130,"חקן":1010,"חקנ":990,"חקר":1503,"יח ":1007,"חסי":1544,"יג ":1633,"יב ":3393,"יה ":40026,"יד ":4579,"ין ":20713,"יס ":3129,"חשו":1442,"יך ":2851,"חשב":3253,"חרת":762,"חרי":2444,"חרו":2409,"יי ":1538,"ים ":101313,"יל ":6999,"כנו":1432,"כני":2511,"כנס":2070,"כפר":832,"לת ":6746,"כינ":1581,"כימ":930,"כיר":1145,"כיב":953,"כיו":2320,"כיה":761,"כים":1975,"כיל":789,"לר ":750,"כמו":1809,"כלכ":1033,"כלל":3229,"כלי":2030,"כלו":1791,"כבי":2214,"כבת":844,"כגו":871,"כדו":2961,"כאש":1171,"לס ":944,"כוכ":1222,"כול":4477,"כון":1365,"כונ":3439,"כזי":1062,"כות":3899,"לק ":2384,"כדי":968,"כוח":1334,"לי ":12633,"לך ":2677,"לט ":1236,"לן ":1554,"לם ":5107,"לל ":3884,"לא ":4586,"לב ":1394,"לה ":14910,"לד ":5523,"לו ":5117,"כר ":1517,"כת ":4160,"כן ":3170,"יפי":1104,"יפו":4212,"יפה":1175,"כו ":1279,"כז ":1400,"יצו":3383,"יצי":2337,"יצא":1573,"יקר":3694,"יקת":771,"יקנ":1394,"יקט":1251,"יקי":1290,"יקל":1432,"יקא":4207,"יקה":6636,"יקו":3145,"ירת":2005,"ירו":10154,"ירה":3648,"כי ":2345,"ירא":823,"ירי":3756,"ישר":9232,"ישו":3196,"ישה":1288,"כך ":1583,"ישי":4067,"כל ":4979,"יתה":3362,"יתו":3399,"יתי":1065,"יתן":1501,"כם ":777,"מת ":6084,"מר ":3374,"מש ":2759,"מס ":899,"מן ":5852,"לתו":964,"לתי":1345,"מל ":1062,"לקו":1461,"לקי":2709,"לקט":1068,"לשנ":1062,"לשי":1010,"לשו":879,"מי ":7001,"לרא":1055,"לרי":1005,"לרו":1023,"מה ":11039,"לעת":1312,"מד ":1904,"לפר":766,"לפנ":1939,"לפי":2283,"מו ":5183,"למע":1288,"למש":1364,"למו":2080,"למד":977,"למי":2394,"למנ":879,"לנד":1704,"לני":1139,"לנו":2241,"לכל":1891,"לכה":1199,"לכו":898,"ליק":1573,"ליצ":890,"ליש":1631,"לית":12132,"לין":1391,"לינ":1320,"לים":8070,"לימ":1810,"ליפ":1428,"ליס":1055,"לכת":1177,"ללי":1608,"לוש":1494,"לות":5393,"לומ":2089,"לום":1009,"לונ":1458,"לון":862,"לוי":1233,"לול":1458,"לור":772,"לוק":1039,"לוס":1978,"לחי":1661,"לטו":1868,"לטי":2006,"לחמ":2604,"ליא":1164,"ליד":1413,"ליה":3296,"ליג":1396,"ליח":784,"ליט":3150,"ליו":3604,"ליז":849,"ליל":2282,"ליי":2952,"ליך":906,"לגו":927,"לגב":764,"לבנ":1140,"לבי":1775,"לבו":2832,"לדו":1001,"לדה":1350,"לדי":1178,"לוג":4860,"לוב":1152,"לוח":1147,"לוו":2569,"להת":947,"להק":2345,"להי":1584,"לאו":4844,"לאח":2966,"לאי":1340,"לאס":784,"לאר":955,"כרי":914,"כרו":1009,"כתי":946,"כתב":2605,"כתו":1006},"n_words":[7414842,8743276,5934016],"name":"he"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hin b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hin new file mode 100644 index 000000000..104ed583e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hin @@ -0,0 +1 @@ +{"freq":{"ौद्":366,"ोली":389,"ोर्":465,"ोमी":388,"्तम":479,"्तन":384,"्तर":2639,"्त्":1391,"्थल":430,"्ता":2582,"्ती":679,"्ति":2706,"्तु":954,"्थि":2834,"्था":3750,"्द्":869,"्दी":1870,"्दू":492,"्दे":907,"्ट्":2750,"्टे":7603,"्टी":634,"्टि":711,"्तक":539,"्बन":468,"्मक":445,"्यक":2308,"्मा":2864,"्मि":1000,"्रं":360,"्मी":437,"्यत":638,"्यय":385,"्यम":558,"्रक":2642,"्यव":609,"्रच":370,"्रज":367,"्यु":778,"्या":6530,"्धा":551,"्धि":463,"्ना":572,"्पन":572,"्पा":591,"्प्":3747,"्गत":419,"्का":992,"्कृ":823,"्कर":450,"्जा":403,"्ञा":1890,"्टर":764,"्चि":1116,"ोंन":705,"ौर ":706,"ं":116003,"ः":743,"ँ":3754,"आ":15110,"इ":21960,"अ":27216,"ऊ":1116,"ई":8670,"उ":14369,"ए":27071,"ओ":3623,"ऑ":695,"ऐ":1181,"ग":41430,"ख":13380,"क":215389,"औ":11975,"छ":5467,"च":24607,"घ":4688,"ट":40532,"ञ":2576,"झ":1114,"ज":58287,"ठ":3871,"ड":21061,"ढ":1924,"ण":16159,"त":129370,"थ":26984,"द":62970,"ध":21789,"न":137720,"प":89801,"फ":9525,"्ग ":934,"ब":39694,"भ":28885,"म":108014,"य":96626,"र":228209,"ल":79901,"व":82288,"ष":22409,"श":41726,"ह":118206,"स":149246,"़":11159,"ि":139433,"ा":290518,"े":193119,"ू":22463,"ृ":6345,"ी":110466,"ु":44034,"ौ":4425,"्":228350,"ो":68898,"ै":59521,"ॉ":2831,"।":45019,"०":5718,"१":6322,"्क ":738,"६":1789,"७":1738,"८":1943,"९":4350,"२":3762,"३":1587,"४":1437,"५":1969,"्न ":1500,"ोजन":549," ख":3003," ग":13738," औ":11821," क":119739," ओ":938," ऐ":1154," ऑ":666," ट":5844," ज":31363," झ":690," च":7337," छ":3781," घ":3397," इ":19284," आ":12686," अ":26917," ए":21008," ऊ":806," उ":13706," ई":1344,"्फ ":515,"्म ":3545,"ोड़":535,"्य ":9507,"्र ":7477,"ोते":895,"ोती":1270,"ोता":2537," २":2506," ३":490," १":5155," ।":6381,"्व ":2678,"ोनो":409,"ोने":1142," प":54146," फ":4760," न":21169," म":54702," य":22634," ब":23290,"्ष ":1625," भ":19961," ड":2225," द":21719," ध":2884," त":12822," थ":8999," ह":72412," स":78945," ल":14663," र":25548," श":12231," व":27670,"्स ":1196,"्च ":578,"्ट ":1436,"्ञ ":468,"्ड ":1049,"्ठ ":1088,"्ण ":1354,"्थ ":1814,"ोगि":441,"ोगो":559,"्त ":4240,"्ध ":2352,"्द ":1588,"्सा":631,"्ष्":370,"्हे":874,"्हो":949,"्स्":3660,"्ली":1260,"्ला":820,"्ले":511,"्रद":1892,"्रथ":561,"्रत":2596,"्रण":709,"्यू":989,"्रप":384,"्रम":2375,"्रभ":518,"्यो":1594,"्रय":1925,"्रव":977,"्रश":494,"्रह":1076,"्रस":1694,"्रा":9061,"्रि":3453,"्री":4034,"्रै":386,"्रे":9372,"्रो":1860,"्षण":540,"्षे":3114,"्षि":1460,"्षा":1408,"्वत":875,"्वर":1044,"्वव":540,"्वप":609,"्वी":1298,"्शन":1985,"्वे":430,"्वि":632,"्वा":6601,"०० ":579,"२००":1298,"१९९":360,"१९६":420,"१९७":415,"ंत ":1187,"ंड ":1010,"ंग ":1786,"ंक ":375,"ंभ ":447,"ंद ":452,"ंश ":574,"ंस ":426,"ंह ":485,"आप ":923,"अंत":806,"अंग":1106,"अक्":469,"इन ":809,"ंचत":1845,"ंचा":2297,"ंग्":1940,"ंगा":789,"ंगी":464,"ं। ":4299,"ंको":451,"ंक्":1624,"ंख्":1085,"ंगल":563,"ंटे":1825,"ंडि":369,"ंजा":609,"ंने":716,"ंबं":450,"ंपा":1007,"ंत्":1705,"ंति":457,"ंतर":775,"ंद्":705,"ंदी":875,"ंदि":932,"ंदर":556,"ंबर":485,"ंयु":368,"ंस्":2087,"ंसा":366,"�":2362,"थे ":819,"दन ":568,"थी ":791,"था ":4899,"त् ":405,"थम ":523,"तंत":641,"तो ":1178,"ं ":59244,"ः ":691,"ताओ":415,"तान":1545,"ताब":607,"तार":557,"तिक":1335,"दो ":833,"तिज":375,"तिन":613,"ँ ":2207,"तिय":1006,"तिर":505,"तिह":787,"आ ":1631,"नई ":675,"धन ":595,"दी ":4353,"दू ":610,"तरी":448,"तरा":413,"तरह":445,"दा ":857,"तर्":854,"दि ":1483,"तमा":404,"तमि":373,"ण्ड":966,"णों":461,"दर ":576,"दल ":742,"तथा":2577,"तत्":438,"णाल":368,"थ ":4109,"द ":7269,"ध ":3357,"न ":42221,"ड ":6850,"था।":3059,"ठ ":1539,"थाप":1123,"ण ":9157,"थान":1787,"त ":29579,"थित":2566,"धी ":490,"ज ":2925,"दक्":984,"ञ ":468,"धा ":464,"नट ":1785,"ट ":6235,"धि ":2431,"थवा":400,"च ":2310,"छ ":1066,"क ":31192,"तों":455,"ग ":7730,"ख ":1929,"त्स":696,"त्व":1830,"त्प":791,"त्र":11745,"त्य":2756,"त्म":761,"त्त":3587,"ए ":4565,"तीन":446,"तीय":3767,"तीस":449,"ई ":6870,"ै ":18248,"दार":977,"दान":855,"दाय":435,"दिल":1253,"दिश":630,"दिर":1086,"े ":101676,"दिय":1540,"दित":1005,"दिन":569,"न् ":786,"दुर":430,"ू ":2066,"दूर":671,"दूस":592,"ि ":14043,"नी ":5102,"ी ":75983,"ु ":3758,"ा ":97285,"़ ":2122,"दस्":366,"ह ":13867,"ने ":12971,"स ":15469,"ष ":2544,"श ":4366,"व ":7299,"ल ":18408,"नि ":406,"दर्":1109,"ना ":7450,"र ":61007,"थी।":911,"य ":22189,"म ":13770,"भ ":1015,"नव ":411,"ब ":2705,"फ ":1049,"थे।":1504,"प ":5685,"टना":394,"डल ":378,"डी ":506,"डा ":698,"टर्":362,"ड़ ":675," �":578,"टती":1811,"ञान":1620,"ट्र":7028,"ट्ट":617,"टेश":7359,"ढ़ ":636,"टीक":471,"णु ":439,"णी ":648,"णा ":355,"तक ":1940,"ति ":4868,"ता ":14635,"तु ":1219,"ती ":9089,"ते ":6248,"तन ":484,"ड़े":606,"ड़ी":1222,"ड़ा":1450,"डिय":1027,"तम ":378,"तर ":1819,"जे ":3791,"जा ":1910,"ज़ ":425,"जी ":1578,"चेन":368,"चीन":1126,"चुन":405,"जो ":3111,"चिक":478,"चित":1154,"चार":1698,"चाल":2122,"चिम":876,"जंक":1375,"च्च":632,"छोट":541,"जन्":1234,"टक ":496,"जधा":578,"जनस":468,"जनी":553,"छूट":1815,"जस्":392,"टन ":357,"जहा":441,"ज़ी":477,"जिस":3147,"जिल":1663,"जिन":942,"जित":402,"जार":493,"जाब":559,"जान":2165,"जात":5721,"जैस":743,"ज्य":2693,"ज्ञ":2457,"जीव":1088,"टर ":1798,"टे ":2183,"टि ":384,"टी ":1658,"टा ":740,"ंघ":459,"ंख":1287,"ंग":7039,"ंक":4013,"ंड":2775,"ंट":3074,"ंज":1716,"ंच":5039,"केन":435,"ंश":984,"ंस":3555,"ंह":717,"ंव":676,"् ":2686,"खने":369,"ंध":1776,"ंद":4729,"ंन":763,"ंथ":399,"ंत":5036,"ंय":471,"ंप":2156,"ंभ":782,"ंब":1984,"ो ":17876,"ँच":523,"कोई":460,"कों":1045,"आत":950,"इं":1275,"कृत":1818,"आज":527,"अस":694,"अव":2719,"आक":698,"अल":1444,"अर":2196,"अभ":1051,"अम":1289,"अब":415,"अप":3105,"आई":372,"अध":2198,"अन":4741,"अथ":432,"इत":740,"इट":387,"आस":422,"इक":606,"आव":1056,"आम":383,"आय":903,"आर":1257,"आप":1303,"कृष":566,"आद":1231,"आध":1054,"आन":511,"अं":2476,"आं":508,"अत":785,"अक":781,"अग":575,"ं।":6630,"उप":2592,"उस":2266,"इन":2901,"इल":681,"इस":13512,"आ।":435,"ईस":387,"उत":2684,"उन":3336,"उद":1042,"कोच":453,"कोड":3985,"एं":534,"कोल":359,"एँ":425,"कोश":370,"एक":15570,"क्ट":677,"क्त":3551,"क्य":529,"क्श":1460,"क्ष":8266,"क्र":2787,"क्स":4316,"ओर":445,"ओं":2444,"ऐस":714,"एव":3043,"एल":360,"एस":427,"गर":2860,"गय":3634,"गल":1055,"गव":557,"खे":1130,"खो":528,"गम":494,"ख्":2681,"गभ":616,"खा":2157,"गठ":414,"खि":516,"खी":461,"घं":1798,"गढ":741,"गण":767,"गत":1406,"गद":372,"गए":383,"क्":22746,"कै":618,"के":37285,"खन":943,"गई":554,"को":17366,"कॉ":440,"कि":12948,"की":20919,"गं":513,"का":35945,"कृ":2446,"कु":3003,"कू":402,"कस":766,"कव":956,"कह":3138,"कल":2049,"खक":372,"कम":1276,"कर":12591,"कप":515,"कथ":448,"कन":1065,"कड":382,"खं":419,"कत":2310,"कट":630,"और":11428,"कई":777,"कं":723,"चु":923,"ची":1816,"जं":1545,"चि":3214,"चा":5438,"चे":1055,"चौ":426,"च्":1117,"० ":1980,"जग":567,"गढ़":657,"चत":1993,"चन":1667,"चर":750,"चल":1479,"घा":478,"चं":451,"। ":33428,"गति":373,"चक":424,"गा":3720,"गह":412,"गी":1381,"गि":1175,"गु":1958,"गो":2483,"ग्":4970,"गे":620,"गै":364,"घर":423,"टन":928,"ञा":1890,"टत":1909,"टा":1764,"टल":396,"टर":2646,"४ ":778,"झा":416,"३ ":798,"टक":827,"जो":3936,"जै":1167,"जे":4339,"जू":402,"जी":3381,"जु":839,"जा":12605,"जि":7022,"ज़":2064,"घंट":1796,"२ ":974,"ज्":5651,"जन":5056,"जध":594,"छू":1841,"छा":395,"जह":523,"जस":483,"१ ":954,"जर":910,"जल":806,"जब":740,"छो":713,"जय":526,"जम":644,"ठा":568,"५ ":1070,"टे":10515,"ठन":369,"ट्":8239,"टो":662,"टी":2663,"टि":1894,"ड़":5317,"डा":1474,"डि":2023,"डी":831,"डल":514,"६ ":930,"गभग":596,"तं":976,"तः":367,"ढ़":1322,"७ ":816,"ड्":669,"डो":499,"डे":781,"डु":358,"णि":851,"णी":758,"णु":577,"णा":1135,"तक":2674,"८ ":811,"णन":433,"९ ":917,"तव":480,"ति":11566,"ता":20016,"तु":2358,"ती":14469,"तत":547,"तथ":2628,"तप":364,"तन":1343,"ण्":1311,"तम":1364,"णो":495,"तल":566,"तर":5109,"थव":456,"था":11678,"थी":1994,"थि":3214,"ते":6961,"तो":1865,"त्":23294,"थम":587,"थल":512,"दक":1341,"दस":512,"दश":363,"दृ":463,"दू":2227,"दु":1528,"दी":5182,"दि":8815,"दा":4680,"थो":462,"थे":2431,"दन":776,"दल":1038,"दर":2412,"थ्":491,"धा":4715,"नट":1830,"नत":1382,"खें":445,"नद":975,"धी":935,"धि":5621,"धु":599,"दो":2067,"दौ":382,"द्":15486,"नई":683,"दे":6364,"धन":912,"नक":3879,"नग":1441,"धर":1283,"नर":642,"नल":477,"नव":1823,"नन":633,"नप":443,"ध्":2713,"नम":981,"नी":7183,"पं":1090,"नु":2801,"ने":15948,"नस":1797,"नह":1786,"ना":16910,"नि":11710,"पक":1243,"नो":2338,"न्":16749,"पत":2217,"पन":4849,"पद":2167,"पड":542,"पट":576,"पश":1179,"पह":3589,"पस":581,"पल":544,"पय":630,"पर":12235,"बई":388,"पे":1223,"पै":501,"पू":3275,"पृ":1255,"पा":8076,"पि":1966,"पी":1550,"बं":1558,"पु":5232,"फल":545,"फर":388,"प्":26390,"पौ":356,"पो":892,"बन":3146,"फे":662,"बद":869,"फि":861,"बड":1139,"फी":943,"फा":687,"बज":3798,"फ़":1678,"फो":368,"फ्":1074,"बर":2061,"बल":818,"गया":3134,"भग":1053,"बस":1999,"बह":1601,"बि":1756,"बा":6278,"बु":789,"बी":1868,"मं":2240,"बे":1048,"बै":523,"बो":1031,"भर":525,"ब्":3946,"मक":1369,"भव":561,"भी":5128,"यं":862,"भि":1870,"भा":13836,"मत":879,"मण":522,"भू":2019,"भु":462,"मन":2122,"मध":940,"मद":711,"भौ":389,"भो":416,"मल":693,"यक":2875,"भ्":381,"मय":1214,"मर":1260,"मश":384,"मस":725,"मह":3586,"मृ":555,"यत":1327,"मू":1671,"ख्य":2528,"यद":785,"मि":6854,"मा":15028,"मु":5029,"मी":3565,"रं":1975,"मो":1712,"यम":1479,"म्":5925,"मे":33130,"यन":1546,"यप":564,"मै":980,"रख":1463,"यव":775,"रग":385,"रक":5780,"यय":399,"यर":1126,"या":29338,"रज":1027,"यह":10437,"रच":1272,"रद":2279,"रथ":786,"रत":13386,"यू":1784,"रण":4290,"यु":3494,"यी":833,"यि":596,"रय":1959,"रम":3670,"रभ":636,"यो":8068,"रब":740,"रप":839,"ये":5448,"रन":4212,"लम":734,"लय":1888,"लब":457,"लन":1624,"लत":1279,"लग":2035,"लक":1497,"र्":27657,"रो":5583,"रै":502,"रॉ":358,"रे":18745,"गां":472,"रू":3986,"लं":804,"री":10641,"रु":2131,"रि":9664,"रा":30478,"रह":3970,"रस":3428,"रश":605,"रव":1845,"रल":964,"वं":3802,"ल्":5184,"लो":3980,"चन ":356,"लै":601,"ले":6664,"लु":426,"ली":6031,"लि":10617,"ला":9912,"लव":4226,"शब":1373,"वो":877,"वै":1045,"शन":10719,"वे":7461,"व्":3139,"शर":623,"वह":1716,"वव":621,"वश":922,"वस":1629,"वृ":595,"शत":728,"वा":18296,"वि":15882,"वी":3437,"वप":710,"वन":1882,"वध":1955,"शक":894,"वल":726,"वर":5872,"वय":393,"वज":391,"वक":455,"वत":1673,"षे":3151,"सन":2988,"सप":658,"सभ":1408,"सब":1580,"सम":9143,"ष्":6623,"सर":4398,"सल":818,"सव":526,"षा":3622,"सट":463,"षि":1967,"सत":766,"सद":867,"शै":363,"शे":1186,"श्":6992,"शो":892,"षय":360,"सक":10544,"शह":1374,"शी":1148,"सं":12512,"शु":1050,"शा":4600,"शि":3780,"गवा":390,"षण":1876,"है":50827,"हे":2158,"हु":7130,"ही":5060,"हि":5996,"हा":10508,"ह्":694,"हो":8889,"हन":827,"से":22788,"सु":1954,"सी":5308,"हत":2956,"सू":1760,"चल ":435,"सि":5630,"सा":11391,"सह":931,"सस":498,"हव":548,"हस":476,"हल":1812,"हम":833,"स्":33294,"हर":3284,"सै":435,"सो":953,"़त":356,"ात":13410,"ाथ":2015,"ाण":2291,"ाठ":433,"िं":3492,"ाड":1607,"ाट":1520,"ाब":2717,"ाभ":451,"ाप":4193,"ाफ":948,"ान":23672,"ाद":7103,"गुर":518,"ाध":1672,"ाव":4478,"िख":1296,"िक":17099,"ाल":13682,"ार":38751,"ाय":6583,"िए":2749,"ाम":8252,"िज":2534,"ाह":4362,"िच":656,"ास":7258,"ाष":4485,"िग":560,"ाश":1899,"़ी":1936,"ां":6856,"़ा":2260,"़ि":839,"ाँ":2505,"़ो":448,"ाइ":2283,"ाई":2655,"़े":807,"ाउ":506,"ाओ":2028,"ाक":3759,"़्":460,"ाए":1076,"ाच":1779,"ाज":7904,"ाग":3365,"ाख":925,"ीड":730,"ुं":2936,"ा।":4894,"ुई":845,"ीत":2135,"ुआ":2021,"ीप":1050,"ीन":3683,"ुए":1050,"ीम":1042,"ीय":7229,"ीब":439,"ील":1370,"ुओ":472,"ीर":2043,"ुग":719,"ुख":2469,"ीव":1580,"गीत":642,"ुक":2798,"ुज":614,"ुछ":884,"ीस":1060,"ुट":385,"िट":1437,"ीं":3186,"गिक":498,"िण":1209,"गाल":415,"ित":17874,"िद":3772,"िध":2081,"िन":9694,"िप":1804,"िब":505,"िभ":1498,"िम":3142,"िर":6200,"िय":18344,"िल":8308,"ीक":2676,"िश":4603,"िव":3402,"िस":8212,"िष":1899,"ीच":800,"िह":1477,"ीज":592,"ीट":1012,"ेव":2738,"ेश":12536,"ैक":523,"ेल":9698,"ेय":725,"ेर":2606,"ेम":795,"ेब":355,"ेप":664,"ेन":6508,"ैद":560,"ैत":376,"ैज":408,"ेह":634,"ेस":4417,"ेष":1173,"ैर":490,"ैल":1189,"ैन":999,"े।":1956,"ॉन":366,"ैस":1223,"ें":31320,"ेक":2519,"ेख":1744,"गों":941,"ेट":1393,"ेड":787,"ैं":11503,"ेत":4873,"ेद":951,"ेग":371,"ेज":1606,"ृत":2832,"ृष":1881,"गोल":437,"ुत":2428,"ुण":594,"ुड":541,"ुन":2123,"ुध":368,"ुद":1873,"ुप":1093,"ुर":6463,"ुम":1318,"ग्ल":427,"ुल":2104,"ुष":645,"ुस":2362,"ुव":1118,"ग्र":3597,"ूच":523,"ूट":2497,"ूत":791,"ी।":1527,"ून":1187,"ूप":2981,"ूब":457,"ूम":650,"ूर":5314,"ूल":1317,"ूष":1076,"ूस":930,"ूह":483,"्व":16523,"्श":2596,"्ष":9849,"्स":6797,"्ह":2245,"्भ":823,"्म":10658,"्य":26066,"्र":57172,"्ल":4149,"ची ":462,"ौत":437,"ौद":469,"ोर":2026,"ोल":2394,"ोब":410,"ोम":1176,"ोस":741,"ोष":453,"ोह":815,"ोश":547,"ोव":518,"्ण":2398,"्त":17955,"्ड":2149,"्ट":15553,"्ठ":1556,"्ञ":2460,"्फ":981,"्ब":2118,"्प":6879,"्ध":4156,"्न":3593,"्थ":9797,"्द":7520,"ौर":1279,"्ज":1507,"्च":2621,"्ग":2050,"्क":4547,"ों":15790,"ै।":21739,"ोई":504,"ॉर":357,"ॉल":485,"ोज":1283,"ोड":4892,"ोट":1429,"ोद":429,"ोत":5502,"ोप":971,"ोध":664,"ोन":2390,"ोक":1863,"ोच":771,"ोग":4303,"००":2062,"१०":362,"१८":536,"१९":2833,"२०":1612,"९६":475,"९५":380,"९८":427,"९७":465,"९९":438,"जन ":1003,"जब ":495,"चती":1825,"चना":962,"गई ":460,"के ":35060,"का ":19876,"कि ":2326,"की ":19870,"कल ":368,"कम ":375,"कर ":3798,"और ":11340,"कित":562,"किन":799,"काफ":651,"काम":601,"कार":8097,"काल":1674,"काश":1174,"काव":390,"कास":610,"किप":365,"किय":4402,"किल":674,"किस":2621,"कीय":409,"कुछ":880,"कुल":589,"कुम":405,"कां":514,"कान":492,"कहत":1259,"कहल":373,"कहा":1242,"कला":836,"गी ":381,"कवि":783,"कम्":429,"कर्":878,"गा ":602,"करा":372,"करे":537,"करत":2060,"करण":990,"करन":3111,"कथा":387,"कता":1005,"कते":720,"गर ":1575,"खंड":407,"गत ":745,"खा ":869,"कंप":421,"को ":9463,"ओं ":2427,"एवं":2948,"एक्":3566,"कई ":776,"ओर ":406,"उसक":842,"उसे":365,"उपन":475,"उपय":550,"एँ ":417,"एक ":11574,"आदि":993,"आधा":542,"आर्":522,"आवश":646,"उन ":374,"इति":479,"अथव":383,"अधि":1401,"अनु":2084,"अध्":641,"अन्":1665,"अने":519,"अपन":2305,"इस ":3686,"अभि":793,"अमे":560,"अलग":451,"अर्":1665,"अवध":1855,"उन्":1250,"उद्":651,"उनक":1565,"उत्":2559,"उस ":606,"इनक":960,"इन्":786,"इसक":6193,"इसम":1168,"इसी":419,"इसे":1083,"इस्":411,"ेश्":531,"ेशो":391," ओर":436," कं":518," कई":773," और":11423," कन":365," कम":1021," कर":8774," कल":965," कव":757," कह":3125," की":14772," कि":9638," का":20292," कृ":765," कु":2268," के":32645," कै":557," गई":551," को":14690,"ेशन":8153," गए":382," क्":4800,"ेवा":915," एक":15549," एव":3020," ऐस":714,"ै। ":17713,"ोई ":492," चौ":410," जग":453," चु":690," ची":475," जं":1512," चि":1251," चा":1105," चे":563," जर":355," जल":669," जब":682," छो":700," जह":416," छू":1830," जन":2746," ज्":953," जि":5438," जा":9396," जु":639," जी":1466," जो":3609," जै":1100," गर":416," गय":3607," खे":428," गण":526," घं":1793," खा":713," गो":922," ग्":1394," गु":1570," गा":1413," । ":3304," चल":837," चर":408," अं":2469," अब":411," अप":3085," अन":4720," अध":2196," अथ":432," आक":690,"ेता":622," अल":1382," अर":2119," अम":1263," अभ":1046," आज":524," अस":670," अव":2716," आत":825,"ेत्":3123," इं":1185," अक":778," अग":573," आं":486," अत":780,"ेपा":393,"ेन्":1060,"ेना":477,"ेयर":374," इस":13352," इल":428," इन":2514,"ों ":14584," इत":729," आस":419," आर":1183," आम":378," आय":881," आव":1052," आन":491," आद":1214," आध":1052," आप":1294,"ेलव":3726," उस":2203," उप":2582," उन":3214," उद":990," उत":2673,"ेरि":755," वा":3866," वी":554," वि":11396," वृ":367," शत":617," वस":497," वह":1459," व्":2079," शर":525," वे":1801," वै":880," शब":1343," शु":774," सं":11345," शि":1818," शा":2156," शह":1270," सक":1827," श्":1605,"ैसे":672," शक":380," वर":2508," लग":1362," ला":1268," लि":5639," ले":1874," लो":1934," रख":1043," रज":470," या":6370," यह":10383," रच":735," यू":702," यु":969," यो":670," ये":2040," रा":8448," रि":478," रह":2139," रे":6398," रू":2374," रु":449," लं":500," रो":897,"ोर ":430," हो":7690," हि":3553," ही":2071," हा":1189," हु":3748," हे":505," है":50701," सम":6692," सभ":777," सब":1516," सन":1812," सर":2776," सट":433," सद":698," सत":571," हम":409," स्":16029," हर":704," सो":571," सा":6452," सि":2848," सह":892," से":17371," सी":1037," सु":1695," सू":1297," दर":820," थे":2324," दू":1295," दृ":400," दी":559," दु":776," दा":748," दि":4337," दक":983," त्":639," तो":1173," था":4674," थी":1702," तम":403," तर":977," तथ":2624," तत":379," ता":833," ति":580,"ोग ":2225," ती":840," तु":355," तक":1670," डा":569," डि":508," ट्":3950,"ोच ":425," मो":707," मे":29038," मै":859," मू":889," यद":611," मा":5157," मि":3653," मी":694," रं":422," मु":2959," मह":3455," मर":397," भौ":360," मन":1109," मध":857," भू":1742," भी":4132," भा":10893," भर":368," ब्":1174," बे":646," बै":464," बो":710," बा":3995," बि":1259," बी":1196," मं":1754," बु":605," भग":427," बह":1547," बस":477," फ्":403," बर":576," बल":422," बद":685," बन":2421," फे":481," फा":416," बज":3787," फ़":822," फि":728," बड":1101," प्":19145," पो":399," पि":711," पा":4190," पु":2921," पी":496," बं":729," पे":601," पै":416," पृ":1225," पू":2103,"ोड ":4034," पर":10662," पश":1088," पह":3539," पड":455," पट":420," पद":1827," पत":1117," न्":487," नह":1717," नि":5215," ना":4741," पं":1035," नी":536," ने":3413," ध्":387," नव":592," धा":800," नद":808," दे":3244," द्":5503," दो":1318," धर":1010," नग":840,"ेंट":533,"ेंद":417," ई ":361,"ेल ":4266,"ेर ":787,"ेस ":3757,"ेष ":525,"ेश ":2529,"े। ":1586,"ेकि":361,"ेक्":824,"ैंड":368,"ैं।":6253,"ेज़":466,"ेजी":411," व ":823,"ृष्":1735,"ें ":29625,"ृति":1045,"ृत्":636,"ेन ":4101,"ेद ":371,"ेज ":388,"ेट ":613,"ैं ":4429,"ेक ":779,"ुष्":405,"ुवा":512,"ुला":407,"ुरा":1009,"ुरस":482,"ुर्":818,"ुरु":791,"ुरू":359,"ुमा":600,"ुनि":743,"ुना":530,"ुद्":1350,"ुत्":627,"ूसर":611,"ूषण":1023,"ूर्":2859,"ूरी":482,"ूटत":1807,"ुस्":700,"ुसा":1149,"िकल":459,"ाला":1369,"ालि":2288,"ाली":1852,"ाले":1192,"ावि":362,"ावा":595,"ुत ":1429,"िका":3179,"िकि":844,"िकी":876,"ावर":399,"िको":367,"िक्":1744,"ाषा":2056,"ासन":527,"ाष्":2240,"ाशि":573,"ासक":514,"ाहि":1577,"ासि":587,"ासा":469,"ासी":381,"ाहर":429,"ास्":1433,"िज्":1407,"ुर ":2020,"िता":1136,"िति":559,"ुल ":595,"ित्":3274,"िद्":3069,"िधि":924,"िधा":871,"िनट":1785,"िना":538,"िनि":795,"िन्":3490,"िपी":396,"िभि":546,"िभा":779,"ियन":355,"ियम":677,"िमी":551,"िमा":800,"ियो":3134,"िये":2350,"िया":10338,"िर्":2740,"िरा":423,"िलत":401,"िले":1007,"िल्":2138,"िलो":516,"िला":1775,"िसम":787,"िष्":1088,"ी। ":1157,"िशा":959,"िश्":1982,"िशे":677,"िसक":1052,"िवा":1432,"िवे":381,"ीका":588,"िवर":417,"ूप ":2670,"िहा":1270,"ून ":537,"िसे":557,"िसी":1508,"िस्":2756,"ीडि":468,"ुंब":372,"ुंच":1928,"ीटर":673,"ूल ":705,"ीति":750,"ूर ":759,"ुआ।":435,"ूह ":393,"ुओं":451,"ीर्":408,"ीमा":484,"ुक्":1845,"ीवन":532,"ुख्":1068,"ृत ":890,"ीं ":2774,"ित ":12024,"िण ":703,"िन ":1347,"िल ":1061,"ीक ":803,"ांग":686,"ांस":610,"िम ":1068,"ांत":1630,"िय ":463,"िर ":1319,"ीच ":562,"ाएँ":397,"िश ":406,"िस ":650,"ा। ":4040,"ुआ ":1392,"ीत ":751,"ागर":849,"ाक्":373,"ाकि":1058,"ाका":641,"ाकर":472,"ाओं":1931,"िंद":1176,"ाड़":911,"िंह":577,"ुए ":894,"िंग":982,"ाटक":402,"ाजा":802,"ाजि":402,"ाज्":2259,"ीप ":552,"ाजन":843,"ाजध":594,"ाजस":382,"ाची":795,"ीन ":2404,"ुई ":687,"ाने":2242,"ाना":1838,"ानि":2065,"ानी":2791,"ुख ":1161,"ानव":590,"ानस":622,"ाध्":419,"ापन":842,"ान्":1734,"ानो":532,"ादी":544,"ादा":388,"ादि":1157,"ानत":633,"ाधि":410,"ानक":524,"ाति":524,"ाता":4840,"ाती":1316,"ाते":918,"ात्":3549,"ील ":655,"ीय ":6964,"ीर ":855,"ारी":1527,"ारि":1016,"ारा":6234,"ारस":394,"ार्":5244,"ारो":922,"ारू":465,"ारे":707,"ालय":1677,"ामि":517,"ामा":1032,"ायक":414,"ाम्":377,"ायन":449,"ामी":544,"ाया":1613,"ायी":366,"ारक":420,"ारण":1386,"ारत":7763,"ाबा":770,"ाब्":555,"ामक":498,"ुछ ":876,"ापा":517,"ाप्":901,"ाफी":651,"ां ":1658,"़ी ":1669,"ाई ":2362,"़े ":628,"हों":935,"है।":21737,"होत":4643,"होन":1130,"ह्म":356,"़ा ":1290,"ाँ ":1565,"ाग ":1189,"ाथ ":1651,"ाद ":3112,"ाण ":964,"ात ":1397,"ान ":8758,"ाज ":1013,"ाश ":423,"ाव ":1068,"िक ":8100,"ाह ":929,"ास ":2767,"ाम ":3709,"िए ":2584,"ाब ":747,"ाल ":3360,"ार ":11273,"ाय ":1113,"समु":515,"समा":1211,"समू":429,"सरक":1452,"समे":1977,"सम्":2440,"सर्":919,"सबस":1305,"समय":1034,"ष्य":501,"ष्ण":694,"ष्ठ":1362,"सभी":533,"सभा":753,"ष्ट":3181,"षेत":2985,"सन्":672,"हत्":826,"हते":1441,"सेन":499,"सें":450,"सीम":423,"सिर":645,"सूर":646,"सूच":437,"सां":361,"साह":1353,"सिद":1352,"सित":526,"साध":457,"सार":1977,"साम":1236,"साय":536,"सिक":706,"साग":441,"सिं":774,"साथ":1234,"सहा":390,"ससे":419," १८":501," १९":2789," २०":1512,"हला":582,"हले":581,"हरा":369,"स्व":2405,"स्य":682,"स्म":485,"स्ल":386,"स्थ":6865,"स्प":4184,"स्ट":9331,"स्त":5132,"स्क":2303,"सेव":720,"हैं":10612,"हें":816,"हुत":957,"हुई":797,"हुए":951,"हुं":1933,"हुआ":1762,"हिन":1798,"हित":1670,"हीं":1893,"हास":1027,"हाव":428,"हार":1703,"हान":874,"हिं":1060,"हाँ":938,"हां":1185,"हे ":650,"है ":18074,"सकी":3365,"सका":2827,"सके":2127,"सत्":357,"षिण":921,"सटी":407,"षित":444,"हो ":1330,"शेष":769,"शों":440,"हा ":1528,"सकत":1521,"ही ":2790,"श्व":2006,"श्र":1917,"श्य":1102,"श्च":1235,"शहर":1243,"से ":20466,"सी ":3799,"हर ":1676,"संच":2031,"शिय":571,"संक":898,"संग":1492,"संख":1034,"शिव":510,"संघ":401,"संब":719,"संप":1355,"संय":444,"संस":2227,"शित":453,"शाह":383,"शास":1407,"शिक":1243,"शाल":480,"वेश":377,"वेद":482,"शता":469,"सर ":563,"सा ":1620,"व्य":2741,"शब्":1328,"वों":401,"वर्":3433,"षा ":2805,"वरी":565,"ववि":516,"शक्":405,"वश्":752,"वस्":1030,"सन ":1657,"वाद":1110,"वान":862,"वाच":378,"विक":1766,"वाल":2753,"वास":1153,"वार":6241,"वाय":555,"वाम":390,"वित":981,"विद":1842,"विध":1382,"विज":1255,"वाह":694,"विच":389,"वीं":679,"विष":806,"विश":2580,"विस":375,"विव":625,"विभ":1112,"वीप":490,"वता":365,"वधि":1770,"वपू":515,"शा ":783,"षण ":1678,"शी ":479,"वंश":456,"शन ":10109,"वे ":5027,"वि ":440,"वा ":1780,"वी ":1441,"ल्प":398,"ल्म":761,"ल्य":463,"ल्ल":1775,"लोक":1046,"लोग":827,"लों":837,"वह ":1195,"लोम":397,"वल ":387,"लेख":932,"लेक":881,"लिय":3022,"वर ":730,"लाक":373,"लात":527,"लिए":2317,"लाल":465,"लिख":696,"लिक":529,"लित":2228,"लिप":379,"वन ":938,"लवे":3731,"लना":388,"लता":462,"लती":425,"वं ":2957,"लगभ":597,"लगा":459,"रेस":3665,"रोग":432,"रों":2025,"र्श":1019,"र्व":3266,"र्स":388,"र्ष":1579,"र्म":3443,"र्भ":362,"र्य":2627,"र्थ":2552,"र्द":1098,"र्ध":360,"र्न":513,"र्फ":531,"र्ब":360,"र्ट":763,"र्ड":507,"र्ण":1686,"र्त":1633,"र्ग":1726,"र्क":924,"र्ज":853,"र्च":479,"रीक":801,"रिव":843,"रिय":2208,"रीय":1696,"रीर":445,"रुप":452,"रूप":2871,"रें":640,"रेज":901,"रेल":6023,"रेन":3698,"रसा":555,"रसि":1094,"रहत":499,"रहा":649,"रहे":489,"रस्":963,"ले ":3374,"रां":1067,"रान":1776,"राप":737,"रात":590,"राण":691,"राज":5799,"राच":861,"राक":432,"रिट":356,"रित":976,"राष":2127,"रास":461,"राम":1378,"राय":1077,"रार":802,"रिक":2624,"राव":460,"ला ":4369,"रयो":985,"रयु":635,"रम्":388,"रमा":570,"रमु":1096,"रवा":666,"ली ":4841,"रने":2577,"रना":959,"रदे":1187,"रदा":576,"रभा":427,"योज":542,"योग":2669,"यों":3685,"या।":1162,"युक":1333,"युत":419,"युद":407,"यान":790,"याप":561,"यात":2560,"याद":888,"यास":655,"यिक":384,"याल":1423,"यार":471,"याय":535,"रता":1516,"रति":1618,"रती":4166,"रते":811,"रत्":447,"रथम":512,"लय ":1619,"यूट":437,"यून":379,"रणा":516,"रचन":643,"रक्":994,"रखे":433,"रजि":411,"यां":725,"याँ":525,"यहा":1528,"लन ":775,"रे ":1761,"मस्":459,"महा":2097,"महत":756,"यक्":1167,"रु ":369,"यका":377,"री ":6215,"मृत":432,"मूह":442,"मूल":727,"मुद":734,"मुख":2339,"रंभ":445,"मुं":391,"मीट":638,"रंग":680,"मिल":1800,"मित":732,"मिन":2223,"मार":2023,"माल":612,"मिक":732,"रो ":378,"माण":1011,"माध":371,"मात":697,"मान":5551,"माज":766,"मां":436,"मों":431,"लग ":468,"यदि":507,"में":27306,"मेर":842,"मेल":1950,"यता":597,"रका":3522,"म्र":418,"म्प":956,"म्ब":1357,"म्म":1860,"रत ":4510,"रण ":3158,"या ":17033,"यु ":436,"यी ":716,"भिन":962,"भाव":792,"भाष":2240,"भार":7799,"भाग":1261,"रम ":841,"यंत":450,"ये ":4867,"मध्":813,"भूम":411,"भूष":1010,"रल ":672,"रा ":9045,"मर्":364,"रह ":1087,"मा ":1358,"भगव":386,"मी ":1758,"मे ":1785,"यन ":960,"बहु":1203,"बसे":1366,"बाल":449,"बार":924,"बाद":1868,"बां":380,"यर ":634,"मंत":477,"मंद":933,"बिह":404,"बीच":558,"मंड":367,"यम ":869,"रक ":417,"यह ":8676,"बोल":432,"ब्र":1124,"ब्द":1896,"प्य":460,"प्र":23891,"प्त":1355,"भा ":824,"भी ":4811,"मन ":544,"फ़ि":394,"बजे":3647,"फिल":452,"मय ":1094,"बड़":987,"बदल":617,"यक ":1025,"फेर":414,"बना":1428,"बन्":526,"फ्र":464,"पहु":2050,"पहल":1024,"पश्":999,"बी ":558,"बा ":412,"पर्":1203,"परम":473,"पयो":528,"परि":1837,"परा":615,"मक ":839,"पृष":917,"पुस":378,"पूर":2834,"पुत":428,"पुर":3647,"पीड":441,"बंग":529,"बंध":817,"पास":574,"पित":787,"पाक":1033,"पान":519,"पात":387,"पाद":1538,"पार":1007,"पाल":950,"पक्":435,"फी ":766,"न्त":2330,"न्ध":640,"न्न":1957,"न्द":3701,"न्य":2792,"न्म":1190,"न्ह":2015,"नों":1406,"पद्":1215,"पदा":458,"भग ":605,"पनी":874,"पना":1055,"पन्":743,"पने":1546,"बर ":1142,"पत्":1249,"पति":612,"पड़":437,"नमे":432,"नवर":402,"नसं":440,"नदी":699,"ध्य":2164,"नुस":1344,"पंज":567,"नीत":724,"नेप":393,"नेत":472,"नेक":552,"बई ":387,"नही":1669,"नसभ":406,"निव":567,"निर":2352,"निय":1801,"निध":617,"नित":1221,"नाव":392,"निक":2637,"नाय":738,"नाम":2777,"नार":680,"नान":715,"नात":423,"नाथ":458,"नाट":450,"नाड":359,"नाग":557,"द्द":569,"द्व":5706,"द्र":2473,"द्य":2403,"द्म":1046,"द्ध":2842,"धर्":969,"नका":1135,"नकी":794,"नके":1054,"देख":471,"देव":1125,"देश":3481,"दों":393,"दोन":372,"धित":713,"धिय":418,"धार":1754,"धिक":1763,"धान":1811,"पर ":7035,"नता":441,"नते":555,"नगर":1205},"n_words":[3436892,4107546,2722787],"name":"hi"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hrv b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hrv new file mode 100644 index 000000000..116cfa0d0 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hrv @@ -0,0 +1 @@ +{"freq":{"D":8690,"E":5169,"F":5109,"G":8706,"A":14720,"B":12556,"C":10193,"L":6822,"M":14153,"N":10511,"O":10729,"H":9113,"I":13451,"J":5359,"K":11989,"U":4743,"T":10711,"W":3179,"V":5850,"Q":585,"P":15109,"S":23054,"R":9319,"Y":1450,"X":701,"Z":4251,"f":16193,"g":88687,"d":148916,"e":436858,"b":60942,"c":64868,"a":586818,"n":342270,"o":415815,"l":177559,"m":139424,"j":258985,"k":204303,"h":49394,"i":501698,"w":7347,"v":140168,"u":209613,"t":201984,"s":238514,"r":271701,"q":1755,"p":126499,"z":85944,"y":9646,"x":2022,"í":886,"é":1412,"á":1674,"ó":546,"đ":8171,"ć":16773,"Č":895,"č":46294,"Ž":887,"ž":23555,"Š":1432,"š":26211," l":9617," m":20259," n":49295," o":45630," h":4791," i":61249," j":56434," k":46966," d":31478," e":6507," f":5286," g":21986,"р":912," a":19142,"с":742," b":17477,"т":629," c":5752," z":19710," u":45274," t":21468," w":820," v":15539," p":67380," s":79773," r":20001," J":5152," K":11465," H":8434," I":11848," N":9837," O":7822," L":5986," M":13514," B":11861," C":9435," A":13018," F":4631," G":8304," D":7573," E":4598,"л":648," Z":4104,"к":817," Y":1407," X":526,"и":1209,"о":1253,"н":943," S":19621," R":8667,"в":563," Q":537," P":14387,"а":1816," W":3048," V":5326," U":4477,"е":917," T":9972," č":5596," Č":887," ž":5028," Ž":838," Š":1403," š":4901,"A ":857,"Da":1321,"Co":1834,"Cr":1328,"Ce":588,"Ch":1843,"Du":764,"Do":1328,"Dr":1133,"De":1138,"Di":1002,"Fe":631,"H ":574,"Fa":563,"Eu":879,"Ge":716,"Ga":972,"I ":821,"Fr":1113,"Fo":779,"Fi":649,"Au":808,"Ar":1684,"At":729,"As":560,"D ":829,"Ba":2710,"Af":545,"Am":1341,"An":1467,"Al":1655,"Bu":1011,"Br":2042,"Ca":2160,"Bi":1321,"Be":1685,"Bo":2115,"Ku":844,"Kr":1748,"Ko":2488,"Le":881,"Li":1283,"La":1685,"Lu":593,"Lo":1036,"Me":1818,"Mi":1887,"O ":2633,"Ma":5853,"Mu":793,"Mo":1972,"Nj":820,"Ni":1096,"Ne":1404,"Na":3401,"No":2003,"Ob":956,"Gl":526,"Gr":2253,"Go":1536,"Gu":881,"Gv":612,"Ha":1340,"He":1374,"Hi":570,"Ho":905,"IS":2154,"Hr":2959,"Hu":536,"In":4619,"Is":978,"Ja":1450,"L ":681,"Iz":610,"Je":1026,"Jo":711,"Ju":1563,"Ka":3681,"Ki":952,"Tu":1072,"Tr":1314,"To":1609,"Th":1212,"Ti":993,"Te":1282,"Ta":1685,"St":1916,"Sv":940,"Su":1303,"Wi":722,"Wa":1107,"Vo":662,"Vi":1040,"Va":1022,"Ve":1522,"Pu":746,"Pr":3018,"S ":720,"Pe":1604,"Pa":2898,"Pl":816,"Po":3639,"Pi":867,"Os":790,"Ov":672,"Op":1011,"Or":735,"Se":1283,"Sj":776,"Si":1385,"Sh":659,"Sl":1203,"Sr":1393,"Sp":846,"So":1277,"Ru":1026,"U ":1401,"Sa":3386,"Re":2977,"Ri":1491,"Ro":1097,"SO":2074,"Ra":1418,"b ":1522,"a ":202747,"Za":2365,"Ze":593,"i ":135497,"ađ":2045,"gd":857,"ge":5429,"ga":10157,"ać":1902,"fi":4106,"fs":661,"fr":2013,"ač":10342,"fu":639,"fo":2404,"j ":16449,"he":4881,"ha":5859,"gn":997,"gl":6895,"gi":6788,"gh":714,"gu":4729,"gr":14473,"go":15835,"du":5516,"dv":2741,"g ":19299,"ea":3988,"eb":4045,"ec":3773,"ed":22606,"de":10224,"dg":624,"di":30316,"dj":3005,"dm":1005,"dl":806,"do":12624,"dn":15638,"ds":4759,"dr":13255,"ew":844,"eu":1755,"ev":10791,"ey":838,"ez":15435,"fa":1476,"h ":20168,"fe":2011,"eh":1279,"eg":7983,"ef":1181,"ee":1826,"el":24518,"ek":14461,"ej":2546,"ei":1534,"ep":5699,"eo":3348,"en":44674,"em":19226,"et":18394,"es":16599,"er":32266,"ca":14154,"e ":160018,"br":6048,"bu":5481,"bn":1412,"bo":6809,"bj":1695,"bl":6540,"bi":13442,"be":6031,"db":626,"da":22107,"f ":1430,"cu":2623,"ct":683,"cr":1908,"co":2679,"ck":2130,"ci":21232,"ch":4164,"ce":10558,"c ":2983,"az":15697,"ay":1948,"ba":10149,"d ":22851,"at":29447,"as":22343,"ar":30709,"aw":1498,"av":28227,"au":3869,"ak":15591,"al":35013,"ai":3078,"aj":16895,"ao":6448,"ap":10100,"am":17849,"an":70440,"ac":13980,"ad":21936,"aa":799,"ab":3879,"ag":6276,"ah":2814,"ae":1668,"af":2077,"nu":8144,"nt":10450,"ns":14593,"ič":14290,"no":45797,"nn":1399,"nz":952,"ny":715,"oe":678,"of":2150,"oc":4342,"od":40790,"oa":2451,"ob":12953,"om":28810,"on":23346,"ok":14795,"ol":17826,"oi":3961,"oj":40426,"og":22833,"oh":1159,"ot":12114,"os":23349,"ov":31034,"ou":2922,"op":11191,"oo":1568,"or":33494,"jč":526,"r ":11028,"ow":1054,"oz":7848,"pe":6182,"pa":15403,"pl":8816,"pn":1287,"po":36246,"ph":606,"pi":11043,"pj":1476,"lo":18651,"ln":5989,"lm":1222,"ll":3111,"ls":2651,"lu":8623,"lt":2358,"o ":61519,"ma":31717,"mb":2862,"dž":894,"me":24452,"ml":1963,"eš":3371,"mi":10591,"mj":5104,"mn":1665,"mp":2261,"mo":11753,"mr":1000,"ms":2000,"mu":3945,"p ":2149,"na":87240,"nc":5972,"nd":11672,"ne":33576,"nf":891,"ež":1706,"ng":7899,"ni":54450,"nj":27833,"nk":2801,"ić":2802,"jv":1605,"eđ":3970,"ju":19590,"eč":2671,"js":8691,"jn":2724,"jo":4699,"eć":4631,"jk":855,"ki":28341,"ke":16969,"kc":1026,"ka":37663,"m ":37899,"ks":2734,"kt":4893,"ku":14523,"kv":1615,"ko":63668,"kr":10108,"kl":4333,"km":1244,"kn":1083,"li":41243,"lk":741,"lj":24378,"le":17764,"ld":889,"lg":643,"la":37196,"lb":2414,"n ":24345,"hr":2448,"hv":1089,"ht":807,"hu":1937,"hi":4652,"hn":862,"ho":4536,"id":4699,"ic":20781,"ib":2814,"ia":4852,"ih":18991,"ig":5433,"if":1923,"ie":2060,"k ":14010,"ir":12272,"is":21664,"it":16417,"iu":848,"iv":14019,"aš":3959,"ij":57037,"ik":23850,"il":22797,"im":27723,"in":47299,"io":10059,"ip":4978,"je":134763,"až":1877,"ji":26676,"iz":19026,"l ":6966,"ja":39549,"z ":7997,"ož":2534,"oš":2893,"wi":861,"rč":1709,"y ":3377,"wa":2878,"we":956,"vl":4881,"vj":3877,"vk":562,"vi":24026,"vu":3419,"vr":6622,"vs":1342,"vn":9959,"vo":21455,"uz":3112,"uv":1349,"ve":22017,"vc":593,"va":35406,"x ":785,"ui":1893,"uj":4079,"uk":4559,"ul":5933,"pć":2758,"ue":1973,"ug":8425,"uh":1544,"ur":9708,"us":10059,"ut":7404,"um":7672,"un":8708,"uo":923,"up":11863,"tu":9961,"tt":1393,"tv":7233,"ođ":1449,"ub":5211,"ua":3882,"ud":5733,"uc":1692,"w ":858,"to":28843,"tn":5773,"tm":575,"tl":1860,"oć":686,"ts":8790,"tr":16932,"oč":4671,"tp":896,"te":22658,"tk":2453,"tj":1700,"ti":34096,"th":3097,"v ":4865,"ta":38983,"su":13292,"sv":6451,"ss":1881,"st":55588,"sl":7897,"sk":52271,"sn":7159,"sm":3278,"sp":5046,"so":5247,"sr":3449,"sc":1522,"se":24429,"sh":2381,"sj":4697,"si":10381,"rz":1007,"u ":87089,"sa":16094,"rr":1162,"rs":8936,"rt":5687,"ru":17434,"rv":8435,"ry":930,"rp":1334,"ro":34834,"rn":10194,"rm":2849,"rl":1655,"rk":2924,"rj":894,"ri":44000,"rh":1312,"rg":3269,"iž":1025,"re":32485,"rd":3070,"rc":1885,"rb":2322,"ra":64303,"t ":14252,"qu":1390,"iš":6125,"s ":15910,"pt":1447,"pu":6628,"pp":658,"pr":27731,"ps":2712,"už":5556,"uš":2233,"rž":4670,"zg":1072,"rš":1722,"zi":22879,"zb":2089,"zd":2018,"ze":4698,"za":19270,"zv":4353,"uč":5083,"zr":2246,"zu":2322,"zo":3146,"zn":8371,"zm":2468,"zl":2200,"uć":2114,"ye":523,"ya":1738,"yo":520,"á ":773,"é ":601,"ć ":1732,"ći":5749,"ću":1057,"ća":4248,"će":3354,"či":7487,"čj":2822,"čk":13325,"čl":554,"če":5735,"ča":5202,"č ":1473,"đe":2942,"đa":1580,"čn":7182,"ču":1818,"đu":2924,"š ":1063,"šć":1355,"še":2480,"ša":1860,"šp":635,"šn":3132,"šk":2964,"šl":591,"ši":3525,"šu":567,"št":7272,"žu":2110,"žn":3428,"žb":852,"že":4351,"ža":6201,"ži":5092,"đen":1909,"đer":597,"đu ":1688,"đun":708,"čun":831," Ga":961," Ge":702," Fo":742," Fr":1109," Fi":643," Ha":1336," He":1372," Go":1534," Gr":2247," Gu":878," Gv":612," Gl":525," Hu":528," IS":2110," Hr":2946," Ho":895," Hi":565," Je":1023," Ja":1447," Iz":607," Is":977," In":4605," Ka":3666," Ki":914," Jo":707," Ju":1556," La":1670," Le":867," Li":1265," Ko":2481," Kr":1745," Ku":843," Ma":5817," Mi":1882," Me":1804," Lo":1032," Lu":587," Ne":1391,"а ":562," Na":3399," Nj":820," Ni":1084," Mo":1968," Mu":787," Am":1333," An":1450," Al":1637," Af":533," Ba":2689," Au":794," At":724," As":558," Ar":1651," Be":1676," Bi":1296," Bo":2110," Br":2033," Bu":1004," Ca":2140," Ce":585," Ch":1828," Cr":1326," Co":1819," Da":1296," Di":998," De":1131," Dr":1125," Do":1300," Du":759," Eu":878," Fe":623," Fa":554," Wi":714," Wa":1098," Ze":593," Za":2362," a ":4274," Ov":665," Os":789," Or":732," Op":1008," Po":3623," Pl":812," Pi":864," Pe":1599," Pa":2881," No":2002," Ob":956," Ra":1412," Ro":1089," Re":2970," Ri":1491," Pr":3007," Pu":743," Sv":937," Su":1301," St":1875," Ta":1677," Th":1189," Ti":990," Te":1277," Tr":1295," To":1604," Ru":1022," Sa":3371," U ":1282," Sh":655," Si":1373," Sj":776," Se":1273," So":1270," Sp":836," Sr":1393," Sl":1201," Va":1018," Ve":1517," Vi":1035," Vo":661," Tu":1066," ja":1334," iz":11704," je":51007," im":3911," in":3359," il":7148," is":4046," ka":7800," ki":1128," jo":810," ju":3163," ha":604," he":608," gl":3276," gr":8161," go":6544," ih":786," ig":1120," hi":648," ho":696," hr":1744," nj":3220," ni":1874," ne":6451," na":34503," mu":1067," mo":4787," mn":528," ok":4011," on":1068," od":15714," of":856," ob":6528," no":2407," le":827," lj":2291," li":2543," la":2172," ku":1972," kn":829," km":1048," kl":1410," kr":4664," ko":26854," me":3676," mi":2188," mj":1905," o ":1165," ma":4891," lo":1177," am":2645," an":1498," ak":848," al":3416," au":1442," ar":1418," at":615," ba":2490," bi":5965," be":1110," bo":2421," bl":1053," bu":691," br":3222," ca":552," et":559," en":2154," el":1166," ek":584," fa":621," fr":941," fo":883," fi":1669," ge":1007," gd":551," ga":1134," i ":27993," cr":1408," ce":1531," ci":1052," da":4574," do":6878," dr":6375," de":2927," dj":1233," di":5389," dv":2035," du":1555," zn":2259," zr":767," zv":702," za":12881," ze":1108," zb":633," už":620," ru":1327," u ":32404," sa":9931," se":16886," sj":3429," si":2544," sn":698," sm":1890," sl":3915," sk":4532," sr":2957," sp":2436," so":944," ra":7698," re":4140," ri":4141," ro":2280," pu":1716," pr":23703," s ":3500," os":3950," ot":2810," ov":1276," op":3149," or":1765," oz":1224," pe":1664," pa":2832," pl":5604," po":28804," pi":966," pj":1218," va":1250," ve":3149," uz":1739," vo":2912," vr":3315," vi":2766," vj":724," vl":1147," ud":648," tv":902," tu":1007," us":1218," ut":721," ur":562," up":1243," um":849," un":999," uk":1055," ul":803," ug":653," ta":2808," st":9162," sv":5803," su":10580," tr":4273," to":2817," th":929," ti":2177," te":5426," če":1938," čl":530," či":1960," št":1607," ši":1148," šp":620," ži":2289," že":880," žu":1586,"Eur":771,"Fra":831,"Her":776,"Gra":1106,"Gor":695,"Ind":3698,"Hrv":2864,"ISO":2034,"Ara":578,"šće":547,"Ame":663,"Car":617,"Bra":541,"Bri":609,"Bos":708,"Chi":621,"Cha":594,"Nal":560,"Nje":555,"Nov":1094,"Opć":766,"Per":568,"Par":726,"Pro":696,"Pri":721,"Pre":828,"Juž":532,"Kal":564,"Kan":524,"Kar":752,"Kra":872,"Man":821,"Mal":573,"Mar":1189,"Mad":576,"Zag":834,"Sta":754,"Sje":767,"Srb":562,"Sre":533,"Slo":726,"Rus":582,"San":791,"Rep":1934,"SO ":2049,"Vel":771,"The":928,"šen":553,"še ":976,"što":1559,"šte":2571,"šti":879,"šta":884,"štv":1041,"ško":1181,"šnj":2421,"šin":692,"šir":1400,"ški":826,"bje":654,"bja":1027,"bit":2079,"biv":585,"bio":1738,"bil":3046,"bin":696,"bij":1580,"blj":1003,"bli":4296,"bla":688,"bol":1257,"boj":638,"bog":903,"bič":654,"bno":610,"bor":1232,"be ":1311,"ban":1537,"bal":1792,"bav":860,"bar":843,"bi ":1256,"ber":918,"ben":1811,"ca ":10450,"car":656,"can":1075,"ce ":5505,"bri":882,"bro":2066,"bra":1828,"bu ":732,"bum":1939,"buh":796,"aka":2848,"am ":2209,"ake":1450,"aki":683,"aji":1629,"ajn":1118,"ajs":690,"aju":3559,"ajv":1325,"al ":2419,"aja":1758,"aje":2556,"ain":623,"ak ":2449,"aj ":1426,"aha":673,"agr":1324,"agu":525,"ago":1080,"anu":1384,"ano":4034,"ant":2834,"ans":7065,"ane":2342,"ang":1485,"ani":9755,"anj":10858,"ank":1213,"ana":11419,"anc":2218,"and":3683,"amo":1853,"ami":1538,"ame":3781,"amb":801,"ama":5199,"ao ":5760,"alu":766,"alt":538,"als":661,"alo":1706,"aln":4903,"all":806,"ali":7309,"alj":2503,"ale":2883,"ala":6700,"alb":1948,"an ":10347,"aku":618,"akt":1211,"ako":4291,"aba":762,"abi":791,"ae ":719,"aca":3812,"ad ":3345,"ac ":1484,"afs":539,"afi":554,"ai ":709,"aga":937,"age":778,"ado":1169,"adr":1028,"adn":3155,"adi":2550,"ade":1153,"ads":935,"adu":1422,"aci":6004,"ach":727,"ada":5689,"azn":685,"azi":7453,"azl":1063,"azv":1013,"azu":592,"aze":804,"aza":1040,"azb":1010,"aya":527,"ba ":2218,"at ":2601,"arh":564,"are":1147,"ard":1409,"ara":6301,"aro":3575,"arn":1712,"ark":1048,"ari":4189,"aru":579,"ars":3100,"art":1393,"asa":826,"asi":1226,"ash":669,"ase":3354,"asn":1043,"asp":540,"ask":1064,"asl":534,"ar ":2545,"apa":4410,"api":1243,"apo":975,"apr":526,"aps":650,"apu":900,"as ":2262,"ava":8033,"aut":1108,"avo":1516,"avn":4358,"avl":3013,"avi":4083,"ave":3087,"ay ":531,"awa":719,"avu":1466,"av ":1100,"ata":3446,"ast":9058,"atn":1424,"atk":562,"atr":1028,"ato":2245,"ate":2791,"ati":6984,"ats":4995,"atu":1171,"aus":601,"jeg":2764,"jed":10627,"jec":1103,"jer":2418,"jek":4521,"jel":6299,"jem":5086,"jen":9322,"jez":10141,"jes":4061,"jet":3631,"jev":7451,"jač":750,"ji ":16045,"ažn":588,"jat":632,"jav":2585,"jal":1858,"jak":822,"jan":5965,"jam":1147,"je ":61320,"ješ":1621,"jni":1204,"joj":1250,"jom":1082,"jiv":803,"jim":3670,"jin":1845,"jih":2364,"ječ":1963,"jeć":1172,"eća":1346,"eće":940,"eći":1617,"ito":2406,"itu":706,"its":544,"isk":1391,"isl":604,"iso":539,"isn":807,"isp":569,"isu":779,"ist":10340,"iv ":1925,"ita":3250,"ite":2457,"iti":4001,"ivo":1642,"ivn":1941,"iva":3738,"ivi":1447,"ive":1512,"is ":1700,"ion":3221,"ipa":1930,"ir ":678,"iro":1457,"iri":1540,"isi":976,"ish":564,"ise":556,"isc":574,"isa":1555,"ire":1683,"ira":5142,"it ":890,"ja ":23119,"iz ":4867,"izu":877,"izv":2232,"izr":793,"izo":774,"izn":759,"izm":2019,"izl":668,"izi":2042,"izd":806,"iza":2198,"kih":5870,"kim":2628,"kin":753,"km ":900,"ki ":16671,"ked":578,"ke ":14258,"kci":941,"kra":4133,"kre":1063,"ku ":4982,"kro":1000,"kru":1711,"kri":1186,"kov":2238,"kot":547,"kor":2342,"kop":1083,"kon":3505,"kom":6854,"kol":2347,"koj":25320,"kog":6388,"kod":903,"knj":735,"ko ":9564,"kla":1495,"klo":701,"klj":755,"eđu":2748,"još":665,"jve":805,"eđe":812,"juj":863,"jug":1520,"jud":1914,"jsk":7836,"jst":574,"eči":628,"ju ":11452,"eče":573,"kaz":825,"kat":974,"kar":1304,"kas":686,"kan":1885,"kao":3422,"kal":1067,"kam":671,"kak":633,"kad":1513,"kac":594,"juž":1378,"ka ":22352,"juč":696,"juć":551,"ha ":913,"han":1101,"har":926,"he ":1979,"her":717,"hin":716,"hit":527,"go ":855,"gle":1361,"gla":3728,"god":2754,"gom":912,"gon":803,"gos":769,"gor":1668,"gov":5098,"gu ":1902,"gru":1369,"gra":9421,"gre":1427,"grč":1302,"ian":1493,"ic ":604,"iba":598,"ibe":551,"ia ":1869,"ifi":824,"ih ":17225,"icu":773,"ici":6028,"ich":645,"ice":4697,"ie ":604,"ica":6876,"idi":521,"ide":1150,"ida":944,"ašn":1360,"ašt":576,"il ":644,"ija":16185,"ije":24598,"iji":7426,"ijo":787,"ijs":5406,"iju":2114,"im ":10462,"ika":7961,"ige":790,"iga":952,"igi":547,"igr":1302,"iho":1185,"ik ":6489,"imo":723,"imp":613,"ime":3556,"imi":856,"inc":1602,"ind":1666,"ina":9909,"ino":2039,"int":1177,"ins":3389,"ine":10127,"ing":2574,"inj":1865,"ini":6764,"inu":1508,"iko":2904,"iki":780,"ike":2426,"ila":3734,"in ":2960,"iku":1705,"ilo":2029,"ill":863,"ilm":540,"ilj":1386,"ili":10385,"ile":865,"ima":9207,"io ":4778,"ils":642,"ilu":562,"hov":1213,"hrv":1503,"hva":1061,"fer":566,"ez ":610,"ezu":527,"eza":1009,"ezn":818,"eze":1246,"ezi":9990,"eta":3704,"ete":898,"eti":2144,"etn":2390,"etl":530,"etk":539,"esn":1243,"est":6673,"eto":1100,"etr":912,"ets":1480,"etu":996,"etv":760,"eve":4353,"eva":1803,"evo":961,"evn":623,"evi":1701,"er ":4432,"epa":580,"es ":2168,"epu":2109,"epo":647,"epr":650,"eri":7215,"erg":698,"ere":1639,"erc":963,"era":4007,"et ":2066,"esk":1461,"esm":595,"esi":709,"ese":1073,"esa":706,"erv":605,"eru":1435,"ert":600,"ers":1367,"ern":3520,"erm":720,"ero":2614,"eki":802,"eko":2778,"eks":1589,"ekt":2568,"eku":789,"en ":4377,"ela":3182,"ele":2918,"eli":4944,"elj":5961,"ell":698,"elo":2967,"elu":1458,"ema":3624,"eme":6131,"eml":1258,"emo":840,"emi":1481,"ene":3561,"eng":1640,"ena":7266,"end":836,"enc":1218,"eno":6088,"eni":7665,"enj":3407,"enu":1213,"ens":1955,"ent":3912,"ego":1890,"egi":1521,"ek ":753,"el ":1052,"ejs":573,"eke":1782,"eka":2350,"em ":3991,"gl ":618,"gij":2556,"gin":523,"gi ":831,"gen":1325,"ger":827,"gdj":702,"ge ":1704,"gar":946,"gal":662,"gan":1740,"ga ":4609,"ađa":855,"ađe":658,"fra":927,"ača":1970,"ače":950,"ačk":3501,"fri":721,"ači":1814,"fsk":622,"aču":958,"for":1658,"ač ":583,"aće":585,"aća":1021,"fil":896,"fik":566,"fin":592,"da ":9164,"de ":2788,"dal":1347,"daj":785,"dat":824,"dar":1385,"dan":5150,"dam":626,"dav":567,"cus":960,"co ":549,"cu ":955,"cea":713,"ch ":519,"ces":1492,"cen":997,"ceg":685,"ci ":6216,"cha":750,"ck ":1290,"che":856,"chi":796,"cij":9280,"cim":1128,"cir":569,"cio":1059,"ed ":1254,"eba":923,"ebe":581,"ean":810,"ea ":773,"duž":619,"ega":1085,"edn":7588,"edi":4719,"ede":1425,"eda":3130,"eg ":2170,"eds":1513,"edo":1202,"eci":935,"eca":935,"dvi":741,"dvo":690,"dva":1103,"drž":4140,"don":1767,"dom":1052,"dol":970,"dok":659,"dov":1189,"dos":617,"diš":1956,"dna":2624,"dne":953,"dni":3564,"dnj":1612,"dno":6490,"dob":1518,"dst":1252,"dra":1195,"dre":1145,"du ":2280,"dru":5517,"dsk":2664,"dic":3889,"der":1371,"des":966,"den":1450,"di ":4014,"do ":2419,"dje":2862,"dim":541,"din":5519,"dio":1844,"dis":1126,"dij":7896,"rađ":876,"rga":1240,"ri ":5834,"rgi":678,"ret":1800,"res":1271,"rev":690,"rez":931,"rać":609,"rač":1555,"reb":1913,"rea":805,"ree":521,"red":6133,"reg":1745,"rem":2802,"ren":2797,"rek":1056,"rel":612,"rep":724,"rdi":692,"re ":4525,"rce":928,"raz":4813,"rd ":686,"rap":1294,"ras":1520,"rat":4060,"rav":4237,"rbi":882,"raj":3616,"rag":678,"ran":11269,"ram":1816,"ral":3163,"rak":1775,"raf":1147,"rad":6716,"rac":1934,"ros":2073,"rot":1439,"rom":2618,"ron":1652,"rop":1763,"roz":1266,"rov":2438,"rob":584,"roa":633,"rod":8265,"roc":1470,"roj":2300,"roi":1622,"rol":793,"rok":933,"rog":1195,"rno":2932,"rič":3609,"rna":1479,"rne":1371,"rnj":845,"rni":2710,"ro ":1317,"rma":1223,"rmi":655,"rlo":551,"rn ":540,"rkv":521,"rka":695,"ređ":981,"reć":667,"raž":797,"rje":601,"riz":799,"rip":1837,"rio":889,"rir":879,"rit":2510,"ris":3174,"riv":1004,"rig":523,"rij":11045,"raš":597,"ril":1430,"rik":1383,"rin":1848,"rim":1849,"ria":651,"rib":805,"ric":1431,"rid":583,"rug":4029,"rup":1471,"run":520,"ruk":844,"rus":1028,"rva":5151,"rvi":1279,"rve":1037,"rvo":605,"ry ":556,"rsk":5201,"rta":726,"rst":2436,"rti":871,"rt ":714,"ru ":2471,"sad":738,"sam":1694,"san":1142,"sat":604,"sas":3039,"sav":1014,"sa ":5478,"ruž":889,"ruš":721,"ruč":2722,"rzi":592,"shi":607,"si ":1399,"sje":4603,"sis":550,"sin":1783,"sil":686,"sim":836,"sij":991,"se ":14671,"ser":1178,"set":665,"sh ":559,"seb":745,"sel":4338,"spo":2263,"spr":578,"spe":611,"spa":672,"sov":613,"son":650,"sob":1342,"su ":8627,"sre":2282,"st ":3926,"slj":632,"sli":1331,"slo":1832,"slu":1752,"sla":2093,"ski":17159,"skl":527,"sko":15307,"skr":553,"sku":5305,"ska":7019,"ske":5955,"sno":3094,"sna":922,"sni":2255,"sne":697,"smj":1004,"sma":1116,"ste":2346,"sta":16592,"sto":9996,"sti":9753,"stv":3654,"stu":2357,"str":6456,"sus":1535,"sva":788,"sve":1415,"svi":1441,"svj":804,"svo":1576,"taj":996,"tak":2161,"tal":4191,"tac":782,"tav":5990,"tat":1128,"tar":4163,"tan":6149,"tam":583,"te ":6089,"ta ":9339,"pa ":1847,"pe ":1308,"par":1595,"pat":647,"pad":4813,"pal":580,"pan":3273,"pi ":571,"per":1812,"pet":668,"pla":1804,"plj":816,"pli":1041,"ple":3986,"plo":1052,"pje":1454,"pij":889,"pin":4572,"pis":2255,"poz":2191,"por":5631,"pop":1191,"pov":2463,"pot":1881,"pos":3892,"poj":1457,"pog":612,"pom":933,"pon":975,"pok":1642,"pol":3220,"pod":6429,"po ":2082,"psk":1887,"pub":2165,"pti":586,"poč":712,"pra":3170,"prv":1850,"pri":7027,"pre":6249,"pro":8677,"put":1060,"pun":676,"pul":698,"iše":1062,"išn":1267,"išt":2503,"qui":570,"ra ":9271,"ngo":698,"ngl":1753,"ni ":16130,"nga":751,"nej":882,"nek":2622,"nen":652,"nep":734,"ner":1509,"net":1026,"nes":1293,"ng ":2367,"nač":2757,"nez":1162,"nci":2911,"nce":931,"ne ":19985,"ndu":534,"ndo":1052,"ndi":5037,"nde":837,"nda":1627,"ncu":940,"nak":2307,"nal":5099,"nam":1658,"nan":1732,"nap":971,"nar":3446,"nac":3781,"nad":1618,"nag":771,"naj":3818,"nd ":1313,"nav":631,"nat":3622,"nas":6912,"naz":2805,"na ":42477,"mož":877,"nut":1280,"nto":781,"ntr":1002,"nti":2109,"nta":2295,"nte":1843,"nst":1771,"nsk":10758,"nu ":5412,"ičn":3327,"ičk":8118,"iči":1329,"iča":967,"nt ":937,"niš":631,"ns ":584,"noa":520,"nog":6035,"noj":3137,"nom":6601,"nos":6166,"nor":535,"nov":4240,"nič":2517,"ića":608,"no ":15032,"nka":782,"nji":3978,"nje":12914,"nja":6205,"ić ":1370,"nju":1904,"njs":879,"njo":1594,"nij":6542,"naš":1014,"nih":6201,"nic":5054,"niz":1589,"nis":1359,"nit":879,"nir":714,"nim":4415,"nin":1303,"nik":4325,"ogr":2375,"ogu":995,"ogi":1476,"ogl":635,"ogo":1802,"oga":1651,"oj ":12832,"ois":1145,"oim":653,"ok ":1418,"oju":1294,"ojs":576,"ojo":759,"ojn":1052,"oji":10382,"oje":6734,"oja":6046,"ol ":664,"oiz":1012,"oce":973,"oci":1114,"ock":1115,"obu":893,"ode":1274,"odi":8132,"odo":921,"odn":4204,"ods":1138,"odr":4259,"of ":888,"oda":2801,"odu":910,"og ":13004,"oan":559,"oba":2782,"od ":14807,"obo":933,"obr":1117,"obl":1881,"obn":555,"obj":1316,"obi":2599,"oz ":529,"ozn":3312,"ozi":1205,"oza":1421,"oti":1557,"ote":985,"otr":921,"otp":614,"oto":4095,"ost":8908,"ota":912,"ov ":1004,"osi":1554,"ose":1141,"osl":1958,"oso":1519,"osn":2717,"ovj":940,"ovi":7022,"ovn":2887,"ovr":829,"ovo":6487,"ova":7007,"ove":3130,"opć":1972,"opo":690,"opi":1778,"opl":1169,"ope":858,"opa":775,"os ":1176,"opu":936,"opr":664,"ops":861,"or ":2008,"orm":1284,"orn":2821,"oro":4229,"ord":815,"ore":2892,"org":1291,"ori":7402,"osa":1092,"ort":1833,"ors":1607,"oru":1306,"ot ":522,"ora":3600,"ola":1856,"on ":4329,"olj":2400,"oli":4446,"ole":1119,"ols":789,"olo":3261,"olu":1664,"oka":2684,"om ":17269,"oke":734,"okr":3164,"oko":3273,"oku":2145,"ona":3954,"ond":619,"one":1941,"ong":1053,"onj":777,"oni":2936,"ono":2047,"ons":1609,"ont":1171,"onu":585,"oma":2281,"ome":2911,"omi":1374,"omp":729,"omo":1785,"la ":9649,"le ":3757,"lac":1275,"lad":1494,"lag":644,"lak":731,"lan":3996,"lam":781,"lar":880,"lat":2578,"las":3015,"lav":4030,"laz":5016,"lbu":1947,"kva":701,"kup":5219,"kul":1164,"ksi":936,"ktr":973,"kođ":596,"ktu":654,"kti":1269,"kuć":703,"lok":712,"lon":791,"lom":1506,"lop":558,"log":2016,"lov":4118,"lno":1832,"lni":2255,"lne":712,"lob":538,"lič":1936,"lna":885,"ltu":737,"lub":608,"lsk":2111,"lu ":2550,"liš":638,"lj ":865,"li ":12760,"les":1936,"let":657,"lem":4158,"len":1436,"lek":2007,"led":614,"lo ":4167,"lla":657,"lle":663,"lli":529,"ljs":545,"lju":4071,"lje":10652,"ll ":619,"lja":4832,"lji":2209,"lit":2066,"lis":1339,"lin":3083,"lim":1508,"liz":1420,"lic":2147,"lia":609,"lik":6521,"lij":3213,"lig":541,"ma ":15645,"luž":1294,"mac":714,"maj":623,"mak":533,"mar":837,"mas":812,"mal":2079,"man":3666,"mat":2524,"mbi":905,"me ":5240,"med":673,"met":3414,"mer":3791,"mel":710,"men":6548,"mač":1334,"lum":944,"loš":641,"mpi":753,"mog":976,"mon":1050,"mor":2726,"mos":601,"mot":653,"mu ":1457,"msk":1673,"mun":787,"mi ":1004,"međ":2505,"mje":5038,"min":2090,"mil":697,"mir":1036,"mis":832,"ešt":1289,"mit":939,"ešk":669,"mij":1629,"mo ":1420,"mlj":1522,"mno":900,"rža":4071,"ča ":974,"čan":800,"čar":558,"čaj":693,"uča":545,"zra":1677,"če ":853,"učj":2470,"uči":687,"čav":1111,"čen":1159,"čet":1250,"čes":595,"zu ":768,"zva":612,"zvi":939,"či ":1484,"zvo":1982,"zum":625,"čij":837,"čic":566,"čit":844,"čin":2554,"čko":4001,"čka":1912,"čke":2028,"čki":5096,"čju":1626,"češ":556,"čla":542,"čni":1699,"čno":3306,"čna":751,"čne":1006,"zi ":3239,"zem":1449,"zer":1084,"ze ":973,"zbo":641,"zda":1154,"zac":771,"zbe":843,"zaj":1076,"zam":819,"zan":918,"zal":859,"zap":3007,"zav":531,"zas":565,"zon":794,"zme":1381,"zna":6328,"zno":753,"zič":837,"zni":942,"zla":762,"uća":616,"zli":1013,"ući":766,"zic":1241,"zij":2320,"rši":715,"zin":1079,"zil":1675,"zik":7193,"zir":891,"ziv":3073,"za ":7407,"ya ":644,"ože":1175,"ću ":879,"ćin":2919,"ći ":2008,"rčk":1144,"oš ":708,"ošk":698,"vrš":1066,"wa ":713,"viš":1245,"vrt":868,"vrs":1358,"vri":916,"vre":806,"vsk":989,"vu ":2689,"vir":547,"vil":1092,"vim":1483,"vin":3680,"vih":903,"vij":3997,"vic":888,"vid":903,"vit":817,"vis":1291,"već":1856,"vje":3831,"vla":1440,"vlj":3383,"vo ":3548,"vne":801,"vna":1303,"vno":3450,"vić":621,"vni":4024,"vod":2717,"vog":1164,"voj":3212,"vol":582,"vom":1226,"vor":5059,"vot":928,"voz":1030,"vi ":4716,"vač":1765,"vez":1580,"ver":4932,"vet":804,"vać":849,"ven":3207,"vel":1857,"ved":700,"ve ":5319,"val":1770,"vak":779,"van":5697,"var":1878,"vat":5563,"vac":751,"vaj":1521,"va ":12711,"uz ":1098,"usk":1818,"usi":743,"ust":3150,"uti":590,"ute":706,"uta":1448,"uto":1403,"us ":1654,"ut ":910,"ura":1400,"ure":1189,"uri":1158,"urn":947,"uro":1486,"urs":550,"uru":580,"upa":2662,"upi":4500,"upe":980,"upo":759,"upr":748,"upn":605,"umi":603,"umj":671,"uma":1379,"umb":688,"ume":724,"unu":749,"uni":993,"und":654,"una":2557,"up ":535,"uko":757,"ukl":657,"um ":2138,"uka":702,"uju":1023,"ult":1215,"pći":2432,"uli":687,"ula":1753,"uhv":776,"uje":2393,"ugi":1126,"uge":731,"ugo":2301,"ugl":583,"uga":1630,"ugu":1137,"uda":924,"udi":2722,"ue ":562,"uci":556,"ug ":588,"ua ":834,"ual":550,"uan":840,"ubl":2337,"tvu":537,"tvr":1039,"tvo":2139,"tve":1133,"ođe":1121,"tva":2106,"tur":2517,"tup":876,"tud":1103,"tre":2014,"oče":731,"tra":6680,"će ":1908,"oči":564,"tri":3139,"tru":1417,"tro":2790,"očn":2463,"tu ":3006,"tsk":7605,"toč":2840,"ćen":895,"to ":5478,"tni":2342,"ća ":3122,"tna":778,"tič":3116,"tno":1901,"toc":579,"toj":1710,"toi":723,"tog":984,"tov":1949,"tom":1889,"ton":1847,"tok":3601,"tol":1732,"tor":3179,"top":785,"ćan":554,"tij":2254,"til":813,"tik":1009,"tih":692,"tir":1327,"tit":1406,"tis":916,"tin":3058,"tim":1630,"tio":1426,"tic":2096,"tiv":2430,"tje":1395,"tko":583,"tka":775,"tla":700,"tem":1590,"ten":2148,"tek":931,"tel":2393,"th ":723,"tet":818,"ter":4781,"ti ":9529,"the":1111,"živ":2628,"žni":894,"žno":1666,"že ":1842,"žbe":582,"žav":3922,"žan":794,"ži ":866,"žen":1273,"užb":678,"uže":864,"uži":889,"užn":2163,"žup":1446,"ušt":795},"n_words":[5153330,5928363,4281211],"name":"hr"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hun b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hun new file mode 100644 index 000000000..77ab7c4c8 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/hun @@ -0,0 +1 @@ +{"freq":{"D":13198,"E":18562,"F":13797,"G":13466,"A":98368,"B":24663,"C":21970,"L":15870,"M":28130,"N":17752,"O":8481,"H":13530,"I":14875,"J":7703,"K":21077,"U":4237,"T":19473,"W":4434,"V":10406,"P":22295,"S":35593,"R":12093,"Y":1303,"X":1480,"Z":4534,"f":108322,"g":317259,"d":216557,"e":996693,"b":219927,"c":121096,"a":1016786,"n":579901,"o":467276,"l":670215,"m":298372,"j":133885,"k":454857,"h":131050,"i":506132,"w":6657,"v":203150,"u":147118,"t":700784,"s":637262,"r":536637,"q":1410,"p":129287,"z":429255,"y":242745,"x":7186,"É":1936,"Á":2646,"í":56628,"é":327830,"á":372527,"ü":54519,"ú":35451,"ö":107023,"ó":117740,"ő":81190,"ű":27405," l":36854," m":86086," n":55262," o":27009," h":46816," i":30318," j":25021," k":101750," d":20317," e":90097," f":58652," g":17434,"р":1511," a":216424,"с":1133," b":38681," c":32807," z":5071," u":7248," t":73839," v":67319," p":25823," s":75268," r":41479," J":7511," K":20282," H":12799," I":11800," N":16438," O":7214," L":14736," M":26568," B":23082," C":19809," A":94593," F":12742," G":12445," D":12015," E":17107,"л":1197," Z":3901,"к":1191," Y":1159,"и":1900,"о":2301,"н":1605," S":32225,"в":1255," R":11088,"а":2749," P":20591," W":4161," V":9030," U":3712,"е":1700," T":17702," á":18269," í":4682," é":57281," ö":8570," ó":3751," ü":2190," ú":3722," Á":2459," É":1858," ő":1879,"A ":56345,"Da":1481,"Cs":2770,"Co":4107,"Ce":1232,"Ch":2651,"Du":1186,"Do":1533,"De":2255,"Di":1628,"Fe":3066,"Fa":1242,"Ez":1912,"Eu":1996,"Er":1727,"El":1696,"Eg":3224,"Ge":1854,"Ga":2079,"I ":2334,"Fr":2249,"Bí":1300,"Fo":1548,"Fi":1170,"B ":1118,"C ":1489,"Au":1680,"Ar":2744,"Ba":3859,"Az":15235,"Ac":1577,"Am":2415,"An":3658,"Al":3816,"Bu":2584,"Br":2522,"Ca":4180,"Bi":1847,"Be":4063,"Bo":3301,"Kr":1187,"Ko":2867,"Le":3145,"Li":2545,"La":4095,"Lo":1996,"Me":3040,"Mi":3545,"Ma":10861,"Mu":1674,"Mo":3340,"Ne":3381,"Na":3799,"Ny":3322,"No":1352,"Ol":1338,"Gr":1713,"Go":1444,"Gy":1283,"Ha":3592,"He":2397,"II":1513,"Dé":1163,"Ho":2637,"In":4213,"Is":1406,"Ja":1924,"Je":1294,"Jo":1519,"Ka":3817,"Ki":3017,"Ke":1650,"Tu":1174,"Tr":2483,"To":1807,"Th":2533,"Ti":1466,"Te":2749,"Ta":2278,"V ":1123,"Sz":12584,"St":3173,"Wi":1325,"Vi":2150,"Va":2270,"Ve":1656,"Pr":2035,"S ":1580,"Pe":2500,"Pa":5475,"Po":2747,"Pi":1727,"Or":1697,"Kö":2908,"Se":1702,"Sc":1225,"Si":1430,"Sp":1130,"So":1614,"Sa":3389,"Re":2307,"Né":1630,"Ro":2833,"Ra":1803,"b ":16527,"a ":242203,"bö":1784,"i ":117842,"bó":6751,"ge":24009,"gf":2198,"ga":25428,"gb":5764,"bé":2495,"ff":1119,"fi":9218,"fr":3611,"fu":1929,"fo":23259,"j ":9703,"gy":101312,"gz":1512,"dá":7767,"he":27807,"ha":38767,"gn":5176,"gm":1339,"cé":2844,"gl":4237,"gk":2851,"gj":4145,"gi":17202,"gh":4135,"gg":3431,"gv":1711,"gu":3889,"gt":2295,"gs":3570,"gr":6943,"cí":4683,"go":14059,"dt":3427,"du":4251,"dv":2240,"dz":1317,"g ":45451,"ea":6887,"eb":8727,"ec":7541,"ed":20502,"de":31392,"dd":1273,"di":23518,"dj":21891,"do":18282,"dn":1552,"ds":5503,"dr":4675,"ex":2202,"eu":3957,"ev":16778,"ey":1469,"ez":42514,"fa":14955,"h ":4414,"bá":5025,"fe":22515,"eh":6429,"eg":88315,"ef":4014,"ee":2573,"el":138888,"ek":55065,"ej":8422,"ei":11205,"ep":13034,"eo":3448,"en":123802,"em":38648,"et":109362,"es":66857,"er":112461,"ca":6636,"e ":99285,"bs":1600,"br":4886,"bu":6371,"bo":9382,"bl":2460,"bi":10991,"bb":21421,"bd":1747,"be":56227,"db":1466,"da":33610,"f ":3042,"cu":2732,"ct":3944,"cs":39940,"cr":1412,"co":5597,"ck":3543,"ci":18130,"ch":10237,"ce":11684,"cc":1311,"c ":4126,"az":52261,"ay":1779,"ba":62023,"d ":20001,"at":73551,"as":35129,"ar":73118,"av":6465,"au":6414,"ak":76786,"al":112498,"ai":30999,"aj":22921,"ao":1282,"ap":21474,"am":34363,"an":99045,"ac":9905,"ad":30543,"aa":1143,"ab":12613,"ag":47002,"ah":3611,"ae":13109,"af":4252,"nu":6592,"nt":48640,"ns":9377,"no":16464,"nn":10307,"nz":2533,"ny":61139,"gő":1259,"jó":1888,"ká":8866,"of":2805,"oc":6235,"od":12616,"ob":7903,"jú":2913,"ké":20553,"om":30097,"on":54876,"ok":33935,"ol":57719,"oi":1954,"og":16189,"oh":1599,"ot":26104,"os":55594,"ov":15603,"ou":3364,"op":11263,"oo":1729,"or":73234,"kí":3018,"kú":6878,"r ":40419,"ow":1527,"kó":3434,"kö":37773,"oz":36942,"lá":37200,"pe":16459,"pa":16699,"kü":4521,"pc":1541,"pl":5060,"lé":24839,"po":17893,"ph":4251,"pi":8966,"pj":2198,"pk":2115,"lo":28055,"ln":6206,"lm":14166,"hé":2687,"ll":38085,"ls":10986,"lr":2355,"hí":1890,"lv":12472,"lu":8529,"lt":43305,"lz":1116,"ly":54235,"o ":10039,"ma":45288,"mb":11466,"me":75090,"iá":11532,"ml":3581,"mi":28248,"mn":1344,"mm":4364,"mp":6217,"mo":16948,"ms":1960,"mu":7004,"fő":4516,"ió":9250,"mz":4734,"p ":5660,"na":50058,"nb":3564,"nc":11966,"nd":37316,"ne":56223,"já":30832,"nf":2395,"ng":19748,"nh":1725,"ni":26541,"nj":1322,"nk":8011,"nl":3257,"jé":12386,"jt":5016,"ju":2496,"jn":3362,"jo":4214,"jl":2908,"fé":13187,"ki":30779,"kh":2892,"ke":42527,"gá":10089,"kc":1158,"kb":6547,"fü":2239,"ka":34729,"m ":27269,"fö":2942,"jz":1414,"gó":4573,"dő":5431,"gö":3372,"ks":5542,"kt":6729,"ku":13047,"kv":1892,"ko":37181,"gí":1165,"kr":7237,"kk":6940,"kl":3302,"gé":11029,"km":3318,"kn":3693,"li":35208,"lh":5532,"lk":11727,"lj":5903,"le":93067,"há":9402,"ld":10308,"lg":5358,"lf":2782,"la":70668,"lc":4145,"lb":4771,"gú":1727,"n ":153664,"hr":1649,"dí":4512,"dó":5588,"ht":1620,"hu":2691,"hi":9568,"hn":1454,"ho":21034,"dé":9871,"id":22338,"ic":13315,"ib":5712,"ia":30517,"ih":1907,"ig":15930,"if":9201,"eá":1335,"ie":7180,"dö":1970,"hy":1869,"k ":156709,"ir":14921,"is":42797,"it":23842,"iu":6023,"iv":7173,"bő":3863,"ii":3341,"ij":1228,"ik":46279,"il":27833,"im":8040,"in":53934,"io":8559,"ip":5320,"fá":1392,"je":23937,"jd":2673,"iz":8720,"l ":91636,"ja":22570,"xi":1625,"té":34673,"tí":4348,"tó":18526,"sö":2411,"só":2652,"sú":4418,"z ":78459,"sü":3136,"tá":43166,"wi":1167,"sé":27679,"sí":6485,"ró":12762,"rö":8024,"y ":64628,"rú":3555,"rü":11432,"wa":1485,"sá":25703,"ré":19532,"vi":19889,"vt":2486,"rí":1306,"vo":15593,"mű":8899,"nő":6159,"ve":52514,"rá":28508,"va":38110,"x ":2815,"ui":1873,"uk":4884,"ul":23432,"ue":1945,"ug":7493,"ur":14404,"us":30910,"ut":12436,"um":11242,"un":8785,"up":2459,"ty":4352,"tu":13656,"tt":50460,"tv":7094,"ub":2532,"ua":1854,"pü":4993,"ud":8185,"uc":2378,"to":52152,"tn":2524,"pé":3054,"tm":2785,"tl":6382,"ts":8729,"tr":17609,"pí":3835,"tf":1412,"te":87104,"pá":7384,"tk":5205,"tj":7119,"ti":40828,"th":9478,"v ":9584,"tb":6187,"tc":1163,"ta":76171,"su":4875,"sv":2378,"ss":22768,"st":26226,"sz":174760,"lő":14903,"sl":2577,"sk":7704,"sn":2526,"sm":5506,"sp":4512,"so":26449,"sr":3213,"sd":1132,"sc":3372,"sf":1789,"se":34881,"sh":2900,"si":20642,"nö":2962,"rz":5827,"u ":5228,"sa":40529,"sb":5688,"rr":6334,"rs":21922,"rt":47601,"ru":7619,"rv":8829,"nó":1459,"kő":1313,"ry":3017,"rp":2572,"ro":47249,"rn":9437,"né":20022,"rm":20825,"rl":4279,"rk":7954,"rj":4223,"ri":45410,"rh":2668,"rg":7757,"rf":3837,"re":67985,"ná":12107,"rd":9230,"rc":7289,"rb":5639,"ra":55047,"t ":159290,"mú":1197,"mó":2093,"qu":1194,"mí":1861,"mé":15355,"má":27550,"lü":5880,"s ":157503,"lö":4000,"pt":5892,"pu":3980,"ló":16644,"pp":2547,"lí":3237,"pr":7474,"ps":3440,"yő":1310,"zü":5181,"zú":1280,"zá":31274,"yú":1973,"yü":3112,"zé":19023,"zí":5603,"zö":10272,"zó":20498,"vű":1517,"yá":13547,"yí":1801,"yé":5272,"yó":2584,"vő":2313,"tű":4358,"vö":1632,"zz":3816,"sű":1526,"tő":14413,"zf":1314,"zg":2806,"zh":3151,"zi":25268,"zb":1632,"zd":4010,"ze":71368,"vá":29898,"za":30193,"yz":1903,"zv":1698,"rű":2676,"ső":8855,"zs":12765,"zu":3963,"zt":36837,"zo":19843,"zn":6608,"ví":2765,"zp":2246,"zk":4768,"vé":17783,"zm":2937,"zl":11760,"yg":1834,"yh":1922,"ye":40237,"uá":1400,"yf":2056,"yc":1116,"ya":26830,"tü":4027,"yb":3764,"tú":2750,"tö":12442,"rő":4773,"yv":4653,"yu":3843,"yt":3497,"ys":7991,"yr":1838,"yp":1398,"yo":12260,"yn":3914,"ym":1973,"yl":2832,"yk":2442,"yi":17109,"ző":8108,"yű":1984,"Ál":1439,"ám":8760,"án":50938,"áp":2119,"áj":7251,"ák":18338,"ál":59120,"ág":29984,"áh":4265,"áb":34134,"ác":4739,"ád":14308,"áz":7779,"áv":4411,"áu":1148,"ár":52483,"át":21141,"ás":47264,"á ":2111,"óz":2079,"ós":5892,"ót":4344,"óv":1296,"óa":1234,"ób":3397,"ój":4542,"ói":2619,"óg":4159,"óf":2044,"ód":5384,"óc":1867,"ór":2907,"óp":3032,"ón":2969,"óm":2752,"ól":15303,"ók":6328,"ó ":44110,"ív":3409,"íz":3248,"ín":4459,"ím":4915,"ír":8949,"ít":21446,"íg":1483,"ík":1149,"íl":1523,"íj":1882,"éz":4750,"ék":26204,"él":30309,"éj":1119,"ép":16482,"ém":6476,"én":36437,"és":84643,"ét":19103,"ér":22242,"év":16532,"éb":17184,"éd":3694,"éc":1321,"éh":4561,"ég":31689,"é ":4130,"úz":1141,"ün":2126,"ül":37857,"ür":1396,"üt":3250,"üz":1153,"üg":2645,"ük":3502,"úl":1994,"új":3185,"út":2986,"ús":1934,"úr":1723,"úa":6976,"úg":2023,"öv":8122,"öz":26938,"ú ":9189,"öt":9388,"ör":17835,"ös":7442,"ön":10766,"öl":8906,"öm":1336,"ök":5801,"ög":3454,"öd":2116,"öb":4016,"ő ":26112,"őv":2032,"őr":2463,"ős":10918,"őt":2983,"őz":2353,"őd":2691,"őb":2103,"őg":1179,"őe":1463,"ől":9494,"ők":4433,"őj":2432,"ői":2735,"őn":2715,"ű ":13555,"űk":1684,"űe":1599,"űs":1405,"űr":1219,"űv":2905,"一":1237," Ál":1439," Ga":2065," Ge":1837," Bí":1298," Fo":1535," Fr":2248," Fi":1161," Ha":3587," He":2393," Gy":1279," Go":1438," Gr":1700," Ho":2631," Dé":1163," Je":1288," Ja":1919," Is":1400," In":4206," Ka":3809," Ke":1641," Ki":3002," Jo":1515," La":4057," Le":3135," Li":2524," Ko":2859," Kr":1178," Ma":10822," Mi":3523," Me":3025," Lo":1988," Ne":3354," Na":3783," Mo":3325," Mu":1669," A ":54120," Am":2399," An":3650," Al":3798," Ac":1573," Ba":3855," Az":15203," Au":1680," Ar":2712," Be":4051," Bi":1842," Bo":3283," Br":2520," Bu":2577," Ca":4107," Ce":1230," Ch":2631," Co":4068," Cs":2760," Da":1472," Di":1622," De":2234," Do":1490," Du":1183," El":1692," Eg":3214," Er":1720," Ez":1906," Eu":1996," Fe":3060," Fa":1224," Wi":1310," a ":114242," Kö":2904," Or":1691," Po":2728," Pi":1722," Pe":2496," Pa":5457," Ny":3316," No":1346," Ol":1338," Ra":1786," Né":1627," Ro":2824," Re":2297," Pr":2030," Sz":12567," St":3106," Ta":2270," Th":2520," Ti":1460," Te":2728," Tr":2468," To":1786," Sa":3377," Si":1425," Sc":1193," Se":1692," So":1606," Sp":1107," Va":2262," Ve":1647," Vi":2142," Tu":1156," ja":1594," je":10035," in":4519," il":2853," is":10067," ir":2442," fü":1523," ka":7871," fö":1646," ki":17579," ke":13720," jo":1938," fé":4201," gy":6161," ha":19271," he":6504," cé":1611," cí":4405," gr":1159," id":3467," ig":3043," hi":3276," dé":2801," ho":8126," dí":1823," ne":18984," já":7979," na":5781," fő":4149," mu":2133," mo":4422," ok":1477," ol":6794," ké":11002," of":1186," ny":10296," no":1409," há":4031," le":17706," li":2353," la":7930," ku":2128," gö":2536," km":2432," kr":1168," ko":9227," me":30782," mi":10796," ma":18644," lo":1099," hí":1381," ad":3539," am":14965," an":8296," ak":3658," al":19507," au":2171," ar":2746," as":2187," ba":7443," az":39674," bi":2851," be":18442," bo":2566," bu":1302," er":6741," es":6369," en":1270," em":3989," el":22279," eg":37244," fe":16017," bá":1342," fa":10457," ez":6961," fu":1228," fr":2101," fo":11286," bé":1167," fi":3986," ge":1465," ga":1837," ci":1469," da":2485," cs":21597," do":1754," de":6050," di":2713," vé":3902," ví":1450," vá":10832," ze":2004," tö":9167," té":2457," tá":3920," nö":1405," sa":2016," se":2587," sp":2365," so":5755," ra":2479," re":19463," né":13996," ro":3461," pr":3595," má":8283," mé":4247," os":10567," kí":1660," or":4197," kö":27883," pe":2664," lá":2021," kü":3017," pa":5441," lé":4236," po":4686," pi":1682," ró":1121," rö":2141," va":20643," ve":9072," nő":1649," mű":3958," vo":11603," vi":8365," ré":10099," tu":3046," ut":3907," ur":1101," ta":23929," sz":51220," st":2457," su":1760," tr":1755," pé":1624," to":2214," ti":2324," te":19251," pá":3006," át":2658," ál":11522," év":4437," ér":4015," és":39564," én":2210," ép":2514," él":3293," ír":3245," ók":1246," ön":2076," ös":3774," ót":1104," új":1846,"ől ":7803,"ője":1778,"ők ":2201,"őne":2127,"ősz":2500,"ős ":1549,"ősí":1918,"ősö":1177,"őtt":1492,"őbb":1227,"ői ":1993,"Áll":1152,"Eur":1570,"Ez ":1152,"Fra":1443,"Bír":1270,"Int":2403,"Az ":14884,"Ame":1184,"Bud":1205,"Car":1146,"Cse":1140,"Egy":3037,"Nem":1251,"Nag":2455,"Nye":1809,"űvé":1367,"Köz":2207,"Pas":2299,"Par":1124,"űve":1432,"űkö":1244,"Lad":1325,"Mar":2612,"Mag":3698,"éhe":3730,"ék ":14028,"ége":6434,"égb":1296,"égi":4433,"égy":1459,"él ":2635,"éde":1275,"ég ":10442,"ébe":12999,"éba":2195,"éve":6732,"ésé":4210,"év ":4758,"ész":20296,"éte":4730,"élő":1204,"ést":1350,"ésr":1270,"épü":1343,"épí":1687,"étr":1526,"éze":2382,"érő":1195,"éme":4235,"ép ":2557,"éne":8073,"éni":1139,"ént":3323,"ény":11240,"ékh":1465,"éke":3632,"éko":2177,"égé":2685,"én ":10291,"éli":2101,"éle":4096,"élk":1173,"ély":3515,"élt":1344,"ére":3670,"érf":1845,"ét ":8716,"ért":4687,"érs":1117,"éri":1359,"ése":7910,"ési":1788,"épe":3380,"ér ":1942,"éps":1130,"élé":8715,"és ":42926,"ésű":1277,"Szl":3665,"Sza":1311,"Sze":2596,"The":1583,"ául":1145,"áts":1437,"áto":1839,"biz":1578,"áss":1306,"ást":1822,"ász":3797,"áró":1875,"ásá":7057,"árá":5593,"áva":2230,"bol":1519,"átó":1225,"áté":2725,"áz ":1260,"ázi":1122,"bor":3409,"áza":2446,"áll":11176,"bbi":2623,"ált":12559,"bba":2240,"ály":14827,"be ":8763,"áma":1434,"ban":38532,"bal":3567,"baj":2665,"áku":1940,"bad":1154,"án ":13154,"ála":2623,"bar":1493,"áli":4198,"álh":2859,"áno":1436,"ány":14546,"ánu":1287,"ámo":1867,"ána":12065,"bda":1545,"áni":2143,"ájá":1672,"áló":2208,"ás ":11271,"bi ":2519,"ár ":6296,"ber":6263,"ben":26680,"bel":7243,"bes":1771,"bet":1775,"ása":4529,"árt":3175,"árs":2861,"áso":5295,"ási":3907,"ásb":2951,"át ":7693,"ámí":1237,"áro":12322,"árm":2982,"ári":3231,"ára":5673,"ács":1314,"áci":2905,"ág ":10677,"ádj":10076,"ábó":2969,"ága":2054,"ágb":3476,"ca ":1909,"ágo":3161,"ági":2804,"ák ":11048,"áho":4041,"ája":2888,"ál ":2859,"ágá":1372,"áki":3435,"ce ":2292,"ám ":1135,"bri":1367,"bra":1211,"bur":1175,"bum":2164,"ád ":2121,"ábo":1867,"ább":3556,"ába":23979,"ajz":1349,"aka":2195,"am ":2190,"agá":2325,"aki":3799,"afé":1601,"ajn":3205,"ajt":2171,"al ":17585,"aja":1802,"ajd":2547,"ain":2508,"ait":1256,"ak ":42544,"adó":2898,"aj ":6376,"agy":29473,"adá":3539,"agj":1385,"ago":2554,"anu":1841,"any":6283,"ano":1477,"ann":3140,"ant":4051,"ans":1439,"ane":1370,"ajá":1272,"ang":7307,"ani":3989,"ank":1265,"ana":3610,"anc":3826,"and":5977,"amm":1385,"amo":3002,"amp":1099,"ami":6863,"ame":12652,"amb":1439,"ama":2681,"alv":1163,"alu":2639,"alt":1806,"alr":1104,"alo":6119,"alm":6541,"all":3854,"alk":5861,"ali":4354,"alc":1755,"ale":2695,"ala":25236,"alb":2678,"an ":50569,"akr":1682,"aku":2116,"akt":1697,"ako":5426,"akk":1936,"aba":1856,"abb":3158,"abd":1557,"ae ":11230,"ad ":2344,"ai ":23587,"aga":3600,"ado":2879,"adi":3222,"ag ":2506,"adt":1359,"aci":1651,"ach":1191,"ace":1933,"ada":7719,"acs":1177,"azo":3899,"azi":1454,"azt":1117,"azg":1460,"aza":1771,"azd":1290,"azz":1187,"az ":35775,"asú":1719,"atá":8809,"ató":6586,"azá":1314,"ba ":10534,"bb ":12760,"at ":13186,"are":1125,"ard":2003,"arc":2552,"ara":12278,"aro":4590,"arm":1949,"arl":1467,"ark":2718,"ari":4156,"aru":1342,"arr":1237,"art":20941,"asa":1245,"aso":1347,"ar ":7389,"akö":2063,"apa":2996,"akú":5988,"alá":20616,"ape":1622,"apc":1186,"apj":1950,"api":1102,"apo":2602,"apt":1225,"aló":3345,"as ":5129,"ava":2849,"aut":1403,"avi":1292,"ará":1634,"asá":3004,"arú":1364,"asz":10871,"atb":1153,"ata":7891,"ast":1692,"ass":5488,"atl":1204,"apí":1933,"atr":1521,"ato":8994,"apá":1330,"ate":2686,"ati":9317,"ath":1161,"att":4210,"aur":1366,"jed":1383,"jel":12132,"jez":1371,"jes":2679,"jai":1887,"je ":3339,"fér":1780,"fél":10120,"job":1168,"jno":2503,"jog":1359,"jle":1493,"itr":1237,"ito":1407,"itt":1847,"isk":1278,"ism":3684,"iss":1661,"ist":5127,"isz":6268,"ita":2682,"ite":2144,"iti":1991,"ius":3051,"ium":2277,"inő":1958,"iva":2264,"ügg":1434,"irá":5579,"ive":1942,"is ":16119,"ion":3768,"ilá":4340,"iro":2666,"ise":2504,"ire":1148,"ira":1291,"it ":5468,"ült":4085,"ülé":2870,"izá":1108,"ja ":16271,"ül ":11962,"ből":3435,"ük ":2123,"itá":2293,"üle":10807,"izo":1300,"ize":1447,"kif":1538,"kik":1160,"kil":1182,"kia":2258,"kin":1795,"kir":2041,"kis":3777,"kit":1528,"úsz":1202,"km ":2029,"ki ":6708,"khe":1740,"ked":3722,"kel":6145,"gál":2697,"ken":2595,"gán":1121,"kes":2444,"gás":1179,"ker":9767,"gár":1661,"ket":5479,"kez":5201,"ke ":3579,"kra":2981,"koz":3084,"kot":2662,"kos":4432,"kor":12163,"kon":4605,"kom":1428,"kol":2622,"kok":2194,"kod":1381,"gés":1802,"kna":1132,"kiá":3411,"géb":1114,"gép":2262,"gén":2847,"kke":2328,"kka":1690,"kbe":2008,"kba":2863,"kat":6062,"kar":2888,"kas":1212,"kap":3160,"kan":1437,"kal":4211,"kai":6519,"füg":1411,"ka ":5099,"föl":2822,"gyé":3341,"gyá":1929,"gyü":2858,"ha ":1609,"han":3792,"haj":2261,"hal":5044,"har":4293,"has":5102,"hat":10778,"hag":1327,"had":1308,"gyű":1250,"he ":2263,"hel":6775,"heg":1841,"hez":5105,"het":6443,"dás":3281,"dár":1447,"her":2201,"hiv":1273,"gla":1955,"gna":2223,"gió":1365,"cél":1462,"úak":6906,"gok":1862,"gol":3486,"gon":2487,"gos":1601,"got":1210,"gra":2375,"gre":1699,"cím":4480,"gsz":2045,"gy ":37866,"gus":1307,"gya":12084,"gye":12610,"gyh":1320,"gyi":8702,"gyk":1565,"gym":1148,"gyo":4080,"úgó":1191,"gys":4096,"iai":5083,"ial":1462,"ian":2020,"iat":1462,"iad":1714,"id ":1248,"ibe":1135,"ia ":14894,"ig ":5385,"ifo":5710,"ife":1711,"ics":1889,"ici":1201,"ich":2336,"ice":1195,"ie ":1156,"ica":2195,"ide":4043,"ida":9550,"ika":8060,"ige":3208,"iga":2520,"ii ":1284,"idé":1418,"ik ":22104,"imp":1521,"inc":1595,"ind":5305,"ina":5669,"ino":2798,"int":11506,"ine":3645,"ing":3990,"ini":2901,"ink":1323,"iká":2172,"inu":1420,"iko":1515,"ike":2523,"ila":1887,"in ":5995,"idő":1933,"iku":4841,"ilo":2015,"ill":7614,"ilm":1881,"ili":3110,"ile":2438,"hoz":7697,"hol":2205,"hon":1202,"hog":3581,"hos":1589,"hor":2048,"dék":1979,"dél":3343,"dés":3202,"dó ":3604,"dít":1872,"díj":1758,"fen":1212,"bán":1642,"fek":1857,"fel":10451,"fej":4036,"fia":1202,"ező":2970,"fal":3069,"faj":8821,"etű":3115,"ető":6086,"ezé":5371,"etü":1875,"esü":1885,"ez ":6988,"eté":6862,"erű":1796,"ezd":1515,"erő":1876,"evé":4056,"ezt":2772,"eze":13658,"ezh":1979,"ezi":1930,"etb":3254,"eta":1302,"ete":14739,"eti":8705,"etl":3489,"etk":2537,"est":5914,"ess":3758,"elő":7242,"esz":10684,"epü":3424,"etr":2609,"ets":2876,"ett":18422,"etv":2394,"erá":1228,"eve":8161,"eré":4519,"eur":1117,"esí":1394,"erü":9565,"epe":2041,"epi":1162,"er ":12986,"es ":29789,"elü":5526,"epl":1338,"elé":3820,"erk":1552,"eri":12722,"erj":2568,"erg":1768,"ere":20225,"erc":2570,"erd":1315,"era":2862,"erb":2020,"et ":26086,"emé":3302,"esi":1683,"ese":5978,"erz":2655,"erv":3920,"err":1968,"ert":6946,"ers":4641,"ern":2834,"erm":4064,"ené":1314,"ero":1595,"eki":1276,"egé":3370,"ekt":2496,"en ":52180,"ela":1439,"ele":27299,"eli":3526,"elj":2109,"elh":1530,"ehé":1275,"elm":4378,"eln":2146,"elk":2863,"ell":9606,"elo":1349,"elv":9038,"els":6778,"elt":4823,"ely":23022,"emb":4386,"ema":1264,"eme":6876,"eml":2503,"emi":1303,"emp":1725,"emz":4591,"ene":6376,"eng":4545,"end":20330,"enc":3429,"ejé":1183,"enn":3397,"enl":1598,"eni":2643,"ens":3074,"ent":14391,"eny":3762,"egk":1751,"egj":2290,"egn":2926,"ege":4339,"egf":1828,"egi":1596,"egh":1485,"egr":1473,"egs":1610,"egt":1312,"egy":47388,"edé":2069,"ehe":2302,"ek ":33389,"ein":1947,"el ":15987,"eit":1126,"ejt":1562,"ejl":2010,"eje":2098,"eke":7178,"ekb":1825,"em ":9006,"ött":6080,"gje":1874,"öss":4328,"gja":1441,"git":1317,"gia":2402,"ört":3402,"örz":1373,"öná":1325,"gha":1393,"ös ":1742,"gi ":5691,"ör ":1444,"gen":2834,"get":4617,"ger":3980,"ges":2578,"gel":2023,"öny":3378,"gek":1625,"önb":1254,"ge ":3243,"gbe":1509,"öld":3665,"gaz":3489,"gba":3483,"ölt":2040,"gas":2172,"gar":1902,"gat":6541,"gal":3993,"ga ":3541,"ök ":2555,"ög ":1983,"ból":6420,"fra":1911,"özö":5568,"özé":2985,"for":12637,"fon":1546,"fol":3847,"özi":2766,"öze":2220,"özs":4673,"özp":1522,"özl":1118,"övé":1547,"fog":4106,"özt":1797,"örü":1396,"fil":2271,"fin":1712,"övi":1986,"öve":4144,"örö":5177,"da ":3729,"de ":4718,"dal":6673,"dae":8117,"dat":1797,"das":1500,"dar":6693,"dap":1398,"cti":1331,"csá":1388,"ciá":1338,"ció":4016,"cs ":2427,"öbb":3612,"cse":2576,"csa":18273,"cso":5464,"csi":2762,"csk":1549,"cea":1428,"ch ":1376,"cer":1367,"cen":1114,"ci ":1364,"cha":1323,"cia":3115,"ck ":1275,"che":1523,"chi":1879,"ed ":1845,"ebb":4696,"ebe":1132,"eae":1455,"ea ":1332,"efo":1148,"ei ":4004,"ega":1438,"edi":4113,"ede":6411,"eg ":8600,"ech":1220,"ect":1158,"ecs":1616,"dor":1576,"don":3362,"dom":3952,"dol":1610,"dot":2319,"djá":9950,"djé":9456,"dsz":3860,"dul":1851,"dt ":1182,"dia":1805,"der":2519,"des":1303,"det":5300,"dez":2835,"del":4174,"den":3777,"di ":3532,"dja":1819,"din":2017,"dig":1984,"dik":7071,"rga":1547,"ri ":7426,"rgi":1214,"rge":1233,"ret":2640,"res":5836,"óta":1799,"rfi":1520,"red":5622,"ósz":1200,"reg":2954,"rem":1197,"ren":20766,"rek":3056,"rel":1449,"nál":7068,"rep":4197,"rde":1294,"ós ":2694,"re ":12803,"rci":1283,"rce":1814,"ópa":1701,"rd ":1700,"ras":2085,"rat":3432,"rba":1762,"rbe":1412,"raj":1914,"rai":1551,"rag":1242,"ran":7745,"ram":2669,"ral":2852,"rak":6278,"rab":2185,"rad":2745,"rac":1357,"rs ":1186,"ror":2542,"ros":13308,"rot":1270,"rom":4552,"ron":3143,"rop":1359,"roz":4272,"rov":1366,"rod":2730,"roc":1647,"rol":2608,"rok":2835,"rog":1810,"rny":1765,"rna":1947,"rne":1337,"rni":1311,"nél":1390,"ném":3320,"nép":2342,"név":7964,"rma":4453,"rme":7442,"riá":1542,"nég":1166,"rla":1110,"rke":1521,"rje":2570,"rit":2732,"ris":3358,"ril":1221,"rik":5031,"rin":5644,"ria":3879,"ric":1848,"rid":1666,"rie":1106,"rif":2877,"rk ":1195,"rsé":1351,"rtá":1222,"rté":4693,"rul":1250,"rus":2059,"rva":1143,"rve":3364,"ry ":1179,"rsa":2647,"rse":2444,"rsz":11249,"rta":3812,"rtj":2461,"rto":16676,"rte":3860,"rti":1302,"óba":1208,"rmé":1800,"rmá":4220,"rt ":8024,"rre":1962,"rra":1492,"sab":1704,"sai":1775,"sak":2444,"sal":14426,"óma":1626,"sba":3589,"sap":1951,"san":2277,"ójá":1365,"sat":1742,"sas":1771,"sa ":7871,"óko":1362,"ók ":2577,"ól ":13016,"ója":2231,"rvá":1234,"rze":1233,"ógi":2210,"ói ":1956,"növ":1656,"rzs":1300,"rvé":1214,"si ":8670,"sid":1199,"sil":1988,"sik":1599,"rző":1316,"se ":7438,"ser":4397,"set":1567,"seb":2714,"sen":5233,"sem":1195,"sel":3187,"sek":2815,"spo":1141,"spa":1306,"sol":2274,"son":4142,"sop":2367,"sor":6863,"sod":2739,"sok":5478,"st ":5212,"sle":1305,"sko":1582,"ska":1477,"ske":1576,"sme":3505,"ssé":2608,"ssá":1740,"sz ":8870,"lőt":1770,"lős":2401,"stá":1316,"sza":14173,"svá":1185,"sze":35971,"szo":9131,"szt":27632,"szu":2442,"szi":9598,"szl":6370,"szk":3277,"szn":4368,"sse":3446,"ssa":2570,"ssz":9449,"ste":4883,"sta":3478,"sto":1355,"sti":2035,"str":2018,"sug":1404,"lő ":3629,"sré":1266,"tai":1258,"tak":4038,"tal":17363,"tag":2404,"tbe":3293,"tba":1669,"tat":5289,"tar":19006,"tan":4747,"te ":9032,"ta ":15756,"szá":22866,"szü":3008,"szé":7434,"szí":4720,"szö":3515,"szó":5026,"ozó":12847,"ozá":2383,"kúa":5586,"pa ":1509,"pcs":1390,"par":3913,"pat":2664,"kül":3938,"pai":1203,"pap":1164,"pan":2344,"pha":1287,"láb":2286,"ped":1503,"lád":12468,"lán":2463,"pen":1323,"per":4376,"lát":1961,"pes":3470,"lás":5210,"lág":4159,"pel":1327,"lál":4812,"plo":1196,"pia":1507,"por":4386,"pos":1197,"pon":4538,"pol":3552,"lét":2548,"lés":5210,"lén":1237,"lék":10125,"lég":1202,"pjá":1227,"psz":1291,"plő":1147,"ló ":6853,"pte":2465,"lít":2551,"pri":1456,"pre":1161,"pro":3235,"lós":1760,"lóg":2572,"pus":1929,"lód":1195,"lön":2431,"lül":5325,"már":3617,"más":7074,"mán":10674,"máj":1466,"még":1185,"mét":1869,"mér":2829,"més":1202,"mél":2519,"mén":4256,"mít":1327,"mód":1366,"ra ":14404,"ngo":3206,"ni ":7437,"nge":3949,"ngy":1650,"jáh":2978,"neg":1502,"nel":1635,"nek":17344,"ják":1953,"ján":4452,"nem":11176,"jár":7148,"ner":1420,"net":3267,"ját":5567,"nes":2093,"nev":9590,"ng ":3420,"jáb":8030,"ncs":2007,"nci":3666,"nce":2318,"ne ":3513,"ndr":1401,"nds":3385,"ndo":2353,"ndj":9787,"ndi":2220,"nde":6999,"nda":1524,"nak":21124,"nal":2777,"nap":2250,"nae":1236,"nag":5845,"nai":2208,"nd ":4041,"nba":1457,"nat":2233,"na ":6605,"mze":3907,"iós":1792,"iój":1245,"nyb":1400,"nya":6957,"nye":12400,"nyi":4978,"nté":5969,"ny ":9196,"nul":2608,"nus":1717,"nty":1140,"nto":3218,"nti":4462,"ntj":1553,"nta":2379,"nte":5991,"nsz":1210,"nse":1158,"nt ":15590,"ns ":1607,"nká":1105,"nok":4021,"nop":1219,"nos":3762,"nov":1101,"nne":2064,"nna":2413,"nni":1136,"nny":1741,"niá":1146,"jéb":6198,"jén":1719,"jéh":3083,"nle":1203,"no ":1255,"nka":1134,"nid":1544,"nic":1428,"nia":2714,"nk ":1863,"nis":2046,"nik":2308,"ogr":1697,"ogl":2068,"oga":3293,"ogy":4073,"ok ":16218,"ol ":3707,"ock":1291,"ode":1450,"odi":3096,"odo":1217,"of ":1189,"oda":2951,"kál":1176,"kán":1252,"káb":1589,"nyí":1276,"obb":3582,"nyo":6087,"nyv":3444,"nyu":2805,"nyt":1370,"nys":1658,"ntő":1470,"jú ":1653,"nyá":1816,"nyé":1280,"oz ":6136,"osí":1185,"köv":1585,"köt":1840,"ozt":1266,"köz":23037,"kön":3656,"köl":1449,"kör":4099,"ozo":1583,"köd":1357,"ová":8369,"ozi":2582,"oza":5292,"ott":13732,"oto":1925,"osz":17179,"ost":2095,"ítő":1100,"oss":3713,"oso":1195,"orú":1625,"osá":2471,"ovi":1122,"ova":1834,"ove":1321,"orá":3688,"íté":2953,"opo":3410,"olá":1371,"ító":2222,"os ":17347,"oló":3495,"opt":1890,"or ":6588,"ítá":3043,"orm":10619,"orn":2184,"oro":8033,"orr":2134,"ord":2929,"oná":1361,"ore":1109,"org":1652,"ori":4752,"osa":4828,"ort":5009,"ors":11126,"orv":1840,"omá":8665,"ot ":4277,"orb":1551,"ora":2591,"ízi":1186,"íto":2971,"ola":3942,"old":2725,"olc":1133,"on ":14829,"oli":4956,"oll":1909,"olg":2986,"ols":1101,"olt":11581,"oln":1426,"olo":2069,"oly":9282,"olu":1943,"okb":1937,"oka":3243,"om ":4999,"okk":1292,"okr":1131,"oks":2384,"íte":4142,"oko":2728,"ív ":1366,"okt":1201,"író":2841,"ona":4624,"ond":2206,"one":1152,"ong":1637,"oni":3479,"ono":2799,"ons":1750,"ont":8687,"ony":4114,"oma":1728,"omb":2831,"omi":1564,"omm":1333,"kék":1183,"kép":5158,"kén":3827,"írá":2059,"omo":2114,"két":4231,"kés":3743,"ímű":2569,"la ":5399,"le ":4396,"lcs":2466,"írt":1125,"lda":1565,"ldi":1183,"lab":1923,"lad":1437,"lag":3296,"laj":1625,"lal":2932,"lak":15098,"lan":5737,"lam":7155,"lap":6224,"lat":10133,"las":4338,"ld ":2188,"lbu":2257,"dő ":2164,"kus":4984,"kul":4809,"ksá":2221,"ksz":1790,"gó ":1820,"gör":2727,"llí":1578,"llá":2364,"lló":2888,"lon":1455,"lom":5872,"lor":1462,"log":1806,"los":2605,"lot":1131,"lov":8327,"lne":1797,"ljá":1491,"lmi":2811,"lme":1597,"lma":4921,"lna":1780,"lto":3300,"lsz":1378,"lta":8440,"lte":3310,"lu ":1887,"lmé":1286,"lre":1816,"lt ":21002,"ldá":1177,"lha":4212,"li ":5160,"ház":2853,"lev":1937,"les":5249,"let":23881,"hár":2058,"lep":3720,"lem":6723,"len":17272,"lek":3977,"lel":1659,"leh":1502,"leg":14221,"háb":1477,"lla":10657,"lle":8630,"lli":2652,"llo":1404,"lko":4418,"lka":2131,"lke":2520,"lgá":2219,"lje":1805,"ll ":3110,"lja":2062,"lit":2107,"lis":6935,"lin":2766,"lim":1567,"lid":1319,"lia":3789,"lik":2243,"lyó":1710,"ma ":5513,"mai":2750,"maj":1342,"mad":7309,"mag":9145,"mar":2289,"mas":1406,"mal":2064,"man":2348,"maz":4614,"mat":4172,"mba":2545,"mbe":4662,"me ":1765,"meg":18261,"iáb":6342,"met":6641,"mes":7852,"mer":9128,"mel":20048,"men":4193,"mek":1223,"mez":3626,"lva":1622,"lve":3172,"lul":1401,"lus":1938,"ly ":11120,"lvt":1957,"ltá":1280,"lsó":1363,"lya":5925,"lyb":1133,"lyi":2296,"lye":12093,"lté":1277,"lvá":1133,"lyo":1466,"lyn":2379,"lys":1166,"lyt":1183,"lső":6342,"lyá":9265,"mpi":1413,"mpl":1595,"mon":2735,"mok":3026,"mos":2616,"mot":1595,"moz":1966,"ió ":2881,"mus":1737,"mut":1302,"mun":2084,"mi ":6215,"min":10577,"mil":1543,"mit":2000,"mia":1836,"mik":1748,"mma":1863,"tő ":4350,"től":2706,"tős":1505,"tőn":1924,"sű ":1297,"zná":3356,"zt ":3494,"víz":2022,"zte":5806,"zti":1839,"zta":2495,"ztr":2410,"zto":1911,"zsi":1572,"ső ":5513,"zul":1547,"ztá":11872,"zté":2691,"rű ":1401,"zsé":5276,"zza":1374,"zga":2049,"zi ":4058,"zhe":2186,"zet":19059,"zes":1480,"zen":10515,"ván":2981,"zem":3342,"zel":4337,"vál":6881,"zek":2284,"vák":7162,"vár":8676,"zer":19180,"ze ":4791,"zda":1164,"zab":2585,"zad":1388,"zak":6902,"zal":1294,"zat":8108,"zot":2710,"zor":2657,"zom":1281,"zon":5431,"zok":2301,"zol":2432,"zpo":1664,"vén":5253,"véd":2112,"vég":2913,"vét":1848,"vés":2023,"zió":1200,"zke":1119,"zle":1674,"zlo":7817,"zig":3735,"zin":2369,"zil":1212,"zik":7225,"zis":1133,"yve":2842,"yug":2984,"ysz":2663,"yok":1279,"yom":2043,"yol":1936,"yos":2298,"yob":2167,"za ":3143,"ről":1883,"ysé":2805,"ye ":3860,"yei":1140,"yek":4530,"yed":1362,"yes":5416,"yer":1837,"yen":2702,"yel":9386,"yez":2468,"yet":5968,"ya ":3038,"yag":1568,"ybe":1927,"yba":1297,"yar":8873,"yan":3850,"tül":2293,"yal":1350,"yak":3842,"yai":1283,"yhá":1178,"yne":2282,"yi ":5728,"yik":7147,"tív":1267,"téz":2544,"tér":3350,"tét":2097,"tés":9077,"tén":6927,"tél":1509,"ték":6622,"töb":3419,"tör":6044,"tó ":7302,"tól":4069,"tán":3887,"tár":7602,"tás":11209,"táv":1125,"ták":3376,"tál":11084,"táj":1226,"sú ":1586,"sül":2209,"só ":1339,"sök":1579,"ség":20101,"sén":1506,"sér":1918,"sét":1189,"sít":5115,"sár":2700,"sát":1861,"sán":1607,"ság":11788,"sáb":4560,"rög":2754,"rök":1818,"röv":1876,"rúg":1325,"rül":11029,"ró ":3203,"vtu":1747,"ról":2801,"róp":2151,"vir":1492,"vil":4652,"vid":4003,"vis":3046,"réb":2703,"rég":2911,"rés":10041,"vol":10664,"von":3245,"vi ":1300,"vez":9822,"ver":7753,"rás":8381,"ves":3105,"vet":5802,"veg":1557,"rág":1665,"ven":5494,"rán":5049,"rál":4428,"vel":6375,"vek":3167,"ráb":2450,"ve ":7296,"val":9128,"van":3020,"var":2245,"vat":2280,"vas":2577,"vad":1432,"vag":11793,"va ":3234,"műv":2529,"műk":1274,"nős":2336,"utó":1685,"utá":2191,"női":1248,"nő ":1717,"mű ":3511,"uró":2193,"usz":5860,"ust":1128,"uta":3446,"uto":1342,"us ":17567,"ura":2400,"urg":1418,"uri":1391,"ulá":1430,"uma":1476,"umb":1113,"unk":2047,"uni":1375,"um ":4397,"ult":3281,"ula":2897,"uk ":1640,"ul ":10317,"uga":4002,"uda":1985,"udo":3577,"pül":4756,"tvá":1162,"trá":1500,"tve":3654,"tur":1775,"tus":2989,"tul":1430,"tum":1120,"tud":4114,"tté":1199,"ttá":1546,"tsé":3581,"pít":3633,"tre":3344,"tt ":30966,"tra":4155,"tri":3477,"tro":2690,"tsz":2410,"tta":4727,"tte":6235,"tti":1842,"to ":1211,"tjá":2955,"tos":4461,"tot":7575,"tkö":1448,"toz":15230,"tom":3113,"ton":3995,"tok":4029,"tol":3082,"tor":5700,"til":2521,"tik":5482,"tis":1923,"tin":5413,"tio":2102,"tiz":1109,"tja":3013,"tke":1731,"tla":1565,"tle":4022,"tem":4106,"pán":1462,"ten":6944,"tei":1486,"tek":7221,"pál":1428,"tel":10568,"teg":2075,"th ":1102,"tet":11629,"tes":7803,"ter":19863,"pár":2273,"ti ":14986,"the":2658,"tha":1854,"ző ":4019,"zöt":4004,"zöv":1986,"zör":1244,"zül":3298,"zás":4765,"zár":4252,"zám":6211,"zál":1821,"zág":9532,"záz":1557,"yüt":2463,"zó ":13810,"vű ":1466,"zít":1657,"zín":2823,"zép":2406,"zér":1246,"zés":6463,"zén":2337,"zél":1670,"zék":2328,"ülö":2566,"ütt":2514,"ülő":1827,"yáb":1633,"yán":7191,"yár":2315,"tű ":2810,"vő ":1785,"yó ":1102,"yéb":2439},"n_words":[10929783,12338513,8457220],"name":"hu"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ind b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ind new file mode 100644 index 000000000..578fd6c45 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ind @@ -0,0 +1 @@ +{"freq":{"D":29898,"E":10468,"F":12839,"G":16234,"A":46756,"B":45618,"C":22345,"L":19113,"M":41589,"N":19093,"O":9096,"H":16882,"I":48750,"J":24390,"K":57099,"U":11179,"T":39498,"W":10090,"V":6089,"Q":1321,"P":55685,"S":65231,"R":21435,"Y":7072,"X":1468,"Z":2501,"f":36925,"g":365165,"d":485064,"e":840847,"b":246328,"c":70473,"a":2100570,"n":996656,"o":305761,"l":430448,"m":362974,"j":64260,"k":378208,"h":280863,"i":864649,"w":50622,"v":31442,"u":508685,"t":522270,"s":482635,"r":589018,"q":2068,"p":245252,"z":10934,"y":153007,"x":3585,"é":2192," l":29162," m":98895," n":17327," o":22384," h":14754," i":38006," j":15556," k":88933," d":239066," e":8087," f":10185," g":12086," a":116958," b":88325," c":8643," y":62811," z":1713," u":21958," t":81597," w":11107," v":3008," p":104408," s":135289," r":13775," J":23985," K":55803," H":16124," I":42065," N":16611," O":7318," L":17821," M":38172," B":43424," C":19640," A":41294," F":11657," G":14895," D":28065," E":8736," Z":2373," Y":6861," S":61440," R":19599," Q":1212," P":52451," W":9492," V":4735," U":10169," T":36300,"ا":1474,"A ":3175,"Da":7353,"Co":3999,"Ce":1371,"Ch":3483,"Ci":2915,"Du":2494,"Do":1602,"De":6798,"Di":6852,"Fe":1983,"Fa":1382,"Er":1543,"Ge":3292,"Ga":2686,"I ":4993,"Fr":1829,"Fo":1312,"Fi":2806,"C ":1897,"Au":2055,"Ar":4506,"As":2577,"D ":1256,"Ba":19721,"Ag":2188,"Ab":1488,"Ac":1714,"Ad":1447,"Am":5332,"An":4093,"Ap":1629,"Al":4784,"Bu":4215,"Br":3076,"Ca":4296,"Bi":2492,"Be":8472,"Bo":3000,"Ku":3549,"Kr":1685,"Ko":9825,"Le":3207,"Li":3131,"La":6311,"Lu":1669,"Lo":2427,"Me":8886,"Mi":3917,"Ma":15663,"Mu":4166,"Mo":3510,"Ni":1382,"Ne":3573,"Na":5130,"P ":1286,"Nu":1142,"No":3476,"Ok":1174,"Gr":2085,"Go":1818,"Gu":2419,"Ha":5613,"He":2039,"II":2521,"Hi":2733,"Ho":2454,"Hu":2080,"Ib":1304,"Ia":3224,"In":24134,"Is":3276,"It":2124,"Ir":1207,"Ja":10872,"Je":6536,"Jo":2100,"Ju":3132,"Ka":22425,"M ":1852,"Ki":1891,"Ke":13666,"Ut":2746,"Un":3136,"Tu":2495,"Tr":1946,"To":2609,"Th":2978,"Ti":8403,"Te":9113,"Ta":6615,"V ":1165,"Sy":1338,"St":3734,"Su":10264,"Wo":1285,"Wi":2707,"Wa":3162,"We":1219,"Vi":1573,"Pu":4020,"Pr":10851,"S ":1994,"Pe":15767,"Pa":12458,"Po":3505,"Pi":2342,"Or":1349,"Se":18572,"Si":5355,"Sh":2006,"Sp":1564,"So":3044,"Ru":2528,"Sa":8331,"Re":4622,"Ri":1937,"SM":1268,"Ro":3385,"T ":1420,"Ra":5456,"b ":5402,"a ":312256,"Ya":1618,"Yo":2051,"Yu":2161,"i ":261146,"ge":17252,"ga":100134,"fi":10254,"fr":1949,"fu":1399,"ft":1686,"fo":4136,"he":8947,"ha":50757,"gn":2069,"gl":1807,"gk":15524,"gi":27056,"gh":4457,"gg":24987,"gu":19428,"gs":5762,"gr":8256,"go":7739,"du":22038,"dy":1437,"g ":127207,"ea":8168,"eb":53877,"ec":18556,"ed":14792,"de":45859,"dd":1120,"di":143405,"do":23309,"ds":1430,"dr":3663,"ew":5523,"eu":3102,"ev":3178,"ey":2387,"fa":4277,"h ":162608,"fe":4040,"eh":16895,"eg":14415,"ef":2165,"ee":3361,"el":59121,"ek":27553,"ej":8227,"ei":5982,"ep":21232,"eo":11093,"en":149316,"em":59371,"et":34760,"es":60149,"er":212475,"ca":27397,"e ":42795,"br":3158,"bu":59966,"bo":6681,"bl":3420,"bi":20522,"be":67748,"da":219838,"f ":6725,"cu":3577,"ct":1798,"co":4648,"ck":2674,"ci":8787,"ch":7724,"ce":8123,"c ":1919,"az":1822,"ay":22914,"ba":74854,"d ":16186,"at":148965,"as":93999,"ar":156214,"aw":19383,"av":2545,"au":33011,"ak":85647,"al":170145,"ai":50563,"aj":9897,"ap":26307,"am":87049,"an":494871,"ac":7825,"ad":111448,"aa":15819,"ab":26392,"ag":30377,"ah":179811,"ae":6490,"af":4082,"nu":12849,"nt":61715,"ns":21631,"no":11352,"nn":7780,"nz":1307,"ny":39684,"oe":1902,"of":3903,"oc":2742,"od":8904,"oa":2254,"ob":5836,"om":19983,"on":61017,"ok":11631,"ol":35874,"oi":1595,"og":9163,"oh":4041,"ot":23779,"os":12530,"ov":13798,"ou":5529,"op":9093,"oo":2776,"or":39625,"r ":75373,"ow":2582,"oy":1610,"pe":68224,"pa":90070,"pl":2952,"po":12602,"ph":1712,"pi":13857,"lo":16018,"ln":1524,"lm":6776,"ll":7645,"ls":1781,"lu":24730,"lt":3200,"ly":1874,"o ":23320,"ma":94460,"mb":26120,"me":93044,"ml":1630,"mi":26777,"mn":2215,"mm":2111,"mp":24012,"mo":8478,"mu":28574,"p ":11473,"na":77075,"nc":11437,"nd":56574,"ne":39080,"nf":2387,"ng":238792,"ni":56068,"nj":13796,"nk":3871,"ju":15959,"jo":2256,"ki":23132,"kh":4590,"ke":56774,"ka":127350,"m ":50860,"ky":1397,"ks":9835,"kt":10395,"ku":22809,"ko":27878,"kr":3523,"kk":1592,"kl":3754,"km":2765,"kn":3265,"li":60829,"lk":2913,"le":44927,"ld":2217,"la":192799,"lb":1849,"n ":334938,"hr":1702,"ht":1424,"hu":19954,"hk":1872,"hi":19755,"hn":2129,"ho":5306,"hl":1668,"id":19549,"ic":8689,"ib":13081,"ia":81624,"ih":9019,"ig":10843,"if":6720,"ie":7742,"k ":77693,"ir":31102,"is":68271,"it":40678,"iu":5028,"iv":4491,"iw":2077,"ij":2865,"ik":61148,"il":48904,"im":30225,"in":117362,"io":16681,"ip":11977,"je":5678,"ji":4743,"iz":1367,"iy":1200,"l ":56560,"ja":34513,"z ":1416,"wi":10306,"wo":1229,"y ":11456,"wa":31269,"we":3398,"vi":15930,"vo":1681,"ve":8269,"va":3932,"x ":1658,"ui":4586,"uj":4080,"uk":44283,"ul":29290,"ue":2818,"uf":1241,"ug":8297,"uh":9753,"ur":39636,"us":36462,"ut":30979,"um":25849,"un":84334,"up":32836,"ty":2279,"tu":61107,"tt":3054,"ub":9153,"ua":56784,"ud":13238,"uc":2268,"w ":1917,"to":20692,"tn":2005,"tl":1402,"ts":2489,"tr":20074,"te":90779,"tk":2568,"ti":55141,"th":5635,"ta":176003,"su":25989,"ss":5417,"st":32797,"sy":2246,"sw":1219,"sl":3160,"sk":6158,"sn":2055,"sm":3761,"sp":3394,"so":6557,"sc":1962,"se":100046,"sh":4276,"si":103815,"u ":69102,"sa":100996,"rr":2177,"rs":13384,"rt":29454,"ru":41105,"rv":1161,"rw":1931,"ry":4130,"rp":3731,"ro":34136,"rn":12088,"rm":13211,"rl":14368,"rk":15615,"rj":5203,"ri":102805,"rh":3147,"rg":10415,"rf":1249,"re":30519,"rd":11856,"rc":2704,"rb":14366,"ra":143028,"t ":74952,"qu":1325,"s ":74416,"pt":3193,"pu":23123,"pr":13816,"ps":1371,"zi":2204,"za":3196,"ye":4611,"ya":121025,"yu":3182,"ys":1566,"yo":3138,"yi":2638,"一":3113," Ga":2665," Ge":3275," Fo":1303," Fr":1822," Fi":2802," Ha":5588," He":2029," Go":1803," Gr":2062," Gu":2405," Ib":1298," Ia":3220," Hu":2077," Ho":2444," II":1738," Hi":2728," Je":6511," Ja":10843," Ir":1206," Is":3262," It":2123," In":24109," Ka":22393," Ke":13629," Ki":1879," Jo":2086," Ju":3129," La":6277," Le":3183," Li":3097," Ko":9805," Kr":1679," Ku":3543," Ma":15603," Mi":3888," Me":8848," Lo":2414," Lu":1657," Ne":3562," Na":5110," Ni":1377," Mo":3486," Mu":4147," Ap":1628," Am":5319," An":4070," Al":4777," Ag":2185," Ac":1711," Ad":1437," Ab":1471," Ba":19679," Au":2049," As":2567," Ar":4490," Be":8434," Bi":2483," Bo":2979," Br":3065," Bu":4209," Ca":4213," Ce":1368," Ci":2897," Ch":3462," Co":3963," Da":7319," Di":6832," De":6775," Do":1546," Du":2487," Er":1536," Fe":1977," Fa":1366," Wo":1267," Wi":2689," We":1211," Wa":3147," Yu":2156," Yo":2043," Ya":1612," Or":1346," Po":3467," Pi":2336," Pe":15730," Pa":12421," Nu":1139," No":3465," Ok":1169," Ra":5409," SM":1160," Ro":3363," Re":4599," Ri":1930," Pr":10827," Pu":4013," Sy":1332," Su":10248," St":3681," Ta":6595," Th":2952," Ti":8388," Te":9090," Tr":1942," To":2586," Ru":2526," Sa":8312," Sh":1982," Si":5333," Se":18549," So":3026," Sp":1555," Vi":1551," Tu":2469," Un":3130," Ut":2746," ja":5269," je":2335," in":24841," il":1562," is":2175," it":1708," ka":17469," kh":1422," ki":3127," ke":41380," ju":6965," ha":6291," gr":1294," gu":1601," ib":1921," ia":3559," hi":4380," hu":2034," ne":5231," na":8812," mu":5887," mo":2739," ol":12623," of":1811," no":1685," le":5736," li":3289," la":14587," ku":3200," km":2201," kl":1852," ko":17290," me":68772," mi":4388," ma":16460," lu":3991," lo":1345," ag":1308," ab":1554," ad":60411," an":11749," ap":1720," ak":5080," al":4506," aw":1213," ar":2749," at":18641," as":3479," ba":29062," bi":8314," be":42050," bo":2101," bu":6066," ca":3227," en":1364," ek":1536," fo":1399," fi":5527," ge":4483," ga":3124," co":1499," ce":1281," da":93500," do":1270," de":28323," di":109723," du":4523," za":1414," ya":62479," ru":1822," sa":30188," se":78628," si":6482," sp":1184," so":1196," ra":4660," re":4944," ro":1171," pu":5843," pr":10257," or":4567," pe":52401," pa":26959," po":5413," pi":2294," wa":3549," wi":6744," tu":4514," ut":3268," um":2172," un":12469," ta":18998," st":3288," su":11745," tr":2305," to":2153," th":1170," ti":9886," te":42313,"Fil":1716,"Ger":1344,"II ":2070,"Han":1227,"Har":1306,"Ing":3276,"Int":1699,"Ind":17352,"Ia ":3146,"Ara":1730,"Aus":1437,"Bah":2306,"Bal":1493,"Ban":5008,"Bar":4958,"Bat":1605,"Agu":1534,"Ame":4085,"Ang":1356,"Ber":2116,"Ben":1538,"Bel":2649,"Bri":1173,"Des":2124,"Dal":2000,"Cha":1289,"Dia":1644,"Neg":1421,"Nov":1144,"Per":8357,"Pem":1634,"Pen":3260,"Pas":1289,"Par":2408,"Pad":2035,"Pan":1988,"Pul":1756,"Pro":7786,"Pre":1253,"Pol":1113,"Ita":1993,"Isl":1234,"Jan":1394,"Jak":1458,"Jep":2416,"Jer":2596,"Jaw":4820,"Jul":1161,"Kab":8059,"Kal":5302,"Kan":1250,"Kat":1399,"Kar":2399,"Ker":1724,"Kep":1438,"Kel":1127,"Kec":4407,"Kon":1421,"Kom":1142,"Kor":1136,"Kot":4453,"Lau":1252,"Men":2499,"Mer":1254,"Man":2093,"Mal":2386,"Mar":3752,"Mas":1454,"Mus":1132,"Yun":1506,"一一":1315,"Sur":1395,"Sum":1934,"Sul":1400,"Sun":2471,"Sta":2065,"Ten":4508,"Tan":2075,"Sin":1312,"Ser":4461,"Sep":1413,"Sel":5571,"Sem":1247,"Seb":1132,"Rus":1267,"Sam":1292,"San":2004,"Rep":1522,"Rom":1304,"Uni":2252,"Uta":2484,"Ter":1521,"The":1859,"Tim":5598,"bis":1615,"bit":1641,"bil":2430,"bin":3990,"bih":2863,"bli":2292,"bol":2158,"ban":15219,"bak":1477,"bal":2565,"bai":2045,"bag":18039,"bah":11866,"bad":2660,"baw":2021,"bat":5802,"bas":2119,"bar":6280,"beb":2207,"bed":1156,"ber":44372,"ben":5468,"bel":6123,"bek":1139,"bes":5623,"bia":3415,"bid":1129,"ca ":1339,"car":5372,"can":2310,"cam":11583,"ce ":2031,"bu ":2451,"bua":22699,"bup":9962,"bur":1967,"bul":1642,"buk":3601,"bun":4326,"bum":1823,"buh":2607,"but":6527,"aka":36392,"am ":27176,"aki":3783,"akh":2140,"al ":32136,"aja":7514,"aik":1989,"ain":9801,"air":2314,"ais":1591,"ait":2311,"ak ":26644,"ahk":1403,"ahi":5150,"ahu":13410,"aha":23711,"agi":8426,"agu":2010,"anu":3628,"any":11108,"ano":1219,"ann":4127,"ant":18067,"ans":3241,"ane":1770,"ang":133187,"ani":10218,"anj":5111,"ank":1863,"ap ":5145,"ana":17620,"anc":4861,"and":16448,"amu":2163,"amp":6554,"ami":2968,"ame":2230,"amb":4802,"ama":38387,"alu":3924,"alo":1291,"all":1612,"ali":20004,"ale":3013,"ala":101814,"an ":259764,"aks":3177,"aku":4198,"akt":4736,"aba":6181,"abi":1719,"abu":12017,"ae ":1556,"aca":2365,"aan":12880,"aat":2166,"ad ":3820,"ab ":3122,"afi":1142,"ai ":28231,"aga":15818,"age":1445,"aer":3528,"ah ":131776,"adi":10057,"ade":2164,"ach":1161,"ace":1304,"ada":91074,"ayu":1260,"aya":17559,"ba ":1212,"at ":42706,"arg":2616,"are":4682,"ard":2694,"ara":50200,"aro":1477,"arn":2327,"arl":1195,"ark":4616,"ari":39797,"aru":4864,"ars":1240,"art":10017,"au ":21880,"asa":28749,"ary":2056,"asi":28272,"ase":1504,"ask":2058,"ar ":23543,"apa":12599,"api":3283,"apu":2004,"as ":18260,"aut":2942,"ay ":1252,"awa":16458,"awi":1328,"ata":52964,"asu":4212,"ast":4229,"ass":1429,"asy":1183,"atk":1321,"ato":2873,"ate":14253,"ati":9780,"aua":1165,"atu":20191,"aup":1527,"aus":1167,"jen":2753,"jad":5570,"jaa":2051,"jab":1150,"jar":5491,"jal":2507,"jak":2749,"jan":3425,"jo ":1155,"ito":1897,"itu":7300,"ism":1635,"isu":1798,"ist":11957,"ita":13383,"ite":4451,"iti":3900,"iwa":1676,"ium":1147,"iun":2068,"ivi":1396,"ive":2266,"ipu":1250,"ipi":1541,"is ":23018,"ion":11007,"ipa":2509,"ipe":2501,"ir ":10536,"irk":1299,"iri":9503,"isi":11065,"ise":5218,"isa":7947,"ire":1684,"ira":4533,"it ":5451,"ja ":5112,"kim":1495,"kil":1164,"kin":2100,"kir":1475,"kis":1425,"kit":4346,"km ":1129,"ki ":8986,"khi":1575,"keb":2854,"kec":8512,"ked":2012,"kek":1191,"kem":4126,"kel":7010,"ken":6683,"kep":3726,"kes":1631,"ker":5150,"ket":3912,"ke ":5970,"ksa":1691,"ku ":4682,"kot":9086,"kon":4219,"kom":5415,"kol":2400,"koh":1184,"ks ":1167,"kny":1410,"kka":1328,"ko ":1260,"kla":1828,"juk":1809,"jun":1767,"jum":1474,"jua":1961,"jug":4990,"kaw":1325,"kat":13174,"kar":11177,"kas":4851,"kap":2757,"kan":62967,"kal":5122,"kam":1705,"kai":2738,"kad":1254,"kab":2943,"ka ":12884,"ha ":2059,"ham":2420,"han":14832,"hak":1134,"hal":1973,"har":6037,"has":12725,"hat":1841,"haa":1690,"had":1765,"he ":2996,"her":1241,"hi ":1844,"hid":1896,"hin":3929,"hir":6378,"hka":1709,"go ":1252,"gku":1576,"gor":1284,"got":2192,"gsa":3115,"gu ":1706,"gra":2940,"gri":3408,"gur":1410,"gus":2168,"gun":9840,"iam":1372,"ial":6166,"ian":16893,"iap":1176,"ias":3614,"iat":1370,"ibi":1510,"ibu":4263,"id ":2050,"iba":3456,"ibe":2500,"ia ":44404,"ier":1178,"ies":1321,"ifi":1731,"ih ":5574,"ich":1544,"ie ":1390,"ica":1838,"idu":1993,"idi":3417,"ide":3199,"ida":6661,"if ":2797,"il ":7886,"ija":1503,"im ":3888,"ika":23689,"iga":3238,"igu":3825,"iha":2592,"ik ":17419,"imp":2775,"ime":1812,"imi":1994,"ind":4767,"ina":9693,"imu":7350,"inn":1767,"ino":1354,"int":9752,"ins":11171,"ine":2698,"ing":27890,"ini":22825,"ink":1199,"iny":3792,"iko":1474,"iki":7614,"ike":5441,"ila":14804,"in ":16335,"iku":2328,"ill":2052,"ilm":5734,"ili":13211,"ile":1187,"ima":9934,"io ":1907,"hny":1246,"hub":1262,"hun":11971,"hus":1117,"fat":1257,"eta":14851,"ete":4068,"eti":4646,"est":3135,"esu":1622,"ess":1214,"etu":1676,"evi":1298,"ey ":1761,"ewa":3433,"epe":3912,"er ":19709,"epa":9668,"eor":7717,"es ":8727,"ept":1302,"epu":3274,"erk":7438,"erl":11827,"eri":25792,"erj":4499,"erg":3829,"erh":2837,"ere":6493,"erc":1371,"erd":7020,"era":35580,"erb":12574,"et ":5262,"esi":21745,"ese":3800,"esa":15867,"eru":21470,"ert":16167,"ers":10880,"ern":7132,"erm":8938,"erp":2943,"ero":2183,"eki":2304,"ekn":1342,"eko":2677,"eks":2683,"ekt":2574,"eku":2083,"en ":21818,"ela":27699,"ele":4883,"eli":4636,"ell":1619,"elo":2885,"elu":8272,"emb":14950,"ema":7624,"eme":9102,"emo":1229,"emi":9424,"emu":4943,"emp":7479,"ene":6504,"eng":44211,"ena":14758,"end":12541,"enc":3844,"eni":5826,"enj":6735,"enu":4939,"ens":2961,"ent":14866,"eny":6205,"ege":2018,"egi":2598,"ehi":1472,"ek ":3218,"ein":1306,"eja":5845,"el ":6722,"eke":1577,"eka":8278,"em ":3699,"gka":11656,"git":1200,"gin":2402,"gio":1293,"gia":7505,"gha":1865,"ggu":3578,"ggr":3634,"ggo":2263,"ggi":3715,"gga":11266,"gi ":10809,"gen":4341,"ger":4633,"gem":1548,"gel":2369,"ge ":1412,"gah":5405,"gai":13025,"gas":1879,"gar":10391,"gat":2080,"gam":3520,"gal":5628,"gan":35620,"gap":1320,"ga ":16084,"for":2821,"fil":3873,"fik":2255,"fis":1267,"da ":32556,"de ":5057,"dak":4551,"dal":74713,"dah":2729,"dae":2768,"dat":2016,"das":2265,"dar":32215,"dap":6287,"dan":52470,"dam":1256,"day":1876,"ch ":1540,"cer":1324,"cha":1339,"ck ":1406,"che":1327,"chi":1177,"cil":1660,"cis":2553,"ed ":1578,"eba":14092,"ebe":8142,"ebi":3337,"ebr":1132,"ebu":26049,"ea ":1655,"ei ":1901,"ega":7504,"eh ":13927,"edi":3728,"ede":1589,"eda":4173,"edu":2208,"eci":1667,"eca":14054,"dus":1247,"don":16622,"dok":1141,"dun":4005,"dup":1272,"dul":1434,"duk":5272,"dua":3278,"dud":2657,"dra":1669,"du ":1319,"did":3706,"dia":10670,"dib":6007,"der":4755,"des":7802,"del":1249,"dek":2240,"den":19332,"dem":1173,"di ":63731,"do ":1904,"dim":2715,"din":3800,"dio":1486,"dip":4666,"dir":8308,"dis":11623,"dit":5425,"dig":4149,"dik":8070,"dil":3331,"rha":2148,"rga":5059,"ri ":42938,"rge":1577,"ret":2887,"res":4698,"rg ":1147,"rea":2388,"rej":1691,"ren":4953,"rek":3031,"rda":4163,"rdi":3109,"re ":2800,"rbu":1584,"raw":1318,"rd ":2133,"rap":3154,"rar":1749,"ras":8094,"rat":11399,"rbi":1817,"rba":6850,"rbe":3317,"raj":2995,"rai":2568,"rah":9741,"rag":1442,"ran":36962,"ram":3611,"ral":3814,"rak":7284,"rab":2762,"raa":1221,"raf":1467,"rad":6359,"rs ":1283,"rpe":1250,"ros":2826,"rot":1395,"rom":1135,"ron":3571,"rop":2512,"rov":9832,"rod":2363,"rog":1358,"rny":1495,"rna":5736,"rmu":1260,"ro ":1992,"rma":9740,"rle":9267,"rla":2281,"rn ":1378,"rki":1226,"rke":4730,"rka":5975,"rja":3509,"rip":1275,"rio":1652,"rit":4490,"ris":9168,"ril":2736,"rik":14926,"rin":9510,"rim":1709,"ria":5936,"rib":1211,"ric":1356,"rid":1193,"rie":1621,"rk ":1641,"rya":1832,"ruh":2011,"rup":16158,"run":3050,"rum":2131,"ruk":1365,"rus":4704,"rut":3005,"ry ":1765,"rsi":3955,"rsa":2467,"rse":3931,"rta":11752,"rte":3710,"rti":7667,"rua":2111,"rtu":2198,"rt ":1478,"ru ":3013,"saa":3516,"sah":3766,"sai":1253,"sak":1265,"sal":14489,"sam":5305,"san":11536,"sat":14608,"sas":2791,"sar":11521,"saw":1247,"sa ":26535,"shi":1399,"si ":37996,"sid":1884,"sia":23497,"sit":3002,"siu":2036,"sir":1424,"sis":6271,"sin":5946,"sio":5312,"sil":3164,"sim":1558,"sik":5796,"sih":1154,"sif":1869,"se ":1750,"ser":7000,"ses":3161,"set":3675,"seh":1426,"sed":1550,"sec":2609,"seb":38986,"sep":5282,"seo":6619,"sen":4315,"sem":4262,"sel":6726,"sek":6032,"sej":4109,"spe":1482,"son":1660,"st ":1847,"ss ":1345,"sli":1139,"sla":1693,"ska":2806,"smi":1231,"sme":1407,"sya":1486,"ssa":1575,"ste":6115,"sta":5899,"sto":1411,"sti":6848,"stu":1610,"str":8471,"sua":5405,"sum":1276,"suk":5658,"sun":2892,"sut":1776,"sus":2249,"sur":1552,"tai":3534,"tak":12396,"tal":4630,"tah":16201,"tab":1684,"tau":16309,"tat":1881,"tas":11773,"tar":15390,"tap":2003,"tan":48487,"tam":7817,"te ":2719,"ta ":30047,"pa ":5126,"par":4662,"pat":19772,"pas":2458,"pad":19421,"pak":16990,"pal":3741,"pai":3130,"pan":11608,"pi ":3245,"pen":20640,"pem":8687,"per":28237,"pes":2547,"pel":2885,"pil":1386,"pin":3678,"pis":1169,"por":1652,"pop":1746,"pos":1337,"pon":1531,"pok":1819,"pol":2768,"pua":1330,"pub":1942,"pte":1271,"pri":2203,"pre":1413,"pro":9219,"pur":2238,"pus":1843,"put":3676,"pun":4895,"pul":5693,"ra ":33891,"ngo":1466,"ngi":5434,"ngk":15500,"ngu":4341,"ngs":5639,"ni ":27725,"nge":5034,"ngg":24626,"ngh":3138,"nga":45848,"neg":5658,"nen":1469,"ner":3870,"net":1984,"nes":16997,"ng ":124434,"nci":3629,"nce":1815,"nca":3309,"ne ":3872,"ndu":6040,"ndr":1343,"ndo":17880,"ndi":8610,"nde":4365,"nda":13200,"ncu":1191,"nak":8053,"nal":12498,"nam":10027,"nan":12711,"nar":2327,"nah":2814,"nai":1146,"nd ":3909,"nat":2083,"nas":5218,"na ":14205,"nya":32061,"nye":2679,"nyi":2079,"nul":1194,"nun":2161,"nus":2178,"nur":1832,"nua":1507,"nto":2680,"ntu":18006,"ntr":1617,"nti":5215,"nta":22900,"nte":7428,"nst":1796,"nse":1390,"nsi":12613,"nt ":2342,"ns ":1443,"nol":1247,"nom":2318,"nny":5115,"no ":2934,"nka":1820,"nja":9105,"nju":2843,"nia":6702,"niv":1591,"nis":7959,"nit":2077,"nin":2190,"nik":2713,"ogr":1789,"ogi":3408,"ok ":3549,"ol ":2833,"ode":3528,"of ":1858,"odu":2149,"oh ":1516,"obe":1842,"ote":1332,"oto":2549,"ota":16038,"osi":2975,"ose":2201,"oso":1148,"ovi":10349,"ove":2391,"oun":1267,"ope":1909,"opa":1279,"os ":1902,"opu":1750,"or ":7039,"orm":2622,"oro":1416,"ord":1550,"ore":2472,"org":2231,"ori":3198,"ort":1972,"ora":11685,"ola":5593,"on ":12856,"oli":4593,"ole":13717,"olo":5388,"oka":1673,"om ":1677,"oko":1983,"ona":7292,"ond":2230,"one":17406,"ong":6397,"oni":2889,"ono":3029,"ons":2868,"ont":3055,"oma":3069,"ome":2094,"omb":1474,"omi":2626,"omp":4769,"omo":1445,"omu":1988,"la ":8248,"le ":2787,"lah":85384,"lag":1642,"lai":7338,"lal":2146,"lak":4119,"lan":18336,"lam":23788,"lap":1829,"lar":2452,"lat":9794,"las":5560,"law":2074,"lau":6152,"lay":9124,"kut":2035,"kus":1523,"kur":1949,"kup":1223,"kun":2321,"kum":1981,"kul":1651,"kuk":1717,"kte":1325,"ksi":4460,"kua":1980,"ktr":1281,"ktu":2650,"kti":1994,"kto":2651,"lok":1231,"lon":2362,"lom":2722,"log":4305,"lny":1353,"lmu":1446,"lua":4860,"lta":1301,"lu ":3267,"li ":7633,"lev":1141,"les":2673,"let":9284,"ler":1546,"lem":2195,"len":2677,"lek":2289,"leh":12733,"leb":3217,"lla":1957,"lle":1326,"lli":1227,"lka":1991,"lm ":4360,"ll ":1780,"lit":5426,"lis":7079,"lir":1515,"lip":1370,"lin":6938,"lim":6542,"lia":5362,"lik":11324,"lih":1781,"ma ":21495,"mah":2164,"mai":3887,"mak":3420,"mad":1850,"mar":3160,"mas":10730,"mal":1793,"man":22564,"mat":17173,"mba":10647,"mbi":2114,"mbe":6808,"me ":2693,"mbu":4891,"med":1539,"met":2294,"mes":1768,"mer":26378,"mem":15519,"mel":4982,"men":35186,"luk":2200,"lui":1193,"lun":1652,"lum":2455,"lus":1551,"lur":4662,"mpi":3325,"mpe":2325,"mpo":2760,"mpu":6558,"mod":1185,"mon":1666,"mor":1409,"mpa":7594,"mu ":1626,"mud":2039,"mua":1660,"mur":7325,"mus":3149,"muk":2006,"mul":2774,"mum":2269,"mun":4790,"mi ":4545,"min":4316,"mil":8646,"mis":1673,"mit":1227,"mia":1700,"mik":1662,"mla":1505,"mny":1911,"zam":1194,"yu ":1225,"ya ":33584,"yat":1924,"yar":2043,"yan":64564,"yak":4682,"yah":7474,"yai":2823,"yi ":1127,"wi ":1323,"wil":6167,"wa ":9713,"wan":5957,"wal":2130,"wak":2165,"wat":1765,"war":3553,"was":1762,"wah":1890,"vin":9845,"vis":1830,"ver":3522,"usi":7004,"use":1166,"usa":6560,"usu":2654,"ust":3983,"uti":2003,"ute":2083,"uta":7869,"utu":1851,"utr":2712,"us ":12050,"ut ":11892,"ura":9315,"uri":1909,"urk":1245,"uru":7051,"uny":2077,"upa":26147,"ur ":13684,"upu":1725,"ump":1843,"umu":2414,"umi":1414,"uml":1462,"umn":1617,"uma":4069,"umb":3461,"ume":1307,"unt":12867,"unu":2087,"uni":6942,"unc":1388,"und":1967,"una":10560,"ung":21765,"une":1335,"up ":3437,"uks":1606,"uku":6493,"uko":1586,"uki":1626,"um ":7458,"uka":7728,"uju":3230,"ulu":3880,"ult":1653,"uli":4656,"ula":12496,"un ":20290,"uk ":22268,"ul ":3263,"ui ":2114,"uga":6118,"uha":3495,"uda":4275,"udi":2630,"ubu":2471,"uh ":4643,"udu":3551,"ua ":5771,"uat":8034,"uas":4449,"uar":6223,"ual":1917,"uan":9121,"ubl":2137,"uba":1945,"uah":19677,"ty ":1866,"tur":4927,"tus":3183,"tuj":1345,"tul":1791,"tuk":15174,"tun":2681,"tum":1823,"tua":3005,"ts ":1124,"tra":8844,"tri":6158,"tru":1229,"tro":2826,"tu ":22458,"to ":3427,"tny":1162,"tob":1155,"ton":2911,"tok":1669,"tol":2048,"tor":4842,"til":2355,"tik":7507,"tif":2658,"tig":1707,"tit":1315,"tis":2474,"tin":8673,"tim":3584,"tio":3164,"tia":2861,"tid":3087,"tiv":1124,"tka":2458,"tem":9574,"ten":16531,"tek":2322,"tel":6089,"th ":1540,"tet":1414,"tes":1167,"ter":45895,"ti ":10357,"the":1811},"n_words":[11077227,12709440,9643042],"name":"id"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ita b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ita new file mode 100644 index 000000000..4ba4b4009 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ita @@ -0,0 +1 @@ +{"freq":{"D":94947,"E":67243,"F":92398,"G":104535,"A":191905,"B":119758,"C":221153,"L":203562,"M":160653,"N":84931,"O":53123,"H":49392,"I":191375,"J":30427,"K":33649,"U":59673,"T":99599,"W":33788,"V":71164,"Q":12325,"P":151391,"S":231227,"R":109065,"Y":11206,"X":16332,"Z":10278,"f":518611,"g":920085,"d":2363397,"e":6056669,"b":494596,"c":2150346,"a":6155041,"n":4141668,"o":4513622,"l":3766393,"m":1338197,"j":22860,"k":110896,"h":452585,"i":5976536,"w":49843,"v":585518,"u":1754682,"t":3725316,"s":2419415,"r":3264659,"q":101625,"p":1281861,"z":475996,"y":114701,"x":30592,"È":18809,"ì":9651,"é":22484,"è":321778,"à":93588,"ù":30198,"ò":27447,"ó":6194," l":332142," m":240472," n":389032," o":184207," h":31309," i":549255," k":13980," d":1574321," e":446281," f":277424," g":138336," a":703335," b":75718," c":722915," z":6698," u":458470," t":223758," v":125009," q":64842," p":570240," s":706865," r":244819," J":29715," K":31685," H":46792," I":159850," N":78119," O":44164," L":197779," M":152789," B":113710," C":207226," A":159909," F":86857," G":100079," D":87417," E":59714," Z":9584," Y":10426," X":11662," S":213852," R":103083," Q":11829," P":141839," W":31372," V":61312," U":56839," T":91377," è":311053," È":18792,"A ":27808,"Da":15987,"Cu":5620,"Cl":7833,"Co":63300,"Cr":10676,"Ce":10902,"Ch":29704,"Ci":11685,"Du":6024,"Do":13966,"De":15564,"Di":21598,"Fe":11756,"Fa":10362,"Eu":7860,"Es":8695,"En":5820,"El":6080,"Ge":15850,"Ga":14081,"I ":31564,"Fu":8170,"Fr":19816,"Fo":12748,"Fi":15192,"C ":10682,"Au":9085,"Ar":21848,"As":8912,"D ":5691,"Ba":27783,"Am":10014,"An":18633,"Al":34245,"Bu":8230,"Br":18440,"Ca":56504,"Bi":8237,"Be":19580,"Bo":19802,"Le":25820,"Li":19778,"La":88640,"Lu":9671,"Lo":25268,"Me":19948,"Mi":23733,"Ma":59219,"Mu":9761,"Mo":30287,"Ni":7514,"Ne":23857,"Na":17893,"No":19720,"Gi":22185,"Gl":5829,"Gr":18092,"Go":9531,"Gu":8537,"Ha":17031,"He":8149,"II":13036,"Ho":8979,"In":30727,"Il":66084,"Is":9021,"It":12730,"Ja":8255,"L ":27703,"Jo":9534,"Ka":7944,"Un":28071,"Tr":15672,"To":14627,"Th":17010,"Ti":6315,"Te":15797,"Ta":10754,"UA":13360,"V ":7192,"St":32757,"Su":12977,"Wi":7930,"Wa":7819,"Vo":7254,"Vi":20021,"Va":13663,"Ve":14211,"Pu":5612,"Pr":25455,"S ":9118,"Pe":16282,"Pa":38366,"Po":20730,"Pi":22494,"Or":10767,"Se":20797,"Sc":24538,"Si":21736,"Sh":7322,"Sp":9077,"So":16973,"Ru":7444,"Sa":46373,"Re":30166,"Ri":14281,"Ro":32671,"Qu":10556,"Ra":11841,"b ":11012,"a ":2254795,"i ":1483483,"ge":88624,"ga":67666,"fl":8575,"ff":35291,"fi":134642,"fr":78002,"fu":41990,"fo":66122,"he":195889,"ha":63814,"gn":70158,"gl":120822,"gi":234393,"gh":24919,"gg":70910,"gu":55229,"gr":73387,"go":71768,"du":52294,"g ":29202,"ea":91863,"eb":24191,"ec":137759,"ed":128701,"de":782039,"dd":10103,"di":854362,"do":146993,"ds":9108,"dr":32135,"ew":7817,"ex":7461,"eu":18301,"ev":52077,"ey":12656,"ez":26509,"fa":71893,"h ":27064,"fe":57833,"eg":172770,"ef":19354,"ee":16955,"el":899715,"ei":89786,"ep":27874,"eo":41068,"en":625515,"em":132418,"et":253878,"es":434221,"er":718824,"eq":6537,"ca":399283,"e ":2094441,"br":59095,"bu":40562,"bo":29867,"bl":42370,"bi":141440,"bb":48744,"be":43765,"da":306546,"f ":15395,"cu":62362,"ct":11024,"cq":7195,"cr":59094,"co":609419,"ck":21526,"cl":55423,"ci":319342,"ch":241963,"ce":223557,"cc":104089,"c ":16295,"az":131617,"ay":15144,"ba":66599,"d ":145378,"at":664795,"as":217940,"ar":494405,"av":77540,"au":53901,"ak":11813,"al":679169,"ai":64110,"ap":84421,"am":172413,"an":700812,"ac":102427,"ad":97495,"ab":100158,"ag":138596,"ah":7533,"ae":26244,"af":30789,"nu":38735,"nt":634979,"ns":87660,"nq":7056,"no":374486,"nn":92022,"nz":76063,"ny":7751,"nv":12211,"oe":12640,"of":30817,"oc":106098,"od":71766,"oa":9353,"ob":27798,"om":291133,"on":807692,"ok":6829,"ol":302572,"oi":49498,"og":89760,"oh":6209,"ot":113582,"os":173480,"ov":109964,"ou":37230,"op":117448,"oo":15155,"or":452213,"r ":177153,"ow":12656,"oz":6935,"oy":5914,"pe":242170,"pa":234524,"pl":24851,"po":213425,"ph":7578,"pi":128997,"lo":210541,"lm":44463,"ll":700194,"ls":12139,"lp":10018,"lv":11056,"lu":64908,"lt":90822,"ly":7335,"o ":1645460,"ma":263312,"mb":52388,"me":350394,"mi":170562,"mm":42029,"mp":106005,"mo":153835,"mu":105465,"p ":14900,"iù":27078,"na":431794,"nc":198192,"nd":220346,"ne":784634,"nf":25150,"ng":109071,"ni":335162,"nk":7990,"ki":12045,"ke":15323,"ka":11574,"m ":76534,"ko":6777,"km":10394,"li":478088,"le":450199,"ld":17670,"lg":10033,"lf":7624,"la":677771,"lc":22009,"lb":26576,"n ":671873,"hr":6559,"ht":9126,"hu":11107,"hi":93831,"hn":5725,"ho":18964,"id":103779,"ic":450726,"ib":38087,"ia":461965,"ig":105629,"if":52751,"ie":183937,"k ":32183,"ir":101293,"is":299704,"it":487446,"iu":44781,"iv":129892,"ik":7413,"il":319428,"im":199167,"in":697560,"io":541230,"ip":107291,"iz":100179,"l ":908043,"ja":6741,"z ":9054,"tà":85596,"wi":6023,"vv":10000,"y ":65822,"wa":12380,"we":6401,"vi":166809,"vo":78376,"uz":20664,"ve":175153,"va":133125,"x ":19811,"ui":79181,"ul":72491,"ue":88946,"uf":10300,"ug":23193,"ur":134766,"us":100555,"ut":118876,"um":71437,"un":561799,"uo":58100,"up":47527,"ty":10365,"tu":164890,"tt":381279,"ub":48232,"ua":156844,"ud":43002,"uc":34894,"w ":10150,"to":743121,"tl":8532,"ts":9120,"tr":295588,"te":580573,"ti":577841,"th":33664,"ta":698330,"su":137066,"sv":16162,"ss":213977,"st":447357,"sl":9152,"sk":10657,"sm":16619,"sp":87152,"so":218207,"sc":157523,"sf":9364,"se":363584,"sh":16912,"si":401810,"rz":16932,"u ":59520,"sa":125213,"rr":72120,"rs":82412,"rt":207644,"ru":63955,"rv":21724,"ry":12041,"rp":15121,"ro":352219,"rn":64837,"rm":75961,"rl":22967,"rk":10623,"ri":614338,"rg":44544,"rf":10278,"re":622304,"rd":75640,"rc":66009,"rb":30426,"ra":583297,"t ":103375,"qu":99430,"s ":156468,"pu":55098,"pp":84071,"pr":255723,"ps":6191,"zz":76375,"zi":221598,"ze":20937,"za":99515,"zo":37143,"ya":7485,"È ":18782,"à ":92132,"ò ":26518,"ì ":8878,"é ":9885,"è ":314074,"ù ":29830," Ga":14003," Ge":15739," I ":16475," Fo":12451," Fu":8160," Fr":19775," Fi":15103," Ha":16981," He":8121," Go":9484," Gr":17959," Gu":8468," Gi":22095," Gl":5798," Ho":8931," L ":24925," Ja":8214," Is":8984," It":12700," In":30290," Il":65842," Ka":7887," Jo":9477," La":88189," Le":25663," Li":19618," Ma":58913," Mi":23636," Me":19838," Lo":25207," Lu":9633," Ne":23724," Na":17829," Ni":7466," Mo":30189," Mu":9681," A ":5979," Am":9971," An":18493," Al":34065," Ba":27690," Au":9040," As":8840," Ar":21718," Be":19500," Bi":8121," Bo":19624," Br":18373," Bu":8165," Ca":56136," Ce":10868," Ci":11600," Ch":29611," Cl":7713," Cr":10596," Co":62928," Da":15272," Di":21504," De":15426," Do":13718," Du":5966," El":6042," Es":8654," En":5749," Eu":7835," Fe":11726," Fa":10272," Wi":7870," Wa":7761," a ":110030," Or":10710," Po":20608," Pi":22451," Pe":16220," Pa":38161," No":19629," Ra":11758," Qu":10458," Ro":32569," Re":30042," Ri":14247," Pr":25353," Su":12949," St":32098," Ta":10678," UA":13306," Th":16944," Ti":6253," Te":15675," Tr":15562," To":14480," Ru":7431," Sa":46303," Sh":7238," Si":21606," Sc":24393," Se":20659," So":16887," Sp":9003," Va":13628," Ve":14047," Vi":19885," Vo":7231," Un":27982," l ":52713," im":22658," in":295683," il":151179," is":14605," it":18185," ha":23853," gi":32407," gl":14007," gr":40025," go":5702," gu":9712," id":6931," ne":275511," na":25351," mu":20050," mo":56127," ol":7856," om":7514," og":8277," oc":9930," of":10734," nu":14604," no":68303," le":52423," li":35936," la":143866," km":9911," me":51316," mi":29028," o ":42065," ma":81024," lu":16900," lo":28809," af":7222," ag":11338," ab":64448," ac":16193," ad":25196," am":20786," an":81988," ap":29511," ai":8950," al":183776," av":17618," au":20712," ar":36060," at":28661," as":31346," d ":20488," ba":32317," bi":8838," be":7889," bo":6391," br":13522," ca":114268," e ":219384," er":25454," et":12895," es":52932," en":13079," ep":5911," el":14730," fe":18710," fa":56978," fu":35844," fr":63957," fo":40785," fi":57936," ge":26299," ga":8284," i ":33110," cl":12326," co":356836," cr":19933," ce":24853," ch":106561," ci":55235," da":211997," cu":28570," do":30811," de":613533," di":670575," ec":32925," ed":39893," du":23486," ru":12186," sa":17824," se":114506," sc":42709," si":147221," sp":37866," so":80656," qu":64678," ra":31475," re":103663," ri":75848," ro":21093," pu":36089," pr":197319," os":7051," ot":10340," ov":5976," op":14803," or":49602," pe":114303," pa":91709," po":66694," pi":52800," va":18746," ve":35685," vo":17500," vi":51221," tu":14428," us":12554," ut":9880," un":408903," ul":5818," ta":13154," st":115114," sv":15397," su":116897," tr":76246," to":12684," th":12060," ti":18079," te":75278," È ":18766," è ":310990,"Eur":6532,"Gio":7152,"Fra":14090,"For":6200,"II ":9095,"Gra":9265,"Int":6283,"In ":9661,"Il ":64107,"Bas":6130,"Alt":6625,"Cal":8462,"Cam":7263,"Cas":9838,"Car":10034,"Can":7902,"Chi":9585,"Cen":5742,"Cha":12533,"Cor":7549,"Com":13539,"Col":6543,"Con":19924,"Dis":7107,"Nel":12164,"Nor":11147,"Per":7527,"Par":12134,"Pro":9921,"Pre":7483,"Que":6463,"Ita":11783,"Le ":10050,"La ":72068,"Man":6976,"Mar":24416,"Mon":12589,"Sta":17125,"UA ":13253,"Si ":7499,"Sai":6635,"Sco":15601,"San":19570,"Reg":7644,"Rom":11444,"Ven":6082,"Val":6880,"Uni":19062,"The":12364,"Tra":6212,"bit":77836,"bil":24167,"bli":33195,"bor":7965,"bbl":30259,"bbe":6273,"be ":7531,"bbr":5663,"ban":14724,"bal":6018,"bat":9698,"bas":13208,"bar":7268,"ber":18766,"bia":7881,"ca ":152253,"car":46789,"cas":12364,"cat":57544,"can":40911,"cap":15975,"caz":8224,"cam":17670,"cal":28832,"ce ":48205,"bri":12930,"bro":7660,"bra":15040,"bre":21272,"bum":18883,"am ":7918,"al ":120078,"ain":14219,"aio":8047,"agl":13391,"agg":47904,"agi":14545,"agn":23437,"ago":14318,"anz":27062,"ano":80778,"ann":47068,"ant":158501,"ans":9496,"ane":24020,"ang":15547,"ani":57213,"ana":44733,"anc":100934,"and":75292,"amm":16889,"amo":10418,"amp":23753,"ami":24192,"ame":55568,"amb":14366,"ama":14741,"alt":24272,"alo":9405,"alm":19827,"all":157126,"ali":107974,"alc":17413,"ald":5979,"ale":157930,"ala":17702,"alb":21166,"an ":45440,"abb":6484,"abi":71766,"abo":7042,"ae ":8196,"ad ":23773,"aff":9278,"afi":13627,"ai ":19697,"aga":10288,"age":5874,"aes":7300,"ado":12933,"adr":12192,"adi":16689,"ade":11907,"acq":6540,"aco":8070,"aci":10043,"ach":7116,"ace":12782,"acc":33357,"ada":10503,"acr":5776,"azi":114771,"azz":11554,"at ":6931,"arg":6155,"are":73118,"ard":28986,"arc":21226,"ara":44876,"aro":14834,"arn":6502,"arm":9201,"arl":10615,"ari":92056,"arr":17226,"ars":9758,"art":120284,"asa":12008,"asi":18399,"asc":31970,"ase":8737,"ar ":13924,"api":8043,"apo":15567,"app":40715,"as ":11094,"ava":20339,"aut":20581,"avo":14059,"avi":12649,"ave":19075,"ay ":7096,"avv":6341,"ata":122912,"ast":41964,"ass":66552,"atr":11363,"ato":251278,"ate":43614,"ati":96839,"att":98894,"atu":21242,"aur":8293,"aus":7205,"ito":68066,"itu":73079,"itt":66676,"ism":9170,"iso":15645,"isp":27507,"iss":18851,"ist":119446,"ita":148002,"ite":23677,"iti":31286,"ivo":23510,"ius":6126,"ium":7439,"iun":5847,"iut":11741,"iva":34645,"ivi":28519,"ive":42061,"ipo":9185,"ipi":8806,"is ":24623,"ion":300543,"ior":37852,"ios":7307,"ipa":67260,"ipe":7498,"iov":6740,"iro":6686,"iri":10262,"isi":24222,"ise":9930,"isc":25942,"isa":8063,"ire":38092,"ira":11739,"irc":16765,"ità":54075,"izz":49660,"izi":46425,"km ":6935,"ha ":20767,"ham":6367,"han":10716,"har":10403,"he ":154969,"het":5812,"her":11167,"hi ":17347,"hie":13497,"hia":17408,"hin":6740,"hil":8553,"hit":6455,"go ":24875,"gle":14019,"gli":101433,"gno":22948,"gni":13103,"gne":7169,"gna":23696,"gol":13409,"gon":12443,"gru":16613,"gra":38555,"gre":12522,"gui":11363,"gua":15610,"gue":16931,"gur":5768,"iam":18301,"ial":41395,"ian":67167,"ias":18220,"iar":13087,"iat":27828,"ic ":7518,"iac":6819,"ibi":9969,"ibr":7455,"ibu":6636,"iaz":6940,"ibe":7052,"ia ":244503,"iet":16601,"iem":9287,"ien":42565,"ier":26963,"ies":15028,"iff":8035,"ife":10392,"ifi":25651,"ico":88289,"ici":66289,"ich":34469,"icc":12587,"ice":31036,"ie ":52789,"ica":189725,"ido":7371,"idi":19231,"ide":49954,"ida":12753,"il ":154014,"igl":35255,"igh":7328,"igi":24518,"igu":7702,"ign":12535,"imo":36242,"imm":6781,"imp":19629,"ime":69205,"imi":17819,"inc":72864,"ind":26998,"ina":84297,"ino":48220,"int":56511,"ins":16076,"inf":11205,"ine":59357,"ing":57070,"ini":52386,"ioc":18011,"inv":7003,"ila":12536,"in ":183514,"ilo":8196,"ill":25371,"ilm":20062,"ili":45534,"ile":34997,"ima":41217,"io ":144991,"ilu":7192,"ffe":9164,"ffi":11476,"fes":8200,"fer":25051,"fia":6078,"fas":16462,"fat":6791,"far":5672,"fam":16618,"fan":7946,"età":10656,"ezz":10468,"ezi":12836,"eta":25147,"ete":11093,"eti":19239,"esp":10424,"eso":7266,"est":82383,"ess":82490,"eto":8361,"etr":19381,"ett":136219,"eve":12042,"eva":15707,"evo":6501,"evi":15209,"eur":6939,"ey ":9468,"er ":129403,"eor":7000,"es ":37108,"epu":6598,"eri":107300,"erg":9054,"ere":60624,"erf":7449,"erc":19250,"era":90400,"et ":14734,"equ":6340,"esi":40808,"esc":25003,"ese":123684,"esa":17222,"erz":5997,"erv":15974,"err":35138,"ert":35208,"ers":54254,"ern":33474,"erm":28661,"erp":7756,"ero":53515,"en ":21820,"ela":13747,"ele":33688,"eli":13565,"ell":470580,"elo":7068,"eo ":15585,"emb":16989,"ema":19885,"eme":23252,"emo":10570,"emi":32972,"emp":19288,"ene":64829,"eng":5768,"ena":16730,"end":39915,"enc":6461,"eno":18323,"enn":25781,"eni":17944,"enu":8919,"ens":28995,"ent":321381,"enz":41200,"egl":30932,"ego":7039,"egn":18128,"egg":11766,"egi":67882,"egu":13973,"el ":344686,"giu":12377,"gis":8322,"gin":21943,"gio":125636,"gic":7947,"gia":27457,"ght":6164,"ghi":6769,"ghe":8042,"ggi":57223,"gge":11031,"gi ":14154,"gen":34367,"get":10150,"ger":10735,"ge ":13833,"gar":8686,"gat":8038,"gan":16471,"ga ":14336,"fra":61392,"fu ":20614,"for":37768,"fon":16839,"fic":48822,"fig":8947,"fil":22511,"fin":27532,"da ":136024,"de ":72497,"dal":94565,"dai":6473,"dat":26742,"dar":7604,"dan":11831,"cun":8420,"cul":6650,"cui":21314,"cur":6089,"cla":11488,"cli":30380,"co ":105436,"cog":6308,"con":172605,"col":60224,"com":159257,"cor":35975,"cos":24601,"cop":26258,"cqu":7001,"cre":13257,"cra":6453,"cri":26431,"cro":12281,"cci":18510,"cch":12126,"cco":24015,"cca":13415,"cce":29193,"ch ":7853,"cer":13344,"ces":73387,"cen":46057,"cel":12841,"ced":6856,"ci ":29747,"cha":6310,"cia":75274,"ck ":12816,"cie":22050,"cid":13163,"che":152251,"chi":60026,"cil":6171,"cir":15709,"cis":9575,"cit":48155,"ciu":9832,"cin":18966,"cio":18635,"cip":33626,"ed ":34167,"ebb":8622,"ebr":5973,"ean":5957,"eal":11897,"eat":17904,"ea ":31185,"efi":7167,"ei ":71643,"ega":13314,"edi":40474,"ede":36599,"ecl":13991,"eci":22204,"ece":13292,"ecc":23316,"eca":6015,"ee ":7306,"eco":39931,"dur":10435,"dut":6584,"duz":6137,"dor":7110,"dop":9690,"don":12153,"dov":9865,"dot":18765,"ds ":7341,"due":12229,"dri":5744,"dra":9112,"dre":9661,"dro":6212,"dic":30670,"dia":36200,"der":31418,"des":28656,"det":11258,"dec":5661,"def":6138,"deg":19555,"dei":52282,"del":486810,"den":37113,"deo":6268,"di ":549365,"do ":64324,"div":20925,"diz":13866,"din":21333,"dio":28106,"dip":45197,"dir":19963,"dis":42122,"dit":11525,"die":7033,"dif":12635,"rga":12245,"ri ":84427,"rgi":7768,"rge":8891,"rgo":7492,"ret":51197,"res":79309,"rev":9081,"rfi":5771,"rds":5842,"rea":31808,"rec":19082,"red":9839,"reg":68923,"rem":13549,"ren":40494,"rel":11321,"rda":7163,"rdo":8984,"rdi":19945,"rde":7719,"re ":253820,"rco":11417,"rci":11839,"rch":14217,"rca":18883,"raz":24666,"rd ":22088,"rap":12296,"rar":11138,"ras":20760,"rat":94270,"rav":8469,"rbi":17348,"rai":8283,"rag":15270,"ran":117955,"ram":19333,"ral":33868,"raf":16450,"rad":21432,"rac":15856,"rpr":6371,"rs ":8921,"ros":16960,"rot":12347,"rom":18807,"ron":34271,"rop":27028,"rov":41355,"rod":22675,"roc":16930,"roi":16969,"rol":9837,"rof":8044,"rog":13121,"rno":15812,"rna":22371,"rne":10164,"rni":10544,"ro ":93036,"rma":38511,"rme":10556,"rmi":17565,"rla":7860,"riz":22621,"rio":45747,"rit":48367,"ris":50562,"riv":16323,"rig":24728,"ril":9910,"rin":43294,"rim":44423,"ria":61665,"rib":8788,"ric":75415,"rid":11323,"rie":41936,"rif":9551,"rk ":5699,"rup":18084,"rus":6787,"rut":6215,"rva":7812,"rvi":6676,"rve":5812,"ry ":9246,"rsi":24369,"rso":28714,"rsa":7860,"rse":7118,"rta":21350,"rto":33655,"rte":47947,"rti":80543,"rt ":10303,"rro":11867,"rri":17046,"rre":16669,"rra":22088,"sal":9289,"san":12698,"sat":15313,"sar":8168,"sa ":55092,"rzo":7427,"si ":104255,"siv":14099,"sie":10542,"sid":14077,"sic":27928,"sia":21469,"sit":73146,"sis":21720,"sin":20546,"sio":35066,"sil":9310,"sim":20855,"sig":13260,"scr":20145,"se ":150356,"sca":15235,"sce":19663,"sci":47092,"sch":12701,"sco":34425,"ser":44878,"ses":5630,"set":14434,"seg":23827,"sed":9878,"sec":24038,"sen":42117,"sem":26599,"spo":16816,"spe":38890,"spi":8159,"spa":13861,"sot":9626,"sol":26000,"son":52029,"sop":6399,"sor":13321,"soc":11137,"su ":15907,"st ":20759,"smo":8359,"so ":74484,"sse":52141,"ssa":30610,"sso":53075,"ssi":64743,"ssu":6194,"ste":66836,"sta":130887,"sto":49939,"sti":78547,"stu":12684,"str":82216,"sua":16483,"sud":8747,"suc":8338,"sul":27351,"sup":11429,"suo":21188,"sur":6713,"svi":7639,"svo":5978,"tal":71028,"tag":17728,"taz":13579,"tav":10674,"tat":99866,"tas":10040,"tar":29860,"tan":110605,"tam":12199,"te ":231097,"ta ":297475,"pa ":11956,"pe ":6955,"par":126674,"pat":12618,"pas":6581,"pag":17667,"pal":29532,"pan":6881,"pi ":12873,"pec":11403,"pen":11283,"per":160544,"pet":24231,"pes":8448,"pli":9280,"ple":7659,"pia":16405,"pic":12371,"pie":7531,"pin":8248,"pio":15425,"pir":5858,"pit":11446,"por":30452,"pop":13161,"pot":6913,"pos":33968,"poi":5808,"pon":18443,"pol":43083,"poc":5679,"ppr":9310,"ppi":6671,"ppo":29526,"ppa":24732,"ppe":7033,"po ":47633,"più":26636,"pub":29314,"pra":8794,"pri":70446,"pre":86755,"pro":88068,"put":6255,"pun":7305,"qua":45208,"que":36643,"qui":15702,"ra ":147867,"ngo":19829,"ngl":15051,"ngu":15413,"ni ":109423,"nge":12593,"ngh":7552,"nga":7243,"neg":12898,"nei":14330,"nel":251833,"nen":19286,"nem":6968,"ner":29386,"net":10607,"nes":22568,"ng ":19777,"nea":10437,"nfi":6288,"nco":13364,"nci":58066,"ncl":16907,"nce":63829,"nch":32511,"nca":8638,"ne ":381891,"ndu":5794,"ndr":9579,"ndo":51716,"ndi":44494,"nde":40952,"nda":41143,"nal":55844,"nam":6348,"nan":9718,"nar":20198,"nag":9973,"nd ":21375,"nat":56733,"nas":7852,"naz":16138,"na ":222844,"iù ":27049,"nve":7397,"num":9332,"nut":9355,"nto":104437,"ntr":54646,"nti":140368,"nta":97179,"nte":203922,"nso":6392,"nse":23034,"nsi":31575,"nt ":19040,"nqu":6994,"ns ":8742,"nol":12956,"nom":37789,"non":21278,"not":13854,"nos":16869,"nor":18667,"nov":9880,"nne":24481,"nna":15245,"nno":16579,"nni":28556,"no ":229968,"nif":7757,"nie":7902,"nic":33089,"nia":32535,"niz":16719,"niv":11731,"nis":28026,"nit":37389,"nio":10735,"nim":18502,"ogr":18460,"ogi":20692,"ogo":10374,"ogn":10473,"oge":8216,"ogg":8490,"oi ":11644,"oir":5807,"oid":15471,"ol ":6484,"oce":16535,"och":7177,"oci":18254,"ock":8603,"oco":10221,"oca":18569,"occ":17275,"ode":8882,"odi":13909,"odo":23349,"of ":9685,"oda":9043,"odu":9647,"obi":7836,"nza":33286,"nze":8647,"nzi":18694,"nzo":13784,"oti":8184,"ote":14816,"ott":46439,"oto":17159,"ost":54505,"ota":15242,"osi":22379,"ose":9147,"oss":25102,"oso":10625,"ovi":33581,"ova":26672,"ove":33842,"oun":6402,"our":8721,"opo":34311,"opp":9241,"ope":36127,"os ":8709,"opr":18087,"or ":15387,"orm":33668,"orn":18923,"oro":17981,"orr":13295,"ord":34705,"ore":83573,"org":19011,"ori":84933,"osa":10641,"osc":18331,"ort":43269,"ors":13700,"orb":16181,"ora":29450,"ola":56821,"on ":116999,"oli":48219,"oll":21894,"ole":18360,"olt":34437,"olo":80006,"olu":13657,"ona":73743,"ond":62359,"onc":11700,"onf":10972,"one":239015,"ong":9187,"oni":83803,"onn":10167,"ono":78642,"ons":27379,"ont":70151,"oma":36812,"ome":71129,"omb":8981,"omi":23159,"omm":10870,"omp":38351,"omo":18571,"omu":77250,"la ":502615,"le ":302428,"lci":6000,"lcu":7598,"lab":6177,"lac":10059,"lan":31109,"lam":6780,"lar":23739,"lat":27051,"las":21662,"lav":9746,"laz":14283,"ld ":6147,"lbu":19083,"lpi":7148,"lon":12253,"lom":6131,"lor":18602,"loc":10691,"log":22625,"los":5990,"lme":20869,"lti":14409,"lto":12474,"ltr":18612,"lta":21939,"lte":12298,"li ":126320,"lev":10337,"les":31571,"let":25767,"ler":10315,"lem":6948,"len":14630,"leg":16217,"lo ":116614,"lla":366876,"lle":95889,"lli":26880,"llo":51317,"lm ":18058,"ll ":147686,"lit":48006,"lis":18952,"lio":27570,"lin":48858,"lim":8378,"liz":23775,"liv":6284,"lic":53902,"lia":69213,"lib":8948,"lig":7530,"lie":14089,"ma ":77830,"mag":30019,"mar":19705,"mas":10652,"mal":8482,"man":52234,"maz":7709,"mat":39139,"mba":7166,"mbi":12940,"mbr":16743,"me ":86094,"med":14225,"met":29612,"mes":11952,"mer":34722,"mem":5945,"men":156332,"lup":7071,"luo":8412,"lun":8513,"lus":8431,"mpi":23542,"mpe":12689,"mpr":10131,"mpo":28943,"mpl":10446,"mod":11161,"mon":36802,"mol":12121,"mor":12412,"mos":9186,"mot":7018,"mpa":14258,"mus":15113,"mun":79273,"mi ":19370,"min":44712,"mil":12857,"mis":11697,"mit":12512,"mic":16950,"mia":19829,"mig":18385,"mo ":49530,"mmi":13753,"mma":13393,"mme":10561,"zzo":8684,"zza":55596,"zi ":8253,"ze ":11813,"zaz":5784,"zat":34965,"zon":11265,"zo ":22095,"zia":26147,"zie":6922,"zio":172644,"za ":45565,"tà ":85470,"vve":6371,"via":17063,"vil":14796,"vin":31306,"vic":6909,"vid":11446,"vie":12590,"viz":5900,"vit":13527,"vis":26147,"vo ":24368,"vol":30564,"vor":8888,"vi ":11655,"ver":60261,"ves":9627,"ven":39876,"vel":9674,"ve ":30393,"val":16987,"van":19808,"vam":6468,"var":11852,"vat":11790,"va ":54959,"uzi":17041,"usi":20123,"use":8740,"usc":8066,"usa":11990,"ust":15108,"uss":11959,"uti":17848,"ute":8898,"uta":15229,"utt":27857,"uto":37177,"us ":15875,"ura":49253,"ure":16806,"urg":6288,"uri":11168,"uro":17633,"uog":8121,"uol":7555,"uov":6581,"ur ":9581,"upe":12180,"upp":25887,"umb":6348,"ume":24760,"uo ":15893,"unt":14471,"uni":39506,"uno":18306,"una":118143,"ung":13147,"une":69547,"um ":26907,"ult":16466,"ull":18007,"ula":8409,"un ":268027,"uin":7055,"uis":8264,"uit":22856,"ul ":12226,"ui ":25799,"udi":18251,"ue ":29020,"ucc":13459,"uer":10140,"ues":18932,"uff":8520,"uen":11155,"uel":14803,"ua ":25910,"uat":61583,"uar":12747,"ual":28454,"uan":11940,"ubi":6952,"ubb":30175,"ud ":7866,"uad":8171,"ty ":9152,"tur":35100,"tut":19514,"tui":7703,"tun":9180,"tua":67153,"tud":14358,"ttà":16625,"tre":43645,"tra":110475,"tri":61377,"tru":14883,"tro":62451,"tta":55228,"tte":61167,"tti":63839,"tto":137927,"ttr":17103,"ttu":21997,"to ":551865,"tog":6135,"tos":6930,"tom":8273,"ton":24892,"tol":23856,"tor":90775,"til":16701,"tif":7476,"tie":11090,"tig":6347,"tir":6554,"tit":35734,"tis":12185,"tin":33317,"tim":54555,"tip":9392,"tio":18064,"tia":7439,"tic":92757,"tiz":5615,"tiv":40919,"tem":30137,"ten":60350,"tel":26672,"tea":13828,"tec":11962,"ted":10497,"th ":7445,"tes":26748,"ter":139440,"ti ":212534,"the":11405},"n_words":[55820958,65476626,49460182],"name":"it"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/jpn b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/jpn new file mode 100644 index 000000000..5a76401a1 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/jpn @@ -0,0 +1 @@ +{"freq":{"é":1545,"и":1279,"а":1241," 『":8564," 』":1624," 。":2126," 、":3623,"あ":3435630,"。":214195,"、":312995," ":2941,"々":3019,"』":21225,"『":21300,"」":29519,"「":29647,"〜":2758,"ア":2611969," あ":52272," ア":58543,"乱":13623,"九":1493,"乗":1644,"久":1407,"主":13646,"丼":69358,"中":24049,"両":2394,"並":1334,"丞":80623,"丕":5670,"世":14223,"丈":118136,"三":6461,"上":13976,"下":7225,"不":54571,"与":2254,"一":26873,"丁":71935,"万":1628,"任":2340,"以":6436,"令":1766,"代":19956,"他":3009,"付":3689,"人":34784,"交":21043,"京":8000,"五":1508,"井":2181,"争":3320,"予":2003,"事":34820,"二":5188,"使":59250,"住":2454,"位":7990,"作":23623,"何":10362,"体":13204,"佐":59544,"伊":1406,"企":2899,"会":27025,"伝":3991,"休":80474,"信":13921,"係":2046,"保":5439,"価":32733,"供":2235," 分":1406,"営":4802,"問":2693,"商":2606,"員":5415,"品":9370,"和":9812,"周":2042,"呼":9439,"命":2467,"味":3638,"含":3079,"名":22983,"同":12059,"吉":1498,"合":22154,"各":2831,"向":3485," 号":4482,"域":5560,"城":2545,"基":5538,"土":3313,"園":3175,"地":19745,"在":13117,"回":5170,"四":2207,"団":7524,"因":1258,"国":40277,"器":3147,"写":1418,"再":1714,"内":9686," 丞":3334," 世":5944," 丈":5457," 丁":2886,"処":1526,"優":2947,"共":7413,"具":1237,"入":4949,"全":10040,"八":1560,"公":10338,"児":1791,"党":2623,"元":7877,"光":3006,"先":1806,"催":4293,"倫":19778,"個":1623,"原":7882,"受":3764,"取":4325,"反":2686,"及":4976,"参":3018,"司":1601,"号":9329,"台":3682,"可":2330,"口":3431,"化":11592," 佐":1439,"区":8504,"医":2840,"南":6511,"協":4447,"博":1814,"単":3157,"千":2088,"十":1946,"半":2617,"劇":2223,"力":7128," 人":2934,"加":4595," 代":2394,"務":6021,"動":13267," 休":1652,"分":13117," 丼":3391,"初":7471,"別":4976,"利":4213,"制":7969,"則":1331,"前":8950,"創":2681,"崎":2237," 大":1534,"工":4508,"州":9754,"川":7871,"山":10018,"属":5936,"展":2319,"屋":2375,"局":4799,"少":2464,"小":30514,"導":2344,"将":1891,"専":2793,"島":7916,"岩":1342,"当":6576,"形":7101,"役":2410,"影":1589,"式":10389,"引":1979,"張":1336,"強":2073,"応":3170,"念":2270,"律":2571,"後":10708,"得":2357,"年":104829,"平":6377,"帝":2972,"布":1306,"常":2950,"師":2527,"建":3787,"店":2005,"庁":1327,"広":4783,"度":5771,"座":1332,"大":35199,"央":2180,"天":5593,"太":2851,"変":3794,"外":5603,"多":7893,"女":5796,"始":3033,"委":1623,"場":13501,"報":4192,"境":2223,"売":8204,"声":8316,"子":14064,"存":4270,"学":37448,"安":3733,"定":14058,"実":7367,"宗":1706,"宮":21279,"客":1436,"家":48873,"富":1327,"察":1679,"対":8681," 回":2984,"曲":6533,"書":6577,"曜":3792,"昭":3661,"映":4870,"星":2861,"時":14954,"果":2006,"査":2002,"木":3174,"本":36912,"朝":4495,"期":7726,"月":55829,"有":6525,"最":8063,"松":2561,"東":13912,"来":4168,"条":3471,"村":4202,"料":2840,"文":11450,"於":1575,"施":4063,"旅":1301,"族":3755,"旧":3190,"日":77379,"放":12785,"改":2906,"支":3198,"教":10820,"数":8554,"整":1308,"技":5374,"投":1259,"所":11171,"手":10767," 年":95958,"戦":13450,"戸":3149,"成":12592,"提":2781,"推":1511,"接":2250,"挙":1713,"持":4610,"指":8229,"情":3302,"急":1371,"感":1443,"愛":3173,"港":2061,"済":2489,"清":1263,"湾":1437,"源":1888,"演":3153,"気":4829,"民":7826,"水":5727,"江":2655,"決":2408,"河":1989,"治":7454,"波":1773,"派":2998,"活":6032,"流":4367,"浜":1603,"消":1291,"深":1258,"機":12320," 時":1629,"権":6128,"横":1498,"標":2070," 月":53298,"武":2753,"止":2016,"正":6725,"死":5205,"歌":3328,"次":4580,"欧":1451,"母":1932,"毎":2982,"比":1391,"殺":5325,"校":9373,"株":3423,"業":15026,"楽":6757,"植":1547,"検":1870,"構":5270," 日":47110,"様":2976,"石":2879,"知":6637,"県":18156,"省":2816,"着":1339,"皇":3000,"的":19048,"目":10668,"直":2224,"白":1686,"発":20771,"登":4069,"病":1859,"症":1381,"町":8545,"画":10139,"田":7594,"由":2916,"用":19757,"産":5875,"生":16324,"番":8301,"略":5228,"界":7422,"環":2235,"理":11169,"球":4459,"現":13270,"王":7473,"独":3082,"状":2926,"物":13688,"特":7417,"照":1250,"然":1440,"無":2728,"点":4161,"火":1398,"置":8277,"美":2548,"群":2041,"義":5850,"習":1334,"素":3072,"約":3788,"紀":4911,"級":2880,"統":4477,"経":5810,"組":11006,"結":4672,"続":3548,"編":3445,"総":5306,"線":8126,"米":2827,"系":6844,"等":8344,"策":1400,"第":13434,"算":1686,"積":1366,"究":4684,"空":6782,"程":1685,"種":6006,"立":12201,"競":4491," 番":1554,"神":6975,"社":17675,"示":2628,"移":1880,"称":14999,"科":5836,"福":3372,"要":4830,"規":3792,"視":1426,"親":1689,"観":2376,"解":3594,"西":7073,"補":1253,"裁":1509,"製":5884,"衛":3099,"術":5314,"行":22080,"衆":5487,"表":10987,"警":1923,"議":4992,"護":2333,"調":2776,"読":1601,"説":4782,"語":21957,"認":2658,"論":4375,"設":10824,"記":10247,"計":5326,"言":6896,"話":3787,"評":1446,"路":5085,"超":1256,"足":1256,"起":2835,"賞":3546,"資":3066,"質":3136,"象":3259,"谷":1834,"近":4077,"農":1628,"載":2905,"転":2711,"車":9144,"身":6802,"自":10797,"者":18526,"聞":12087,"聖":2242,"聯":10502,"育":4279,"能":5243,"華":1394,"般":3860,"航":2825,"興":1400,"艦":4184,"色":1827,"英":9312,"信ああ":2064,"葉":3002,"著":2162,"風":1713,"食":1713,"領":3103,"項":2228,"類":3952,"馬":3385,"駅":2902,"館":2783,"高":11470,"連":10914,"造":5408,"進":3210,"送":12678,"通":11192,"速":1858,"遺":1795,"選":8114,"過":1669,"運":6072,"達":1651,"郡":4845,"部":17131,"都":8516,"郎":2090,"配":2845,"金":5425,"野":8402,"量":2343,"重":4451,"鉄":5783,"銀":1566,"録":3006,"関":12598,"間":11298,"開":13989,"門":4039,"降":1592,"限":2003,"院":3827,"陸":3351,"阪":2944,"防":2270,"離":1558,"電":7996,"隊":3468,"際":6340,"青":1618,"非":1816,"面":3571,"響":1740,"音":7019,"始ああ":1913,"殺ああ":2295,")":148109,"(":149030,":":12250,"=":3484,"~":3083,"交味あ":2597,"使ああ":9134,"使アア":1628," (":4296," )":9852,"価ああ":5083,"行ああ":10289,"組ああ":2099,"表ああ":2782,"一種あ":1572,"類ああ":1338,"手ああ":1245,"場合あ":2928,"世界大":1450,"大ああ":1950,"多あ。":1570,"多ああ":2150,"構成あ":1846,"倫ああ":2719,"成ああ":4644,"部ああ":1870,"戦ああ":1623,"続ああ":1414,"等学校":2276,"売ああ":5009,"声ああ":1329,"通ああ":1426,"送ああ":5822,"生ああ":4620,"ア語:":1902,"造ああ":1673,"ア連休":1985,"世紀あ":1284,"用アア":1501,"作品あ":2764,"ア選手":1921,"用ああ":9493,"佐売あ":1480,"。 ":13103,"、 ":31983,"』 ":1427,"不聯あ":1405,"あ ":66354,"地域あ":1988,"ア ":32799,"催ああ":3126,"あ連":2419,"あ通":3320,"あ選":1976,"あ運":3219,"あ都":1640,"あ金":1288,"あ重":1969,"ア語":8308,"あ電":1906,"あ際":1362,"あ音":2155,"あ関":6111,"あ開":8435,"あ間":2317,"あ認":1333,"あ記":3845,"あ設":5283,"ア系":1829,"あ製":2477,"あ表":4499,"あ行":10711,"あ規":1437,"あ言":4181,"あ解":1569,"あ西":1435,"あ近":1371,"あ起":2247," 『ア":2743,"ア連":2828,"あ高":3598,"ア郡":1249,"ア選":2094,"ア教":1868,"ア放":1489,"ア文":1270,"あ無":1446,"あ特":3612,"あ物":2014,"あ独":1271,"ア朝":1242,"、第":1727,"あ現":2680,"あ王":1453,"あ用":4828,"あ生":5118,"あ略":1610,"あ登":3137,"あ発":11033,"あ目":3554,"あ知":3796,"あ構":3048,"ア州":5899,"、特":1256,"あ機":2062,"あ毎":1746,"あ殺":2375,"あ死":2199,"あ正":1615,"。現":1855,"あ水":1343,"、現":2451,"あ活":3109,"あ流":1320,"ア番":2807,"あ自":4181,"あ聞":2418,"あ聯":1675,"あ者":1261,"))あ":1638,"あ著":1250,"ア社":1403,"あ移":1304,"あ称":1389,"あ神":1585,"あ社":1649," あ ":1635,"あ第":4428,"、英":3619,"あ立":1390,"、自":1350,"あ続":1310,"あ総":2605,"あ結":2983,"あ経":2414,"あ組":1899,"あ統":1376,"ア王":2616,"あ置":2229,"あ国":6666,"あ基":3151,"あ地":4866,"あ呼":9152,"、小":1990,"あ含":2942,"あ同":5129,"あ名":6504,"あ合":3012,"あ各":1270,"あ加":1535,"あ務":1340,"あ動":1382,"あ初":2158,"あ分":4627,"あ制":2425,"あ利":1785,"あ前":1691,"あ創":1816,"あ原":2367,"あ参":1928,"あ取":2481,"あ受":2846,"あ単":1416,"あ南":1637,"あ倫":4845,"あ内":1663,"あ入":1803,"あ全":3374,"あ公":3342,"あ共":2253,"あ元":1846,"、大":2783,"あ乱":3962,"あ上":3029,"あ下":1378,"あ不":14639,"あ丈":32792,"あ三":1486,"あ丞":19819,"あ世":2331,"あ中":9465,"あ丼":18051,"あ主":4771,"あ他":2009,"あ付":1399,"あ代":2198,"あ企":1331,"あ事":5294,"あ交":5865,"あ人":7782,"あ作":6813,"あ何":3230,"あ佐":13423,"あ位":2504,"あ使":13500,"あ伝":1495,"あ会":1351,"、国":2207,"あ休":17591,"あ信":2085,"あ保":1720,"あ価":8783,"、同":2022,"あ一":16360,"あ丁":17347,"あ東":3287,"あ本":3519,"あ有":3083,"あ書":1761,"あ最":4488,"あ時":2327,"あ映":1487,"あ日":8737,"あ文":2466,"あ教":1976,"あ数":1984,"あ支":1653,"あ放":6620,"あ改":1615,"ア大":3211,"あ提":2042,"あ指":5951,"ア国":2219,"あ持":3443,"ア地":1445,"あ所":2803,"あ戦":3270,"あ成":1753,"あ手":1859,"。本":2143,"あ形":2406,"あ当":1618,"、本":1964,"ア合":4791,"、東":2694,"あ後":3036,"。日":2366,"、日":7073,"あ建":2122,"あ広":2188,"ア共":1242,"ア公":1517,"あ属":1897,"あ小":6851,"ア使":2442,"あ学":2960,"あ存":2964,"あ子":1693,"あ家":4670,"あ宮":4858,"あ定":2671,"あ実":3992,"あ対":5932,"ア事":1661,"ア人":2775,"ア休":2911,"ア佐":2436,"ア作":1731,"あ外":1294,"あ多":5332,"あ変":2304,"あ大":8249,"あ天":1336,"あ女":1848,"ア丁":1757,"ア丞":2294,"ア不":5250,"ア丈":4131,"ア丼":2746,"あ始":1317,"あ場":4272,"あ声":3268,"あア":156757,"ああ":1909463,"あ。":138896,"あ『":3993,"あ』":1518,"あ「":15609,"あ」":3632,"第二次":1255,"あ、":216446,"、あ":21490,"。「":2184,"、『":1828,"、「":4201,"。ア":19354,"、ア":64525,"々あ":2319,"。あ":13106,"『あ":1353,"」あ":19753,"「あ":2018,"」、":1525,"」。":1249,"『ア":7054,"』あ":7906,"「ア":7862,"、使":1676,"、価":1248,"、休":3597,"、佐":2726,"。休":1576,"、人":2001,"、丞":3869,"。丁":1388,"、不":3337,"、丁":3572,"、丈":7156,"、一":1931,"。丼":1300,"。丞":1247,"、主":1393,"、丼":4218,"、中":2406,"。丈":2918,"アア":2154092,"アあ":155866,"ア」":6771,"ア『":1584,"ア』":6210,"ア。":10635,"ア、":16488,"ア)":16388,"ア(":33336,"ア=":3214,"場ああ":3434,"入ああ":1917,"現在あ":4587,"、)":1834,"』(":8152,"」(":2340,"あ)":37153,"あ(":5782,"会社あ":2364," ああ":28860," あ、":7361," あア":3298," アア":57211,"次世界":1361,"日)あ":7258,"不身あ":2968,"日( ":2303,"一部あ":1349,"作曲家":1274,"基ああ":1599,"録ああ":1363,"対ああ":2786,"あ行あ":9249,"分ああ":1730,"設ああ":2171,"使究あ":1369,"記ああ":2072,"ア番組":2746,"位置あ":2308,"株式会":2868,"小ああ":3121,"言ああ":1584,"家ああ":5177,"あ置あ":2118,"あ総称":1606,"所属あ":1341,"主あ":3885,"丼ア":1464,"丼あ":19189,"使用あ":2638,"乱あ":3541,"与あ":1930,"不あ":8122,"丈ア":3173,"下あ":2803,"上あ":5913,"丈あ":27006,"丈、":1500,"丁ア":1890,"丁あ":18102,"一あ":5817,"丞あ":21257,"丕あ":1261,"世あ":2310,"不ア":1421,"中あ":5030,"丞ア":1844,"人あ":9122,"人。":1476,"人ア":1242,"他あ":1896,"付あ":2208,"代あ":6798,"代ア":1373,"争あ":1758,"事あ":9346,"交あ":4806,"不家":3233,"中国":2514,"作あ":7059,"何あ":2412,"体あ":6471,"位あ":2264,"佐あ":15860,"丼休":1592,"丼丞":2055,"丼丈":2151,"丼丁":1684,"丼丼":1418,"中使":3153,"会あ":6508,"丞佐":1535,"不使":1765,"休。":1523,"休あ":23904,"丞丈":2889,"丞丁":2038,"休ア":2507,"丞丞":1742,"不交":1422,"丈休":2694,"丈使":1243,"丈丈":5575,"丈丞":2374,"丈丼":3223,"丁休":1545,"一価":1575,"不不":1538,"丁丞":1826,"丁丈":3406,"丁丼":1794,"丈丁":3527,"信あ":4017,"交味":2982,"全 ":1304,"以下":1516,"、英語":1539,"係あ":1321,"供あ":1476,"価あ":9568,"使あ":19446,"中央":2121,"使ア":1968,"事交":2728,"丞家":1297,"一種":2197,"事業":2439,"二次":1389,"世界":5865,"佐丁":2480,"佐価":1425,"佐佐":1269,"倫あ":5771,"休丈":2771,"不治":2327,"休佐":1324,"休休":1921,"主義":2043,"人物":1891,"企業":2138,"一般":3547,"不聯":2198,"催あ":3689,"前 ":1371,"宮ああ":1909,"作家":1397,"作品":5289,"世紀":2728,"価使":2601,"佐売":2092,"あ目的":2533,"あ発表":1274,"あ第 ":2940,"内ああ":1292,"丞 ":1754,"丈 ":1322,"丁 ":1266,"丼 ":1638,"在あ":8533,"地あ":4409,"国あ":10614,"国ア":2658,"団あ":1724,"あ音楽":1319,"合衆":4737,"問宮":1556,"可能":1378,"名称":3513,"器あ":1492,"使(":1266,"動車":2200,"営あ":2139,"休(":1962,"和国":2518,"会(":2933,"分類":1336,"分野":1390,"多あ":4892,"大あ":3257,"あ開発":3310,"外あ":1908,"声あ":2287,"売あ":5710,"地区":1390,"地域":3263,"学ああ":2317,"国家":3119,"地不":3338,"在位":1282,"場あ":5556,"域あ":3413,"団体":2330,"あ開催":2692,"基あ":1982,"ア語あ":2144,"あ間あ":1859,"あ関あ":3802,"全国":1795,"加あ":2048,"力あ":3213,"共和":2791," 人あ":1389,"共同":1280,"化あ":4450,"和 ":3168,"動あ":4507,"務あ":2872,"前あ":3176,"制あ":1242,"定ああ":5359,"別あ":1751,"初あ":3667,"交通":1522,"代表":2575,"使用":3017,"使理":2476,"京都":3402,"佐県":1437," 世あ":1718,"会議":1333,"分あ":3773,"位置":2501,"ア語 ":2251,"使究":4609,"元あ":1489,"一部":2055,"不身":4258,"作曲":2528,"会社":6167,"内あ":4013,"語ああ":3397,"休画":2321,"入あ":2695,"全あ":1427,"品。":1238,"品あ":4556,"丈(":2884,"丁(":1789,"参加":1290,"員あ":2076,"丞(":2210,"丼(":1739,"含あ":3008,"協会":2160,"味あ":2957,"呼あ":8214,"化学":1687,"利用":1828," 世紀":2518,"制度":1248,"及あ":4790,"受あ":2030,"取あ":2208,"号あ":3953,"名あ":9335,"同あ":1953,"合あ":7017,"向あ":2543,"制作":1942,"区あ":2907,"家路":2125,"度あ":3326,"年ア":1913,"年あ":20990,"年、":1688,"広あ":1712,"帝国":1623,"形あ":1829,"年代":2422,"島県":1368,"専門":1642,"当あ":2190,"あ運営":1448,"小説":1987,"対象":1561,"式あ":3352,"川あ":1268,"州あ":2489,"州ア":2755,"常あ":1310,"小治":1760,"学者":3831," 年 ":49544,"成 ":1708,"当時":1631,"応あ":1648,"念あ":1283,"得あ":1713,"後あ":4649,"式会":2869,"平成":1905,"大学":6830,"あ設置":1507,"大戦":1559,"委員":1355,"女小":1372,"女子":1397,"子ア":1884,"子あ":3923,"あ起あ":1522,"場合":3557,"始あ":2180,"あ製造":1274,"子ああ":1318,"国際":4256,"子アア":1695,"あ設立":2139,"家 ":3003,"大会":3699,"物ああ":1862,"大阪":2112,"存在":3074,"家人":2908,"あ記休":1293,"年 ":51327,"島あ":1817,"あ表記":1710,"学校":6834,"家律":2208,"実施":1278,"天皇":1405,"学あ":6550,"定あ":7748,"宮あ":4230,"家ア":2140,"家、":2464,"家。":3423,"家あ":12300,"業ああ":1572,"あ言あ":2286,"小あ":7489,"対あ":3405,"属あ":3978,"局あ":2353,"東不":1238,"東京":5181,"本名":1618,"放送":10914,"映画":3085,"曲家":1330,"施設":1651,"曜日":2035,"教育":2974,"校あ":3206," 日 ":12276,"最初":1340,"楽あ":1408,"時間":1682,"業あ":4045," 月 ":44960," 日あ":15057,"株式":3061," 年(":5941," 年)":9287,"時あ":3451,"教会":1452,"教休":1250,"文使":1758,"文化":2253,"族あ":1560,"日あ":17278,"化ああ":2739,"昭和":3444,"時代":5531,"来あ":2732,"立ああ":3753,"あ放送":5748,"あ東京":1323,"果あ":1257,"日本":21674,"曲あ":2900,"あ日本":7358,"文学":1588,"月あ":5637,"有あ":1810,"最あ":1431,"書あ":2853,"選手権":2431,"本ア":2290,"本あ":10875,"期あ":4322,"日 ":12954,"手権":2431,"、東京":1480,"所属":2119,"月 ":45103,"数あ":3827,"あ戦あ":1312,"教あ":1272,"技術":2097,"務ああ":1643,"年(":6245,"年)":9425,"提供":1355,"指あ。":1899," 年あ":19179," 年、":1517," 年ア":1448,"家(":2915,"成あ":6012,"情報":2756,"戦あ":3394,"あ持あ":3321,"手あ":2666,"あ指あ":3829,"所あ":3296,"持ああ":1475,"ア合衆":4629,"戦争":2199," 年代":2242,"指あ":4364,"持あ":3953,"あ属あ":1826," 日)":9957," 日(":2924,"あ存在":2820,"点あ":3120,"ア不身":1594,"あ家律":1357,"江戸":1490,"あ広あ":1286,"活丞":1276,"活動":3023,"校(":1251,"動ああ":2193,"、日本":6502,"。日本":2210,"あ国家":1342,"あ地域":1419,"次世":1446,"構造":1383,"毎佐":1485,"日)":10122,"日(":3117,"加ああ":1583,"あ場合":3488,"派あ":1250,"流あ":1921,"正式":1441,"あ多あ":3964,"あ大あ":1447,"機能":1261,"機関":2979,"権あ":1708,"あ国際":1794,"機あ":2329,"共和国":2495," 月あ":5223,"あ対あ":3165,"殺あ":2872,"構成":2233,"止あ":1308,"称あ":9039,"称。":1304,"種あ":3083,"社会":2785,"発表":1469,"種ああ":1425,"第 ":9134,"目的":2889,"社あ":6402,"示あ":1874,"社ア":1383,"あ用あ":3710,"あ生あ":1801,"県家":2001,"発生":1334,"知あ":3526,"番組":5337,"発売":5037,"登場":2565,"略称":3022,"用語":1380,"目あ":4296,"あ知あ":3198,"あ登場":2375,"県あ":2733,"あ発売":3969,"界大":1455,"発あ":3815,"的あ":13077,"環境":1290,"理学":1713,"町あ":2460,"画あ":2581,"現在":6030,"用あ":12045,"用ア":1581,"自動車":2063,"界あ":1868,"独立":1445,"生あ":6030,"産あ":1671,"現ア":1355,"現あ":1628,"理あ":2327,"運営あ":1562,"特別":1260,"大学あ":1847,"衆国あ":2595,"ア放送":1421,"特あ":1759,"物あ":5383,"あ活丞":1241,"般あ":1349,"あ活動":1498,"艦あ":1387,"能あ":2381,"、現在":1773,"英 ":1379,"。現在":1490,"義あ":2621,"大会あ":2008,"総称":1629,"者。":2220,"者、":1458,"者あ":10349,"者ア":1305,"聯あ":3977,"聞あ":3281,"総合":1331,"置あ":6978,"経済":1991,"線あ":3253,"続あ":2112,"組佐":2309,"競馬":1452,"系使":1769,"等学":2286,"競技":1586,"組あ":3887,"組。":1569,"ア州あ":1713,"結あ":1657,"ア州ア":2558,"紀あ":1438,"系あ":2247,"素あ":1485,"あ殺あ":1580,"約 ":1619,"第二":1891,"立あ":5248,"究あ":1391,"空あ":1393,"等あ":3921,"あ構成":1941,"科学":1994,"象あ":2019,"設立":2500,"設置":1708,"賞あ":1603,"製造":1966,"計画":1610,"あ。 ":6469,"あ、 ":22576,"ああ ":39188,"論あ":1674,"記休":1374,"表記":2830,"身あ":4282,"車あ":2896,"路あ":1577,"象ああ":1255,"開ああ":1704,"起あ":1745,"設計":1269,"言語":1842,"質あ":1680,"郡あ":1437,"部あ":6774,"関ああ":4613,"。アア":19255,"日本ア":2092,"日本あ":9641,"、アア":64286,"路線":1359,"設立あ":2048,"送あ":7525,"通あ":2755,"造あ":2715,"連あ":1360,"進あ":1274,"『アア":7047,"近あ":1367,"』ああ":2158,"「アア":7790,"」ああ":7507,"間ああ":1397,"『ああ":1282,"載あ":2293,"称ああ":4464,"「ああ":1846,"通称":1887,"選手":4697,"、ああ":21181,"都事":2774,"。ああ":12750,"野あ":1575,"運営":1939,"運動":1644,"語:":3289,"連合":1965,"通信":1344,"連休":3247,"自治":1375,"(昭和":2128,"線(":1472,"航空":2161,"営ああ":1448,"自動":2405,"あ、)":1236,"ああ)":35187,"ああ(":4198,"英語":4067,"ああ自":1831,"ああ行":2651,"ああ表":1577,"ああ記":1483,"ああ言":2300,"ああ設":1654,"ああ開":2170,"あ、同":1707,"ああ丞":6562,"ああ一":3244,"ああ丁":5744,"ああ不":4855,"ああ丈":10564,"ああ丼":5871,"ああ主":1236,"ああ中":2062,"ああ価":2294,"ああ使":4600,"ああ作":2558,"ああ佐":5045,"ああ倫":1458,"ああ交":2092,"ああ人":3676,"ああ事":3171,"ああ休":6525,"あ、国":1738,"ああ他":1319,"あ、丁":2287,"あ、一":1711,"あ、不":2123,"あ、丈":4708,"あ、丞":2433,"あ、佐":1739,"あ、休":2616,"あ、人":1506,"あ、主":1290,"あ、丼":2884,"あ、中":1791,"あ。丈":1605,"ああ大":3222,"ああ多":2733,"ああ学":1481,"ああ家":2341,"ああ宮":1422,"ああ小":2540,"あ。日":1290,"あ、日":6150,"あ、東":1989,"ああ後":1790,"術あ":1484,"ああ分":1352,"ああ全":1444,"ああ公":1285,"あ、大":2131,"行あ":14000,"ああ名":2507,"ああ同":2111,"あ、小":1427,"ああ呼":3646,"ああ地":2280,"ああ国":2987,"ああ場":2933,"表あ":3761,"あ、現":2057,"ああ指":1536,"ああ戦":1238,"ああ最":1780,"ああ日":4356,"ああ放":1785,"あ、英":2463,"ああ第":1398,"ああ特":1792,"ああ現":1367,"あ、第":1316,"ああ目":1662,"ああ発":3602,"ああ知":2352,"ああ用":1755,"ああ生":1691,"設あ":3061,"記あ":3151,"言あ":3035,"製作":1647,"説あ":2100,"語あ":8268,"話あ":1899,"ああ。":128417,"ああ、":114147,"ああ『":1790,"ああ「":7669,"ああ」":2702,"行不":1963,"語 ":3303,"あ『ア":1268,"あ「ア":4056,"あ」あ":2473,"あ、ア":42684,"あ。ア":9708,"あ。あ":10112,"あ、あ":15664,"あ、「":2860,"あアア":151645,"あアあ":3890,"衆国":4735,"要あ":2289,"ああア":66491,"あああ":1201680,"時代あ":3504,"発表あ":1306,"高等":2629,"昭和 ":2986,"社アア":1256,"社ああ":2086,"丞(あ":1427,"本あア":1472,"本ああ":2442,"州アア":2688,"品ああ":1797,"本アア":2199,"分野あ":1258,"録あ":1741,"書ああ":1478,"鉄家":3515,"野球":2343,"設置あ":1442,"月ああ":2434,"間あ":6535,"開あ":1967,"関あ":5450,"有ああ":1305,"隊あ":1519,"関係":1758,"際あ":1785,"開催":3071,"面あ":1724,"項あ":1394,"開発":5246,"類あ":2486,"目的あ":2661,"電気":1300,"駅あ":1276,"音楽":3430,"曲ああ":1651,"高あ":1592,"属ああ":2285,"あ事あ":1426,"あ丼あ":5850,"あ丁あ":4319,"あ一あ":4453,"あ丈あ":8854,"あ上あ":1542,"あ不あ":2773,"あ中あ":2093,"あ丞あ":5276,"あ使あ":4014,"あ価あ":2254,"あ佐あ":3168,"あ作あ":1416,"利用あ":1328,"あ丈丁":1285,"あ丈丈":1864,"あ休あ":5479,"あ中使":2747,"あ他あ":1258,"あ丁丈":1300,"点ああ":1562,"あ利用":1457,"あ含あ":2902,"あ名あ":1668,"あ呼あ":8161,"記休あ":1285,"あ名称":2151,"高等学":2175,"丈(あ":1828,"存在あ":2940,"あ基あ":1594,"東京都":2018,"あ交味":2831,"呼ああ":6929,"あ不治":1330,"あ世界":2001,"あ一種":2121,"あ作品":1789,"あ価使":1553,"あ一般":1707,"あ人物":1374,"味ああ":1844,"あ一部":1521,"あ作曲":1773,"あ休画":1355,"あ代表":1400,"あ使用":2721,"あ位置":2381,"あ使究":1788,"あ務あ":1339,"表記あ":2011,"あ取あ":1899,"あ受あ":1927,"アあ作":1244,"アあ丼":1341,"アあ丁":1432,"アあ一":1999,"アあ不":1243,"アあ丈":2548,"アあ丞":1512,"アア、":16393,"アア。":10631,"アア」":6705,"アア』":6191,"アア『":1500,"アアア":1729078,"アアあ":151645,"アあア":19640,"アああ":55529,"アあ、":4837,"ア』あ":2640,"ア。ア":1791,"ア」あ":4452,"ア、ア":8332,"アあ開":1642,"アア語":8298,"アア系":1825,"アア社":1262,"アア番":2788,"受ああ":1416,"アア王":2579,"アア教":1744,"アア放":1421,"アア州":5894,"アア大":2784,"アア国":1719,"放送あ":6907,"アア合":4757,"アア公":1422,"アア休":2327,"アア事":1564,"アア人":2578,"アア作":1525,"アア佐":1706,"アア使":2109,"アア丼":1996,"アア丞":1556,"アア丈":2749,"アア不":4656,"アア ":31584,"ア。 ":1580,"アあ ":4215,"名ああ":2758,"最初あ":1276,"学校あ":2147,"番組。":1557,"番組あ":2493,"向ああ":1587,"知ああ":3322,"校ああ":1456,"含ああ":1792,"アア連":2243,"アア選":2079,"号ああ":1619,"ア』(":1980,"アア=":3088,"アア)":16080,"アア(":33305,"合ああ":3958,"=アア":3113,"年代あ":1428,"開発あ":3113,"登場あ":2088,"略称あ":1402,"発売あ":3963,")あ ":2592,"義ああ":1444,"機関あ":1580,"あ)あ":31163,"あ(あ":1574,"あ)、":1476,"あ)。":2164,")あア":7291,")ああ":30137,")あ、":47800,"(ああ":48329,")、ア":1251,"(アア":20979,"ア=ア":3175,"ア(ア":4269,"ア)あ":13245,"ア(あ":3617,"団体あ":1276,"ア( ":1748,"置ああ":4412,"合衆国":4735,"丁アア":1421,"上ああ":2005,"丈ああ":11397,"丈あア":1286,"丁ああ":8466,"一ああ":3370,"一あ。":1355,"平成 ":1642,"年) ":3918,"年( ":2247,"年)あ":3507,"式会社":2868,"国あア":1384,"国ああ":2054,"国アア":2374,"年(昭":1867,"載ああ":2044,"地ああ":1883,"者ああ":4317,"丼ああ":8612,"在ああ":4158,"中ああ":1478,"丞アア":1255,"目ああ":1258,"丞ああ":10116,"不ああ":3457,"車ああ":1306,"丈アア":2349,"与ああ":1754,"界大戦":1365,"名称あ":2696,"事ああ":3528,"起ああ":1658,"開催あ":2711,"年あア":3603,"年ああ":7456,"年アア":1814,"乱ああ":1859,"人ああ":3885,"活動あ":2178,"的ああ":3866,"発ああ":2687,"交ああ":1899,"組佐あ":1397,"会(あ":1757,"))":1846,"()":1332,"丈丁あ":1330,"丈丈あ":1676,"休アア":1927," )あ":8664,"会ああ":2436,"休ああ":11780,"(昭":2135,"代ああ":2253,"代アア":1273,"(現":2804,"(英":2015,"付ああ":1616,"=ア":3230,")ア":1792,"(ア":21128,")あ":114771,")」":1247,"(あ":48841,")。":7779,")、":5848,"対象あ":1241,"( ":12526,") ":6625,": ":1725,"~ ":2043,"作ああ":4059,"何ああ":1301,"佐ああ":8185,"体ああ":2330,"当ああ":1803,"日ああ":8218,"日あア":2005,"、)あ":1731,"』(あ":3555,"』(ア":2402,"中使あ":2391},"n_words":[10754229,8353071,5774482],"name":"ja"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/kan b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/kan new file mode 100644 index 000000000..7a599ba75 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/kan @@ -0,0 +1 @@ +{"freq":{"ುರಾ":118,"ುರು":200,"ುರಿ":88,"ುರ್":91,"D":56,"E":62,"A":159,"B":71,"C":144,"M":84,"N":67,"O":52,"I":126,"ುವಂ":99,"T":67,"P":98,"S":150,"R":60,"ುಳ್":57,"f":152,"g":241,"d":295,"e":941,"b":240,"c":337,"a":826,"n":692,"o":625,"l":414,"m":349,"k":67,"h":439,"i":767,"w":97,"v":70,"u":387,"t":822,"ುಲೈ":89,"s":460,"r":646,"p":275,"y":151,"x":98,"ುಮಾ":253,"ುಹಿ":52,"ುಸ್":88,"ುವೆ":67,"ುವು":360,"ುವಿ":157,"ುವಾ":127,"ುವರ":100,"ೂಕಿ":129,"ೂಕು":69,"ುಷ್":56,"ುಟು":84,"ುಟ್":157,"ುಡಿ":58,"ುನಾ":71,"ುನಿ":57,"ುತಿ":69,"ುತ್":1508,"ುದು":441,"ುದಾ":117,"ುದರ":81,"ುದ್":264,"ುದೇ":91," o":90," i":63," a":111," c":81," t":207," p":123," s":73," r":80,"ೀರಿ":62,"ೀರ್":102," I":78," M":62," B":59," C":95," A":102," S":86," P":57,"ುಖ್":182,"ುಗಳ":475,"ೀವಿ":81,"ೀವನ":57,"ುಕೊ":61,"ುಕ್":140,"ುಂಬ":175,"ುಂದ":93,"ೀಡಿ":58,"ೀಟರ":52,"ಿಸಿ":1001,"ಿಸು":679,"ಿಸೆ":100,"ಿಸ್":325,"ಿಹಾ":108,"ೀನ್":58,"ೀತಿ":89,"ೀಡು":53,"ೃಷ್":171,"ೆಯ ":906,"ೃತಿ":133,"ೃತ್":89,"ೇಕ ":98,"b ":108,"a ":86,"ೂಲಧ":77,"ೇ":5578,"ೆ":15840,"ು":25709,"ೂಲಕ":96,"ೀ":3205,"ೃ":757,"ೂ":3992,"್":52148,"ೌ":422,"ೈ":1240,"ೋ":2829,"ೊ":2928,"ೂರು":339,"ೂರಿ":178,"he":101,"ೂರ್":274,"೧":1776,"೦":1187,"gh":67,"೯":1054,"೮":516,"೭":491,"೬":491,"೫":520,"೪":472,"೩":669,"೨":1050,"ಐ":161,"ಒ":2005,"ಓ":71,"ಕ":16773,"ಖ":1270,"ಗ":16945,"ಘ":299,"g ":53,"ಚ":3279,"ಛ":94,"ೂರದ":77,"ಜ":4576,"ಞ":287,"ೂರನ":53,"ಟ":6023,"ಃ":62,"ಂ":14035,"ಅ":4390,"ಇ":2785,"ಆ":1877,"ಉ":1108,"ಈ":873,"ಊ":90,"ಏ":267,"ಎ":1847,"ಲ":19400,"ಳ":7999,"ರ":33568,"ಶ":3961,"ೂಮಿ":116,"ಷ":3572,"ವ":18565,"ಸ":14830,"ಹ":6186,"ಾ":27485,"ಿ":36903,"ಣ":3561,"ಡ":6448,"ಠ":200,"ಧ":2658,"ದ":26224,"ಥ":2061,"ತ":20028,"ಫ":753,"ಪ":9255,"en":84,"ನ":22644,"ಯ":14816,"ಮ":11705,"es":68,"ಭ":2607,"er":150,"ಬ":6283,"e ":261,"f ":64,"co":54,"ce":55,"d ":123,"at":112,"ar":92,"al":103,"an":163,"nt":61,"of":64,"on":129,"or":85,"r ":107,"mb":124,"na":66,"nd":87,"ng":73,"li":80,"le":62,"n ":194,"ht":76,"hu":109,"ic":76,"ia":57,"ig":78,"is":75,"it":67,"ೆದ ":99,"in":127,"io":72,"l ":78,"y ":108,"x ":86,"um":122,"to":56,"te":89,"ti":95,"th":193,"ta":55,"st":72,"ri":121,"re":74,"ra":68,"t ":164,"ೂಡಿ":63,"s ":195,"px":81,"ೂನ್":106," ಇ":2754," ಆ":1860," ಅ":4360," ಏ":265,"ುಖ ":181," ಎ":1695," ಊ":90," ಉ":1101," ಈ":872," ಖ":225," ಗ":2051," ಕ":5524," ಒ":1995," ಓ":65," ಐ":147," ಟ":281," ಜ":2387," ಚ":1161," ಘ":128,"ೀಯ ":460," ನ":3476," ಪ":4927," ಫ":377," ಬ":2936," ಭ":1657," ಮ":5657," ಯ":687," ಡ":389," ತ":2162," ದ":2528," ಧ":353," ಹ":3705," ಸ":5985," ರ":2258," ಲ":607," ವ":3839," ಶ":1153," ೬":68," ೭":68," ೮":53," ೯":53," ೨":675," ೩":313," ೪":88," ೫":77," ೧":1407,"ಾಂಶ":59,"ಾಂತ":277,"ಾಂಕ":60,"ಾಂಗ":132,"ಾಂಡ":169,"ೀತ ":103,"ಿಯ ":653,"ಿಮ ":103,"ಿನ ":1775,"ಿಧ ":52,"ಿದ ":402,"ಿತ ":279,"ಿಣ ":191,"ಿರಾ":52,"ಿರಿ":113,"ಿರ್":396,"ಿರು":1115,"ಂದ ":957,"ಿಲಿ":76,"ಿಲ್":730,"ಿಳಿ":79,"ಿಳು":52,"ೀಕರ":77,"ೀಕ್":78,"ಿವರ":110,"ಿವೃ":57,"ಿವಿ":95,"ಿವಾ":109,"ಿವೆ":147,"ಿಶ್":268,"ಿಸಬ":56,"ಂಬ ":229,"ಿಷ್":256,"ಿಸಲ":564,"ೃತ ":73,"ಿನಿ":232,"ಿನಾ":81,"ಿನಲ":259,"ಿನ್":254,"ಿಪ್":89,"ಿಭಾ":100,"ಿಯಂ":74,"ಿಮೆ":73,"ಿಯನ":554,"ಿಯಮ":111,"ಿಮಾ":95,"ಿಯು":246,"ಿಯೆ":150,"ಿಯೇ":59,"ಿಯೊ":67,"ಿಯರ":85,"ಿಯಲ":402,"ಿಯವ":134,"ಿಯಿ":76,"ಿಯಾ":494,"ಿಡಿ":78,"ಿಟ್":81,"ಿತ್":753,"ಿತರ":53,"ಿತವ":177,"ಿತಾ":52,"ಿತಿ":175,"ಿತು":240,"ಿದ್":1341,"ಿನಗ":88,"ಿಧಾ":82,"ಿನದ":58,"ಿದವ":67,"ಿದರ":307,"ಿದಾ":54,"ಿದೆ":1016,"ಿದು":62,"ಾಷ್":299,"ಾಸದ":54,"ಾಷೆ":295,"ಾಸನ":52,"ಾಷಾ":53,"ಿಗೆ":716,"ಿಗಾ":54,"ಾಶಿ":63,"ಾಹಿ":266,"ಾಸ್":461,"ಾಸಾ":72,"ಾಸಿ":149,"ಿಜ್":143,"ಿಟಿ":66,"ಾರವ":174,"ಾರಾ":172,"ಾರಿ":438,"ಾರು":321,"ಾರೆ":385,"ಾರ್":898,"ಾಲದ":109,"ಾಲಯ":138,"ಾಯಕ":132,"ಾಮಾ":287,"ಾಮಿ":92,"ಾಯನ":84,"ಾರಂ":66,"ಾಮ್":142,"ಾರಗ":62,"ಾರಕ":63,"ಾಯಿ":381,"ಾರದ":175,"ಾರತ":711,"ಾರಣ":117,"ಾಯು":52,"ಾರರ":107,"ಿಕಿ":78,"ಿಕಾ":233,"ಾವಣ":88,"ಾವಳ":55,"ಿಕೆ":452,"ಿಕೊ":215,"ಿಕ್":429,"ಾವು":111,"ಾವಿ":144,"ಿಗಳ":606,"ಾವ್":94,"ಾಲು":54,"ಾಲೂ":145,"ಾಲಿ":154,"ಾಲ್":298,"ಾಲೆ":294,"ಾಳಿ":56,"ಿಕವ":96,"ಿಕರ":56,"ಿಕದ":55,"ಾನಿ":272,"ಾನೆ":71,"ಾಧ್":78,"ಾನವ":177,"ಾನ್":541,"ಾಪಕ":91,"ಾದಿ":124,"ಾಧನ":72,"ಾದವ":55,"ಾದರ":121,"ಾನದ":188,"ಾದ್":141,"ಾನಗ":87,"ಾಮದ":98,"ಾಪು":93,"ಾಪಿ":108,"ುವ ":1824,"ಾಪ್":60,"ಿಂದ":1207,"ಿಂತ":88,"ಾಡಲ":88,"ಂಗ ":59,"ಾಡು":222,"ಾಡಿ":260,"ಾಟ್":67,"ಿಂಗ":466,"ಾಟಿ":63,"ಾಟಕ":338,"ಾತ್":294,"ುರ ":111,"ಾತನ":55,"ಾತಿ":122,"ಾತು":101,"ಾಣದ":83,"ಾಣಿ":182,"ಾಣು":83,"ಾಗ್":60,"ಾಗಿ":2495,"ಾಗು":715,"ಾಗೂ":350,"ಾಗರ":116,"ಾಗಲ":56,"ಾಗವ":78,"ಾಗದ":149,"ಾಕ್":170,"ಾಗಗ":52,"ಾಕಾ":66,"ಾಕಿ":70,"ಂತ ":350,"ಾಜ್":424,"ಾಜಿ":104,"ಾಜಧ":76,"ಾಜಕ":69,"ಾಚಾ":64,"ಂಡ ":134,"ಸರಾ":57,"ಸರಿ":110,"ಸರು":177,"ಸರ್":187,"ಸಮಾ":89,"ಸಮು":96,"ಷ್ಣ":158,"ಷ್ಟ":615,"ಷ್ಯ":148,"ಸಸ್":84,"ಸಲ್":204,"ಸಲು":129,"ಸಲಾ":407,"ಸೂರ":160,"ಸುಮ":185,"ಸುವ":474,"ಸುತ":345,"ಸಿನ":84,"ಸಿಯ":74,"ಸಿರ":109,"ಸಿಸ":62,"ಸಾರ":89,"ಸಾಯ":93,"ಸಾಮ":345,"ಸಿಕ":210,"ಸಾಲ":56,"ಸಾಧ":119,"ಸಿದ":904,"ಸಾಹ":178,"ಸಿಂ":68,"ಸಾಗ":104,"ಸಾಂ":87,"ಸೇವ":115,"ಸೇರ":192,"ಸೆಪ":83,"ಹದಿ":73,"ಸೆಂ":112,"ಹತ್":113,"ಶ್ಚ":149,"ಶ್ರ":321,"ಶ್ವ":281," ದ ":69,"ಶೇಷ":56," ನ ":221,"ಶೋಧ":52," ರ ":72,"ಷಿಣ":245,"ಷೇತ":113,"ಷೆಯ":163,"ಷೆಗ":96,"ಸತ್":52," ದೂ":111," ದಾ":111," ದಿ":826," ನಂ":173,"ಾಜ ":54," ತೆ":86," ದಕ":243," ತಾ":436," ತಿ":392," ತೀ":71," ತು":140," ತನ":105," ತಯ":72," ತಮ":160," ತರ":68," ತಂ":275," ಡಿ":173," ಡಾ":64," ಟ್":64," ಟೆ":75," ಮಲ":65," ಮರ":148," ಮಹ":275," ಮೂ":466," ರಂ":117," ಮೀ":91," ಮು":503," ಮಾ":930," ಮಿ":112," ಮ್":74," ಮೊ":287," ಮೋ":54," ಮೈ":149," ಮೆ":105," ಮೇ":303," ಬ್":257," ಭೂ":150," ಮತ":1392,"ಾದ ":915," ಭಾ":1269," ಭೌ":68," ಮಧ":122," ಮನ":105," ಫ್":115," ಬಳ":309," ಬಲ":53," ಬರ":237," ಬಹ":140," ಬಾ":244,"ಾಣ ":79," ಬಿ":202," ಬೀ":65," ಮಂ":165," ಬು":58," ಬೆ":486," ಬೇ":140," ಪೋ":52," ಪ್":2223," ಬಗ":131,"ಾತ ":80," ಬಣ":53," ಬದ":90," ಫೆ":69," ಪಶ":122," ಪರ":473," ಪೂ":178," ಪು":317," ಬಂ":203," ಪಿ":89," ಪಾ":318," ಪಕ":77," ನ್":129," ನೈ":64," ನೋ":69," ಪದ":311," ಪತ":98," ಪಟ":103," ಪಡ":148," ನಲ":117," ನವ":140," ನೀ":205," ಪಂ":148," ನೇ":153," ನೆ":157," ನಿ":719," ನಾ":379," ಧರ":127," ನಗ":232," ದೇ":439," ದೊ":195," ದ್":175," ನಡ":222," ನದ":175,"ಾನ ":293," ಧಾ":127," ನಟ":71," ವೇ":103," ವೈ":156," ವೆ":106," ವ್":384,"ಾಮ ":87," ವಸ":135," ವಿ":1423," ವಾ":355," ಶತ":99," ಶ್":256," ಶಿ":219," ಶಾ":196," ಸಂ":1268," ವರ":800,"ಾಲ ":93," ಲೋ":89," ಲ್":70," ಲೇ":112," ಲಿ":71," ಯು":227," ಯಾ":161," ರಚ":137,"ಾರ ":382," ರೋ":82," ರೇ":54," ರೀ":66," ರೂ":111," ರಾ":953," ರಿ":89," ರಸ":87," ರವ":64,"ಾಯ ":86," ರಲ":134,"ಿಕ ":878,"ಾಳ ":52," ಹು":167," ಹೆ":576," ಹೇ":108," ಹಾ":768," ಹಿ":369," ಹೊ":508," ಹೋ":156,"ಾಸ ":73," ಸದ":81," ಹಂ":55," ಸಣ":52," ಸರ":313," ಸಲ":64," ಸಮ":357," ಸೆ":143," ಸೇ":325," ಹದ":68," ಹಣ":89," ಸೂ":152," ಹತ":79," ಸು":425," ಸಾ":912," ಸಿ":289," ಸಸ":67," ಸಹ":107," ಹಳ":93," ಹಲ":156," ಹರ":112," ಸ್":892," ಸೌ":54," ಸೋ":68," ಸೈ":56," ಅಂ":408,"ಸ್ಥ":756,"ಸ್ಪ":98,"ಸ್ಯ":165,"ಸ್ಕ":258,"ಸ್ಟ":445,"ಸ್ತ":931," ಆಟ":96," ಇಂ":246," ಆಡ":86," ಆಚ":60," ಅವ":421," ಆಗ":261," ಅಸ":94," ಅಲ":154," ಆಕ":73," ಅಮ":216," ಅಭ":111,"ಸ್ವ":337,"ಸ್ಸ":91," ಅರ":279," ಅಪ":94," ಅದ":274," ಅಥ":645," ಅನ":330," ಅಧ":417," ಅತ":346," ಅಡ":73," ಆಂ":116," ಅಗ":62," ಅಕ":181,"ಹರಿ":90,"ಹಲವ":148,"ಹಳ್":97," ಊರ":63," ಎನ":126," ಎತ":68," ಎಂ":869," ಇಪ":84," ಇನ":85," ಇಲ":141," ಇರ":180," ಇವ":618," ಉಂ":56," ಆದ":131," ಆಧ":97," ಆಫ":103," ಆಯ":65," ಆರ":223," ಆಲ":68," ಆಳ":54," ಆವ":57," ಆಸ":93," ಇತ":184," ಇದ":1044," ಉಪ":269," ಉದ":185," ಉತ":320,"ಹಾಸ":180,"ಹಿತ":251,"ಹಿಡ":63,"ಹಾರ":180," ಒಳ":146,"ಹಾಕ":59,"ಹಾಗ":543,"ಹಿಂ":230," ಕಂ":258," ಕರ":597,"ಹುಟ":85," ಕಲ":170," ಕನ":397," ಕಥ":54,"ಹುದ":165," ಕಟ":67," ಕಣ":68," ಖಂ":56," ಕಡ":102," ಕ್":901,"ಹಿಸ":111," ಕೆ":308," ಕೇ":216," ಕೊ":245," ಕೋ":98," ಕಾ":889," ಗಂ":57," ಕಿ":200," ಕೂ":99," ಕು":307," ಕೃ":156," ಕವ":70," ಏಪ":62," ಎಲ":152," ಎರ":162," ಏಷ":55," ಒಂ":1369," ಒಬ":182," ಒಟ":63," ಚೆ":63," ಚಿ":486," ಚಾ":99,"ಹೆಸ":279," ಜಗ":78," ಜನ":678,"ಹೆಚ":200," ಜಲ":69," ಜೋ":71," ಜೊ":56," ಜಿ":489," ಜಾ":210," ಜು":99," ಜೀ":215," ಜೂ":94,"ಹೊಂ":267," ಜ್":80,"ಹೇಳ":76," ಗಣ":150,"ಹೋಗ":60,"ಹೊಸ":67,"ಾಗ ":150," ಖ್":54," ಗಳ":238," ಘಟ":60," ಗಾ":155," ಗು":365," ಗಿ":82,"ಹೊರ":79," ಗ್":584," ಗೋ":85," ಚಂ":64,"ಹ್ಯ":58," ಚಲ":126," ೨೦":198," ೧೯":643," ೧೨":59," ೧೧":53," ೧೪":61," ೧೬":69," ೧೫":80," ೧೮":164," ೧೭":110," ೩೦":63," ೨೫":63,"ಳ್ಳ":382,"ಳೆಯ":131," ೧೦":72,"ಶ್ ":57,"ಳೂರ":208,"ಳುವ":137,"ವಣೆ":61,"ಷ್ ":79,"ಷೆ ":91,"ಲ್ಯ":182,"ಲ್ಲ":5639,"ಲ್ಪ":335,"ಲ್ಕ":111,"ಲೋಹ":64,"ಲೊಂ":55,"ಳನ್":731,"ಲೆಂ":287,"ಲೇಖ":144,"ಲೆಕ":53,"ಲೆಗ":94,"ಲೆಯ":429,"ಲಿಯ":252,"ಲಿರ":303,"ಲಿಸ":109,"ವ್ ":88,"ಲೂಕ":200,"ಳಿಂ":159,"ಳಾಗ":68,"ಳಿನ":117,"ಳಿತ":74,"ಳಿದ":77,"ಳಿಕ":53,"ಳಿಗ":310,"ವಂತ":117,"ಳಿಸ":102,"ಳಿಯ":166,"ಷದ ":67,"ಳಸಲ":88,"ಳಲ್":724,"ಷಗಳ":63,"ವೇದ":77,"ಶದಲ":55,"ವ್ಯ":542,"ಸಂಘ":68,"ಶಿಷ":59,"ಶಿಸ":74,"ಸಂಖ":127,"ಶಿವ":89,"ಸಂಗ":227,"ಸಂಕ":77,"ಶಿಯ":58,"ಸಂದ":52,"ಸಂಸ":304,"ಸಂಯ":79,"ಸಂಪ":131,"ಸಂಬ":98,"ಷದಲ":459,"ಶಸ್":149,"ಶಾಸ":280,"ಶಾಲ":53,"ಶಿಕ":64,"ವರನ":53,"ವರೆ":141,"ವರಾ":53,"ವರು":761,"ವರಿ":316,"ವರ್":898,"ವಳಿ":93,"ಸಿ ":303,"ವಲ್":60,"ವತ್":64,"ವಧಿ":53,"ವದಲ":53,"ವನ್":720,"ವಾಗ":1342,"ವಾದ":543,"ವಾತ":70,"ವಾಣ":65,"ವಾಡ":79,"ವಾಮ":73,"ವಾಯ":90,"ವಾರ":197,"ವಿಗ":77,"ವಾಸ":169,"ವಾಲ":67,"ವಿಕ":218,"ವಾಹ":85,"ವಿಜ":170,"ವಿಧ":170,"ವಿದ":296,"ವಿನ":163,"ವಿತ":66,"ವಿಭ":117,"ವಿರ":130,"ವಿಮ":65,"ವಿಯ":106,"ವಿವ":124,"ವಿಲ":62,"ವಿಸ":121,"ವಿಶ":329,"ವಿಷ":94,"ವೀಪ":59,"ವುಗ":98,"ವುದ":425,"ಸ್ ":791,"ವೃತ":84,"ಶತಮ":88,"ವೆಂ":214,"ವವಿ":62,"ಶಕ್":84,"ಸು ":82,"ಶಗಳ":199,"ವಹಿ":89,"ವಸ್":273,"ಮೊದ":199,"ಯನಿ":63,"ಯನ್":821,"ಮೈಸ":89,"ಯಮ್":96,"ಮ್ಮ":313,"ಮ್ರ":69,"ಮ್ಯ":104,"ಲಿ ":3648,"ರಕಾ":170,"ಲಾ ":127,"ಯಲ್":813,"ಯಲಾ":117,"ಯರು":78,"ರಚನ":78,"ಲೂ ":94,"ಲು ":400,"ರಗಳ":381,"ಯವಾ":336,"ಯವು":63,"ಯವಸ":110,"ರಕ್":198,"ಯವರ":158,"ಯವನ":100,"ಮಹಾ":203,"ಲದ ":112,"ಮಾಜ":102,"ಮಾನ":565,"ಮಾಣ":151,"ಮಾಡ":381,"ಮಾತ":89,"ಮಾಹ":71,"ಮಾರ":439,"ಮಾಲ":61,"ಮಿಕ":75,"ಮಿಯ":113,"ಮಿತ":67,"ಮೂರ":118,"ಮೂಲ":335,"ರಂದ":193,"ರಂಭ":108,"ರಂಗ":139,"ಮಿಸ":75,"ಮಿಳ":54,"ಮುಂ":173,"ಮುದ":121,"ಮುಖ":451,"ಮೆರ":66,"ಮೇಲ":169,"ಮೇರ":140,"ಯತೆ":52,"ಲಯ ":63,"ಯದಲ":149,"ಯೋಗ":170,"ಯ್ಯ":64,"ರರಾ":68,"ರರಂ":62,"ರಮು":225,"ರಮಾ":162,"ರರು":63,"ಳಿ ":203,"ರಲ್":544,"ರಶಸ":112,"ಳು ":1195,"ರವು":117,"ರವಾ":329,"ರವಿ":59,"ರವರ":144,"ರವನ":89,"ರಸಿ":199,"ರಸಾ":67,"ರಸ್":141,"ಯಸ್":73,"ರಚಿ":80,"ಲೆ ":252,"ಲೇ ":70,"ರಜ್":65,"ಯಾಂ":162,"ಯಾಕ":83,"ಲೈ ":93,"ಯಾಗ":387,"ಯಾದ":236,"ಯಾತ":133,"ಯಿಂ":142,"ಯಾಟ":89,"ಯಾಪ":150,"ಯಾನ":165,"ಯಾವ":134,"ಯಾಯ":90,"ಯಾರ":155,"ಯಾಲ":340,"ಯಾಸ":109,"ಯಿತ":172,"ಯಿಸ":93,"ರಡನ":86,"ಯುಕ":79,"ರಡು":80,"ಯುತ":201,"ಯುದ":79,"ಯುರ":59,"ಯುವ":150,"ರತದ":423,"ರಣೆ":97,"ರಣಿ":54,"ಲ್ ":636,"ರಣವ":59,"ರತ್":73,"ರತಿ":180,"ರತೀ":142,"ರದರ":55,"ರದಲ":281,"ರದೇ":250,"ಯೆಯ":95,"ಯೆಗ":53,"ರದಾ":69,"ರದಿ":71,"ರನ್":145,"ರಪಂ":68,"೨೦೦":138,"ರ್ಮ":390,"ರ್ಯ":406,"ರ್ವ":378,"ರ್ಶ":130,"ರ್ಷ":704,"ರ್ಸ":72,"ರ್ಟ":71,"ರ್ಡ":92,"ರ್ತ":167,"ರ್ಣ":195,"ರ್ದ":177,"ರ್ಥ":249,"ರ್ನ":341,"ರ್ಧ":61,"ರ್ಪ":57,"ರ್ಗ":212,"ರ್ಕ":216,"ರ್ಜ":96,"ರ್ಚ":113,"ವನ ":77,"ವದ ":73,"ಲಕ್":112,"ರೂಪ":165,"ರುವ":1148,"ರೀಯ":191,"ರೀತ":68,"ರೀಡ":60,"ರಿಸ":509,"ರಿವ":56,"ರೀಕ":90,"ರಿಲ":102,"ರಿಯ":766,"ರುದ":52,"ರುತ":402,"ರುಗ":103,"ರಿಂ":256,"ರಾಟ":71,"ರಾತ":76,"ರಾಣ":153,"ರಾನ":117,"ರಾದ":125,"ರಾಕ":64,"ರಾಗ":268,"ರಾಜ":696,"ರಾಚ":61,"ರಿಟ":72,"ರಿತ":118,"ರಿದ":175,"ರಿನ":273,"ರಾಯ":125,"ರಾಮ":296,"ರಾರ":74,"ರಾವ":128,"ರಿಕ":602,"ರಾಷ":292,"ರಿಗ":296,"ರಾಸ":60,"೧೯೭":59,"೧೯೬":77,"ಳೆ ":85,"೧೯೯":64,"೧೯೩":78,"೧೯೨":62,"೧೯೫":67,"೧೯೪":74,"ರಾಂ":137,"ರೋಗ":76,"ರೋಪ":59,"ರೆಗ":378,"ರೆದ":71,"ರೆಯ":331,"ವಿ ":195,"ವಾ ":561,"ವು ":807,"ಲವು":161,"ಲವಾ":103,"ಳಕೆ":83,"ಲಯದ":79,"ವೆ ":451,"ಲಾಯ":82,"ಲಿಗ":61,"ಲಿಕ":80,"ಲಾವ":62,"ಲಿನ":461,"ಲಿದ":161,"ಲಾಗ":564,"ಲಿಂ":75,"ಲಾದ":129,"ಳಗೊ":121,"ವೂ ":55,"ಶದ ":217,"ಲದಲ":69,"ವರ ":374,"ಲಧಾ":75,"ಲನಚ":87,"ಪ್ಟ":118,"ಪ್ರ":2498,"ಪ್ಯ":75,"ಪ್ಪ":318,"ಪೂರ":201,"ಪಿಸ":139,"೬ನೇ":54,"ಬಂಧ":106,"ಬಂದ":116,"ಪುಟ":63,"ಪುರ":302,"ಮದ ":92,"ಪಶ್":122,"ಪಿಯ":85,"ಪಾರ":115,"ಪಾಲ":72,"ಪಾತ":114,"ಪಾದ":107,"ಪರ್":164,"ಪಯೋ":105,"ಪರಮ":64,"ಪರಿ":273,"ಫ್ರ":149,"ಬರಿ":53,"ಬರು":198,"ಬರೆ":81,"ಬರ್":426,"ಬಳಕ":77,"ಮ್ ":312,"ಬಣ್":56,"ಬದಲ":69,"ಫೆಬ":56,"ಯದ ":342,"ಮೇ ":71,"ಯನ ":58,"ಮೆ ":97,"ಮಿ ":137,"ಬಗ್":95,"ರಾ ":66,"ರಿ ":689,"ಬ್ದ":64,"ಬ್ಬ":413,"ಬ್ಯ":92,"ಬ್ರ":245,"ಬೇಕ":58,"ಬೆಳ":196,"ಬೆಲ":56,"ಬೆಟ":70,"ಬೇರ":65,"ಬೆಂ":161,"ಬುದ":201,"ಮಂಡ":85,"ಮಂತ":82,"ಬಾಲ":61,"ಬಾರ":62,"ಯೇ ":65,"ಯೆ ":129,"ರದ ":417,"ಬಹು":249,"ರತ ":132,"ರಣ ":118,"ಯೂ ":79,"ಯು ":397,"ಯಿ ":133,"ಬಳಸ":168,"ಯಾ ":166,"ಬಳಿ":64,"ಬಲ್":56,"ಯಕರ":55,"ಯಕ್":233,"ಯಗಳ":256,"ಮರಾ":59,"ಮರ್":71,"ಮಧ್":119,"ಲಕ ":102,"ಮನ್":73,"ಮನೆ":57,"ರ್ ":1282,"ಭೂಮ":114,"ಮದಲ":87,"ಮತ್":1394,"ಭಾಷ":355,"ಭಾವ":93,"ಭಿನ":73,"ಭಾಗ":330,"ಭಾರ":739,"ಯಂತ":301,"ರೆ ":804,"ರು ":2581,"ಮಗಳ":92,"ಭವಾ":52,"ರೀ ":91,"ಮಕ್":73,"ರೂ ":136,"ಥೆಯ":123,"ದನೆ":56,"ದನ್":281,"ದರಿ":133,"ದರು":453,"ದರೆ":272,"ದರೂ":102,"ದರಲ":91,"ದರ್":155,"ದಲಾ":57,"ದಲು":62,"ದಲ್":2055,"ದವನ":56,"ದವು":75,"ದವರ":138,"ದಸ್":52,"ಪದ ":80,"ದಾಗ":201,"ದಿನ":874,"ದಿದ":212,"ದಿಸ":72,"ದಿರ":178,"ದಿಯ":160,"ದಾದ":115,"ದಿಂ":295,"ದಿಕ":52,"ದಿಗ":178,"ದಾರ":359,"ದಾಯ":84,"ದಾನ":52,"ದುರ":81,"ದುಕ":71,"ನಂತ":150,"ನಂದ":72,"ದೂರ":133,"ಧತಿ":57,"ದೇಶ":726,"ದೇವ":195,"ಧನೆ":64,"ದೊಡ":174,"ದ್ದ":1224,"ದ್ಧ":445,"ದ್ವ":154,"ದ್ಯ":488,"ದ್ರ":521,"ಪಿ ":59,"ಧರ್":147,"ನಕ್":67,"ನಗಳ":229,"ನಗರ":304,"ಪು ":78,"ನಚಿ":88,"ನಡೆ":173,"ನಡು":55,"ಧಿಸ":90,"ನಡದ":107,"ಧಿಯ":80,"ಧಾತ":90,"ಧಾನ":211,"ಧಾರ":211,"ಧಿಕ":334,"ನದಲ":85,"ಪ್ ":121,"ನನ್":63,"ನದಿ":214,"ನಪ್":62,"ಧ್ಯ":309,"ನಲ್":436,"ನವನ":120,"ನವರ":180,"ನವಾ":90,"ನವು":53,"ನವೆ":88,"ನುವ":99,"ನೀರ":61,"ನೀಡ":120,"ಪಂದ":55,"ನಿಸ":295,"ಪಂಚ":105,"ಫ್ ":93,"ನಿವ":80,"ನಿಲ":70,"ನಿಯ":276,"ನಿರ":415,"ನಿಗ":99,"ನಾದ":62,"ನಾಲ":99,"ನಿಕ":181,"ನಾಮ":59,"ನಾಯ":110,"ನಾರ":70,"ನಾಗ":147,"ನಾಥ":61,"ನಾಟ":338,"ನಿಂ":150,"ನಾಡ":89,"ನೆಗ":163,"ನೇಕ":77,"ನೆಲ":86,"ನೆಯ":329,"ಪಕರ":55,"ಬಿ ":56,"ನ್ಸ":171,"ನ್ಯ":464,"ನ್ಮ":57,"ನ್ನ":3456,"ಪಕ್":91,"ಪದವ":93,"ಪತ್":245,"ಪತಿ":53,"ಬ್ ":71,"ಪಡೆ":154,"ಪಡು":141,"ಪಡಿ":52,"ಪಟ್":240,"ಪನ್":57,"ಪನಿ":89,"ಪದ್":89,"ಡೆಸ":85,"ಡೆದ":156,"ಡೆಯ":184,"ಥವ ":102,"ಡ್ಡ":232,"ಡಿತ":54,"ಡಿನ":68,"ಡಿದ":293,"ಡಿರ":86,"ಡಿಯ":235,"ಡಿಸ":241,"ಡಿಕ":76,"ಡಿಗ":58,"ಡುತ":146,"ಡುವ":315,"ಡುಗ":71,"ತ್ ":173,"ಡೆಗ":53,"ಥೆ ":99,"ಣಗಳ":143,"ಣರಾ":65,"ತಂದ":116,"ತಂತ":159,"ತಂಡ":77,"ದಲ ":85,"ಣದಲ":85,"ದರ ":265,"ದೇ ":231,"ದೆ ":1948,"ಣಿಗ":82,"ಣಿಯ":81,"ಣಿಸ":84,"ಣಿತ":57,"ದಿ ":230,"ದೂ ":160,"ಣವಾ":87,"ತಗಳ":66,"ದು ":3600,"ತರಾ":116,"ತಮ್":117,"ತರದ":65,"ತಯಾ":73,"ಣ್ಯ":74,"ತಮಾ":89,"ಣ್ಣ":250,"ಣೆಯ":103,"ತದೆ":688,"ತನ್":101,"ದ್ ":83,"ತದಲ":113,"ಣೆಗ":103,"ದಂತ":81,"ತುಗ":83,"ತೀಯ":160,"ತೀರ":77,"ತುವ":100,"ನನ ":106,"ತಿಂ":268,"ತಾನ":117,"ತಾದ":59,"ತಾರ":223,"ತಾಯ":91,"ತಿಗ":244,"ತಿಕ":121,"ತಾಲ":214,"ತಿನ":126,"ತಿತ":52,"ತಿದ":136,"ತಿರ":166,"ತಿಯ":448,"ತಿಸ":85,"ತಿಹ":93,"ತಿಳ":56,"ನದ ":230,"ಧಿ ":63,"ತವೆ":173,"ನಡ ":231,"ತವಾ":246,"ನಿ ":257,"ದಕ್":378,"ನಾ ":82,"ತ್ವ":161,"ತ್ಸ":90,"ತ್ಮ":97,"ತ್ಯ":494,"ತ್ರ":1536,"ತ್ಪ":98,"ತ್ನ":61,"ತ್ತ":3794,"ತೆಯ":160,"ತೆಗ":110,"ಥೆಗ":52,"ನ್ ":1307,"ಥಾನ":142,"ಥಾಪ":134,"ಥಿತ":69,"ನೆ ":323,"ನೇ ":743,"ನೂ ":58,"ಥವಾ":557,"ದಗಳ":58,"ನು ":2464,"ಟಿ ":147,"೧೦ ":57,"ಟು ":213,"ಟೆ ":76,"ಜಿನ":61,"ಜಿಲ":446,"ಜಾಲ":52,"ಜಾತ":92,"ಜುಲ":91,"ಜೀವ":240,"ಟ್ ":637,"ಜೂನ":90,"ೆನ":244,"ೆದ":362,"ೆಬ":114,"ೆಪ":117,"ೆರ":365,"ೆಯ":2599,"ೆಮ":88,"ೇಖ":200,"ೆವ":58,"ೇಕ":249,"ೆಳ":254,"ೆಲ":491,"ೆಸ":577,"ೆಹ":62,"ೇಗ":75,"ೇಜ":68,"ೇಟ":120,"ೇದ":127,"ೇತ":222,"ೆಕ":157,"ೆಗ":1392,"ೆಚ":219,"ೆಟ":300,"ೆಡ":111,"ೇಂ":180,"ೈನ":129,"ೈವ":57,"ೈಲ":128,"ೈಸ":184,"ೊಂ":945,"ೇಮ":53,"ೇನ":121,"ೈಕ":103,"ೇಳ":166,"ೇಶ":901,"ೇವ":379,"ೇರ":613,"ೇಯ":97,"ೇಲ":240,"ೈಟ":55,"ೇಷ":160,"ೇಸ":99,"ೈದ":86,"ೂಪ":194,"ೂರ":1041,"ೂಮ":136,"ೂತ":53,"ೂನ":169,"ೂಲ":387,"ion":67,"ುಪ":145,"ುಬ":131,"ುಭ":63,"ುಮ":379,"ುರ":798,"ುಡ":140,"ುಣ":155,"ುತ":1697,"ುದ":1164,"ುನ":256,"ೂಚ":55,"ುಹ":87,"ೂಟ":104,"ೂಡ":144,"ುಲ":232,"ೂಕ":272,"ುಳ":152,"ುವ":2954,"ುಸ":149,"ುಷ":80,"ೆಂ":1198,"ೃತ":380,"ೃದ":63,"ೃಷ":194,"ಜ್ಯ":449,"ಜ್ಞ":280,"್ರ":7384,"್ಯ":5185,"್ಮ":1098,"್ಭ":55,"್ಳ":385,"್ಲ":6122,"್ಸ":715,"್ಷ":1648,"್ಶ":149,"್ವ":1581,"ೋತ":79,"ೋದ":91,"ೋನ":101,"ೋಧ":91,"ೋಪ":132,"ೋಜ":72,"ೋಟ":142,"ೋಡ":153,"ೊಲ":98,"ೊಳ":303,"ೋಕ":95,"ೋಗ":340,"ೊಸ":100,"ೊಬ":113,"ೊಮ":81,"ೊರ":184,"ೊತ":77,"ೊನ":118,"ೊದ":217,"ೊಡ":288,"ೊಟ":69,"ೊಗ":56,"್ಪ":943,"್ಬ":531,"್ಫ":53,"್ದ":1537,"್ಥ":1015,"್ನ":4079,"್ಧ":516,"್ಡ":394,"್ತ":5341,"್ಣ":606,"್ಞ":286,"್ಠ":60,"್ಟ":2345,"್ಚ":591,"್ಜ":168,"್ಕ":1695,"್ಗ":432,"ೌರ":85,"ೌಲ":59,"ೌತ":60,"ೋಹ":109,"ೋಷ":61,"ೋಸ":106,"ೋವ":84,"ೋಶ":58,"ೋಳ":74,"ೋಲ":103,"ೋರ":455,"ೋಮ":87,"ೋಬ":137,"೦೦ ":84,"ಜಗತ":55,"ಟದ ":65,"೧೯":659,"೧೮":176,"೧೭":128,"೧೬":85,"೧೫":91,"೧೪":72,"೧೨":74,"೧೧":70,"೪ನ":53,"೨೦":221,"೨೧":53,"೦೦":269,"೧೦":100,"೦ರ":61,"೦ದ":80,"ಜಧಾ":74,"ಜನಪ":57,"ಜನನ":108,"ಜನರ":79,"ಜನಸ":53,"ಜನವ":106,"ಜನಿ":197,"೯೯":86,"೯೭":74,"೯೮":65,"೯೫":81,"೯೬":94,"೯೩":91,"೯೪":81,"೯೧":62,"೯೨":81,"೯೦":57,"೯ರ":54,"೮ರ":60,"೫೦":53,"೬ರ":52,"೬ನ":59,"೫ರ":52,"೫ನ":55,"೩೦":80,"೨೪":61,"೨೫":72,"೨೨":62,"೨೩":65,"೨೯":62,"೨೬":59,"೨೭":59,"ಏಷ":56,"ಒಂ":1369,"ಒಬ":183,"ಒಟ":63,"ಒಳ":146,"ಕಂ":287,"ಚರಿ":67,"ಕಪ":63,"ಕನ":521,"ಕಥ":62,"ಕದ":288,"ಕಳ":92,"ಖಕ":55,"ಕಲ":280,"ಕರ":1275,"ಕಮ":65,"ಕಗ":118,"ಕಕ":54,"ಕತ":77,"ಕಣ":99,"ಕಡ":111,"ಖಂ":114,"ಕಟ":188,"ಕೆ":1476,"ಕೇ":322,"ಖನ":70,"ಕೈ":57,"ಕೊ":554,"ಕೋ":259,"ಕ್":4088,"ಖರ":77,"ಕವ":314,"he ":68,"ಕಾ":1989,"ಗಂ":72,"ಕೀ":159,"ಕಿ":814,"ಕೂ":238,"ಕು":604,"ಕೃ":380,"ಗನ":75,"ಖ್":433,"ಗಮ":88,"ಚಲನ":114,"ಗಲ":148,"ಗರ":505,"ಗವ":163,"ಗಳ":4635,"ಗಗ":111,"ಗಡ":160,"ಖಾ":80,"ಗದ":413,"ಗತ":118,"ಗಣ":242,"ಗೆ":1418,"ಗು":1317,"ಗೂ":445,"ಗಿ":3142,"ಗೀ":235,"ಘಟ":107,"ಗಾ":676,"ಗಸ":140,"ಗ್":1370,"ಗೌ":65,"ಗೋ":407,"ಗೊ":342,"ಚಂ":92,"ಚಕ":52,"ಚನ":130,"ಚದ":87,"ಚಿಮ":122,"ಚಿನ":103,"ಚಲ":161,"ಚಿಸ":104,"ಚರ":168,"ಚಾರ":154,"ಚೆ":127,"ಚಾ":329,"ಚಿ":1078,"ಚೀ":83,"ಚು":203,"ಜಕ":77,"ಜಗ":96,"ಚಿತ":435,"ಚ್":491,"ಚಿಕ":171,"ಜನ":825,"ಜಧ":76,"ಜಲ":84,"ಜರ":102,"ಜಯ":76,"ಜು":167,"ಜೀ":273,"ಜೂ":99,"ಜಿ":789,"ಜಾ":390,"ಜೋ":82,"ಜೊ":58,"ಜೆ":97,"ಜ್":917,"ಟಕ":392,"ಟಗ":141,"ಞಾ":215,"ಟಣ":83,"ಟದ":127,"ಟನ":129,"ಟರ":243,"ಟವ":113,"ಟಾ":225,"೨ ":199,"೧ ":173,"೪ ":159,"ಂಸ":383,"ಂಶ":181,"ಂವ":61,"ಂಯ":79,"ಂಬ":1236,"ಂಭ":148,"ಂಪ":432,"ಂದ":5006,"ಂಧ":211,"ಂತ":1631,"ಂಥ":91,"ಂಟ":300,"ಂಡ":1562,"ಂಚ":262,"ಂಜ":146,"ಂಗ":1536,"ಂಖ":130,"೩ ":171,"ಂಘ":78,"ಂಕ":337,"ಅಗ":63,"ಅಕ":181,"೬ ":165,"ಅತ":348,"ಅಡ":73,"ಆಂ":116,"ಚೀನ":76,"೫ ":171,"ಅಂ":414,"ಆಸ":93,"೮ ":158,"ಇದ":1048,"ಇತ":185,"ಆಫ":104,"ಆಧ":97,"ಆದ":131,"ಆವ":58,"ಆಳ":54,"ಆಲ":68,"ಆರ":228,"ಆಯ":65,"ಆಚ":60,"ಅವ":422,"ಆಗ":261,"೭ ":172,"ಅಸ":94,"ಆಟ":97,"ಇಂ":249,"ಆಡ":86,"ಅಪ":94,"ಅದ":275,"ಅಥ":647,"ಅನ":333,"ಅಧ":417,"ಅಲ":154,"ಆಕ":75,"ಅಮ":219,"ಅಭ":111,"ಅರ":281,"ಚ್ಚ":307,"ಉತ":320,"ಉದ":186,"ಇಲ":141,"ಇರ":180,"ಇವ":619,"ಇಪ":84,"ಇನ":88,"ಉಂ":56,"೯ ":167,"ಊರ":63,"ಉಪ":269,"ಟಕ ":183,"ಎಂ":888,"ಎಲ":159,"ಎರ":162,"ಎಸ":63,"ಏಪ":62,"ಎಎ":79,"ಎತ":68,"ಎನ":130,"ಲೂ":332,"ಳದ":98,"ಲೇ":336,"ಳನ":786,"ಲೆ":1225,"ಲೈ":134,"ಲೋ":199,"ಲೊ":116,"ಲ್":7197,"ಳಲ":778,"ಳಕ":140,"ಲವ":387,"ಳಗ":277,"ಲಸ":91,"ಲಾ":1226,"ಲಿ":5377,"ಲೀ":90,"ಲು":562,"ಳೆ":375,"ಳ್":432,"ಜಿ ":102,"ಳವ":134,"ಳಸ":184,"ಳಾ":158,"ಳು":1449,"ಳೂ":229,"ಳಿ":1334,"ವಂ":199,"ರೇ":335,"ರೆ":1812,"ರು":4505,"ರೀ":683,"ಲಂ":108,"ರೂ":345,"ರ್":5601,"ರೈ":117,"ರೋ":413,"ರೊ":96,"ರವ":930,"ರಶ":156,"ರರ":275,"ರಲ":578,"ರಳ":88,"ರಾ":3110,"ರಿ":4229,"ರಸ":502,"ರಹ":213,"ಲನ":192,"ಲಧ":79,"ಲದ":305,"ಲತ":56,"ಲರ":69,"ಲಯ":223,"ಲಗ":86,"ಲಕ":273,"ಷರ":95,"ಸಕ":90,"ಷವ":55,"ಸಗ":60,"ಷನ":59,"ಶೇ":96,"ಶೈ":56,"ಶೋ":71,"ಶ್":926,"ಶಿ":491,"ಶಾ":465,"ಶು":62,"ಶೀ":53,"ಸಂ":1411,"ಷತ":59,"ಷಣ":159,"ಷದ":539,"ಷಗ":72,"ಶಸ":149,"ಸಲ":766,"ಸರ":765,"ಹಗ":69,"ಹಕ":66,"ಸವ":133,"ಷೇ":140,"ಸನ":125," of":57,"ಸಮ":419,"ಷ್":1158,"ಸಬ":77,"ಸಣ":55,"ಹಂ":68,"ಷಿ":475,"ಷೆ":352,"ಸದ":188,"ಸತ":71,"ಷಾ":85,"ವಲ":178,"ವಳ":120,"ಶಕ":218,"ವಯ":77,"ವರ":2811,"ವದ":177,"ವಧ":55,"ವನ":1004,"ವತ":235,"ವಣ":147,"ವಜ":56,"ವಕ":121,"ವಗ":66,"ಷಕ":61,"ಶವ":121,"ಶರ":52,"ವ್":725,"ಶಬ":54,"ವೊ":56,"ವೇ":345,"ಶನ":143,"ವೈ":184,"ಶದ":301,"ವೆ":860,"ಶತ":100,"ವೃ":137,"ವೂ":60,"ವು":1384,"ವೀ":183,"ವಿ":2666,"ವಾ":3557,"ವಹ":172,"ವಸ":327,"ಶಗ":201,"ವವ":155,"ಸಾ":1235,"ಸಿ":2058,"ಸಸ":92,"ಸಹ":114,"ಸೆ":366,"ಹನ":99,"ಸೇ":360,"ಹದ":135,"igh":65,"ಸೂ":287,"ಹಣ":147,"ಹತ":133,"ಸೀ":80,"ಸು":1321,"ಹರ":198,"ಸ್":4080,"ಸೌ":55,"ಸೋ":90,"ಸೈ":69,"ಹಸ":55,"ಹವ":83,"ಹಳ":189,"ಹಲ":179,"ಹಾ":1242,"ಹಿ":907,"ಹೀ":57,"ಹೆ":605,"ಹೇ":123,"ಹು":431,"ಹೂ":52,"ಹ್":175,"ಹೊ":532,"ಹೋ":187,"ಿಪ":236,"ಿನ":2977,"ಿಧ":213,"ಿಮ":515,"ಿಭ":159,"ಿಬ":92,"ಿಡ":230,"ಿಟ":228,"ಿದ":3371,"ಿತ":1841,"ಿಣ":314,"ಿಹ":188,"ಿಷ":392,"ಿಸ":2818,"ೀಟ":93,"ಿಲ":986,"ಿಯ":3289,"ಿರ":1992,"ಿವ":655,"ಿಶ":439,"ಿಳ":170,"ೀಕ":215,"ೀನ":225,"ೀಪ":138,"ೀಯ":562,"ೀಮ":67,"ೀಡ":224,"ುಂ":466,"ೀತ":316,"ೀಸ":69,"ುಚ":64,"ುಟ":277,"ೀರ":351,"ೀಲ":114,"ುಕ":335,"ೀವ":282,"ುಖ":454,"ುಗ":730,"ಾಂ":1000,"ಾಜ":887,"ಾಚ":176,"ಾಖ":102,"ಾಗ":4356,"ಾಕ":469,"ಾಪ":496,"ಾಭ":74,"ಾಬ":132,"ಾಧ":258,"ಾದ":1706,"ಾನ":1975,"ಾಣ":559,"ಾಥ":81,"ಾತ":838,"ಾಟ":601,"ಾಡ":732,"ಿಂ":1911,"ಿಜ":269,"ಾಶ":207,"ಿಗ":1656,"ಾಷ":669,"ಾಸ":1090,"ಿಚ":104,"ಾಹ":451,"ಾಲ":1507,"ಾಳ":273,"ಿಕ":2705,"ಿಖ":52,"ಾವ":819,"ಾಮ":995,"ಾಯ":1047,"ಾರ":4215,"ತಗ":107,"ಣವ":210,"ತಕ":168,"ಣು":184,"ಣಿ":524,"ಣಾ":151,"ಣನ":52,"ಣದ":261,"ಣರ":86,"ಣಗ":184,"ಣಕ":131,"ತಂ":382,"ಡೆ":640,"ಡೇ":56,"ಡು":959,"ಡ್":778,"ಡಳ":71,"ಡಲ":204,"ಡವ":88,"ಡಿ":1466,"ಡಾ":222,"ಡನ":199,"ಡದ":306,"ಜ್ ":103,"ಡರ":323,"ಡಕ":55,"ಡಗ":107,"ಟಿ":799,"ಟೀ":72,"ಟು":403,"ಟೆ":354,"ಟೇ":63,"ಟೋ":167,"ಟ್":2145,"ನದ":576,"ನತ":67,"ಧಿ":651,"ನಡ":623,"ಧಾ":588,"ನಟ":88,"ನಚ":96,"ನಗ":604,"ಧವ":68,"ನಕ":147,"ಧರ":218,"ದ್":2979,"ದೊ":278,"ಧನ":157,"ದೇ":1188,"ದೆ":2081,"ದೂ":324,"ಧತ":62,"ದಾ":1139,"ದಿ":2445,"ದೀ":64,"ನಂ":266,"ದು":3947,"ದಸ":55,"ದಲ":2370,"ದವ":372,"ಥ್":61,"ದರ":1541,"ಥೆ":287,"ದದ":103,"ದನ":456,"ಥಿ":158,"ಥಾ":314,"ಥವ":694,"ದಗ":126,"ತ್":6565,"ಥಮ":57,"ದಕ":447,"ಥಳ":111,"ತೇ":59,"ತೆ":663,"ತೋ":73,"ತೊ":91,"ತಾ":1049,"ತಿ":2648,"ತೀ":321,"ದಂ":194,"ತು":2278,"ತವ":560,"ತಶ":56,"ಥಗ":54,"ht ":63,"ತಹ":98,"ತಯ":76,"ಣ್":346,"ತಮ":315,"ತರ":927,"ತಲ":96,"ತತ":62,"ಣೆ":345,"ತದ":1260,"ತನ":354,"ತಪ":55,"ಪೋ":69,"ಪ್":3265,"ಬಗ":149,"ಫಿ":80,"ಬಣ":56,"ಫೆ":85,"ಬದ":151,"ಪರ":638,"ಪಯ":118,"ಪಶ":129,"ಪವ":80,"ಪು":628,"ಬಂ":329,"ಪೀ":61,"ಪಿ":494,"ಪಾ":718," ri":59,"ಪೇ":72,"ಪೆ":86,"ಪೂ":243,"ನೈ":115,"ನೊ":113,"ನೋ":140,"ನ್":5580,"ಪಕ":225,"ಪಗ":72," px":81,"ಪಟ":267,"ಪಡ":351,"ಪತ":304,"ಪದ":446,"ಪನ":246,"ನಪ":122,"hum":105,"ನನ":201,"ಧ್":402,"ನಮ":102,"ನಲ":470,"ನರ":234,"ನವ":655,"ನಸ":130,"ನಿ":2138,"ನಾ":1363,"ನೂ":140,"ನು":2795,"ನೀ":276,"ಪಂ":242,"ನೇ":1015,"ನೆ":1144,"ರಜ":113,"ಯಾ":2655,"ಯಸ":104,"ರಚ":194,"ರಕ":548,"ರಗ":490,"ಯಶ":64,"ಯವ":894,"ಯರ":301,"ಯಯ":55,"ಯಲ":992,"ರಬ":144,"ಯೋ":318,"ರಭ":83,"ಯ್":184,"ರಮ":614,"ರಯ":73,"ಯೇ":137,"ರನ":308,"ರಪ":191,"ಯೊ":109,"ರತ":1050,"ರದ":1229,"ರಧ":52,"ಯೆ":362,"ಯಿ":713,"ರಡ":219,"ಯು":1152,"ಯೂ":247,"ರಣ":519,"ಮಹ":299,"ಮಸ":60,"ಯಗ":270,"ಮವ":111,"ಯಕ":439,"ಮಲ":102,"ಮರ":288,"ಮಯ":65,"ಭ್":65,"ಯಮ":248,"ಮ್":861,"ಮೊ":334,"ಮೋ":102,"ಮೈ":166,"ಮೆ":345,"ಯನ":1088,"ಮೇ":483,"ಯದ":586,"ಮೂ":556,"ಯತ":120,"ರಂ":561,"ಮೀ":223,"ಮು":926,"ಮಾ":2202,"ಮಿ":718,"ಮಗ":156,"ಭವ":125,"ಬ್":957,"ಮಕ":218,"ಮದ":290,"ಮಧ":132,"ಮನ":323,"ಭೌ":76,"ಮಟ":57,"ಭಾ":1580,"ಭಿ":188,"ಯಂ":366,"ಮಣ":82,"ಭೂ":208,"ಮತ":1458,"ಬಹ":299,"ಬಸ":64,"ಫ್":310,"ಫೋ":52,"ಬಳ":371,"ಬಲ":150,"ಬರ":893,"ಬೆ":594,"ಬೇ":205,"ಭದ":68,"ಬೈ":80,"ಚನೆ":74," th":169,"ಬಾ":388,"ಬಿ":415,"ಬೀ":91,"ಮಂ":262,"ಬು":293,"ತರ ":414,"ೂ ":1096,"ಡದಲ":57,"ಡನೆ":57,"ಡನೇ":52,"ಾ ":1624,"ಡನ್":62,"ು ":14575,"ೀ ":229,"ಿ ":8907,"ತನ ":68,"ಹ ":251,"ಶ ":222,"ವ ":2270,"ಸ ":186,"ಷ ":133,"ತು ":1867,"ಲ ":511,"ಳ ":1320,"ತೆ ":302,"er ":60,"ಮ ":601,"ಯ ":3177,"ರ ":2974,"ತಹ ":86,"ಪ ":166,"ಡರ್":274,"ಬ ":384,"ಡಲಾ":92,"ಥ ":133,"ದ ":5745,"ತಿ ":665,"ಧ ":252,"ಡಳಿ":71,"ತಾ ":62,"ನ ":3185,"೦ ":330,"ಟೆಂ":84,"ght":64,"ಣದ ":121,"ಟುಂ":86,"ಟಿಕ":121,"ಟಿದ":82,"ಟಿನ":67,"ಟಿಯ":94,"ಟಿಸ":83,"ಣು ":78,"ಣಿ ":100,"ಣೆ ":124,"ತದ ":400,"ಟ್ರ":464,"ಟ್ಟ":861,"್ ":7021,"ಟೋಬ":94,"ೊ ":102,"ೋ ":134,"ೈ ":170,"ೆ ":6915,"ೇ ":1293,"ಟನೆ":65,"ಡ್ ":396,"ಃ ":52,"ಂ ":134,"ಞಾನ":208,"ಡೆ ":91,"ಟವಾ":66,"ಟರ್":142,"ಟ ":308,"ಜ ":97,"ತ ":1468,"ಣ ":786,"ಠ ":61,"ಡ ":654,"ಗ ":398,"ಖ ":205,"ಡದ ":222,"ಕ ":1763,"ಡು ":260,"ಟಗಾ":53,"ಟಗಳ":71,"ಡಿ ":212,"ಡಾ ":70,"ಟಕದ":131,"ಆ ":74,"ಈ ":714,"ಕಗಳ":105,"ಗು ":199,"ಗೂ ":397,"ಗಿ ":1320,"ಗೆ ":1195,"ಖಂಡ":114,"ಕಟ್":111,"ಗ್ ":190,"ಕತೆ":52,"rig":61,"ಗರ ":186,"ಗಳ ":1047,"ಗದ ":146,"ಕಂಡ":123,"ಕಂಪ":101,"ಕ್ ":357,"ಕು ":163,"ಕಿ ":188,"ಒಳಗ":120,"ಕಾ ":103,"ಕೆ ":697,"ಕರ ":75,"ಒಟ್":62,"px ":80,"ಒಬ್":183,"ಕದ ":188,"ಒಂದ":1351,"ಚಂದ":71,"ಗ್ಗ":161,"ಗ್ಲ":159,"ಗ್ಯ":52,"ಗ್ರ":702,"ಗೊಳ":102,"ಗೋರ":246,"ಗೋಳ":55,"ಚ್ ":122,"ಗೆಯ":68,"of ":53,"ಗೊಂ":193,"ಗಾಗ":97,"ಗಾಂ":64,"ಗಿನ":109,"ಗಿರ":313,"ಗಿಸ":155,"ಗೀತ":186,"ಗುಂ":62,"ಗಾರ":173,"ಗಾಲ":60,"ಗಿತ":64,"ಗಿದ":943,"ಗುರ":169,"ಗುವ":283,"ಗುಣ":80,"ಗುತ":373,"ಗಳಲ":710,"ಗಳನ":727,"ಗಳೂ":224,"ಗಳು":1084,"ಗಳಾ":97,"ಗಳಿ":589,"ಚು ":103,"ಗವಾ":67,"ಗಸ್":126,"on ":65,"ಖ್ಯ":409,"ಗರದ":116,"ಗದಲ":154,"ಗತ್":77,"ಗಣಿ":86,"ಗಡಿ":73,"ಗಗಳ":101,"ಕ್ಷ":939,"ಕ್ರ":668,"ಕ್ಯ":360,"ಕ್ತ":356,"ಕ್ಟ":186,"ಕ್ಸ":118,"ಕೋಟ":60,"ಕ್ಕ":985,"ಕೊಂ":167,"ಕೊಳ":121,"ಕೊಡ":66,"ಕೆಲ":163,"ಕೃಷ":124,"mb ":102,"ಕೃತ":250,"ಕೆಗ":100,"ಕೆಟ":113,"ಕೇಂ":134,"ಕೆಯ":206,"ಕಿಸ":52,"ಕಿರ":95,"ಕಾಸ":55,"ಕಾವ":68,"ಕಾಶ":87,"ಕಾಲ":240,"ಕಾಯ":81,"ಕಾರ":767,"ಕಿನ":176,"ಕಿತ":62,"ಕುರ":58,"ಕೂಟ":53,"ಕೂಡ":86,"ಕೀಯ":82,"ಕುಟ":89,"ಕಾಣ":65,"ಕಿಂ":74,"ಕಾನ":57,"ಕಾದ":114,"ಕಾಗ":98,"ಕಾಂ":80,"ಕಲಾ":56,"ಕಲ್":114,"ಕವಾ":159,"ಕವಿ":72,"ಕರಣ":88,"ಕರೆ":221,"ಕರಿ":97,"ಕರು":101,"ಕರಾ":121,"ಕರ್":467,"ಕದಲ":61,"ಕನ್":423,"ಉತ್":319,"ಉದ್":135,"ಉಪಯ":103,"ಎಸ್":57,"ಏಪ್":62,"್ಥೆ":228,"್ಥಾ":284,"್ಥಿ":119,"್ದವ":56,"್ದರ":183,"್ದೇ":157,"್ದು":363,"್ಧತ":61,"್ದಾ":350,"್ದಿ":75,"ಎಂಬ":368,"ಎಂದ":448,"್ಣು":59,"್ಣಿ":64,"್ತದ":721,"್ತರ":338,"್ತವ":225,"್ತನ":109,"್ತಿ":826,"್ತು":1699,"್ತೆ":63,"್ತಾ":369,"್ಥಳ":111,"್ತ್":311,"್ಪತ":108,"್ಪಡ":151,"್ಪಟ":116,"್ಪನ":87,"್ಪಾ":63,"್ಪಿ":65,"್ನಡ":386,"್ಧಿ":63,"್ಧಾ":55,"್ನಾ":402,"್ನಿ":122,"್ನೂ":64,"್ನು":2402,"್ನೆ":94,"್ನೊ":55,"್ಮಾ":125,"್ಮಿ":138,"್ಯಗ":175,"್ಯಕ":269,"್ಮದ":87,"್ಮನ":56,"್ಯಂ":192,"್ಯು":176,"್ಯಾ":1532,"್ರಜ":97,"್ರಗ":251,"್ಯವ":564,"್ರಕ":297,"್ಯರ":131,"್ಯಮ":116,"್ಯಯ":54,"್ಯನ":119,"್ಯದ":366,"್ಮೆ":64,"್ಯತ":58,"್ಬರ":145,"್ಮಕ":73,"್ಲೂ":97,"್ಲಾ":202,"್ಲಿ":4561,"್ಲದ":116,"್ಳು":109,"್ಳಿ":142,"್ಲೊ":95,"್ಲೇ":124,"್ಲೆ":484,"್ಲ್":60,"್ರವ":349,"್ರಶ":142,"್ರಸ":283,"್ರಹ":151,"್ರಾ":846,"್ರಿ":942,"್ರೀ":518,"್ರು":70,"್ರತ":249,"್ಯೂ":155,"್ರಣ":55,"್ರದ":625,"್ಯೆ":160,"್ರಪ":133,"್ರಮ":468,"್ರಭ":71,"್ರರ":86,"್ರಯ":66,"್ರೆ":357,"್ರೈ":58,"್ರೇ":163,"್ರ್":78,"್ರೋ":120,"್ಕ್":92,"್ಕರ":72,"್ಕೃ":119,"್ಕೂ":68,"್ಕು":73,"್ಕೆ":541,"್ಕಿ":142,"್ಕಾ":226,"್ಚಾ":65,"್ಚಿ":204,"್ಚು":144,"್ಗೆ":104,"್ಟರ":54,"್ಟಣ":72,"್ಟದ":57,"umb":108,"್ಞಾ":215,"್ಚ್":78,"್ತಕ":66,"್ಣವ":52,"್ಡ್":103,"ಎಎಎ":72,"್ಟೆ":135,"್ಟೋ":119,"್ಟ್":671,"್ಟವ":59,"್ಟಿ":399,"್ಟಾ":78,"್ಟು":217,"ಎತ್":68,"್ವವ":82,"್ವರ":147,"್ವಿ":108,"್ವಾ":248,"್ವಹ":80,"್ಶನ":54,"್ವೀ":99,"್ವದ":124,"್ವತ":116,"್ಷರ":65,"ಎಲ್":119,"್ಷಿ":380,"್ಷೇ":121,"್ವ್":52,"್ಷಗ":60,"್ಷಣ":115,"್ಷದ":530,"್ಸ್":339,"್ಷ್":53,"್ಸೆ":62,"್ಸಿ":119,"ಎನ್":124,"thu":103,"ಎರಡ":156,"the":64," ಆ ":74," ಈ ":713,"ೋಗಿ":116,"ೊಳಿ":52,"ೊಳ್":156,"ಂಸ್":307,"ೊಮ್":67,"ಂತೆ":162,"ಂತ್":364,"ಂತರ":298,"ೋಬರ":94,"ಂತಹ":96,"ಂತಿ":112,"ಂತಾ":62,"ಂದೆ":162,"ಂದೇ":82,"ಂದ್":319,"ಂಧಿ":104,"ಂದರ":313,"ಂದಿ":541,"ಂದಾ":143,"ಂದು":2122,"ಂದೂ":183,"ಂಡದ":109,"ಂಡರ":290,"ಂಟ್":69,"ಂಡ್":203,"ಂಡಿ":293,"ಂಡು":195,"ೋತ್":57,"ಂಭವ":62,"ಂಬು":192,"ಂಬಿ":59,"ಂಬಾ":53,"ಂಬರ":342,"ಂಯು":54,"ಂಪ್":93,"ಂಬಂ":87,"ಂಪು":57,"ಂಪಿ":53,"ೋಡಿ":64,"ಂಪನ":65,"ಅಂದ":78,"ಅಂತ":160,"ೋರಾ":52,"ೋರಿ":296,"ೋರ್":74,"ೈಸೂ":88,"ೈಸ್":52,"್ಕ ":65,"್ಗ ":60,"ೊಂಡ":342,"ೊಂದ":551,"್ಣ ":181,"್ಡ ":146,"ಂಕ್":62,"್ದ ":187,"ಂಗಳ":447,"ಂಖ್":129,"ಂಗದ":91,"ಂಗಡ":60,"್ಧ ":174,"್ತ ":281,"ಂಕರ":53,"್ಥ ":67,"ಂಚದ":64,"ಂಗೀ":161,"ಂಗಾ":120,"ಂಗ್":337,"್ಟ ":206,"್ಲ ":152,"ೊದಲ":197,"ೊಬ್":70,"್ಷ ":91,"್ವ ":146,"್ಪ ":91,"ೊಟ್":56,"್ನ ":174,"್ರ ":555,"್ಯ ":846,"್ಮ ":242,"್ಬ ":139,"ೊಡ್":169,"ಇದು":518,"ಇದೆ":55,"ೆಪ್":108,"ಇದರ":166,"ಇದನ":181,"ೆಬ್":91,"ಇನ್":84,"ೆದು":87,"ೆದಿ":70,"ೆನ್":134,"ಇತಿ":65,"ಇತರ":85,"ೆಲ್":157,"ೆಳೆ":86,"ೆಳಗ":64,"ೆಲವ":94,"ೆಲೆ":75,"ೇಖಕ":54,"ೇಖನ":56,"ೆಯಲ":526,"ೆಯು":360,"ೆಯಾ":224,"ೆಯಿ":119,"ೆಯನ":236,"ಆಸ್":78,"�":222,"ೆರೆ":114,"ೆರಿ":98,"ೆಸರ":280,"ಆರ್":99,"ೆಸ್":116,"ೆಸಿ":79,"ಆಫ್":99,"ೇತ್":125,"ೇಶವ":74,"ೇಶ್":84,"ೇಶಿ":67,"ೇಶಗ":141,"ೇಶಕ":79,"ಉಂಟ":54,"ೇವೆ":92,"ೇಶದ":265,"ೇವಾ":53,"ೇವಿ":64,"ೇಲಿ":68,"ೇಲೆ":114,"ೇರಿ":374,"ೇರೆ":53,"ೇರು":61,"ಇವರ":508,"ಇಲ್":125,"ಇರು":142,"ಇಪ್":83,"ಅತಿ":137,"ಅತ್":191,"ಅಥವ":638,"ೇಶ ":126,"ಅಕ್":155,"ೆಂಗ":155,"ೆಂಬ":309,"ೆಂಟ":57,"ೆಂಡ":313,"ೆಂದ":240,"ಇಂಡ":64,"ಇಂದ":55,"ಇಂಗ":69,"ಆದರ":63,"ಅಸ್":52,"ಆಗಸ":106,"ಆಗಿ":88,"ೆಗಳ":621,"ೆಗಾ":62,"ೆಗೆ":326,"ೆಗೊ":53,"ೆಗೋ":241,"ಅರ್":136,"ಅಮೇ":112,"ಅಮೆ":58,"ೆಕ್":125,"ಅವರ":214,"ಅವು":57,"ಅಲ್":103,"ೆಚ್":218,"ೆಟ್":262,"ಅನು":103,"ಅಧ್":96,"ಅನೇ":75,"ಅನ್":71,"ೇಂದ":169,"ಅದರ":105,"ಅಧಿ":313,"ಅದು":55,"ಅಭಿ":89},"n_words":[514512,567770,395860],"name":"kn"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/kor b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/kor new file mode 100644 index 000000000..1f30ef966 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/kor @@ -0,0 +1 @@ +{"freq":{"정리이":69,"바뀌었":102,"²":131,"·":6405,"×":65,"í":141,"é":560,"è":77,"ç":72,"젤레스":103,"ä":74,"á":169,"ü":183,"ö":136,"ó":126,"참여했":93,"ā":193,"ī":75,"참여하":278,"방글라":64,"ˈ":80,"́":127,"μ":101,"ν":231,"ο":310,"ι":218,"κ":112,"λ":169,"δ":75,"ε":146,"η":94,"α":368,"β":61,"γ":80,"ά":91,"ί":112,"ω":66,"ό":88,"σ":105,"ς":279,"ρ":207,"개발 ":675,"π":78,"υ":78,"τ":170,"ь":58,"я":64,"ы":64,"ч":103,"р":321,"с":201,"т":190,"у":110,"К":57,"С":60,"л":238,"к":231,"й":118,"и":464,"о":480,"н":337,"м":118,"г":82,"в":283,"а":488,"е":318,"д":121," ·":941,"장이었":82,"람이 ":326,"و":102,"ي":163,"ل":186,"م":122,"ن":119,"د":84,"ب":85,"ا":266,"س":58,"ر":100,"람의 ":253,"사상가":98,"산에 ":201,"았다 ":914,"미리 ":99," К":57,"포트 ":65,"놓고 ":101," С":60,"사와 ":395,"산업 ":379,"미를 ":234," ا":105,"람은 ":91,"래에 ":110,"람을 ":297,"물질을":114,"로그 ":136,"물질이":123,"물질의":91,"미르 ":149,"농구 ":70,"생명과":67,"장인물":96,"정리로":90,"장으로":586,"나에서":75,"야기 ":98,"전문적":89,"전송 ":81,"크기가":57,"이팅 ":102,"아들 ":170,"설로 ":135,"나오는":326,"인트 ":75,"· ":502,"의회 ":231,"장이다":475,"랑을 ":65,"사원 ":75,"라질 ":121,"롭게 ":172,"방검찰":64,"사용 ":140,"렸다 ":419,"생산 ":224,"안된 ":100,"é ":165,"란시스":115,"키고 ":206,"서대문":75,"가로서":123,"ể":108,"∼":121,"사이 ":125,"정서 ":66,"찰청 ":197,"사인 ":233,"사일 ":104,"프가니":112,"날에는":70,"따른 ":260,"바라 ":72," ∼":97,"사의 ":834,"가리킨":657,"가리키":646,"서만 ":126,"가마쿠":67,"종교적":110,"딸로 ":77,"사상의":73,"사상이":110,"사상을":91,"표에 ":65,"차이를":67,"야구 ":394,"러드는":78,"생명체":80,"서를 ":347,"성남시":83,"거는 ":139,"코프 ":86,"소가 ":256,"ああ ":309,"밀도는":453,"련된 ":456," 《":4309," 》":621," 〈":549," 『":98," 「":147,"㎞":62,"사적 ":294,"㎢":2033,"㎡":66,"초대 ":388,"가리아":156,"생물학":287,"키가 ":87,"애나 ":67,"ㆍ":388,"あ":1627,"》":5027,"《":5040,"〉":601,"〈":607,"』":119,"『":118,"」":186,"「":184,"가르침":80,"사전 ":487,"ア":1597," ㎞":62," ㎢":2029,"산의 ":346,"알고리":206,"장치 ":174,"아동 ":67,"산이 ":146,"전시 ":66,"크다 ":72," あ":325,"정상 ":60," ア":198,"산은 ":120,"않다 ":121,"백과사":636,"전반에":79,"드시 ":89,"사소송":106,"산을 ":359,"제르바":102,"크는 ":102,"전반적":63,"로구 ":380,"생물의":77,"사자 ":61,"처리하":131,"론과 ":129,"배경으":124,"사장 ":72,"세네갈":68,"남쪽 ":131,"않는 ":497,"바로 ":210,"민들의":77,"이토 ":77,"성된 ":636,"랑스에":91,"랑스어":228,"랑스와":71,"민들이":87,"나이며":210,"남아시":146,"들어 ":501,"악단 ":108,"》에서":140,"내지 ":84,"乱":136,"乩":112,"乞":60,"乙":3650,"乘":609,"乎":59,"么":100,"之":14530,"丹":2134,"丼":110,"临":105,"丫":150,"中":433,"両":683,"並":12874,"丙":894,"丘":5494,"丛":58,"丟":765,"丞":224,"丑":412,"专":172,"丕":293,"且":380,"丈":1178,"三":20984,"성동 ":77,"세대 ":267,"一":284,"丁":10402,"万":311,"仕":271,"仗":58,"亳":204,"人":513,"亥":108,"亨":114,"프는 ":76,"亞":4771,"亟":76,"亀":254,"亂":4287,"于":245,"성공회":174,"佇":187,"佛":194,"佐":64,"미디어":463,"조건을":75,"俘":194,"侶":558,"侃":89,"侏":196,"세계의":336,"자이자":420,"세계적":310,"자이언":74,"세계에":387,"나이다":1203,"남아메":109," 冲":247,"럭비 ":120,"이터 ":437," 兌":119,"아닌 ":431,"년대부":66,"것과 ":178," 僅":104,"咀":213," 傭":293,"개를 ":145,"吾":169,"圓":737,"國":1227,"在":61,"차원의":57,"国":85,"차이다":148,"조는 ":153,"冲":466," 丙":282," 丘":1641," 丟":262," 丞":90," 丑":173," 丕":104," 丈":484," 三":5820," 一":101," 丁":2901," 万":65,"남아프":161,"작용하":94,"兌":396,"傭":628,"傀":77,"무총리":119,"약간 ":80,"僅":349,"倣":128,"倉":3517,"倖":139,"드와 ":234," 侶":151,"차이나":64," 俘":77,"厥":67," 倉":1228," 佛":82," 佇":65,"정부 ":492,"라에서":173,"자유주":102," 侏":88," 人":94," 亳":67," 仕":88," 両":199," 並":3333," 中":269," 丹":1249," 之":4377," 乘":159," 乙":1383,"자전거":100," 亂":1372," 亀":76," 于":69," 亞":903,"유하는":80,"로나 ":78,"감독하":72," 大":668,"드에 ":180,"尙":86,"彦":59,"차이가":126,"자이며":181,"年":139,"랑스의":605,"남아있":64,"大":1261,"세기경":68," 吾":77," 咀":127,"쟁이 ":102,"세계화":76,"작이다":110,"유하고":203,"때로 ":69,"아는 ":196," 圓":305," 國":341,"발로 ":61,"세기부":84,"月":80,"인천광":247,"이트 ":656,"반대로":62,"이틀 ":64,"디렉터":60,"日":322,"敎":382,"拼":71,"바르 ":85,"바른 ":114,"셔널 ":194,"너먼트":71,"드어 ":66,"체되었":67,"표적 ":60,"센고쿠":141,"전문대":61,"바니아":130,"렸던 ":58,"년대에":224,"제로는":86,"거나 ":1548,"淸":143,"포함 ":105,"받는다":110,"나이티":86,"편하여":83,"나이트":65,"재연구":60,"상스 ":59,"나치 ":142," 敎":71," 日":116,"있지만":276,"사에 ":412,"ος":126,"眞":108,"的":166,"개되었":111,"사업 ":385,"노동 ":64,"키기 ":205,"상북도":406,"ς ":268,"전문가":188,"랑수아":66,"물체의":76,"서로 ":648,"α ":114,"爲":79,"의할 ":57," 淸":90,"전사 ":94,"임진왜":116,"의해 ":1904,"남으로":73,"아노 ":115,"크기의":78,"세기에":313,"의학 ":91,"의한 ":415,"장에서":426,"세기의":90,"유형문":67,"창시자":86,"밴드 ":173,"래의 ":272,"장애인":188,"자치 ":104," 眞":65,"자적인":76,"제부 ":75,"硏":108,"인텔 ":106,"의하고":60,"자치도":165,"자치단":144,"응하여":78,"가문 ":83,"ск":57,"람에게":86,"입한 ":113,"정부의":282,"개념이":228,"개념을":110,"개념으":199,"때는 ":184,"저우 ":125,"라이다":188,"라이더":86,"산식품":614,"표준 ":235,"라이나":257,"녀는 ":98," · ":456,"갖는다":62,"나의 ":717,"а ":76,"절에 ":78,"라이브":286,"й ":90,"의하는":116,"н ":64,"성되었":222,"성되어":523,"내부에":78,"в ":66,"내부의":59,"크로 ":125,"라이버":78,"상적 ":74,"어가 ":375,"남아 ":134,"가들의":84,"아를 ":247,"가들이":99,"ч ":81,"라이며":60,"아르 ":58,"ко":62,"ич":83,"세를 ":145,"ор":58,"ов":121,"но":66,"악단이":78,"ви":93,"ан":66,"첫번째":86,"반대하":127,"정부를":59,"색의 ":117,"재지이":107,"적에 ":98,"驿":62,"라이언":123,"라이온":80,"鬪":67," 靑":75,"라이스":87,"민법 ":58,"색을 ":142,"나인 ":170,"색은 ":70,"성모 ":93,"나이 ":96,"라이선":82,"아니라":536,"로는 ":3890,"정보통":139,"처에 ":89,"간되었":75,"전에 ":1190,"드리아":129,"청북도":246,"아니아":146,"표시하":91,"이터베":227,"최근 ":95,"년대 ":557,"이터를":186,"서부 ":369,"아니스":70,"鎭":93,"않는다":348,"송국 ":85,"초로 ":510,"인터내":76,"정보화":76,"인터넷":668,"난을 ":59,"정부에":116,"정부와":65,"임한 ":86,"靑":123,"자치구":154,"인터페":232,"감독을":67,"아누스":72,"감독의":83,"감독이":123,"타고 ":84,"아로 ":63,"적인 ":4808,"적이 ":256,"총괄하":84,"꾼":109,"꾸":368," 갈":698," 각":2309," 가":18345," 간":2103," 같":2403," 개":12530," 객":258," 값":267," 감":1783," 갑":208," 갖":887," 강":4617,"꿈":119,"꿀":77,"꼬":171,"꼭":124,"꼴":114,"꼽":179,"저장 ":80,"꽃":296,"꺼":75,"께":1579,"껍":85,"긴":797,"기":57951,"길":1653,"글":2723,"긍":81,"긋":58,"금":4364,"급":4129,"깥":84,"깨":247,"깔":123,"깝":68,"깃":99,"김":2072,"깊":200,"까":5090,"권":5693,"궁":939,"궐":79,"궤":302,"귀":1039,"전은 ":325,"규":2589,"균":820,"근":3205,"그":19235,"극":2043,"관":22357,"괄":288,"광":6130,"괴":686,"이트로":57,"교":18288,"구":31163,"국":45098,"굴":660,"굳":64,"군":9174,"굿":62,"굽":77,"겐":407,"겔":142,"겉":64,"게":11654,"것":8442,"검":1618,"겸":469,"겹":91,"겼":193,"경":17015,"결":4818,"격":2956,"겨":1106,"겪":88,"견":1448,"겠":90,"물학 ":86,"계":15438,"과":26837,"곽":179,"공":20325,"곰":87,"곱":284,"곳":1654,"골":1102,"곤":459,"곧":180,"곡":2975,"고":47107,"값":459,"갑":443,"감":2792,"갖":908,"강":6713,"갔":159,"같":2537,"객":963,"개":15756,"가":55413,"각":5239,"간":9024,"갈":1359,"갱":78,"갤":95,"걀":59,"건":6543,"거":8987,"걸":1105,"아니다":144,"라운드":96,"날의 ":126,"점에 ":197,"전을 ":820,"버그 ":126,"이트를":58,"반드시":88,"드리드":67,"램을 ":192,"이티드":93,"전의 ":495,"발되었":131,"작한 ":541,"라오스":74,"져서 ":63,"널리 ":525,"사연구":82,"전이 ":205,"전인 ":79,"의회는":86," 뛰":288,"콘텐츠":192,"몇":457,"명":15332,"몰":624,"몽":572,"몸":435,"못":710,"몬":786,"모":11378,"목":6926,"멘":418,"멜":262,"메":5400,"멕":373,"멍":84,"멀":284,"멸":484," 뚜":58,"며":20876,"면":9744,"멤":213,"먼":1045,"머":1633,"먹":424,"므":521," 러":1462," 럭":156," 런":332," 레":2242,"산업기":64," 렌":152,"발달하":67,"믹":261,"미":17448,"믿":187,"민":16451,"흑해 ":60,"뮌":153," 랭":89," 랩":96," 랴":57,"뮤":598,"뮬":208," 띠":142," 라":5313," 락":86,"의하면":109," 람":83," 란":706," 래":122," 랜":122," 랑":74," 뜨":65,"묘":914," 뜻":2081," 띄":61,"물":10422,"묻":74,"문":17304,"묶":127,"무":13084,"묵":131," 디":2243,"룰":113,"룽":97,"룹":837,"룸":158,"룡":457,"룬":460,"루":6886,"룩":203," 등":10121," 들":1303,"료":2691,"뢰":281,"조를 ":342," 득":75," 드":1545," 듀":145," 뒷":121," 뒤":936,"롱":332,"롭":295,"롬":294,"롯":651,"롤":575,"론":3597,"로":96384,"록":4253," 둥":104,"례":1168," 둘":552,"렸":708,"령":3201," 두":3055,"렴":153," 둔":309,"렵":166,"련":2464,"렬":396,"력":5587,"려":5019,"렛":83,"렘":205,"렐":151,"렉":716,"레":10369,"렌":918,"렀":295," 될":193,"렇":142,"매":4904,"맥":997,"맡":729,"맨":507,"맷":142,"맵":77," 또":8172,"맺":226,"맹":992,"링":1187,"만":12443,"많":2444,"작품 ":175,"마":15987,"막":1783,"말":8244,"망":1651,"맞":936,"맛":168,"리":49017,"릭":1201,"린":3639,"릴":663,"릿":184,"립":9031,"림":3191," 떠":221,"름":4869,"릇":64," 떨":873,"릉":452,"륭":84,"륨":139,"률":1185,"를":36449,"른":4259,"반도체":99,"르":15981,"륵":60,"륜":185,"류":4914,"륙":763," 때":4328,"발매 ":81," 땅":251,"뤼":174,"자치시":91,"뤄":108," 딸":364," 따":3445," 딴":80," 몽":316," 못":580," 몸":407," 몰":372," 몬":267," 모":6818," 목":4311,"뻗":112," 묘":385,"블":1922,"븐":182," 먼":230," 머":458," 먹":353,"브":4958," 메":2219," 멕":332," 멜":173," 멘":88," 멀":265,"빗":71," 면":2578,"빛":405,"반도에":120," 멸":242,"빙":357,"빅":263," 멤":202,"비":15033,"빈":832,"빌":1411,"빵":82,"빼":105,"빠":443," 명":7874," 몇":341,"빨":181," 뮤":321,"전용 ":96,"뿌":188," 미":9777,"최고 ":196," 민":2788," 믿":184,"뿐":444,"뿔":93,"램의 ":106," 및":5809," 밀":1074," 받":1853," 반":3359," 밝":338," 발":8680," 밑":142," 밖":243," 박":1386," 바":4874,"뼈":195," 무":4302," 묵":81," 묶":123," 물":2886," 문":7777," 묻":68,"뽑":108," 뮌":99,"래스카":63,"벽":406,"벼":128,"벳":78,"벨":1138,"베":5169,"벡":239,"벤":610,"벗":142,"법":11136,"범":2511,"번":6501,"벌":1869,"버":5133,"볼":1272,"본":10004,"복":3536,"보":17044,"반도의":107,"병":2570," 루":1582,"별":5261,"변":3473,"배":4005,"백":2909,"밴":506,"밸":82," 로":5189," 록":326,"밥":125,"밤":208,"방":12878,"밭":81,"밑":146,"밖":309,"바":9518,"박":2316,"받":2627,"반":9065,"발":14073,"밝":341,"밀":2017,"및":5896,"밍":463," 롱":64,"뱅":123," 롤":179,"뱀":171," 론":58," 롯":72," 마":7115," 막":816," 많":2225," 만":6286," 링":189," 맛":124," 맞":858," 망":371," 말":7151,"불":5804,"붉":133," 리":3407,"부":33314,"북":7080,"분":9424,"붙":797," 린":107,"붓":60,"붕":269," 릴":78,"문학 ":248,"뷰":194," 맨":215," 매":2433," 맥":407," 맡":725," 맹":113,"코틀랜":227," 맺":219,"뷔":356," 류":171,"봄":175,"봇":228,"봉":1368," 뤼":59,"미로는":60," 르":285," 를":2001," 깨":169,"뉘":227,"뉜":158,"뉴":2112,"눌":108,"눈":377,"눅":106,"누":1558," 길":1008," 긴":363,"눔":57," 기":21288," 까":271," 깊":185," 김":1910," 깃":81,"니":10368,"닉":426,"닌":1054,"닐":137,"닛":171,"님":381,"닝":259,"살았던":73,"다":127946,"닥":218,"단":12729,"닫":65,"달":3219,"닭":75,"닮":58,"답":174,"담":2045,"닷":134,"당":8583,"닿":168,"늄":159,"는":119185,"느":753,"늘":901,"능":2952,"늦":65,"늬":121,"던":5053,"덜":472,"더":3069,"덕":1078,"델":977,"데":8452,"덱":63,"덴":904,"덩":135,"덮":120,"덧":84,"덤":174," 꼽":102,"댐":73,"자치주":85," 꼭":115," 꼬":116,"댄":184,"대":50380," 꽃":178,"돕":110,"돔":57,"동":26013,"도":42958,"독":6183,"돈":384,"돌":1249,"돼":177,"상시키":58," 꾸":91,"전세계":81," 꿈":78," 게":2860," 겉":64," 검":993," 것":7525,"끼":482," 겐":93,"끌":362,"끊":85,"끈":119,"끄":190,"끝":732,"뒤에 ":105," 걸":1004," 건":2744,"끔":84," 거":3157,"뀌":174,"사업에":67," 갤":90,"냥":141," 관":8286," 광":2185," 곧":169," 곤":198," 고":8430," 곡":823,"냈":722," 골":477,"냉":198," 공":10814," 곳":1375," 곱":95,"냐":427," 곰":60," 과":4291,"날":1685," 계":3522,"남":10366,"납":236,"났":694,"낭":223,"낮":351,"낱":236,"낳":117,"내":7694,"낸":788,"낼":133," 겪":88," 겨":197," 격":403," 견":241,"낌":58," 결":2608,"낚":60," 겹":79,"낙":450," 겸":396,"나":29545," 경":10290,"난":2693,"논":1278,"노":7620,"녹":472," 권":1787," 궁":394," 굴":151,"라우저":117,"녕":139," 군":3102,"념":1682," 굳":62," 국":11641," 구":9126,"년":50612,"녁":59,"녀":836," 교":6257,"넷":970,"넨":74,"넬":161,"넣":275,"넥":130,"네":5012,"넘":422,"널":1956,"넓":520," 괴":232,"너":1765,"넌":123," 글":778," 긍":64,"뇨":62," 금":1723," 급":1151," 근":1629," 극":746," 그":13695," 균":198,"뇌":397," 규":1420," 귀":590,"의해서":178,"사업이":73,"놓":470,"높":1411,"사업으":67,"사업을":303,"놀":416," 궤":202,"놈":67,"사업의":104,"농":2894,"또":8222," 뉴":1506," 느":260," 는":22679," 늘":155," 늦":61,"적은 ":2122," 능":471,"뚜":90," 닌":150," 니":852," 닛":81,"자치체":176,"의하여":356," 단":4273," 닮":58," 달":1640," 닭":57," 다":9191," 닥":60," 당":2886," 닿":61," 담":1163," 대":30352," 댄":143,"뛰":296,"개로 ":124," 더":1674," 덕":284,"적을 ":427,"뜻":2127," 던":104,"뜨":161," 데":3003," 덴":317," 델":206,"띄":63," 덧":76," 덩":92," 덮":105,"라":32052,"락":940,"띠":194,"랜":2761,"랙":360,"래":5947,"랑":3926,"랐":156,"람":3445,"랍":361,"랄":216,"란":5893," 동":9304," 돕":101,"략":655,"랴":119," 돌":648,"랭":236,"랫":313," 돈":178,"램":1320,"랩":147," 도":8642," 독":3941,"드로이":60," 돼":72,"량":2327," 되":3560,"럿":63,"럽":1862," 된":1374,"럼":922,"런":983,"럴":253,"러":8043,"럭":336,"될":754," 끈":60,"됨":160," 끊":84," 끌":148," 끝":706,"됐":304,"되":20943,"된":15250,"둥":406," 난":587," 나":7418," 낙":348,"둔":452,"두":5194,"둑":155," 끼":191,"둘":641," 냉":157,"사에서":413,"뒤":1008,"반면 ":75,"뒷":122," 남":6428," 납":167," 낮":336," 낭":128," 날":631," 낸":132," 낳":116," 낱":228," 내":4309,"듬":206,"듭":58,"듯":149," 너":176,"들":14979,"든":2442," 넘":356,"등":12499," 널":543," 넓":459,"듈":72,"듀":325,"득":672,"드":16369,"따":3543,"딱":94,"딴":97,"딸":420," 년":48504,"딩":848,"디":7187,"딕":142," 넷":115,"딘":221,"딜":107," 넣":235," 넥":74," 네":2034," 높":1360," 놓":344," 놀":187," 농":2185," 논":982," 노":3844," 녹":420,"땅":275,"때":4902,"떻":123,"너무 ":59,"떨":893,"적의 ":167," 뇌":233,"떠":388,"떡":75,"떤":684," 눈":259," 누":647,"최":4895," 즉":844," 즐":195," 증":1529,"촌":871,"초":5803,"촉":534,"총":3611,"촬":196," 쥐":90," 짧":228,"취":1270,"책으로":129,"번길 ":62,"출":6229,"춘":568,"추":3536,"축":3493,"충":2231," 질":809,"춤":162," 진":3320," 직":1757," 지":18217," 짜":63," 징":255," 짐":132,"춰":72," 집":1925," 짓":61," 족":223," 조":9648,"챔":331," 존":1937,"품에 ":127," 졸":350,"채":1834,"책":2191," 좀":85," 좁":161," 종":5121," 좋":260," 좌":466," 젠":66,"찌":102,"찍":137,"찰":1432,"찾":410,"창":3609,"참":2285,"찬":711,"차":8220,"착":921," 주":18427," 죽":642,"쳐":1531," 중":15239," 준":801,"쳤":211," 줄":1147,"천":5793,"처":4102,"척":639,"첼":120,"첸":85,"체":12407,"청":5830,"첫":1006,"첩":200,"첨":248," 죄":242,"철":3109,"콤":255,"콥":103,"콩":581,"콰":92,"콕":119,"코":6706,"콜":1028,"가루 ":61,"콘":1127,"켰":242,"케":2788,"켄":203,"켈":258,"켓":371,"켜":465," 찍":69,"쿨":196,"쿤":100,"쿠":2769,"쿼":162,"쿄":510,"뮤직 ":109,"차지했":173,"쾌":99,"차지하":297,"차지한":93,"카":9618,"칼":897,"칸":851,"칠":510,"칭":3334,"침":1007,"칩":118,"친":1771,"칙":994,"치":17866,"층":1482,"츠":2145,"측":1172,"컷":121,"컴":2082,"컵":693,"컬":664,"컫":637,"컨":597,"커":1445,"하게 ":1996,"캡":77,"캠":218,"캘":291," 쪽":266,"캐":1331,"캔":130,"캄":196," 씨":235,"줄":1396,"준":5183,"중":19356," 알":4152," 안":3009," 않":2884,"상업 ":66," 아":13909," 악":593," 앞":452," 앙":302," 압":445," 암":698," 앨":831," 애":1646," 액":406," 앤":321,"남서부":201," 약":2469," 야":1729,"쥐":185," 앵":118," 얇":61," 양":2789,"즌":623,"즉":849,"즈":4475," 어":3828," 억":453,"즐":322," 얼":375,"증":2825," 얻":540," 언":2186,"즘":584," 업":1023," 엄":237," 없":1907," 엔":883," 에":9796," 엑":221," 엘":468,"직":4986,"지":53776," 엠":95,"진":12339,"질":3981," 역":3833," 여":5825,"짓":174," 연":8997,"짐":242,"집":3847," 열":2188,"징":1361," 염":317,"짜":260,"짝":66," 영":8578," 였":167,"짧":228," 옆":106," 예":3334,"째":2610," 옛":404,"젝":447,"제":29441,"정":32064,"접":3114,"점":4065,"절":1922,"젊":125,"전":32225,"저":3863,"적":24870,"져":2433,"젤":356,"젠":397,"졌":1373,"남은 ":81,"졸":392,"족":4176,"설립 ":259,"조":17636,"존":3442,"종":10038,"좁":164,"좀":88,"좌":857,"좋":275," 쓰":2084," 쓴":417," 쓸":74,"죄":910,"주":32946,"죽":799,"제목으":67,"때까지":243," 음":3514," 읍":148," 은":18917," 을":2254," 의":13217," 응":652," 율":199," 유":10518," 육":1054," 윤":588," 으":1482," 융":126," 잎":227," 있":30440," 잉":461,"내어 ":68," 임":1668," 입":1910," 잇":347," 잃":123," 잘":752," 잔":258," 작":5027," 자":10494," 읽":214," 일":35680," 인":14925," 익":323," 이":43056,"가니스":126," 잡":554," 잠":484," 장":5226," 잭":118," 재":4073,"쯤":58," 전":16035," 적":1958," 저":2089," 절":733," 젊":120," 정":13855," 점":1342," 접":1777," 제":14773,"록된 ":160," 왜":181," 왕":3468," 왔":270," 와":1869," 완":998," 옹":146,"이하 ":136," 옵":60," 옷":75," 온":1154," 올":1715," 옮":203," 오":7708," 옥":336," 욕":102," 요":2831," 왼":84," 외":2265," 원":4962," 월":24581,"쪽":5565," 움":282," 웅":75," 워":458," 우":4532," 운":3277," 울":664,"이한 ":104," 용":2153,"킨다 ":728," 위":16296," 윌":374,"쟁에서":112," 윈":737," 웰":69,"쫓":57," 웹":637," 웨":474,"엘":1142," 쇼":552,"에":103036,"엑":271,"엔":1496,"었":13976," 쇠":160,"엇":117,"없":2196,"업":9251,"엄":815," 수":15278," 숙":319," 순":1149,"염":794,"엽":300,"연":14124,"열":3577,"역":14028,"여":21379,"엠":137,"인한 ":217,"양":9401,"얇":61,"얄":66," 송":804,"얀":299,"얼":821,"언":4279,"남의 ":128,"얻":540,"어":34822,"억":684," 셰":135,"앗":139,"압":954,"암":1495,"앙":2107," 셸":66,"았":1705,"앞":482,"아":34158,"악":3379,"않":2900,"안":8284,"알":4503," 손":892,"앵":203," 솔":307,"약":5189,"야":6719,"애":2683,"액":892,"앤":486,"앨":898," 소":11517," 속":3191," 성":6301," 센":729," 섹":60," 세":12291," 설":6591," 선":5904," 섬":1862," 섭":109,"살인 ":59," 셀":192,"씬":77,"씨":1169,"씩":216," 셋":131," 샤":410,"쓸":88," 섞":117," 서":10967," 석":713,"ال":101,"쓰":3096,"쓴":426," 삭":82," 사":27351," 삼":1735," 삽":115," 살":1329," 삶":242," 산":3915," 샌":184," 색":449," 새":1434," 상":6949," 생":4620," 샘":83,"·기":95,"쑤":93,"하고 ":9739,"천시 ":225,"내에 ":438,"쟁":2447,"잭":163,"재":12501,"잡":1143,"잠":605,"장":20415,"잘":775,"자":37700,"작":11270,"잔":750,"잉":715,"있":31718,"잎":326,"잃":128,"잇":387,"입":4066,"임":6953,"익":1489,"이":165423,"읽":225,"일":45548,"인":47192,"응":1476," 썼":110,"의":128021,"을":57826,"은":55316,"음":8005,"읍":818," 써":106,"융":702,"으":50795,"유":15783,"육":5384,"윤":825,"율":1139,"윗":76,"위":24705,"윈":893,"윌":390," 쌍":317,"웨":2585,"웠":203," 쌀":75,"웹":654," 쌓":108,"웰":170," 십":304,"워":2364," 심":1298,"웅":321," 실":3412,"움":1073," 신":6386,"웃":221," 싸":282,"월":25278,"원":21744," 싱":605,"용":15333,"울":4973," 시":17424," 식":1730,"우":13058,"욱":203,"운":8938," 슬":354," 스":7245,"상에 ":382," 승":1448,"요":6682,"욕":736," 습":160,"아나톨":89," 슈":770,"왼":87,"외":4313,"완":1509,"와":17969," 쉬":131,"왈":71,"왕":5728,"왔":670," 쉽":226,"왜":332,"오":14295,"옥":684,"온":2639,"옮":206,"올":2277,"옷":147,"옵":67,"옴":62,"옹":454," 술":278,"였":9350,"영":13611,"옆":120," 숨":146,"예":5314," 숫":155,"옌":106," 숭":142," 숲":99,"옛":409,"솔":474,"손":1670,"속":9079,"소":20178,"하계 ":200,"송":3868," 뷰":70,"쇄":396," 블":858,"아래 ":167,"쇼":889,"쇠":250," 브":1829,"섞":131,"석":3098,"서":56814,"센":1955,"섹":86,"세":16513,"성":22377,"섬":2116,"섭":330,"섯":386,"설":10723,"선":15146,"션":2286,"셜":299,"셔":528,"셋":215,"셈":160,"셉":104,"셀":498," 붙":702,"셸":100,"셰":320," 붕":186," 불":4668," 붉":127," 부":9201," 북":4515," 분":5145," 벤":222," 벡":158," 베":2451," 벨":486,"전부터":113," 벼":76," 벽":136," 별":990," 변":2214,"삭":178,"사":52637,"삶의 ":107,"삶":243,"살":2436,"산":15857," 병":912,"삼":2361,"삽":121,"상":21682,"색":2020,"새":1818,"샌":195," 보":8766," 복":1706," 본":2950,"샘":118," 볼":809,"생":10052," 봄":131,"샤":806," 봉":588,"샹":63," 방":5542," 밤":177," 밥":73," 밴":412," 백":1337," 배":2328," 뱀":75,"청사 ":99,"아랍 ":69," 번":5470," 벌":737,"은행이":86," 버":1308," 벗":132," 법":2859," 범":953," 뿐":232,"일컫는":617," 뿌":163,"선되었":89,"따로 ":85,"쏘":63," 뽑":105,"·관":58,"·공":88,"쌓":116,"쌍":397,"쌀":100,"법과 ":132,"썼":127,"·교":69,"써":1331,"스":47455,"슨":692,"슭":65,"슬":1694," 뻗":111,"슷":450,"책이다":168,"슴":118,"습":1034,"승":3768,"슈":1775,"슐":101,"ن ":67,"·경":73,"실":7842,"신":14225,"십":781,"심":4418," 뼈":65,"싱":1106,"싼":122,"싸":555,"삶을 ":67,"시":47707,"식":10614,"숫":164,"숨":182," 빈":391," 빌":529,"숭":331,"술":6046," 비":6448," 빅":231," 빛":315," 빙":124,"숲":113,"숙":641,"수":29032,"순":2152,"쉬":296,"입출력":62,"쉽":270," 빨":157," 빠":372," 빼":98," 빵":61,"이프 ":175,"·연":85,"남서쪽":252,"·유":61,"·일":61,"·의":63,"·이":73,"아날로":71,"·정":112,"·전":81,"따라 ":1673,"남자 ":113,"·조":86,"문화 ":681,"학과 ":472,"·중":79," 표":2914,"양군 ":70," 풋":113," 품":311," 풍":535," 풀":299," 푸":531,"·수":74," 프":8266," 플":1603," 퓨":70," 필":1793," 핀":310," 한":15848," 하":15057," 학":3148,"·시":65," 피":2290," 픽":92," 행":4241," 했":855," 핫":66," 합":1642," 함":2804," 항":2107," 할":1260," 핸":86," 해":6139," 핵":492," 헌":637," 허":1093," 헝":262," 향":878," 혁":595," 현":7804," 혈":203," 협":1285," 혐":108," 형":3039," 혜":164," 헤":908," 헨":184," 헬":298," 호":4483," 혹":1415," 혼":618," 환":1277," 활":2664," 화":2857," 확":1802," 홋":133," 홈":481," 홍":939," 홀":264," 황":1758," 획":175," 회":3401," 횡":97," 효":1076," 후":4257," 훈":284,"년까지":1214," 휘":398," 휴":496," 흉":74," 흘":204," 흙":65," 흐":416," 흑":305," 흔":541," 희":405," 흥":265," 흡":176," 흰":126," 힌":195," 히":1017," 힘":385," 힙":241," 힐":117,"퓨":1797," 탈":393," 탄":758," 타":2520," 탁":97," 택":119," 태":2959," 탕":57," 탑":249," 탐":420," 킬":163,"풍":1318,"품":4217,"풋":127," 키":961,"풀":607," 킹":119,"·비":57,"푸":1058," 크":2443," 큰":1228," 클":1230,"표":6870," 큐":81,"퐁":58," 퀴":87," 퀸":110,"헨":491,"헬":461,"헤":1267,"험":1933,"헝":266," 퇴":255,"허":1930,"헌":1331,"향":3265," 통":6217," 톰":97,"했":6623,"행":10972," 톤":103,"햄":124," 토":1698,"해":24304,"핵":714,"핸":99,"할":7046,"학교 ":1462,"합":7081,"함":6807,"핫":70,"항":4366,"핑":263,"하":77112,"학":20317,"한":70049,"핀":882,"필":2371," 텔":530," 텐":79,"피":5014,"픽":1356," 텍":216," 테":1319," 터":808,"례로 ":60," 털":121,"프":15322,"책임을":92,"플":2945,"픈":291,"훌":63,"훈":752,"후":8266,"·사":104," 티":587," 파":4031," 팀":912," 팝":144,"훼":98," 팔":592," 판":1566,"회":16026,"획":1122," 특":3708," 트":1409,"효":1679," 틀":69,"횡":121,"프라 ":59,"로드 ":165,"홀":471,"홍":1228,"홉":95,"홈":507,"홋":134,"화":22028,"확":2379,"활":4194,"환":3339," 튀":144,"황":3546," 튜":103,"혁":1204,"혀":399,"현":10322,"혈":413," 투":1343,"혐":136,"협":3198,"혔":85," 툴":85,"형":7186,"혜":431,"호":10715,"혹":1549,"혼":1062," 폴":656," 폰":261," 포":4550," 폭":878,"힙":246," 편":1366,"힘":444," 펼":268,"힐":206,"히":4751,"힌":432," 펠":137," 폐":695,"·소":58," 평":2091,"흔":563,"흐":924,"흑":351," 퍼":552,"흘":226,"흙":94,"·서":57,"흉":89,"흰":134," 펑":85," 펜":287," 페":1515,"흥":1435," 펄":70,"흡":255," 펀":62,"희":960," 펌":73,"휘":984," 팽":80," 팩":61," 패":1010," 팬":166,"나지 ":80,"휴":649,"키":6923,"킬":397,"킨":1373,"킷":112,"킴":109,"킹":435," 철":1617," 청":1846," 첨":172," 첫":1002," 체":2408,"탠":112," 초":3045," 촉":322," 촌":94,"탱":122," 총":2665,"타":10431,"탁":475,"탄":2414,"탈":2257,"탑":422,"탐":512,"탕":687,"택":1124,"태":6303," 책":837," 채":1344,"퀸":127," 챔":308,"퀴":217," 찬":190," 착":270," 차":4515," 창":2458," 찾":380," 참":2071,"퀘":136," 찰":178,"크":10562," 처":2216," 척":276,"큼":124," 천":2298,"큰":1271,"러스 ":211,"클":2167,"가능성":147,"큐":382,"통":12139,"톱":213,"톰":149,"톤":509,"토":6975,"톡":100,"톨":856," 춤":75," 충":1498,"퇴":541,"낮은 ":181," 취":867," 최":3844,"털":869,"턴":933,"터":15066,"턱":68," 촬":156," 춘":234," 출":3768," 추":2201," 축":1679,"·문":85,"템":1444,"텐":677,"텔":1214,"텍":454,"테":4250," 캠":159,"튀":186," 캡":60,"설되었":185,"튜":408,"특":6554,"트":19866,"튼":328," 커":696,"틀":1105," 컬":177," 컨":381," 컵":92," 컴":1913," 켄":86," 케":706," 켈":106,"틴":890,"틱":267,"티":5222,"틸":257," 측":539," 층":841,"투":4120," 치":1335," 친":965,"툼":59,"툰":121,"툴":145," 칭":340," 칩":93," 침":590,"퉁":60," 칠":288," 칼":602," 칸":291," 카":3225," 캄":163," 캘":285," 캔":83," 캐":1108,"펑":115,"내외 ":104,"펙":119,"페":3911,"펜":502,"펀":122,"펄":94,"펌":98,"펴":73,"편":2910,"펼":268,"펠":315,"폐":1040," 쿼":94," 쿠":694," 쿨":64,"평":3725,"폴":1296,"폰":647,"폼":238,"강남구":284," 퀘":74,"포":9485,"폭":1205,"팜":57,"·보":96,"팝":166,"판":4057,"팔":900,"파":8561,"팀":1526,"팅":740," 콘":727," 콜":444,"팽":145," 코":2601,"팩":183,"패":1550,"팬":246,"팡":90," 콩":260," 콤":104,"퍼":1823," 쾌":61,"정부가":179,"쟁이다":79,"라이터":66,"쟁으로":65,"사실상":154,"창원시":139,"키는 ":1035,"정부기":114,"라이트":130,"정보를":393,"미상 ":70,"정신 ":68,"라이프":136,"건강 ":58,"양과 ":150,"체로서":85,"네덜란":393,"세로 ":103,"사실을":90,"태가 ":128,"이후 ":1284,"이탈리":1091,"정보의":92,"조로 ":180,"정보원":60,"간단한":90,"응하는":87,"한국 ":743,"간단히":170,"초기에":174,"·철":281,"내셔널":212,"정부는":58,"이타마":68,"크를 ":175,"가며 ":64,"상위 ":110,"사전》":334,"초기의":150,"드리히":131,"각류 ":61,")":98,"(":82,"-":78,",":74,":":84,"정보교":91,"�":268,"가능한":325,"가능하":380,"정보기":60,"천문학":192,"자체를":63,"품의 ":269,"가를 ":483,"하기 ":3613,"프로 ":559,"사진 ":92,"상은 ":241,"거가 ":72,"상을 ":1272,"등록되":68,"내의 ":242,"로도 ":664,"산스크":81,"배를 ":124,"가리 ":150,"인해 ":467,"품을 ":440,"았던 ":129,"품은 ":147,"암동 ":90,"상의 ":1371,"나아가":97,"재지는":153,"로그래":368,"로그램":1142,"일한 ":393,"성되는":97,"정식 ":393,"상이 ":314,"이크로":588,"성된다":104,"상인 ":81,"가대표":141,"람으로":164,"량에 ":62,"품이 ":87,"람이다":230,"서버 ":134,"흔히 ":416,"클럽 ":144,"거리 ":240,"들에게":459,"곡가 ":133,"장한 ":247,"크바 ":154,"亂三並":62,"亂三三":97,"개봉한":58,"가의 ":726,"들어가":153,"고가 ":108,"처를 ":60,"초가 ":61,"정적 ":84,"가상의":121,"주가 ":198,"주간 ":66,"력과 ":185,"《삼국":90,"전시키":66,"거를 ":112,"낱말이":57,"전직 ":79,"차원 ":181,"쿠오카":77,"애를 ":72,"었고 ":892,"런던 ":156,"디아 ":131,"드에서":276,"널드 ":60,"들어서":94,"제이 ":61,"제인 ":105,"간을 ":392,"제일 ":77," �":76,"일하게":128,"려고 ":142,"미술 ":75,"디오 ":872,"간의 ":1177,"제작 ":170,"가장 ":2202,"청남도":310,"남성 ":89,"간은 ":169,"아라비":118,"청나라":162,"타공공":108,"라서 ":346,"박람회":78,"드워드":102,"사람에":109,"사람으":156,"사람의":207,"사람을":267,"사람은":77,"에게 ":2107,"각이 ":58,"산부 ":97,"사람이":649,"제의 ":613,"디언 ":96,"디어 ":334,"쓰인 ":79,"각을 ":142,"차와 ":63,"가사키":57,"사령관":124,"》에 ":263,"가인 ":211,"각의 ":236,"거대한":110,"들었다":123,"이하의":127,"풀로 ":63,"미스 ":121,"제정 ":71,"강에 ":127,"남시 ":83,"제적 ":226,"주고 ":119,"애니메":619,"결과를":92,"밴드이":74,"이해하":86,"방법 ":120,"갈의 ":77,"따서 ":170,"결과로":66,"타나 ":60,"재한 ":154,"》은 ":258,"》을 ":87,"려가 ":67,"타낸 ":57,"간인 ":57," ال":89,"간이 ":309,"차에 ":82,"》의 ":292,"재해 ":65,"인하여":149,"주군 ":164,"라마이":104,"양경찰":118,"러가지":95,"처럼 ":457,"업과 ":165,"세기 ":1033,"없고 ":95,"때로는":64,"전에는":239,"각종 ":375,"랫동안":75,"가수이":107,"주교 ":119,"제조 ":126,"정식으":79,"정신적":68,"정신을":88,"믹스 ":77,"가족 ":81,"이후로":131,"키나파":72,"亂之 ":165,"섬과 ":107,"개발과":79,"경기 ":281,"페테르":78,"포유류":74,"사법 ":61,"전적 ":75,"거래 ":75,"채무자":67,"젊은 ":80,"並國三":63,"들이며":112,"나에 ":58,"남부에":295,"정에 ":426,"무함마":66,"레고리":71,"크라이":244,"이트에":84,"절을 ":58,"亂亞 ":92,"전쟁 ":655,"이트의":60,"이트이":90,"전자 ":409,"아들로":224,"작해 ":65,"들이다":337,"키나와":91,"야기를":124,"상당한":67,"상대적":107,"크로아":167,"들이었":59,"발매되":369,"들이자":64,"발매된":203,"드컵 ":186,"개발사":89,"크로소":373,"라북도":260,"크로스":85,"박사 ":73,"네그로":106,"등에서":329,"亂丁 ":125,"산물 ":91,"크래프":177,"렀다 ":170,"개발된":147,"개발되":172,"안드레":67,"亂三 ":194,"서기 ":77,"새로 ":127,"안드로":92,"아들인":70,"아들이":502,"亂丘 ":69,"亂並 ":148,"체계에":64,"석기 ":98,"의회에":71,"저수지":79,"폐지되":230,"체계이":67,"체계적":153,"의회의":78,"문학의":69,"라스 ":165,"문학자":106,"이풀로":78,"포츠 ":283,"전주 ":94,"성군 ":116,"체고비":106,"성구 ":108,"вич":79,"드웨어":181,"문학에":61,"세계 ":1954,"점성술":118,"점이 ":245,"문화교":73,"간에 ":460,"가와 ":443,"프가 ":107,"장치를":95,"문학상":112,"개발에":94,"점의 ":91,"개발원":63,"개발을":139,"거로 ":203,"가에 ":200,"제에 ":283,"점을 ":418,"들에서":74,"체계를":103,"점은 ":106,"들어진":480,"들어지":82,"드이다":163,"찰스 ":128,"제어 ":96,"들어졌":219,"개발자":101,"무형문":79,"타는 ":77,"사람들":653,"박물관":464,"물학적":58,"문화를":243,"정이 ":195,"체는 ":221,"내버스":159,"성과 ":408,"나오 ":65,"나온 ":159,"물학자":103,"체결된":76,"정의 ":333,"야구장":186,"발생 ":60,"정을 ":810,"발매하":71,"발매한":190,"야구의":96,"나와 ":213,"잡한 ":94,"문화방":94,"정상적":60,"장치이":90,"정은 ":136,"성경 ":87,"개발하":315,"개발한":476,"남부의":85,"제와 ":152,"세가 ":207,"변경 ":58,"ич ":79,"얀마 ":62,"책을 ":239,"조사 ":371,"정안전":64,"책의 ":157,"아서 ":221,"작하여":246,"작하였":243,"문화예":200,"설된 ":121,"사스 ":116,"문화에":102,"크리스":321,"문화와":78,"결국 ":113,"미아 ":71,"앨범 ":191,"문화사":76,"따라서":342,"얻는 ":71,"라에 ":165,"레드 ":122,"전자의":59,"들을 ":1666,"중국 ":1103,"태는 ":61,"중구 ":288,"라엘 ":114,"들은 ":1170,"어도 ":114,"작했으":59,"들의 ":1830,"저장하":84,"문화체":1127,"사실 ":77,"문화의":338,"문화유":176,"정에서":302,"미야 ":93,"남부 ":379,"남북 ":100,"전쟁에":156,"문화재":744,"문화적":145,"전쟁이":130,"전쟁의":144,"전쟁을":114,"조선 ":921,"조성 ":57,"포인트":69,"참조 ":61,"크리트":128,"정책 ":233,"양력 ":94,"체를 ":702,"역과 ":276,"타나는":152,"클리드":62,"등에 ":576,"끝에 ":190,"亞之三":65,"표면에":74,"크립트":86,"들이 ":2342,"버드 ":86,"미에 ":63,"어권에":64,"타난다":90,"들인 ":119,"디미르":96,"타낸다":124,"뜻으로":193,"것도 ":92,"타내는":318,"박스 ":90,"뮤지컬":91,"미와 ":58,"계가 ":265,"뜻이다":146,"재판소":104,"랑스 ":981,"날로그":71,"게는 ":216,"새로운":612,"亞三並":82,"점으로":208,"亞三三":101,"亞並三":64,"자회사":108,"책은 ":69,"제였다":63,"점이다":97,"클라우":75,"클라이":98,"라비아":197,"중기 ":60,"클래식":69,"경과 ":111,"클래스":59,"반민족":66,"성공적":59,"자협회":65,"제에서":125,"세는 ":97,"들에 ":340,"세계대":169,"종류로":101,"아메리":675,"아르헨":188,"세계사":60,"성공하":63,"포지션":88,"야를 ":102,"정의된":86,"정의되":69,"정으로":195,"세계를":63,"어느 ":223,"힙합 ":161,"어는 ":592,"크로프":81,"책에 ":96,"삼성 ":130,"체로 ":467,"초기 ":285,"족문화":157,"클럽이":60,"야마 ":336,"성당 ":102,"정이다":317,"드인 ":58,"미생물":76,"여객 ":65,"장하기":60,"아마추":89,"장하고":143,"령과 ":60,"드의 ":963,"종류의":195,"종류이":108,"장한다":129,"장하는":775,"산시 ":253,"창설되":77,"성경의":62,"미사일":222,"개선 ":77,"떻게 ":119,"쳤다 ":134,"성격을":73,"잔티움":169,"임했다":113,"라인 ":429,"미의 ":189,"등의 ":1883,"등이 ":948,"가상 ":104,"선거로":128,"민사소":63,"생명 ":64,"철도의":57,"이후에":218,"입하는":64,"이후의":91,"람에 ":59,"란을 ":119,"방송 ":364,"전에서":232,"야로 ":92,"런던에":68,"랍어 ":64,"년경 ":243,"적용된":77,"적용되":101,"갈리아":61,"건담 ":64,"전차 ":64,"란의 ":103,"사망하":111,"사망한":67,"사망했":57,"알렉산":236,"미술관":126,"사무관":181,"사상 ":967,"민을 ":66,"란이 ":83,"아름다":121,"가서 ":69,"어가는":73,"산림청":142,"입하여":105,"입하였":66,"품부 ":541,"일환으":83,"민의 ":363,"타로 ":84,"나머지":129,"아르메":80,"러를 ":61,"크스 ":85,"년간 ":196,"로가 ":240,"주기 ":97,"풋볼 ":85,"민이 ":110,"히틀러":64,"거구에":103,"내부 ":106,"임하였":204,"알려졌":143,"알려져":958,"거구제":58,"중간 ":77,"반부터":67,"러리 ":73,"알려진":400,"알려지":101,"亞亂 ":111,"선거구":247,"적이고":205,"철도역":58,"제시하":89,"제시한":63,"전철 ":57,"서는 ":3203,"강력한":114,"선거는":100,"나서 ":76,"亞亞 ":112,"라의 ":696,"라이 ":172,"초구 ":243,"샤를 ":93,"가문의":115,"철도공":82,"亞之 ":255,"사무소":268,"사무실":1870,"적으로":6876,"새롭게":76,"적이다":168,"선교사":68,"아랍어":113,"저작권":130,"전체 ":252,"아래에":87,"亞三 ":239,"작하는":103,"적용하":90,"어난 ":785,"었기 ":131,"전으로":231,"전자기":148,"어나 ":278,"라운 ":61,"亞丁 ":83,"산성 ":74,"적이며":61,"방식 ":87,"려는 ":293,"키며 ":125,"작품은":98,"작품을":152,"작품으":141,"작품의":71,"작품이":311,"가수 ":210,"어날 ":66,"작하고":60,"작품에":75,"평화 ":62,"亞並 ":263,"년과 ":135,"방법이":266,"방법으":220,"설가이":93,"방법을":165,"민족 ":187,"결과 ":148,"방법원":75,"선거인":76,"따르는":60,"차의 ":172,"작했다":157,"선거에":114,"설계되":58,"설계된":59,"처리 ":166,"전이다":158,"래시 ":66,"라와 ":158,"넘는 ":95,"래식 ":58,"사무를":174,"생물 ":118,"점차 ":76,"따르면":285,"종로구":365,"등을 ":1775,"서기관":301,"서도 ":661,"듯이 ":69,"あああ":724,"점에서":270,"생들이":69,"가스 ":119,"등은 ":87,"유일하":126,"작사 ":62,"유일한":211,"반의 ":260,"일본식":166,"남동부":196,"유전자":195,"라트비":70,"터가 ":163,"반이 ":63,"이비드":96,"루고 ":252,"과는 ":512,"의자 ":89,"보고 ":146,"뒤를 ":85,"일반화":65,"익보호":63,"이브러":106,"의의 ":313,"타르 ":110,"밖의 ":84,"타를 ":73,"가타 ":92,"래픽 ":199,"드니 ":63,"흥을 ":81,"반은 ":58,"반을 ":232,"체가 ":464,"래한 ":106,"내로 ":72,"라틴어":370,"게르만":68,"남동쪽":276,"했다 ":3529,"공과대":62,"변경되":110,"바의 ":87,"일반직":142,"로레슬":124,"드는 ":685,"하다는":80,"체계 ":105,"바일 ":130,"사람 ":176,"일스 ":70,"바이 ":61,"이벤트":59,"자리에":188,"하다고":79,"의원 ":442,"가지의":94,"흥원 ":58,"검사 ":107,"하다가":230,"흐스탄":57,"강점기":429,"일본군":83,"자리잡":146,"일반적":1125,"일반의":63,"공공기":200,"일반인":59,"검색 ":91,"갖춘 ":115,"하느님":102,"보가 ":128,"동차가":80,"하로 ":57,"하는데":508,"용하지":112,"삼국지":82,"민지 ":138,"플리케":102,"용하였":172,"삼동 ":85,"해도 ":118,"발에 ":103,"공간을":116,"계로 ":314,"롤라이":60,"용해서":66,"공간의":61,"공간이":89,"공간에":115,"임무를":62,"필름 ":57,"용하여":659,"응을 ":89,"한나라":81,"자리를":100,"나들목":286,"이베이":60,"하나의":423,"하나이":1414,"하나인":156,"돌프 ":87,"뀌었다":80,"건물이":107,"되었는":98,"강으로":96,"레슬링":130,"가지로":201,"해결하":97,"하나였":68,"상당 ":305,"원후 ":60,"벨기에":181,"레슬러":60,"보》 ":158,"표한 ":280,"의와 ":140,"삼국시":89,"용하며":100,"결되어":107,"되었다":5986,"강이다":118,"되었던":228,"도쿠가":148,"용했다":68,"반에 ":227,"원회 ":556,"이스 ":652,"레스타":99,"도한 ":102,"차로이":131,"음이 ":93,"되었고":629,"이베리":109,"육청 ":61,"공개되":85,"이바지":269,"차례의":95,"용한다":393,"가지는":177,"음의 ":177,"미지 ":78,"용하는":892,"가진다":98,"흥에 ":88,"하라 ":165,"건설 ":140,"민주 ":136,"이미지":182,"워크에":63,"밖에 ":144,"음을 ":323,"응용 ":195,"의에 ":179,"곡동 ":69,"음은 ":101,"강원도":332,"용하기":171,"동차의":79,"동차이":57,"력에 ":158,"나무 ":204,"가지가":83,"든다 ":84,"견되었":130,"용하고":267,"가지고":705,"임명되":96,"타마 ":101,"해군의":95,"받아 ":360,"방송되":109,"방송된":59,"인민공":988,"울특별":2233,"방이 ":101,"크에 ":114,"워크를":60,"려운 ":66,"배우 ":114,"고도 ":1655,"고고학":81,"나라의":375,"나라에":236,"태로 ":448,"자료를":144,"인물이":326,"나라와":67,"방의 ":527,"삼각형":57,"나라이":90,"창단되":64,"원형 ":65,"산된 ":75,"제국 ":423,"방송국":244,"방송공":57,"방은 ":58,"미이다":94,"채널이":57,"방을 ":182,"타디움":74,"민운동":60,"로리다":73,"들도 ":99,"학대학":68,"행된 ":137,"자로서":148,"학명 ":83,"인먼트":266,"원한 ":71,"고구려":194,"쟁력 ":98,"나로서":116,"가치 ":92,"되었을":105,"되었으":1444,"합뉴스":77,"방사성":62,"이므로":99,"방사선":62,"됐으며":61,"되었지":87,"인물로":179,"이센 ":70,"로마의":132,"하면 ":687,"보기 ":63,"되어있":155,"하며 ":3509,"핀란드":235,"제공 ":74,"로마에":76,"천구 ":60,"이션 ":833,"정규 ":302,"고대 ":811,"보급 ":119,"천군 ":115,"이묘로":166,"법률 ":166,"정권 ":76,"한다는":384,"산광역":497,"했던 ":888,"련을 ":63,"나라가":92,"음에 ":134,"일리아":483,"발전 ":299,"광고 ":99,"사도 ":73,"력이 ":338,"인사 ":61,"가이자":300,"인리히":70,"쓰고 ":113,"점기 ":106,"력의 ":179,"동한 ":119,"베네치":57,"위치 ":109,"히브리":114,"하루 ":70,"인류학":75,"력을 ":1046,"곡가이":164,"고는 ":197,"간이다":99,"발생하":361,"발생한":413,"이상 ":271,"려의 ":141,"원칙으":57,"간으로":125,"럽에서":169,"거리에":131,"력은 ":109,"정구 ":74,"원칙이":63,"미에서":158,"한다고":160,"산당 ":105,"본과 ":65,"려져 ":976,"나라를":93,"정과 ":186,"민에게":63,"발이 ":61,"변경하":100,"가이며":162,"산동 ":114,"자라고":70,"이면서":108,"이사 ":68,"나라로":69,"살던 ":66,"방에 ":408,"베네수":63,"자라는":57,"행동 ":67,"하마 ":73,"밝은 ":60,"하도록":282,"미어리":61,"발의 ":57,"발음 ":82,"생긴 ":128,"인류의":69,"발을 ":206,"재를 ":220,"이를테":61,"련이 ":125,"거리를":101,"가이다":1033,"나라는":63,"허가 ":79,"로서 ":2731,"장되어":72,"음악 ":533,"크와 ":130,"받을 ":101,"발생시":61,"받은 ":355,"미얀마":91,"련의 ":320,"관급 ":76,"제가 ":421,"하를 ":73,"킬로미":80,"제도 ":358,"간에서":92,"석과 ":60,"제국에":76,"나라 ":614,"령에 ":106,"있어 ":371,"방식을":150,"인인 ":98,"방식으":206,"인이 ":565,"이전 ":225,"방식의":98,"방식이":202,"이저 ":232,"민주당":259,"받았다":382,"산되었":75,"받아들":112,"일의 ":934,"산면 ":79,"음으로":564,"민족주":86,"선과 ":211,"일이 ":179,"서구 ":260,"려시대":128,"민족이":83,"민족의":109,"일은 ":171,"일을 ":555,"원회가":79,"제공한":140,"제공항":114,"해당되":71,"제공하":545,"제국이":104,"제국의":612,"바에서":60,"제국을":60,"동일한":145,"가에서":199,"도지사":58,"유통 ":76,"이사회":105,"이자 ":2852,"표하는":228,"정된 ":457,"산드로":63,"관광 ":81,"사들이":79,"태를 ":373,"천광역":247,"함되어":129,"설계 ":121,"점기에":78,"산드리":57,"장소 ":58,"체나 ":63,"재산 ":60,"정권을":71,"합되어":80,"둘러싸":178,"나뉜다":143,"점기의":205,"위한 ":2048,"인의 ":1094,"천동 ":70,"상대로":69,"해를 ":391,"원하여":159,"설과 ":84,"위해 ":2768,"위치한":3432,"제거하":73,"위치하":1705,"례에 ":90,"위치해":340,"나로 ":1168,"민족문":161,"상대방":151,"크의 ":348,"후쿠오":77,"가운데":1210,"인은 ":257,"히로시":66,"정교회":151,"인을 ":537,"임에 ":72,"이션의":58,"이션을":57,"나누어":113,"위하 ":73,"이션이":144,"사립 ":60,"로스 ":346,"이사장":71,"터널 ":62,"원하기":109,"경기장":259,"경기이":114,"원하고":76,"졌고 ":82,"베리 ":112,"사망 ":84,"로미터":82,"제는 ":260,"이선스":78,"익을 ":208,"학문 ":67,"제국과":91,"계된 ":80,"정동 ":164,"이의 ":892,"개신교":188,"방송통":78,"공기 ":138,"계기로":63,"처드 ":102,"되자 ":84,"가였다":74,"관계 ":273,"생기는":109,"하드웨":180,"정구역":186,"로바키":85,"원하는":219,"정도 ":616,"정기관":402,"원한다":72,"령을 ":243,"터넷 ":430,"령은 ":67,"백작 ":70,"려진 ":441,"관과 ":150,"이상의":447,"방송하":72,"철도 ":369,"동조합":172,"생된 ":67,"이상이":81,"낸다 ":189,"인용 ":127,"위치에":98,"들기 ":69,"경기를":148,"레이더":57,"객이 ":71,"레이드":84,"령의 ":138,"유지하":156,"택되었":69,"산맥 ":122,"레일리":489,"정당 ":75,"반직 ":94,"령이 ":148,"공군 ":73,"키백과":58,"음악을":113,"음악의":121,"선거 ":137,"자본주":105,"음악이":74,"제강점":66,"로써 ":1184,"레이블":111,"위치를":101,"일에 ":1924,"쓰는 ":227,"로버트":170,"음악에":71,"베르 ":73,"함된다":101,"방송사":59,"후한 ":94,"루는 ":422,"경기에":89,"레이션":267,"등과 ":260,"방송의":67,"음에는":128,"해로 ":77,"방송이":79,"레이스":190,"방송을":83,"받지 ":116,"래했다":68,"레이시":146,"설가 ":74,"이용 ":83,"서관 ":112,"일어 ":137,"바이잔":107,"레임워":62,"레이저":82,"바이올":96,"바이오":87,"생각하":93,"강제 ":60,"음악가":117,"로부스":65,"래픽스":66,"자발적":68,"익에 ":75,"나를 ":121,"필리프":61,"필리핀":358,"낙동강":59,"같이 ":509,"보는 ":244,"반이다":146,"바이에":102,"과가 ":110,"레이오":85,"공고 ":59,"미터 ":147,"전기의":97,"했는데":97,"레이어":194,"전기적":63,"너가 ":60,"래하였":76,"개인 ":152,"이온 ":68,"레이크":71,"상남도":478,"이오 ":93,"례의 ":123,"경기도":912,"사단법":1681,"전까지":207,"래프트":205,"레이트":129,"과거 ":210,"레이터":99,"했다고":109,"인어 ":69,"개의 ":1769,"표현한":83,"표현하":178,"자베스":57,"인에 ":164,"보다 ":794,"이완 ":109,"이와 ":277,"했다는":112,"경기는":58,"생대 ":149,"크스주":60,"로부터":1174,"바이러":161,"룬다 ":177,"저기압":67,"강이 ":84,"백질 ":70,"공격 ":71,"반으로":349,"등급 ":68,"서가 ":115,"보건복":107,"별로 ":156,"이언 ":67,"나며 ":96,"이어 ":549,"개월 ":84,"계는 ":211,"장르의":62,"이에 ":1223,"키보드":63,"사를 ":1011,"같은 ":1766,"흑인 ":59,"제나 ":71,"경계를":120,"값이 ":80,"전광역":266,"겼다 ":99,"일부이":124,"동쪽에":157,"동쪽은":73,"동쪽으":984,"적도 ":70,"경계로":137,"프의 ":110,"결된 ":163,"값을 ":97,"강의 ":289,"두번째":73,"운행하":134,"표하였":66,"되지 ":512,"강을 ":180,"해당하":270,"해당한":149,"가진 ":547,"가지 ":694,"탈리아":1095,"강은 ":65,"이안 ":61,"공개 ":76,"이아 ":80,"냈다 ":524,"로비치":78,"공간 ":182,"나뉘어":85,"민주화":70,"유주의":100,"율적인":84,"율적으":85,"일부터":916,"타리오":112,"일본제":58,"일부로":118,"일본어":214,"일본에":462,"방지 ":78,"일본의":1226,"일본이":57,"일본인":94,"음식을":58,"유전체":77,"견된 ":134,"일부를":110,"음식이":66,"학부 ":102,"터는 ":441,"받았으":82,"임스 ":235,"민주주":682,"하려고":72,"고기 ":102,"의적 ":151,"하려는":180,"건물 ":86,"나다의":116,"표현이":66,"강서구":79,"임시 ":75,"민족행":60,"유전학":62,"사로 ":539,"감을 ":118,"고급 ":121,"이에서":435,"보급을":72,"관리 ":537,"이어서":70,"전동차":102,"강화 ":81,"방으로":94,"인에게":123,"례를 ":88,"이에른":91,"레마이":67,"발전에":578,"게임 ":779,"법률에":63,"벨라루":58,"장에 ":303,"보교환":61,"과대학":155,"포함해":70,"포함한":517,"포함하":554,"발전시":125,"량이 ":162,"계산 ":77,"두었다":75,"별도의":74,"족과 ":94,"작성하":88,"법률의":65,"법률이":85,"이었던":250,"이었다":1368,"발전을":350,"량을 ":270,"이언트":66,"계속 ":137,"량은 ":105,"인에서":57,"항구 ":67,"탄소 ":65,"히어로":65,"래이다":109,"일에는":57,"조금 ":68,"아가 ":238,"표적인":377,"보급하":100,"상가 ":71,"이용되":115,"국과 ":645,"크에서":153,"개혁 ":71,"자주 ":141,"이오스":98,"키아 ":114,"버스 ":485,"량의 ":196,"일어난":375,"일어나":250,"일어났":108,"이언츠":61,"난다 ":199,"유클리":61,"발전하":100,"참가했":85,"참가한":160,"참가하":322,"국계 ":80,"이었지":81,"이었으":387,"국경 ":65,"등록 ":59,"꼽힌다":72,"이어지":79,"보드 ":159,"거에는":64,"있지 ":161,"포항시":66,"이올린":74,"자신들":66,"고려대":68,"라크 ":131,"개최하":103,"동하는":170,"가톨릭":535,"해가 ":130,"항공 ":158,"방에서":152,"작이 ":58,"발전과":240,"본거지":83,"의정부":87,"발원하":120,"사기 ":58,"작은 ":650,"작을 ":162,"키에 ":57,"자인 ":552,"작의 ":72,"본격적":88,"동했다":59,"프를 ":82,"들면 ":66,"보고서":76,"반응을":70,"공립 ":63,"포함된":182,"바이트":101,"포함되":256,"자의 ":1228,"살고 ":126,"포하는":115,"나다 ":436,"동하고":132,"백악기":102,"산군 ":87,"합과 ":58,"조가 ":151,"자유 ":190,"산구 ":126,"방영된":79,"방영되":154,"들목 ":196,"음주의":62,"본관은":510,"함과 ":91,"나는 ":720,"국가 ":668,"작전 ":71,"크이다":81,"동하였":160,"키와 ":57,"이었고":95,"발전소":109,"강한 ":187,"유한 ":186,"전달하":101,"표이다":71,"공동으":122,"임시정":57,"의적인":85,"한글 ":77,"반적으":847,"나가와":69,"반적인":257,"과를 ":382,"이야기":454,"아과 ":60,"공동체":220,"구가 ":427,"산과 ":144,"의원이":92,"의원을":113,"필드 ":75,"이징 ":127,"이진 ":64,"뜻한다":497,"이지 ":498,"끼리 ":67,"인슈타":59,"뜻하는":380,"검은 ":78,"하는 ":18164,"품안전":65,"보내는":62,"으킨 ":120,"사관 ":76,"전력 ":61,"이즈 ":185,"개최된":194,"개최되":218,"입이 ":60,"하거나":693,"이스하":64,"랑크 ":135,"사고 ":119,"라틴 ":103,"위탁집":59,"내는 ":646,"있을 ":239,"자와 ":463,"쓴다 ":92,"입자 ":81,"내각의":69,"내각이":64,"드라마":492,"것이 ":936,"키의 ":170,"휘하는":77,"라트 ":74,"일시적":63,"찬가지":135,"것의 ":67,"남도 ":1094,"관련 ":511,"잎은 ":109,"것을 ":2109,"것은 ":829,"차는 ":139,"백제의":59,"램으로":79,"차관급":64,"램이다":179,"사건 ":437,"의자들":60,"고등학":392,"자원 ":102,"인지 ":119,"과로 ":135,"의인민":505,"작용 ":98,"교관 ":61,"이스볼":109,"것에 ":138,"드라이":156,"러운 ":114,"났다 ":378,"표준화":112,"방자치":117,"피드 ":77,"사가 ":831,"럼비아":66,"터내셔":76,"채널 ":133,"인조 ":92,"바지하":107,"바지함":89,"원회는":112,"베를린":147,"각한 ":85,"건이 ":129,"이스라":226,"배우이":125,"건은 ":246,"이스를":85,"건을 ":482,"이슬란":101,"이슬람":294,"발족하":147,"가한 ":185,"건의 ":226,"법상 ":135,"의에서":83,"베르트":104,"이시아":128,"해군 ":184,"각형 ":66,"임의 ":182,"작업 ":64,"입을 ":113,"자연 ":134,"입은 ":73,"표준이":73,"교구 ":85,"레스 ":275,"임이 ":89,"이스테":112,"베르크":152,"이스트":150,"뜻하며":87,"의약품":99,"로로 ":225,"법무부":66,"베리아":142,"하나 ":294,"인종 ":68,"이스에":70,"일정 ":91,"원회에":81,"이스의":66,"이중 ":62,"일제 ":401,"갖추고":82,"원회의":88,"전략 ":114,"위키백":58,"임은 ":107,"함께 ":1469,"임을 ":405,"자에 ":270,"방정식":221,"한국인":156,"한국전":116,"일종의":150,"보로 ":117,"일종으":266,"가치를":121,"한국어":281,"한국에":288,"로마 ":867,"러의 ":97,"프레임":130,"로만 ":108,"거운 ":93,"등교육":72,"한국의":765,"텐도 ":71,"이지만":374,"베스 ":74,"자연적":68,"있으면":59,"있으며":2859,"한국시":112,"임의의":76,"작업을":98,"프로이":170,"고를 ":213,"프로젝":410,"플라스":132,"프로야":90,"풍으로":73,"발트 ":82,"자체 ":74,"학기술":709,"번에 ":61,"품의약":58,"한국철":84,"일정한":279,"일종이":264,"사고이":102,"교가 ":168,"차를 ":208,"프로세":418,"보다는":163,"프로스":78,"학교이":155,"학교의":215,"이크 ":192,"번역 ":68,"학교와":105,"고리 ":71,"프로그":1505,"학교에":231,"사거리":82,"프라이":147,"건설되":84,"사고는":93,"로를 ":314,"남구 ":380,"내각 ":119,"사는 ":696,"프랑스":2191,"거의 ":466,"프레드":80,"한국농":75,"자역학":77,"프랑수":66,"프레스":87,"쟁의 ":196,"프로레":124,"한국사":95,"작으로":431,"자원의":107,"자원을":67,"프랑크":230,"작용을":104,"이집트":409,"료가 ":69,"거인 ":70,"자이다":1129,"쟁은 ":76,"자유민":74,"한국불":125,"쟁을 ":247,"품이다":304,"프로듀":150,"사건이":570,"사건의":71,"했기 ":58,"품으로":223,"사단 ":91,"사각형":73,"자이너":75,"하기도":550,"한국방":93,"사건으":140,"사건을":260,"사건은":231,"키스탄":273,"한국문":122,"사고로":88,"자유를":60,"사건에":107,"자유롭":67,"자유로":59,"터로 ":147,"이클 ":128,"정보 ":449,"자에게":301,"고려 ":339,"키지 ":73,"택시 ":63,"하고있":61,"하고자":204,"하던 ":520,"제명 ":69,"인정받":89,"《한국":70,"거에 ":119,"로듀서":129,"러싸고":66,"학교는":93,"아나 ":116,"한국기":62,"전라북":260,"고로 ":237,"은하 ":58,"조나 ":59,"임으로":241,"프란시":116,"쟁에 ":89,"자연과":58,"학교로":108,"한다 ":13903,"일으킨":137,"일으키":165,"전부 ":107,"학교를":131,"한국과":105,"한국교":74,"독특한":83,"려서 ":64,"나기 ":67,"임위원":62,"건에 ":136,"있으나":300,"가치가":81,"잡지 ":125,"타운 ":91,"자였다":159,"임이다":401,"되지만":116,"타워 ":79,"은행 ":219,"했고 ":365,"록되었":91,"방지하":84,"록되어":194,"레비전":409,"학과를":67,"본래 ":178,"으키는":87,"행과 ":57,"인정하":121,"임워크":62,"하다 ":1598,"인접해":357,"로몬 ":72,"자에서":67,"학교가":70,"터를 ":399,"인으로":806,"정도의":111,"인이다":2750,"정도이":95,"레옹 ":96,"레오 ":64,"보면 ":81,"인이나":74,"이전까":77,"안과 ":124,"터리 ":112,"재위 ":590,"타이 ":170,"이익에":60,"제를 ":765,"하나다":64,"공기업":62,"해당 ":227,"하나님":89,"럽의 ":196,"타의 ":138,"드로 ":276,"나가는":87,"정동으":58,"정동이":148,"있었고":57,"인이며":112,"하나로":1278,"일요일":80,"임에서":89,"있었다":516,"정되었":453,"정되어":273,"버스는":71,"이익을":123,"반한 ":62,"타인 ":187,"장소에":66,"재산을":59,"타임 ":62,"크톱 ":64,"제도로":95,"않고 ":518,"테네그":93,"러진 ":169,"제도를":150,"있었던":279,"종과 ":71,"제리 ":77,"탄의 ":170,"힘을 ":86,"프린스":68,"일이다":180,"버스를":60,"한때 ":76,"일원으":71,"본명 ":192,"탄을 ":70,"위하여":1507,"재의 ":594,"위해서":284,"항공사":85,"이치 ":126,"있어서":333,"안구 ":63,"량이다":57,"안군 ":67,"인이었":103,"량으로":84,"잠수함":77,"벌인 ":97,"악기 ":166,"제도에":143,"들로 ":446,"이전의":127,"함된 ":80,"법원 ":127,"이전에":294,"종교·":271,"보물 ":70,"해는 ":66,"인정되":99,"인이자":288,"종교 ":464,"발한 ":578,"전라남":362,"있었으":214,"일제강":66,"탄생하":60,"도하는":89,"프리카":740,"합된 ":92,"내기 ":85,"러시아":1259,"제도의":156,"제도이":151,"사나 ":68,"과거에":114,"재에 ":70,"개인이":78,"드를 ":373,"관계가":119,"로봇 ":68,"플레잉":80,"차례 ":100,"전문 ":280,"보를 ":504,"플레이":676,"플랫폼":184,"경되었":98,"제로 ":572,"자신의":370,"프리드":163,"자신이":152,"공격하":60,"계를 ":823,"차로 ":128,"계대전":148,"개인용":83,"개인의":86,"드르 ":75,"루가 ":76,"이외에":93,"레이 ":338,"이유는":64,"레인 ":73,"항공모":59,"정당이":122,"이외의":104,"레잉 ":75,"관광객":71,"프리미":129,"일에서":154,"공기관":197,"이오프":76,"레의 ":65,"공동 ":225,"이유로":136,"재산권":68,"건복지":107,"졌다 ":803,"플라이":63,"이용자":68,"인천 ":74,"플래시":78,"강조하":64,"상과 ":312,"장은 ":771,"장을 ":940,"차량 ":86,"정도로":127,"로벌 ":412,"정리 ":264,"정도를":60,"이이다":59,"렉산드":154,"관계를":280,"내고 ":139,"태양 ":74,"삼국 ":84,"둘째 ":87,"장의 ":441,"렉산더":61,"하드 ":77,"장이 ":399,"정된다":136,"게서 ":71,"프로토":225,"정되는":135,"관계에":153,"법에 ":402,"번의 ":336,"았고 ":97,"관광부":1127,"장인 ":112,"태에 ":107,"항공기":266,"이용해":188,"이용한":219,"이용하":540,"이용할":86,"플로리":82,"쓰다이":179," 권 ":193,"약으로":104,"외전화":76,"노 ":946,"류는 ":92,"야이다":152,"논 ":119,"본부 ":174,"송의 ":131,"독을 ":96," 국 ":173," 구 ":910," 군 ":386,"념 ":104,"도의 ":1235,"아카데":151,"약이다":130,"치해 ":314," 교 ":197,"편되면":82,"넷 ":554,"도인 ":130,"독의 ":116,"울의 ":64,"녀 ":215,"우수성":57,"이나 ":3015,"서태평":66,"페라이":66,"년 ":40320,"있기 ":171,"나게 ":58,"너 ":308,"수도권":102,"분과 ":75,"널 ":639,"성한 ":265,"독일 ":770,"도자 ":82,"독이 ":70,"수단이":125,"술로 ":87,"수단으":59,"수단은":92,"네 ":732,"수도는":71,"올라 ":62,"도서관":240,"영화제":129,"차가 ":177,"수를 ":679,"영화이":249,"영화의":83,"왕가의":62,"냐 ":176," 곳 ":60," 공 ":72,"영화에":74," 곧 ":122," 과 ":1102,"내 ":913,"왔다 ":379,"어와 ":330,"남 ":651,"치한 ":2915,"수립 ":59," 곡 ":60," 고 ":93,"낼 ":127,"언어 ":291,"낸 ":543,"나고 ":122,"날 ":645," 계 ":88," 경 ":182,"난 ":1514," 겸 ":249,"나 ":11468,"코나미":58,"우승을":222," 것 ":328,"어야 ":159,"르기 ":103,"우수한":99,"도와 ":396,"우주 ":186,"여러해":77,"끈 ":67,"우스의":77,"수도원":123,"불교 ":309,"동부에":445,"수도이":101,"수도인":69,"베스트":178,"세한 ":63,"열렸다":111,"포드 ":79,"움을 ":181,"어에 ":175,"성화 ":93,"로크 ":62,"오늘날":414,"으로 ":33705,"자기 ":286," 개 ":1973,"트페테":64,"북구 ":168,"월부터":252,"루마니":186,"바티칸":62,"자군 ":57,"오페라":314," 강 ":510,"페르디":70," 각 ":779," 가 ":1852,"도어 ":73,"퍼스 ":60," 간 ":172,"속씨식":90,"외교 ":73,"의된 ":59,"수도회":61,"도에 ":499,"번역되":60,"영등포":159,"파크 ":92,"기》":151,"오랜 ":123,"아트 ":64,"오래 ":72,"야에서":263,"나급 ":176,"이너 ":95,"잡고 ":153,"속에서":155,"련한 ":84,"대회의":76,"대회이":310,"로켓 ":60,"코드 ":238,"법인 ":238,"월에 ":731,"법이 ":149,"대회에":121,"소에서":153,"판에서":87,"바키아":85,"번주 ":58,"이는 ":2155,"박테리":63,"양으로":132,"연속 ":101,"수들이":80,"바탕으":333,"버지 ":158,"대회로":103,"올린 ":87,"어져 ":580,"대회를":64,"우승팀":125,"되면 ":130,"얻은 ":80,"원에 ":338,"께 ":1488,"보디아":75,"대항하":93,"대회는":163,"되며 ":566,"법의 ":384,"버스터":121,"와라 ":58,"파이다":83,"법을 ":510,"법은 ":260,"관ㆍ":62,"법상의":86,"안한 ":113,"범을 ":60,"범은 ":63,"이거나":117,"동물의":147,"동물이":83,"음력 ":492,"별시 ":2065,"러피언":110,"이곳에":70,"이더 ":126,"방향 ":69,"원산지":59,"커뮤니":173,"특히 ":652,"길 ":492,"연맹이":57,"기·":85,"이던 ":135,"긴 ":534,"러해살":77,"범죄 ":90,"김 ":69,"유럽과":60,"원은 ":642,"인다 ":433,"장군 ":139,"대한제":216,"어인 ":140,"원을 ":808,"르가 ":94,"대학을":73,"인구가":178,"대학으":61,"대학의":118,"윌리엄":254,"대학이":119,"부가 ":501,"원의 ":690,"역사 ":258,"판으로":77,"속이다":111,"글 ":394,"아케이":78,"용어이":331,"업에 ":215,"금 ":663,"급 ":1684,"여서 ":467,"원이 ":411,"미합중":60,"원인 ":98,"위성 ":107,"극 ":392,"치체를":60,"그 ":5244,"여섯 ":109,"여성 ":225,"으며 ":7980,"근 ":449,"으면 ":156,"파이어":96,"대회가":57,"소이다":165,"인구는":2448,"원자 ":102,"언을 ":82,"센터는":143,"약칭 ":297,"기 ":12721,"양에서":166,"속으로":235,"이도 ":156,"∼ ":117,"베이 ":167,"파일을":68,"원장 ":135,"요가 ":84,"어사전":65,"대한민":7350,"재가 ":151,"소재로":63,"귀 ":64,"용어는":192,"미한다":599,"카자흐":73,"대한불":58,"열리는":184,"렉트로":73,"미하는":189,"오피스":122,"손으로":97,"석하는":74,"이것이":59,"두는 ":58,"장관 ":152,"이것을":92,"이것은":282,"인간이":102,"인간의":257,"르게 ":297,"장과 ":256,"오피아":86,"이다 ":44553,"균 ":216,"규 ":410,"법적 ":132,"오를 ":79,"스가 ":772,"용어로":228,"어의 ":700,"센터에":60,"왕국이":67,"대해서":237,"왕국의":244,"파이터":67,"궁 ":201,"대하여":393,"대학에":115,"로젝트":389,"나가 ":143,"굴 ":183,"번째 ":1634,"국 ":12549,"대학원":221,"데이터":858,"구 ":8696,"구·":91,"국·":107,"용어를":67,"미하며":79,"델이다":57,"군 ":3195,"력한 ":146,"대학생":58,"번지 ":352,"르고 ":392,"권 ":1513,"유래되":83,"유래된":87,"되도록":63,"용자들":92,"에서의":511,"록한 ":134,"대하는":92,"법인이":2000,"법인의":65,"법인으":81,"껍질":59,"때 ":2169,"원숭이":76,"웨어 ":581,"애플 ":68,"련하여":63,"법정동":157,"된다는":107,"번주이":218,"딸 ":107,"병원 ":128,"딴 ":82,"손자이":109,"대표하":220,"인기를":112,"양주시":57,"오랫동":75,"따 ":83,"끄는 ":125,"꼬리":79,"용이다":73,"딩 ":636,"유러피":111,"리고 ":1415,"데이비":123,"용으로":300,"인된 ":59,"대표팀":149,"오래된":193,"용과 ":88,"리게 ":92,"대표적":477,"운영되":116,"외교관":176,"소장은":80," 개국":359," 개교":77," 가나":171," 객관":69,"용자가":142," 개관":128," 강남":325,"에서부":139," 간단":314,"대표이":78," 가능":764,"떤 ":678,"소유하":90,"파트 ":89," 가는":110," 가공":207," 각국":128,"대학교":1503,"꾸는":62,"소재지":313," 각각":403,"발행하":79," 가격":195," 개가":76," 강과":184,"당하였":79," 갖고":277,"른다 ":763,"에의 ":102," 감각":84,"유래했":74," 가깝":67," 가까":264,"인구의":90,"기초":552,"까지":4684,"기체":184,"도시 ":600,"유럽의":184,"인도 ":427,"균형":133,"유래하":101,"유래한":138,"득 ":112,"르기도":285,"드 ":7173,"포로 ":81,"근하":60,"유럽에":197,"김천":58,"안토니":87,"들 ":1322,"든 ":2179,"역번호":77,"우가 ":328,"기준":2706,"코드를":100,"길을":64,"장기 ":92,"길이":553,"센트럴":124,"기존":438,"기종":131,"에서만":99,"기지":219,"김정":94,"까운":158,"김일":103,"원전 ":1040,"까이":70,"버지는":99,"깊은":85,"버지니":97,"스과 ":57,"자나 ":108,"이기도":812,"르기까":96,"왕후 ":114,"대표로":57,"법으로":406,"기하":531,"기한":151,"디 ":655,"딕 ":78,"인데 ":220,"기획":281,"발하였":89,"기회":128,"기화":84,"발하여":147,"딘 ":125,"기호":268,"당한다":198,"되는데":137,"범으로":68,"기후":219,"본선 ":60," 년 ":39188,"김해":119,"당하는":446,"영상 ":190,"범이다":175,"인구밀":163,"속적인":79,"소재하":88,"속적으":84,"급한":91,"급하":294,"기타":646,"에서는":2546,"당했다":95,"코드는":96,"등 ":2664,"에서도":483,"유롭게":61,"법원에":72,"우에는":147,"도스 ":66,"법원이":60,"창군 ":59," 네 ":279,"이동 ":119,"법이다":392,"있던 ":494,"방행정":150,"일까지":745,"아키텍":133,"근에":408,"그와":139,"국화":64,"구회":87,"국회":507,"둘 ":109,"그에":296,"배하는":77,"극에":58,"구현":195,"구협":65,"둔 ":252,"규정":490,"국해":88,"국하":80,"국한":79,"급시":77,"두 ":2443,"규제":83,"급수":72,"구할":69,"구한":114,"구하":801,"기부":230,"기병":61,"당하고":80,"금속":226,"기본":591,"기보":62,"기법":290,"연방의":172,"기반":832,"당하기":83,"운영하":421,"교황":497,"부는 ":372,"구팀":94,"기물":83,"교환":215,"교회":1206,"술부 ":260,"귀족":311,"방향으":165,"교향":157,"르는 ":1003,"교하":132,"국토":367,"기리":116,"기름":86,"기를":1419,"베이스":456,"기록":1098,"기로":698,"될 ":726,"기의":1771,"기이":523,"기인":192,"기자":720,"기장":468,"기재":80,"김영":83,"기적":272,"기전":79,"기점":130,"뒤 ":432,"기와":342,"근처":198," 내 ":198,"업인 ":92," 낸 ":84,"기원":1347,"병의 ":61,"김씨":66,"우이다":123,"없이 ":416,"기압":128,"기아":138,"수록된":81,"수록되":127,"기에":2090,"기여":1114,"기어":60,"기억":172,"기업":1321,"금지":206," 남 ":62,"었을 ":154," 난 ":119,"급제":92,"양자역":76,"규칙":225," 날 ":143,"급을":163,"급으":81,"금의":358,"급은":66,"기슭":65,"기스":70,"금이":141,"급의":120,"워싱턴":116,"방해양":72,"금을":242,"금은":170,"금으":71,"금융":485,"급이":114,"기시":64," 나 ":149,"글이":148,"글을":102,"본식 ":161,"기소":84,"권한":204,"극적":138,"역시 ":1264,"작가로":60,"기수":80,"기술":2933,"어진 ":1828,"다》":68,"글자":184,"그이":134,"기사":297,"용자의":81,"의료 ":61,"극을":92,"그의":1129,"둥 ":134,"금액":59,"급에":136,"기서":167,"워진 ":158,"근의":142,"극장":238,"금에":66,"극작":92,"기생":113,"기상":277,"극이":61,"국외":69,"법칙 ":74,"국왕":350,"예루살":108,"구원":461,"국역":58,"국영":89,"국에":2267,"기기":316,"구역":938,"기까":238,"군에":440,"구와":486,"구장":488,"업을 ":671,"국인":683,"국이":927,"구자":155,"구인":96,"구이":427,"국의":7823,"공화":2272,"군의":841,"국장":157,"과하":139,"과학":2295,"군은":187,"군을":273,"군으":160,"공했":63,"업은 ":103,"급되":106,"공해":80,"공항":327,"공학":446,"공한":214,"공하":712,"국은":420,"국을":477,"공헌":123,"동 ":5208,"료의 ":83,"국으":324,"구의":1030,"국유":104,"이때 ":93,"기경":136,"근대":297,"곡한":152,"곡하":125,"기계":386,"기고":122,"교적":271,"벤처 ":66,"교정":87,"도 ":19093,"기관":3227,"독 ":328,"교의":1054,"그대":267,"교이":272,"교인":98,"교장":78,"고한":57,"고학":98,"고하":102,"구약":91,"공포":158,"기금":119,"돌 ":128,"포를 ":110,"그들":327,"국어":699,"구에":986,"골프":78,"있다 ":14608,"기구":741,"돈 ":121,"성하고":147,"도·":76,"국악":57,"교와":220,"구시":81,"성하기":80,"군수":86,"구스":198,"교에":493,"교역":61,"국수":106,"그녀":205,"계획":601,"위스 ":122,"로프 ":73,"업의 ":668,"계화":120,"운영에":81,"기갑":60,"기가":643,"교육":2560,"기간":605,"아테네":86,"그는":921,"교원":80,"병을 ":93,"데에서":64,"공통":193,"국식":78,"국시":294,"구사":107,"구상":120,"국사":242,"국산":101,"베이니":80,"경향":176,"용인시":67,"경험":178,"번지에":231,"경하":130,"업이 ":195,"국소":69,"구속":114,"그나":76,"구소":547,"금까":92,"구성":2022,"군산":96,"국세":95,"계한":64,"계학":71,"계하":113,"군사":580,"관측":213,"극복":58,"근본":126,"교통":744,"구치":82,"교토":91,"괴하":71,"포니아":254,"오디오":134,"의로 ":155,"기라":71,"버지이":112,"교파":61,"된 ":12222,"있는 ":7557,"리가 ":556,"기둥":76,"근무":149,"기들":73,"국철":110,"구체":168,"군청":66,"구축":271,"도모하":352,"도모할":62,"기능":861,"광학":98,"기는":959,"글로":653,"규범":69,"그룹":828,"권위":161,"그마":69,"기대":121,"그림":313,"그리":2785,"기다":78,"그린":273,"궁전":122,"기니":172,"그를":132,"인근에":94,"권이":270,"권익":212,"이드 ":468,"권의":270,"권을":623,"권은":116,"권으":128,"긴다":73,"기되":97,"돼 ":80,"글리":111,"기동":137,"권자":142,"기도":3690,"기독":739,"잇는 ":257,"관한":1484,"관하":360,"국제":2470,"규모":583,"국정":128,"관해":84,"이들 ":222,"기나":120,"관할":563,"구적":61,"군인":461,"군이":624,"구제":159,"국적":195,"국전":133,"공회":208,"규명":89,"괄하":139,"교차":238,"르다 ":174,"그러":521,"그런":74,"그랑":78,"그라":318,"구조":960,"그램":1195,"그래":891,"군정":60,"그랜":101,"교체":59,"그로":269,"글라":119,"번째로":469,"그렇":75,"관현":159,"그레":393,"국주":73,"그려":165,"기념":619,"권에":285,"구지":95,"근로":136,"글러":60,"국지":159,"그루":101,"군주":362,"글랜":378,"계약":484,"여왕 ":58,"결정":751,"계열":387,"광범":88,"교들":65,"경우":1823,"계에":1064,"고시":148,"계와":142,"역사가":122,"국농":82,"고스":110,"겸임":57,"고슬":67,"육상 ":106,"고서":106,"격자":62,"倉丘 ":68,"견을":57,"격적":116,"교도":126,"것처":82,"광물":81,"곡선":132,"고성":119,"구나":78,"고속":845,"결의":140,"경에":408,"교동":80,"결을":132,"국내":616,"경영":484,"걸친":86,"권과":106,"결이":61,"경연":59,"이끌어":63,"계의":805,"구대":120,"계이":169,"과사":639,"국대":144,"계인":107,"계자":130,"군대":278,"언어학":160,"계적":562,"倉三 ":204,"경주":361,"국도":235,"구동":102,"경유":80,"겨지":139,"겨진":136,"경으":205,"경은":67,"경을":557,"경의":245,"공산":474,"경인":98,"공사":628,"경이":223,"광부":1133,"경쟁":408,"구는":2663,"계유":60,"倉丁 ":151,"경전":188,"경제":1825,"구단":288,"고와":65,"국들":75,"곡에":64,"교로":205,"고원":88,"관심":174,"율리우":65,"고용":223,"광산":147,"관습":89,"아프가":115,"고안":197,"군도":75,"구되":67,"관성":72,"관세":134,"료에 ":73,"구들":66,"외한 ":214,"고에":169,"경지":70,"고양":226,"공식":660,"공신":113,"더 ":1406,"공업":378,"공에":64,"덕 ":151,"경찰":561,"고정":166,"곳에":821,"고전":364,"던 ":4707,"교문":57,"공연":355,"구라":68,"고조":104,"공여":69,"권도":62,"공예":112,"공영":61,"고종":145,"고유":256,"교리":113,"곡은":123,"곡으":120,"고의":311,"교류":510,"고위":328,"교를":330,"거하":226,"곡을":163,"고인":82,"고이":182,"곡의":107,"고있":175,"곡이":253,"고자":344,"공적":170,"공전":79,"구르":74,"구를":602,"구름":70,"계층":171,"국립":960,"과이":162,"구매":106,"공정":235,"구리":185,"공제":58,"과의":611,"구마":87,"공익":127,"공인":185,"덤 ":58,"공작":278,"공자":115,"공의":311,"공이":148,"에스페":64,"교법":60,"공장":150,"곳을":106,"잉글랜":374,"곳은":97,"곳으":142,"고지":182,"곳이":283,"공으":88,"에스파":105,"공을":239,"관여":73,"관에":348,"과와":60,"곳의":66,"공유":261,"구려":197,"공원":601,"구로":546,"계청":60,"국령":72,"과에":332,"공용":107,"관악":84,"격파":66,"델 ":199,"고체":92,"관적":103,"에스토":68,"관점":111,"덴 ":238,"공직":57,"국문":157,"국무":264,"과정":1002,"과적":120,"데 ":4107,"공중":115,"격투":81,"벗어나":80,"과제":59,"궤도":196,"광양":81,"공주":233,"관장":263,"광역":1560,"번이다":102,"세포의":69,"과일":57,"관위":96,"관으":1430,"교부":78,"倉之 ":137,"관의":2174,"규격":148,"관을":436,"관은":726,"관인":90,"관이":1515,"구멍":69,"근거":264,"격하":210,"격한":92,"권리":429,"국불":143,"그것":304,"구분":457,"계통":173,"곤충":101,"교사":363,"국보":135,"우치 ":58,"그가":220,"군벌":62,"구별":243,"관직":120,"광장":110,"역에 ":645,"국방":338,"국민":1323,"구밀":163,"권력":210,"구미":92,"성한다":77,"급격":65,"고타":71,"달하는":148,"결혼":181,"페르시":179,"고쿠":186,"금강":116,"성하는":565,"과천":96,"관차":147,"관찰":160,"근교":78,"광진":58,"광지":58,"교수":610,"발표된":92,"발표되":107,"결합":346,"결하":438,"결한":100,"웨이 ":207,"倉並 ":110,"견해":92,"군부":82,"광주":542,"견한":104,"견하":126,"는 ":115688,"언어에":73,"관광":1592,"관구":95,"늘 ":65,"관급":89,"광객":71,"가축":73,"언어의":102,"고는":199,"언어이":170,"광고":267,"고대":997,"능 ":323,"가치":461,"고도":1752,"경로":111,"건설":619,"곡동":96,"경력":62,"의도동":78,"연안 ":64,"입된 ":104,"개척":110,"갖춘":117,"검색":157,"쟁과 ":63,"고등":647,"계로":351,"개체":157,"곡들":64,"검사":367,"객체":131,"거스":89,"갖추":158,"개최":745,"가타":160,"골든":61,"공단":148,"경마":75,"과는":512,"계를":823,"개칭":76,"공되":110,"과대":160,"공동":868,"가톨":538,"도메인":70,"닉 ":179,"계몽":70,"과도":95,"니 ":1434,"독립하":59,"게서":76,"닌 ":658,"고래":67,"고라":68,"고로":318,"거에":255,"고려":896,"관되":68,"가포":95,"건에":176,"경보":91,"게시":63,"골라":80,"고르":135,"고를":213,"작가이":229,"교가":179,"작곡가":402,"고리":445,"닝 ":121,"거의":471,"예술 ":247,"님 ":88,"거운":99,"도사 ":75,"경부":199,"경북":127,"건이":681,"가했":110,"거점":73,"것에":206,"교과":83,"거제":96,"교관":186,"곡면":66,"다 ":111349,"간하":67,"닥 ":58,"간한":58,"자는 ":1091,"번역하":66,"거인":110,"거이":70,"개통":175,"경비":85,"건으":192,"건은":246,"가하":646,"가한":227,"료와 ":63,"도모를":115,"건을":482,"검역":179,"건의":278,"각한":97,"가해":91,"각하":172,"간호":75,"달 ":337,"성하여":117,"성하였":153,"결성":349,"벌어진":238,"거주":408,"공룡":180,"과로":156,"검은":129,"단 ":1654,"각형":159,"교구":291,"건전":253,"콜라 ":66,"간행":103,"공로":98,"건조":153,"고문":120,"고무":61,"경상":955,"담 ":279,"검정":63,"강한":188,"강하":127,"관료":227,"관련":1378,"것을":2110,"아파트":117,"것의":67,"것으":1506,"게오":79,"것은":830,"개편":325,"공립":95,"예수 ":112,"여야 ":87,"것인":86,"것이":2686,"거지":151,"계선":74,"강화":343,"공무":742,"구경":84,"개한":63,"국경":557,"국계":88,"개하":180,"관리":2036,"고분":99,"공모":103,"언어를":125,"당 ":2124,"게임":2275,"게이":356,"계사":104,"계산":303,"경성":115,"구가":459,"구간":259,"과를":382,"결승":176,"국가":3195,"구개":146,"거창":63,"계수":70," ∼ ":97,"군과":252,"국교":130,"관목":62,"구권":57,"국군":183,"개화":66,"계속":320,"괴되":57,"고비":130,"개혁":328,"구관":145,"국고":62,"구광":218,"대 ":7820,"과목":73,"국과":776,"국공":136,"국관":64,"의를 ":445,"언어로":146,"계승":345,"국기":252,"거쳐":379,"구기":227,"격에":68,"공법":70,"관문":69,"구글":106,"루스 ":303,"거치":92,"격이":190,"격의":79,"고사":138,"건축":557,"격을":325,"검찰":214,"격으":151,"변에 ":94,"교단":121,"교는":208,"걸쳐":621,"결에":59,"공부":145,"이끄는":118,"겨울":101,"개미":141,"건너":96,"언어들":71,"개발":2877,"개방":130,"독립적":105,"거나":1557,"우주의":58,"본명은":189,"으로부":448,"개막":77,"각본":92," 길 ":123,"간부":65,"개명":89,"어에서":253,"강릉":107," 기 ":194,"개를":146,"가보":96,"것과":204," 긴 ":204,"감소":107,"게는":217,"자금을":57,"계가":271,"것도":92,"강서":89,"경계":516,"경과":169,"가수":461,"으로서":1111,"결과":527,"감사":119,"가스":350,"격기":81,"결국":131,"가슴":62,"가시":211,"올랐다":64,"울주군":82,"가설":126,"가서":87,"건담":81,"언어는":67,"간섭":83,"간선":71,"가속":96,"온라인":297,"거두":93,"갈색":63,"거는":139,"개별":97,"독립을":81,"개봉":161,"가사":265,"가산":81,"으로써":965,"우즈베":76,"거대":185,"가상":319,"독립운":225,"간을":392,"건립":125,"간의":1187,"감염":98,"간인":100,"동부 ":460,"간이":504,"가입":188,"경남":138,"가자":80,"각이":151,"가장":2280,"각자":67,"간으":125,"간은":170,"가을":69,"가의":732,"각을":142,"가인":226,"각의":239,"가이":1724,"거를":112,"고가":145,"곡가":419,"거리":759,"고객":146,"아티아":132,"가요":88,"가우":57,"가운":1240,"갈어":69,"발행되":71,"간에":601,"겠다":82,"개신":194,"가와":549,"개시":97,"가였":116,"가오":62,"각에":105,"거로":219,"계기":156,"계급":233,"가에":444,"왜란 ":94,"가야":126,"개수":58,"이란 ":1323,"거래":321,"경기":2213,"겨난":61,"이라 ":885,"것들":114,"감시":118,"계관":69,"개성":108,"계곡":114,"개선":303,"개설":104,"우주선":91,"느 ":258,"아티스":65,"이래 ":159,"공급":250,"관계":1290,"계된":88,"공기":688,"개조":143,"계되":101,"대통령":1050,"관과":175,"건복":108,"발표하":134,"발표한":276,"개장":97,"거부":132,"공국":116,"공군":148,"발표했":57,"으로만":64,"개정":217,"강점":455,"공고":79,"과가":110,"개의":1771,"계대":179,"공공":459,"공과":122,"강제":215,"개인":627,"강조":121,"경되":110,"과거":402,"객이":82,"오브 ":217,"개입":58,"변의 ":108,"늄 ":94,"감정":123,"개원":65,"개월":142,"간지":80,"공격":404,"계는":211,"같은":1786,"외국인":172,"같이":515,"게르":135,"공간":766,"겼다":112,"값이":110,"강의":343,"강이":240,"강은":66,"강을":182,"가지":2292,"가진":654,"공개":410,"강으":96,"각지":87,"고급":165,"감을":118,"결되":247,"결된":216,"값을":97,"수많은":217,"간주":126,"건물":382,"고기":355,"강원":385,"각종":393,"작된 ":349,"격되":57,"고구":210,"간접":88,"견된":179,"견되":279,"가져":156,"각적":77,"뉴 ":162,"가정":341,"가적":80,"고고":132,"고교":84,"가족":289,"간적":65,"갈의":77,"강에":164,"가졌":76,"각기":59,"가까":268,"가깝":67,"가기":142,"개가":139,"발하는":83,"강과":253,"갖고":277,"외국어":63,"가가":352,"각각":410,"유명하":406,"유명한":333,"가고":100,"유명해":61,"가공":315,"변을 ":61,"가게":78,"가격":229,"자동 ":86,"가경":58,"간고":62,"간과":147,"가구":64,"음반 ":194,"간격":58,"감각":102,"도마뱀":70,"각국":139,"작곡한":149,"작곡하":118,"가능":974,"가는":573,"가다":72,"가니":157,"강남":335,"가대":160,"영미법":57,"간단":335,"간다":177,"독립된":72,"으로는":2876,"우고 ":113,"뇌 ":72,"가도":58,"개관":130,"객관":70,"가나":261,"개교":78,"개국":380,"가노":67,"으로도":374,"강동":69,"강도":90,"가량":79,"개된":94,"》는 ":359,"가락":137,"개되":181,"가라":155," 급 ":610,"가들":383,"간되":110,"간된":75,"개념":759,"가된":598,"가되":103,"각되":72,"같다":132,"갈등":59,"감독":690," 그 ":3864,"갔다":90,"갖는":232,"발하고":100,"강력":160,"갈리":113,"누 ":64,"거구":248,"법에서":118,"건강":248,"가면":128,"가며":64,"감리":65,"가미":121,"개로":133,"개량":160,"가문":317,"수사 ":66,"눈 ":92,"건국":190,"갈래":67,"가루":139,"가로":847,"갈라":146,"객들":72,"거가":75,"가리":1920,"육성 ":90,"가마":120,"각류":82,"가르":365,"가를":483,"성으로":264,"역을 ":746,"역의 ":612,"성이다":196,"여자 ":201,"로스트":70,"역이 ":202,"사회학":136,"이런 ":124,"보에 ":94,"자기장":84,"여성의":88,"역인 ":105,"으로의":77,"포가 ":68,"이로 ":257,"역사학":74,"상품의":60,"상품을":66,"칭하는":246,"웨스턴":61,"세웠다":74,"연을 ":133,"동체 ":85,"이론 ":210,"연의 ":81,"웹사이":130,"분기점":81,"세청 ":72,"원에서":238,"유민주":67,"자들 ":77,"본어 ":107,"위에 ":582,"불구하":86,"섬이다":96,"의미 ":59,"약한 ":189,"보와 ":132,"어졌으":85,"소송 ":68,"업체 ":73,"본에 ":135,"위와 ":92,"렸으며":77,"특징이":235,"특징을":85,"칭한다":172,"설치 ":74,"파와 ":67,"웨스트":211,"월간 ":75,"령으로":158,"사회에":170,"령이다":76,"케스트":70,"연장 ":111,"판에 ":66,"사회의":194,"사회적":296,"로스앤":97,"사회주":304,"영어 ":539,"들고 ":146,"일러 ":99,"도쿄 ":329,"동이다":346,"열을 ":131,"동으로":429,"베타 ":78,"예비치":64,"열의 ":161,"되어 ":4088,"올림픽":756,"영에 ":111,"소수 ":73,"셋째 ":57,"콜롬비":70,"들과 ":470,"판이 ":87,"어이다":784,"상호간":218,"이니아":108,"상하이":159,"드가 ":238,"상하였":80,"역사는":67,"동아시":126,"판의 ":77,"본사는":86,"로소프":372,"도자이":65,"어있다":103,"독일어":182,"독일에":106,"독일의":688,"판을 ":143,"어있는":86,"성장하":60,"동안에":69,"어이며":75,"독자적":97,"아프리":752,"역삼동":82,"장관이":63,"원이다":371,"재는 ":561,"장관을":107,"론적 ":99,"성적을":87,"엔진 ":111,"일로 ":158,"동양사":141,"원으로":777,"업연구":87,"선진화":57,"서쪽으":883,"서쪽은":82,"벡터 ":62,"본사를":78,"동아일":75,"위원 ":99,"서쪽에":179,"역사를":147,"친환경":81,"수는 ":371,"재단 ":121,"상했다":89,"오리지":76,"보의 ":153,"파인 ":61,"러한 ":557,"소스 ":199,"도입하":78,"원자력":149,"론을 ":213,"론은 ":142,"원자로":90,"론이 ":58,"파의 ":209,"동에서":90,"보이 ":67,"역사상":171,"이를 ":1065,"론의 ":239,"이름 ":428,"복을 ":86,"려져있":78,"원이었":68,"역사적":299,"인도네":219,"판은 ":76,"동차 ":460,"속버스":59,"역사와":60,"위인 ":74,"원의원":81,"역사에":123,"으면서":126,"장군이":119,"세워졌":73,"역은 ":410,"세워진":147,"별자리":112,"본은 ":113,"인류 ":64,"파일 ":247,"어졌다":315,"위의 ":333,"업에서":66,"동영상":97,"역상으":142,"장된 ":102,"원인이":59,"치한다":628,"로의 ":620,"베이징":158,"록은 ":122,"본부는":115,"치하는":172,"업적을":72,"였을 ":64,"평균 ":104,"록을 ":144,"패션 ":61,"상황에":103,"원작으":116,"려졌다":93,"요한 ":1062,"원장은":99,"불가능":81,"상황을":61,"도이다":379,"영의 ":109,"특정한":270,"치하며":277,"일대에":115,"동쪽 ":179,"도입된":60,"도입되":74,"소비에":317,"독으로":61,"로세스":161,"도이기":66,"불가리":157,"여진 ":140,"로이 ":96,"영상을":69,"록의 ":66,"움직임":86,"움직이":119,"로세서":244,"영을 ":122,"올바른":82,"로서의":214,"원칙 ":76,"이며 ":7170,"부대 ":58,"도움을":80,"도자로":59,"도이며":276,"우체국":67,"수다 ":66,"로서는":102,"앙행정":163,"수단 ":74,"인도양":80,"치하여":88,"샌프란":83,"치하였":59,"영이 ":63,"인도에":68,"인도의":191,"로운 ":749,"독이다":59,"케인 ":80,"애플리":100,"웨어를":99,"이동하":97,"있는데":320,"상호작":138,"세인트":105,"술개발":68,"있다고":197,"으므로":160,"세츠 ":90,"우는 ":262,"료를 ":341,"양한 ":767,"요구하":87,"팀은 ":106,"북도 ":876,"없으며":74,"있다는":230,"원과 ":225,"었으나":628,"의료기":64,"론에 ":135,"어지고":78,"로와 ":177,"부기관":105,"업이다":206,"서초동":58,"동시에":375,"돌아가":62,"영역 ":58,"원주민":78,"업으로":181,"웨어이":75,"웨어의":74,"파에 ":57,"팀을 ":101,"열이 ":57,"티스트":94,"버트 ":241,"팀인 ":106,"었으며":1637,"팀이 ":193,"끌고 ":65,"이들의":125,"이들은":168,"이들을":80,"컵의 ":85,"이들이":88,"롬비아":69,"력으로":173,"있는지":77,"어진다":212,"일명 ":77,"어지는":358,"도에서":324,"레지스":65,"업인이":86,"부근에":142,"자력 ":84,"재까지":179,"로에 ":104,"인들에":65,"로어 ":69,"자로 ":938,"원군 ":162,"원구 ":57,"보안 ":111,"수도 ":546,"소비자":202,"인물 ":119,"치하고":1297,"세종특":81,"역시의":94,"성직자":104,"오스 ":205,"성질을":132,"불교의":418,"인들은":69,"인들을":66,"이듬해":68,"인들의":133,"인들이":149,"도체 ":99,"서초구":253,"불교사":82,"인디언":128,"록에 ":92,"이미 ":149,"료로 ":215,"론으로":87,"생하였":144,"로이센":147,"인민 ":73,"생하여":71,"이버 ":210,"입되었":102,"론이다":163,"입되어":66,"특한 ":81,"겐 ":159,"자니아":79,"이번 ":130,"게 ":7497,"걸 ":59,"건 ":812,"예수의":57,"검 ":84,"것 ":343,"소설가":209,"음성 ":63,"예술의":117,"어트 ":59,"업진흥":67,"케이드":87,"거 ":803,"》 ":2725,"《 ":66,"외하고":65,"〉 ":274,"소와 ":115,"자료 ":141,"곡 ":443,"고 ":30643,"곤 ":148,"되면서":411,"복지 ":67,"티칸 ":59,"운데 ":1085,"겸 ":297,"경 ":1590,"워크 ":327,"계 ":4339,"겨 ":191,"あ ":337,"격 ":421,"별지방":128,"있도록":441,"견 ":139,"결 ":234,"패의 ":75,"일반 ":275,"자리 ":281,"로이다":326,"광 ":234,"이라고":1978,"쿠니 ":89,"장남이":65,"관·":148,"로이드":134,"용해 ":222,"자를 ":1000,"관 ":2189,"과 ":18300,"곳 ":78,"록이다":99,"공 ":940,"웨이의":60,"곱 ":113,"분류 ":142,"골 ":227,"곧 ":133,"운동 ":385,"케이블":113,"교·":290,"용할 ":375,"선총독":94,"부를 ":654,"연안에":133,"케이션":201,"웨일스":98,"역에서":460,"용한 ":474,"소에 ":141,"교 ":3766,"유성구":90,"생하는":237,"괴 ":95,"쿠가와":148,"속에 ":300,"생한다":87,"생활을":151,"생활의":64,"이렇게":62,"소장 ":152,"이라면":58,"생활에":67,"동인 ":74,"설치된":235,"설치되":170,"동이 ":214,"소설이":157,"속이 ":83,"분된다":62,"용된 ":167,"소송법":99,"유사하":81,"유사한":151,"의사 ":123,"동생이":135,"소의 ":297,"소속된":73,"소속되":78,"육의 ":116,"속은 ":58,"동을 ":1013,"속을 ":100,"동은 ":194,"퍼레이":61,"육을 ":217,"이라는":1497,"속의 ":605,"코미디":122,"북동부":261,"유의 ":224,"센터 ":405,"선출하":127,"동의 ":429,"론에서":229,"부동산":93,"었지만":266,"갈 ":248,"이블 ":130,"가·":97,"간 ":2583,"이븐 ":57,"율을 ":155,"각 ":1502,"가 ":25131,"소설로":59,"이브 ":214,"개 ":2483,"객 ":182,"육성하":58,"와서 ":62,"강 ":1090,"코스 ":158,"감 ":193,"팀이다":183,"갑 ":72,"작되었":341,"값 ":73,"우도 ":215,"작되어":105,"팀으로":74,"이론과":70,"일본 ":2149,"일보 ":109,"ア ":202,"우구스":84,"소속기":439,"유적 ":73,"북동쪽":269,"션으로":78,"예수교":59,"의무를":57,"자동차":777,"예술가":65,"용될 ":69,"로아티":131,"로에서":97,"음반이":168,"션이다":124,"일랜드":482,"전과 ":393,"요리 ":109,"설한 ":86,"위에서":153,"이루고":127,"일부 ":510,"여졌다":78,"영어권":66,"보전 ":62,"의미로":213,"의미를":182,"위가 ":174,"설치하":82,"설치한":64,"도중 ":60,"우크라":193,"역이었":65,"의미가":67,"도시를":74,"이라크":126,"본이 ":103,"이러스":164,"평가를":70,"본을 ":178,"역이며":57,"운행 ":58,"의미는":59,"본의 ":1263,"도시로":1022,"역임하":186,"역임한":62,"역임했":134,"포구 ":295,"온의 ":60,"의미이":69,"의미의":91,"의미에":122,"이르기":105,"업체이":81,"베트 ":83,"소송을":60,"로야구":89,"외부 ":93,"틴어로":69,"재로 ":182,"이룬다":93,"소속의":361,"소속으":82,"이루는":173,"자들에":142,"보스니":124,"별자치":252,"이론에":160,"보존 ":138,"자들이":347,"레코드":185,"자들의":199,"자들은":141,"소속이":111,"자들을":122,"이론이":166,"용노동":84,"페라 ":140,"이론은":70,"이론을":75,"이러한":453,"율적 ":57,"이론의":70,"도시에":84,"오의 ":93,"오사카":137,"전국 ":139,"도시이":464,"도시의":101,"영어로":117,"이론적":57,"자바 ":87,"일보》":157,"의식 ":75,"송을 ":189,"서태지":87,"오와 ":60,"코리아":162,"쉽게 ":173,"세포 ":173,"의미한":603,"의미하":328,"전기 ":326,"위이다":181,"번호 ":230,"이른바":70,"일련의":181,"유지 ":127,"이른다":109,"이르는":307,"류가 ":152,"동안 ":746,"요로 ":75,"루를 ":71,"돈을 ":58,"이르렀":73,"이르러":58,"이루어":990,"우드 ":107,"수로 ":513,"수록 ":68,"요하다":73,"티오피":85,"범한 ":75,"도시는":118,"이름을":619,"이름은":905,"이름으":571,"이름의":95,"이름이":757,"이름인":68,"약품안":57,"위원회":1083,"이맥스":73,"평가하":59,"재단은":166,"역이다":379,"엔진이":58,"재단법":390,"역으로":485,"도시가":58,"엔진을":65,"센트 ":61,"선형 ":74,"위원장":186,"동에 ":602,"보스턴":85,"이름에":98,"점과 ":81,"여의도":98,"열차 ":88,"일렉트":97,"운드 ":160,"부로 ":338," 본 ":154,"생 ":830," 볼 ":404,"면의":154,"면으":111,"면은":81,"면을":202,"목사":132,"명에":192,"오스트":938,"샤 ":153,"면이":257,"없다 ":290,"새 ":176,"무공":61,"무관":282,"색 ":724,"아스 ":84,"선수가":86,"속되어":95,"속되었":68,"문과":177,"명시":68,"불렀다":77,"맨해":63,"무국":71,"물건":208,"물관":507,"물과":183," 또한":784,"무기":312,"물고":100,"문구":184,"면에":519,"쪽에 ":528,"면역":75,"문기":69,"선수권":182,"명제":72,"선이 ":276,"무대":221,"무덤":62,"명종":57,"대자동":69,"문대":131,"모아":148,"모양":499,"먼트":452,"모야":73,"면적":2044,"목소":65,"명예":174,"무네":57,"별한 ":132,"모스":327,"모습":277,"멸종":98," 라고":1124,"모시":69,"명을":535,"명은":636,"명으":376,"몬스":58,"명의":990,"명이":1234,"명인":142,"무는":91,"무늬":117,"선수단":172,"웠다 ":98,"메스":59,"목록":269,"모로":214,"쓰이고":88,"본주의":134,"마틴":68,"마티":65," 별 ":66,"었다 ":8595,"모를":206,"모르":159,"불렸다":153,"립허":405,"성에 ":315,"립했":99,"리히":298,"립한":356,"립하":482,"마포":172,"멕시":360,"림픽":766,"메시":170,"선수들":135,"마토":82,"리프":182,"몇몇":116,"립트":86,"명명":152,"마드 ":89,"만큼":116,"모라":68,"부르고":80,"마트":201,"모래":91,"복지부":89,"명문":66,"설이 ":126,"리눅스":103,"리핀":364,"리한":242,"리학":967,"리하":714,"매년 ":363,"머지":135,"삼 ":80,"명사":136,"만화":639,"산·":76,"모바":156,"용되고":286,"설을 ":221,"무거":57,"메인":168,"메이":1331,"메일":86,"매하":265,"매한":223,"무게":90,"용되기":81,"용도로":77,"문가":203,"설은 ":94,"망한":94,"망하":162,"상 ":4129,"망했":69,"명성":146,"무가":118,"대전광":266,"업한 ":64,"마하":117,"산한 ":76,"사 ":5233,"모리":571,"산하 ":318,"사·":132,"말하":599,"말한":3393,"말해":114,"알바니":106,"설의 ":132,"살 ":233,"만한":100,"모모":86,"면서":1898,"먼저":128,"산 ":2364,"연극 ":67,"림축":110,"마찬":135,"리코":146,"모노":103,"매주":81,"매장":77,"리카":1441,"리칸":149,"림청":142,"르프":78,"매일":93,"명된":68,"명되":255,"리치":164,"메모":272,"리케":256,"모나":69,"맹에":60,"르헨":201,"였으며":1303,"맡은":78,"매우":478,"명단":130,"망을":100,"리츠":81,"몽골":207,"메리":794,"메르":162,"멜로":63,"리처":147,"마주":117,"만족":167,"마지":479,"만주":184,"망원":114,"메로":64,"맥에":68,"리청":92,"리로 ":428,"마쿠":85,"몰도":68,"모듈":69,"모든":1119,"모드":98,"《글":317,"매체":185,"머스":152,"맞추":113,"더스 ":76,"마크":376,"몬드":71,"리포":321,"리투":109,"마케":253,"목동":57,"명령":365," 법 ":85,"《고":72,"멸망":116,"리튼":79,"리트":432,"멤버":200,"모두":692,"리티":185,"링크":113,"모니":182,"릭터":187,"리토":63,"마카":106,"선수를":64,"마치":202,"양하고":63,"쇼군 ":68,"모델":475,"리킨":658,"리키":700,"루지야":62,"선수로":140,"리크":106," 번 ":635,"리타":117,"맹이":84,"맺은":57,"모는":61,"마추":91,"리적":466,"린이":257,"르카":91,"립에":85,"린의":68,"리이":430,"매사":94,"리인":91,"리잡":147,"르침":80,"르치":74,"리자":271,"명과":183,"메달":133,"대이다":77,"리의":878,"리위":69,"메니":147,"리우":347,"간과 ":140,"리원":62,"연주자":75,"없는 ":605,"리올":65,"리와":436,"마시":117," 배 ":81,"명가":99,"린에":77,"동당 ":72,"리온":117,"리오":529,"류큐":59,"마스":330,"르체":115,"리엔":67,"리에":1417,"리엄":263,"리얼":106,"리어":346,"리언":69,"리야":146,"리아":4106,"리안":159,"면과":138,"선조 ":80,"만든 ":839,"워드 ":182,"부로부":57," 밤 ":74,"만들 ":66,"른쪽":57,"맡았":269,"アアア":910,"맡아":66,"말의":116,"말이":844,"메라":241,"르트":563,"르티":105,"만의":176,"류한":91,"류하":347,"류학":112,"르투":301,"많은":1276,"많으":66,"만이":234,"를테":61,"말은":132,"목과":78,"말을":157,"멀리":64,"많이":591,"마음":149,"만원":63,"마의":295,"막으":95,"막을":84,"막의":105,"마이":1302,"르토":132,"마일":89,"명나":114,"마인":99,"마자":90,"만으":117,"만을":299,"말에":148,"모가":149,"마을":459,"머리":313,"르키":132,"리지":401,"만에":262,"립적":128,"마운":61,"마우":104,"르타":206,"림이":95,"만약":57,"많아":58,"립을":177,"림의":63,"마에":203,"림을":114,"르크":924,"마와":68,"립자":112,"리즘":285,"맥스":130,"리즈":1369,"마오":77,"메디":104,"맞는 ":58,"립운":266,"르쿠":64,"릴적":114,"마쓰":345,"르케":65,"르코":77,"연구 ":736,"리조":116,"미디":615,"무총":163,"민들":272,"물체":288," 《 ":64,"대주교":92,"바니":158,"바다":409,"바닥":88,"바닷":63,"에게서":75,"받는":351,"덴마크":199,"반대":455," 》 ":203,"말기의":111,"발달":319,"바둑":111,"반도":781,"미래":237,"소를 ":405,"복잡한":88,"였고 ":681,"미로":269,"발되":197,"밀라":58,"니콜라":139,"발된":170,"바디":62," 러브":58,"반드":90,"미르":208,"에트 ":311," 럭비":135,"보장하":64,"였으나":406,"미를":235,"미리":145,"대적인":85,"북부 ":315,"원도 ":290,"바라":259,"바람":163,"말기에":91,"대적으":83," 뜻하":527," 뜻한":499,"쇼 ":167,"밀리":163,"반란":144,"묘호":73,"박람":78,"부분 ":310,"발라":85,"바로":295,"대전에":70,"발레":115,"발렌":61,"밴드":389," 로도":98,"바르":450,"바른":136,"발로":78,"에는 ":3701,"미법":59,"민과":66,"손 ":238,"씨의 ":120,"본적은":117,"본적으":80,"㎢ ":1457,"민국":7568,"본적인":119,"소 ":1996,"모험":72,"보컬 ":70,"속 ":1432,"민경":63,"모형":163,"미국":5159,"리대신":59,"미군":124,"민공":1009,"문에":1412,"르메니":81," 런던":288,"무와":74,"뮬레":141,"못하":264,"무용":185,"무엇":78,"무에":108,"석을 ":172,"무역":348,"속도로":609,"무의":163,"오스만":137,"송 ":796,"되고 ":1458,"무장":362," 라스":58,"무이":87,"무인":90,"무자":113,"못했":96,"못한":122,"물에":348,"무원":831,"무위":67,"물인":66,"물이":1091,"미나":192,"물의":738,"물을":636,"물은":155,"어나는":167," 레닌":99,"문제":1052,"받게":60,"서의 ":942,"물자":101,"문적":150,"문이":527,"문의":337,"문으":196,"문을":285,"문은":98,"번호는":213,"무제":84,"발간":137,"문장":149,"문자":743,"문인":134,"바깥":84,"발굴":181,"미노":144,"므로":460,"소리 ":122,"가고 ":59,"반구":82,"바그":84,"발과":99,"미널":258,"발견":763,"미네":81,"받고":279,"미니":258," 레드":100,"방과":160,"방공":70,"미는":124,"방검":64,"받기":77,"반기":87,"무지":87,"백과":766,"니케이":87,"방글":64," 라우":71,"쇄 ":106,"배경":222,"대중교":58,"방국":87,"바뀌":172,"민당":124," 라오":74,"바꾸":197,"데서 ":76,"물질":647,"미드":124,"바노":62,"미들":57,"배급":90,"밀도":557," 라인":139," 라이":756,"배구":85,"바나":90,"쪽의 ":187,"셔 ":93,"어떤 ":676,"션 ":1251,"면허":59,"문법":143,"더불어":242,"묘사":175,"무부":172,"각각 ":274," 분 ":172,"석이 ":101,"명하":918,"명한":593,"명해":88,"모터":117,"뮤니":177,"명했":79," 불 ":168,"모토":300,"무사":118,"리를 ":1377,"셜 ":158,"쪽은 ":318," 부 ":168,"모티":57,"쓰인다":281,"영역에":73,"무스":102,"무슬":67,"무성":57,"문사":91,"명확":97,"무선":162,"아버지":563,"몬테":144,"무상":72,"문서":608,"무소":302,"쓰이는":420,"보유하":119,"미가":155,"가가 ":278,"모함":111,"서인 ":81," 뜻은":75," 뜻으":193,"오전 ":100," 뜻을":185,"민간":303,"석의 ":89," 뜻의":103,"모하":434,"모할":70," 뜻이":249,"목포":121,"무실":1878,"무신":111,"목표":383,"속도를":65,"문신":350,"목을":213,"목으":232,"모의":222,"목은":112,"모음":164,"목이":209,"모임":172,"모이":107,"목의":117,"물들":160,"멀티":173,"메타":96,"메탈":156,"모에":58,"모어":73,"목에":288,"묘로":172,"모여":147,"무렵":74,"무로":175,"선 ":3009,"무력":69,"설 ":998,"멘트":73,"서 ":35405,"석 ":585," 라는":949,"무라":196,"명체":83,"선의 ":720,"메트":127,"영역을":65,"사할 ":58,"목적":2924,"물리":852,"세 ":2296,"었던 ":886,"사한 ":256,"물류":61," 라디":307,"성 ":4445," 뛰어":203,"대응하":136,"무리":134,"무르":110,"무를":833,"섯 ":281,"물로":548,"물론":141,"명칭":965,"코의 ":222,"섭 ":81,"섬 ":744,"선을 ":465,"섬에 ":188,"물러":57,"선은 ":236,"무료":103,"에게는":108,"베트남":406,"셀 ":135,"문명":266,"센 ":259,"성인 ":111," 때는":150,"성이 ":557,"류군":65,"운동에":85,"로즈":93,"른바 ":70,"로지":186," 디렉":63,"루를":71,"류가":157," 뒤에":143,"루마":207,"레프":79,"세운 ":205,"론의":239,"러한":558,"론을":213,"론은":142,"론으":87,"러피":111,"록이":179,"로자":119," 때까":219,"로이":916,"록의":66,"어났으":91,"록은":122,"록을":144,"로의":623,"렉터":64," 들면":62,"료를":341,"데뷔 ":105,"렉트":128,"론적":143,"로젝":410,"포시 ":85,"러해":78,"론이":279,"론인":135,"로어":89," 둘째":114,"에도 ":1237,"로에":225," 드림":64,"로야":96,"레코":236,"로아":218,"성장 ":64,"로운":756,"로우":91,"복음서":69," 등록":235,"레타":68,"로와":192,"론에":369,"본으로":94,"록에":122,"료로":247,"마는 ":64,"령을":243,"령으":158,"려진":458,"령은":67,"령의":138,"대에는":126,"로시":141,"렸으":99,"려지":128,"루이스":129," 드라":584," 드래":82,"령이":322,"루는":434," 드러":122,"로써":1210,"례의":129,"룬다":192,"력자":59,"련을":64,"련의":320,"련이":137,"로서":3082,"로세":432,"려져":1058,"령어":129,"려졌":161,"령에":131,"로소":400,"액션 ":92,"료되":58," 동해":190,"상한 ":61,"려주":69,"독교의":109,"례에":105," 동화":66,"로스":851,"도동 ":93,"운동으":60,"운동을":238,"운동은":65,"력에":199,"운동이":163,"운동의":127,"운동장":67,"렌즈":95,"레지":140,"려오":65,"롬비":71,"려운":69,"력이":427,"력의":188,"로사":75,"력은":109,"력을":1047,"려의":143,"력으":173,"였기 ":60," 두었":68,"레의":65,"래프":324,"레이":2571,"레인":196,"레일":572,"레임":136,"복음주":62,"루가":93,"로봇":217," 되지":86,"래하":136,"래한":155,"루고":261,"립된 ":2847,"래했":80,"람회":84,"레잉":82,"로부":1256,"래픽":327,"울대학":150," 뒤를":83,"로비":221,"보》":174,"랫폼":184,"레우":79,"로버":215,"로벌":433," 독특":101,"성전 ":62,"캠퍼스":89,"로베":142,"랑하":95,"성적 ":116,"로미":125,"레오":247,"럽이":82,"레온":77,"려시":129,"로바":151,"레옹":150,"어내는":57,"러진":185," 등급":161,"러지":66," 등기":66,"마다 ":357," 몇 ":197,"럽의":198,"료기":76,"수가 ":625,"어났다":277,"레아":111," 명 ":3052," 등과":227,"페이스":345,"로몬":89,"라프":68,"로망":63," 돼지":64,"려서":69,"락하":73,"럽에":218,"라하":106,"료가":69," 도쿠":173," 되어":644," 도쿄":425,"로를":314,"로만":123,"빙 ":74,"로마":1459,"러의":97," 되었":1574,"로리":196,"편집 ":64,"업기술":80,"송되었":59,"렌스":99,"롤러":79,"러운":114," 면 ":100,"예정이":232,"레시":93,"로로":266,"롤라":89,"레스":841,"레슬":216,"렉스":73,"빌 ":184,"러에":64,"라파":96,"로레":146,"로렌":92,"란트":70,"빈 ":332,"도공사":78,"랑크":259,"라틴":522,"라티":92,"라트":181,"로라":126,"비 ":1194," 두번":84,"란토":57," 동쪽":939,"렉산":237,"라톤":92,"라토":75,"라테":80,"서쪽 ":159,"세의 ":523,"례를":88," 도착":65,"랑카":81,"롯데":72,"량이":250,"런스":86,"량의":196,"라키":103,"량을":270,"량은":105,"량으":84,"러싸":178,"러시":1282,"라크":271,"로디":91,"러스":472,"예전에":64,"례로":68,"로드":367,"보이는":153,"레비":475,"량에":67,"록된":166,"록되":319," 동적":58," 동전":120,"로듀":151,"라쿠":58,"개가 ":134," 동원":67," 동위":64,"라카":115,"페인의":159," 둘러":256," 두루":60," 동의":119," 동인":124," 동이":75," 동일":295,"략적":66,"로도":729,"로동":69," 동작":222,"레바":60," 독점":68,"뜻하":537," 동영":96,"로는":3896,"뜻한":519,"로닉":61," 도중":97,"로니":159,"럼비":69,"븐 ":128," 도입":355," 독일":2033,"로네":72,"였지만":104,"영국 ":794,"세이 ":81," 독재":77," 동안":690," 동아":274,"램의":106,"페이지":237,"블 ":323," 독자":160,"램으":79,"램을":192," 동양":311,"보인다":123,"램이":268," 도요":85," 돌아":168," 도와":123,"럭비":137,"케이팅":98," 도움":142,"브 ":1116,"로나":143,"러브":90," 동시":463,"웨덴 ":161,"레르":65,"강과 ":246,"랑이":109,"렸던":58,"래의":273,"레마":102,"래이":139,"갖고 ":272,"운동량":60," 되며":91," 되면":122,"람이":690,"람의":253,"람은":92,"람으":164,"래에":165,"람을":297,"로그":1803,"랑을":65,"라진":68,"당에서":58,"라질":223,"라지":147,"롭게":172,"렸다":446,"케이프":74,"라즈":65,"로교":66," 동생":173,"운데에":81,"뷰 ":75,"페인어":121,"련되":65,"련된":461," 동서":118,"론과":135," 동성":75,"로구":410,"막부":166,"름에":203,"우리 ":186,"르자":62,"리사":226,"르이":139,"매매":71,"망명":76,"대원군":58,"르의":306,"매를":90,"메가":77,"말부":57,"리소":182,"당이다":139," 떨어":835,"린스":117,"사회 ":554,"르지":156,"리시":222," 바 ":139,"당으로":105,"릭스":107,"리스":2842,"름인":68,"름이":849,"름의":136,"름을":721,"름으":597,"름은":938,"보여주":101," 및 ":5806,"르주":61,"마사":281,"마산":169,"림수":541,"머니":414,"먹는":147,"선수이":268,"용되어":68,"용되었":289," 반 ":121,"말로":462,"마를":97,"마르":609,"리보":100,"리본":58,"마리":562,"말레":213,"ああ":1092,"마루":87,"리버":108,"률에":74,"리베":90,"세에 ":126,"사후 ":103,"섬을 ":86,"말리":164,"리브":160,"마모":59,"률을":89,"률의":82,"유가 ":79,"류의":468,"류이":218,"루프":57,"륙의":69,"류인":86,"우를 ":179,"선시대":218,"본에서":359,"르에":154,"만명":119,"률이":149,"리비":231,"뿐 ":113,"르웨":217,"마법":87,"표기법":77,"아어 ":389,"마뱀":70,"르와":82," 미 ":80,"마디":57,"맞는":62,"마드":193,"리로":509,"맞닿":106,"맞대":170,"만든":919,"만드":289,"만들":1730,"리를":1378,"루터":61,"매니":102,"리마":98,"베키스":65,"리만":74,"어로 ":1139,"리모":80,"리면":59,"르세":70,"리며":220,"리메":102,"료하":61,"많다 ":288,"아에 ":243,"루트":166," 또는":7044,"매되":436,"마라":171,"매된":213,"운동가":315,"류에":196,"마련":128,"와이 ":67,"르시":280,"류와":152,"리바":71,"섬의 ":133,"리미":169,"르스":205,"말라":199,"마로":110,"륙에":126,"와의 ":292,"만나":155,"않아 ":81,"리들":59,"마노":70,"리드":424,"리듬":79,"립대":87,"만년":233,"르미":76,"마누":86,"르바":197," 딸이":114,"른바":71,"르베":87,"마는":64,"코어 ":106,"립되":628,"립된":2855," 때에":297,"마니":282,"마다":425,"막대":84,"르부":80,"동가이":124,"많다":296,"리랑":80,"리라":82,"르비":233,"용되지":64," 때의":151,"매년":365,"루지":119,"리눅":103," 디젤":62,"룹이":172,"룹의":106,"리노":143,"마그":94,"르렀":74," 디자":437,"르러":58,"많고":58,"만과":68,"마구":74,"월까지":163,"리나":257,"마나":106,"리되":201," 따위":129,"리된":63,"르면":329,"리도":58,"르모":65,"를린":149,"르몬":72," 디지":563," 따왔":76,"르메":125,"르며":194," 따온":72,"맡고":199," 디즈":98,"리더":98,"상품 ":73,"린다":701,"르마":127,"리대":73,"르만":187,"리니":123,"르를":106,"리다":169,"매개":71,"리단":71,"리는":1356,"말기":395,"를로":97,"로회":57,"루에":65,"르드":132,"름다":121,"루었":69,"리그":1570,"루어":1049," 때부":83,"리교":75,"롤플":72,"릭교":272,"루아":114,"리고":1473," 등의":1711,"록한":139,"록하":240," 등을":1621," 등은":71," 등으":490,"용된다":504," 등장":882,"르도":108,"리공":66," 등이":930," 디스":332,"로프":248,"료이":131,"료의":83,"르데":87,"로하":57,"리게":121,"로피":98,"른다":783,"루이":519,"용되는":630," 등지":163,"류를":301,"세와 ":160,"마가":184,"립국":88,"루의":66,"룡이":113,"립과":102,"립공":193,"롯한":246,"롯하":108,"롯해":85,"리기":520,"류로":226," 따서":167,"르디":177," 들어":754,"론토":100,"로트":65,"류되":96,"류된":67,"르나":166,"성을 ":1294,"로테":59,"アア":1184,"류는":92,"령하":64,"니티 ":64,"로토":241,"루살":113," 때로":79," 물 ":110," 떠나":66," 등에":874,"부등식":78," 들이":58,"리가":609,"르니":86,"르단":65,"르다":274,"부문 ":76,"성은 ":337,"대에서":249," 때문":1317,"르는":1030,"룹이다":116,"서식한":105,"서식하":112,"로파":60,"르네":183,"료와":64,"루시":73,"료에":110,"르노":173,"로페":81,"루스":522,"르가":186,"씨식물":94," 따로":85,"려하":124,"르게":347,"르고":464,"력하":175,"력한":156,"포스 ":94,"루미":72," 따라":2041,"표기하":113,"르기":616,"로크":88,"용되며":85," 디비":65,"로키":66,"름과":57,"로타":76,"뼈 ":57,"련하":119,"련한":87,"로켓":139," 딸로":65," 따르":395," 따른":279,"로코":155,"성의 ":571,"월드 ":285,"비즈":153," 면이":112,"술관 ":61,"서울대":188," 목사":116,"비주":93,"술과 ":112,"비전":604,"비정":124," 면역":63,"비잔":183,"비자":254," 면에":75,"비의":141," 무기":218,"비이":110,"비유":59," 물고":76,"비율":126," 물건":200,"비용":150,"어를 ":713," 색 ":76," 맨해":60,"선에서":160,"비오":69," 새 ":102,"비에":454,"비영":173," 모아":120,"포스트":82,"다음과":165," 무대":132," 명제":57,"빼앗":60," 명의":647," 명이":852," 모스":252," 모습":262," 멸종":93,"데미 ":77," 명으":136," 명을":174," 명에":64," 목소":63," 면적":1943," 명예":164,"빛을":75,"빛의":78,"빛이":59," 선 ":178," 메트":66,"빅토":130,"류와 ":147," 무렵":70," 무력":62,"상태에":175," 서 ":81,"비크":81," 목적":2802," 메타":86," 메탈":133,"쓰 ":219," 모음":140," 모임":130,"양부 ":86,"쓴 ":323," 모여":146," 모양":452," 멀티":170,"비치":319,"상태이":66,"비해":227,"비하":168,"씨 ":474,"비행":326,"립대학":73," 물리":729,"수권 ":164,"비평":114," 세 ":1630," 문명":202,"단어이":100," 무리":83," 성 ":737,"비판":182," 무료":100,"위는 ":290," 섬 ":655,"소련의":131," 명칭":907,"대신을":63," 물론":123,"비트":348," 메모":266,"왕의 ":270,"비로":129,"비롯":537,"빌라":66," 매장":60,"비례":72,"마르 ":85," 매일":60,"대중 ":103," 마찬":135,"부터":5834,"비를":209," 매주":80,"서울시":173,"마를 ":96,"서유럽":60," 만주":134," 망원":101," 리처":111," 만족":131,"빌딩":554," 마주":96,"단에서":85," 메리":77,"스》":261," 몽골":174," 메르":63," 맡은":78," 매우":478," 명단":126," 마지":456,"대수학":86," 멸망":115,"르부르":74," 모두":685," 멤버":192," 링크":71,"분포":314,"왕이 ":131,"영토 ":78,"분파":90,"브스":61," 리투":93,"비밀":157," 마케":230," 명령":322," 맞추":106,"부하":241,"부학":61,"부한":79," 마크":121,"북한":235,"말로 ":363,"빠르":149,"빠른":101,"부품":104," 몰도":67," 《글":315," 모드":84," 모든":1118," 모듈":58," 매체":153,"빌리":113,"부통":99,"다양하":99,"다양한":769,"솔로몬":76," 마치":120,"부패":65," 모델":414," 마카":90," 모니":75,"브웨":59," 마틴":63," 모래":84," 모로":109," 목록":249,"비상":121,"비사":81,"률에 ":68," 멕시":326," 마포":164,"비서":71," 메시":150,"블이":59," 모르":86,"아와 ":370,"분해":122,"분할":143,"분한":71,"분하":183," 만큼":59,"빌보":67,"부활":98," 명명":148,"부호":224," 명문":58,"분화":119," 몇몇":116,"부흥":81,"안에 ":523," 만화":581," 모바":147," 명성":112,"비아":1009," 상 ":162," 메이":433," 메인":91," 무거":57," 무게":59,"비어":60," 《대":64,"왕을 ":61," 모리":222," 》는":90," 마하":64,"비슷":450,"다양체":72,"비스":1259," 사 ":101,"비시":110," 먼저":127," 말하":595," 말한":3392,"마니아":199," 산 ":314,"립되어":101," 말해":112,"립되었":460," 바닷":63," 받는":232,"얼 ":291," 물체":225,"억 ":318," 바다":321," 바닥":59,"언 ":512,"어 ":13255," 미드":74," 미디":308,"뿐만":235," 반드":89,"요르단":59,"뿌리":157,"업 ":1759," 미래":216," 반도":513," 바둑":89,"엄 ":340,"오고 ":79," 반대":427," 발달":304,"않을 ":58,"류인 ":79,"않은 ":396,"외버스":131,"엘 ":358,"코에서":61,"엔 ":200," 미리":101,"왕위 ":75,"에 ":60715,"륙의 ":69,"역 ":2192,"여 ":11527," 발렌":60," 발레":96," 밴드":336," 바로":243," 반란":141,"연구기":185," 묘호":66,"㎢이며":85," 바라":115,"단위이":64," 바람":140," 수 ":4761,"연대 ":75,"안의 ":228," 문학":506,"연구관":133," 발매":1040," 반면":95," 무형":61,"염 ":118," 문헌":108,"엽 ":65,"류의 ":468," 박물":283,"다이아":64," 바르":206," 민법":129,"연 ":555,"연구가":59,"연구개":126,"열 ":422," 미분":130," 무함":67," 무한":103,"표되었":92," 반발":61,"예 ":316,"컨트롤":65,"상호 ":183," 방면":68," 반복":102," 미사":275," 백만":60," 문화":3374,"영 ":1172," 발명":156," 뮤직":150," 뮤지":132,"안을 ":183," 번길":63,"마리 ":98," 미술":327,"옛 ":293,"단이다":349,"도는 ":1874," 민속":126," 미스":154," 방법":913," 민사":90," 방문":137,"능한 ":349," 미생":74," 바빌":60,"다음으":96,"올 ":130," 박사":165,"연고로":70," 반사":111,"오 ":2121,"꾸는 ":60,"단으로":253," 미시":127,"온 ":1060," 벨기":181,"옥 ":109," 묘사":165,"씩 ":192," 문법":92,"씬 ":58,"분석 ":120,"뻗어":76,"비히":129,"빌헬":89,"서에서":124,"서양에":67," 모터":106,"안 ":2071,"다이묘":287,"부속 ":57,"아 ":8561,"여겨진":95,"여겨지":132,"악 ":699," 무선":135," 명확":90," 몬테":130,"알 ":228,"원래 ":383," 모토":78," 무사":83,"앙 ":331,"아인 ":67,"역대 ":70,"악의 ":190,"압 ":126,"세종 ":61,"암 ":229,"안산시":60,"아이 ":66," 문서":489,"단위로":101,"르비아":166," 문신":338,"애 ":160,"액 ":125," 목표":359," 목포":112,"앨범이":199,"상태를":182," 무신":103,"아의 ":1952," 무슬":66," 민간":289,"다이라":201,"악을 ":149,"앤 ":156,"우디아":57,"오에서":59," 소 ":58," 속 ":64," 모험":70," 미국":5128," 미군":118," 모형":148,"펼친 ":88," 무엇":78,"연결된":112,"연결되":159," 무역":240,"상태로":92,"쿠데타":107,"육군 ":150," 못하":260," 무용":112," 물에":69,"야 ":1639," 못한":122," 못했":94,"약 ":1839," 송 ":74,"얀 ":94," 무인":69," 무장":257," 문인":57," 문자":616,"어린 ":76," 문장":142," 발간":125," 물을":74," 미나":115," 물이":74,"쪽에는":101," 받고":185," 미네":57," 발견":731," 문제":899," 발굴":168," 바깥":84,"양 ":1169," 바그":80,"단체 ":215," 미니":154," 바꾸":196," 물질":502," 바뀌":168,"대신하":67," 배경":215," 배구":64," 백과":71," 방글":64,"오가 ":92," 밀도":372," 배급":88,"㎢이다":412,"바타":69,"바키":98,"배출":125,"바탕":457,"박테":79,"케팅 ":75," 루마":188,"보드":262,"별명":122,"포의 ":126,"버스":1087,"보디":132,"바퀴":74,"법사":70,"외에 ":210,"방출":95,"《한":112,"법상":248,"버시":57,"여기에":152,"만나는":64,"대서양":169,"보도":136,"병력":63,"대인 ":123,"더라도":75,"미트":96,"습 ":140,"별로":160,"보는":250,"미터":286,"보니":57,"보다":1010,"앞에 ":58,"승 ":599,"미토":66,"아주 ":103,"미크":58,"백질":181,"서》":62,"슨 ":398,"봉기":75,"보내":172,"미코":72,"상트페":66,"보나":64,"션은 ":114,"백제":182,"업단지":59,"벨리":83,"방지":261,"션을 ":118,"미카":113,"미치":144,"백인":67,"션의 ":92,"방정":311,"베리":361,"연구하":376,"받지":126,"법무":134,"스 ":13453,"백작":129,"병대":98,"방의":550,"방이":189,"방인":58," 레코":213,"성에서":91,"アア ":190,"바지":303,"방을":182,"방은":68,"방으":94,"베르":797,"베를":164,"방전":97,"방자":121,"배우":453,"반직":145,"본부":489,"분과":114,"연구자":69,"배하":244,"밝히":70,"사하였":95,"부고":63,"사하여":75,"부과":108,"불가":326,"불리며":153,"배했":65,"범죄":410,"별시":2275,"방향":410,"부가":553,"보보":58,"방행":151,"연구원":419,"쪽에서":93,"범주":67,"베이":1145,"번지":621,"법정":263,"연구와":136,"대상이":87,"법적":239,"발효":94,"법전":58,"번째":2258,"법조":75,"방해":160," 르네":101,"대상으":305,"보병":102,"방하":123,"여기서":132,"법인":2460,"밝혀":97,"버지":661,"배포":144,"바흐":101,"병사":95,"베어":68,"분류하":120,"범은":64,"범으":68,"범을":60,"사학자":68,"반화":65,"법으":406,"법은":260,"법을":510,"변수":210,"범이":273,"법의":401,"범인":79,"발현":63,"번주":320,"법이":695,"본명":404,"발하":523,"싼 ":93,"발해":78,"법원":385,"복무":64,"보물":134,"발한":597,"범위":305,"발했":61,"발행":355,"버전":329,"보면":93,"볼리":68,"설이다":223,"반하":117,"반한":76,"사학위":59,"부산 ":108,"벌이":122,"벌인":102,"번이":145,"동과 ":314,"벗어":103,"별히 ":78,"발표":789,"번의":336,"법에":547,"범에":61,"싱 ":188,"복리":93,"보리":111,"보를":504,"보르":185,"사항을":108,"반포":61,"십 ":167,"심 ":452,"벌어":349,"쿠라 ":120,"보통 ":571,"번역":488," 로켓":129,"번에":76,"발트":112,"민회":89,"베스":344,"버에":60,"보로":179,"선정되":73,"본래":267,"실 ":537,"신 ":2121,"시·":101,"바티":117,"표를 ":238,"보라":58,"대의 ":1668,"바트":73,"아시리":63,"시 ":11102,"식 ":2547,"어떻게":123,"별법":78,"미합":62,"미하":416,"미한":620,"배치":148,"민스":65,"방부":88,"벨기":186,"연결하":272,"소셜 ":67,"었다가":169,"박사":214," 레오":139,"델로 ":62,"불리는":292,"반사":163," 로버":203,"변경":400,"미쓰":125," 로베":67,"불린다":546,"방문":160,"사회를":100,"민사":140,"었다고":153,"반부":115,"바빌":62,"미소":59,"콘서트":79,"사》":106,"대성당":95,"미술":456,"민속":159," 로마":1229,"안전 ":96,"미스":278,"어드벤":57,"방법":1110,"미시":173,"에너지":555,"믹스":156,"연구소":525,"술 ":1167,"문화":5237," 라트":76,"반민":78," 빈 ":109,"뮤지":139,"뮤직":175,"사회민":64,"번길":63,"동계 ":168," 로렌":78,"배를":124,"방면":99," 라틴":503,"법과":157,"반발":61,"반복":104," 레슬":75,"미상":126,"미생":82,"법규":59,"미사":365,"백만":74," 레스":71,"사회복":58,"윈도 ":523," 로드":134,"리드리":128,"민법":149,"바리":82,"섬으로":166,"물품":90,"무하":135,"무한":119,"무함":67,"미분":165,"소속 ":308," 러시":1253,"수나 ":68,"무형":102,"반면":95,"발매":1060,"업하고":81,"숙 ":91,"문하":118,"문학":996,"수 ":7565," 롯데":68,"버그":188,"발명":165,"박물":478,"었다는":78,"문헌":145,"물학":358,"순 ":180,"연구에":78,"슈 ":248,"받을":102,"보관":133,"받으":61,"받은":358,"발의":72,"발음":233,"본격":104,"방어":137,"발을":206,"방언":181,"박정":58,"보교":91,"발이":87,"방에":589,"밝은":61,"반정":76,"방영":378,"발자":127,"반적":1188,"보건":323,"밖의":84,"발원":228,"반응":325,"방안":91,"반으":349,"반은":59,"반을":232,"반이":289,"대용 ":70,"법령":101,"반의":263,"본거":86,"반인":88,"보고":314,"법론":58,"별도":116,"산하의":96,"보급":496,"배에":64,"보기":184,"배열":85,"별된":62,"벨라":135,"발족":210,"방위":167,"본과":71,"본관":553,"변동":70,"백악":117,"발적":105,"발전":2168,"법률":748,"본국":57,"본군":86,"반에":291,"리며 ":216,"받았":547,"민중":107,"바오":74,"받아":531,"연고지":92,"민주":1442,"벌레":89,"반영":96,"생활 ":136,"미지":217,"바에":127,"베드":57,"소설 ":296,"밀접":73,"미주":57,"밖에":180," 로서":72,"부르크":380,"버로":72,"버리":89,"부르키":72,"리되어":97,"보가":134," 로스":253,"바일":167,"바이":1137,"박이":57,"바의":87,"밀집":72,"연구를":213,"발에":122,"평양에":104,"바위":87,"민지":365,"민의":388," 레지":112,"민을":66,"민이":137,"배상":72,"방송":1655,"불리고":64,"병과":64,"미이":133,"연한 ":80,"미의":191,"민운":60,"베니":113,"방식":893,"밑에":68,"뮌헨":76,"버러":63,"민족":1125,"연합 ":418,"민정":107," 렌즈":75,"불리기":218,"생태계":74,"쉬 ":68,"버드":123,"미에":254," 로부":64,"미어":138," ㎢ ":1456,"미야":182,"베네":199,"단지 ":89," 레이":539,"미얀":97," 로봇":182,"미아":149,"발생":1139,"열대 ":90,"발사":358,"방사":203,"미우":66,"밀양":61,"었는데":175,"미와":61,"에티오":85,"바실":66,"민에":93,"박스":126,"앙에 ":58,"바스":196,"부시":91,"보편":89,"《동":63,"부스":118," 메가":61,"《대":78," 망명":76,"부속":120,"분석":483," 막부":162,"당시의":130,"보험":439,"비공":80,"복합":220,"보행":57,"복하":136,"북아":337,"보화":79,"부아":90,"보호":994," 먹는":127,"비교":324,"덜란드":394,"동기 ":74,"비가":127,"사하고":71,"보한":539,"보하":152," 리스":112,"별한":142,"별하":152," 마리":480,"변형":136,"분비":61,"변호":218,"콘스탄":176,"변화":514,"변환":239," 말리":67,"불법":161," ああ":304,"부분":1658,"부부":74,"북부":794," 말레":203,"보컬":139," 리버":60,"변하":108," 말로":338," 마르":422,"다에서":81,"부산":804,"서울특":2233,"부사":121,"별히":78,"부상":150,"보통":876,"북서":597,"부선":57,"부설":70,"본토":85,"분산":123,"부서":74,"였던 ":503,"단어는":61,"》는":360," 마법":66,"사하는":206,"《뉴":90,"어떠한":155," 리비":141,"쪽으로":3077," 뿐 ":75," 만명":106,"병하":65,"병합":73,"분리되":151,"소리를":144," 만에":155,"블루":171," 많아":58,"북쪽":976," 메디":66," 마오":62,"브리":671,"분류되":81,"비는":93,"분류된":61,"블로":244,"블록":95,"붙은":60,"붙이":74,"붙인":86,"브르":78,"아직 ":93,"분지":84,"브뤼":58,"브루":161,"부지":240," 마쓰":270,"블레":66," アア":171,"블랙":152," 말이":732," 말의":90," 맡아":66," 맡았":269," 멀리":60," 많이":589,"부총":58," 말은":95," 말을":102,"원대학":60," 많으":66,"비디":498," 많은":1059,"부처":108,"비드":137,"부천":98,"역학 ":84," 마일":63," 명나":109," 막의":74," 마이":939,"역한 ":65,"부착":63," 마음":145," 마을":343,"매된 ":209," 머리":222,"비되":67," 말에":106,"블리":126," 마우":75,"부위":94,"북위":64,"북유":57,"부의":976,"북으":70,"부이":295,"부인":395," 마스":139,"불어":280,"영국군":62,"부원":64,"봉한":65,"부였":63,"영국과":68,"불안":74,"부와":395,"분에":266,"분열":122,"당시에":146," 마산":139," 마사":186,"비극":79,"부에":2420,"보훈":113,"석으로":73,"분야":1297,"부여":260,"여할 ":326,"블라":186,"브로":228,"붙어":138,"북조":69,"브랜":239," 매사":94,"브러":125,"브레":203,"붙여":262,"여한 ":90,"붙었":64,"》를":132,"분쟁":215,"부정":220,"부제":59,"빨간":59,"부적":74,"분자":304,"브란":69,"부족":250,"브라":793,"부조":64,"불이":70,"붉은":121,"비나":140,"분으":162,"분은":160,"서이다":247,"부장":172," 류큐":57,"부자":61,"부작":96,"서울지":61,"분이":366,"분의":455,"표로 ":284,"분을":409,"법칙":261,"코스트":84,"보시":70,"벤처":112,"대전 ":499,"보스":329,"병원":361,"본식":170," 많고":58,"대적 ":85,"봉사":97,"병이":85,"르바이":113,"병의":61,"편으로":96,"병을":93,"부담":95,"별지":141," 마그":88,"편이다":60,"섬에서":72,"부는":373,"분류군":63," 리눅":99,"마로 ":78,"분당":74,"북대":84,"륙에 ":70,"북단":60,"부대":314,"부도":71,"부동":151,"북도":1000,"북동":589,"《아":100,"법학자":59," 매개":67,"보안":263,"보아":63," 말기":330,"버트":260,"보에":135,"》에":434," 리더":83,"부등":87,"보여":239,"오카 ":175,"분되":78,"분된":74," 맡고":199,"본에":513,"보와":133,"보였":72,"본어":215,"북구":223,"부근":226,"불과":67,"백화":66,"부기":151,"왕조 ":222,"북극":86,"불구":99,"불교":1054,"분기":161,"변에":132," 롤플":72,"《삼":93,"《사":79,"였다 ":5818," 리그":1028,"붕괴":176,"보상":91,"보살":73,"복사":130,"부르며":106,"변을":61,"변의":108,"본사":255,"변이":82,"보성":57,"복선":58,"산하는":104,"마누엘":65,"병역":76,"별이":83,"복소":98,"본선":122,"별자":389,"교·철":266,"변조":64,"《스":59,"보수":235," 루이":396,"복수":116," 만들":1714," 만든":918," 만드":275,"엔터테":273,"분리":365," 맞는":58,"아시아":1039,"아시안":64,"분류":756," 마드":70,"부리":81," 매년":364,"생한 ":427,"부문":240," 매니":71," 루터":58,"불리":906,"선이다":194,"불린":592,"부모":121," 맞닿":106," 맞대":170,"북면":63," 마라":96,"북방":63,"연구회":81," 루트":124,"북미":98," 리메":64,"동구 ":190,"부르기":284," 말라":128,"대장 ":64,"선으로":205," 마련":126,"변화 ":64,"니카 ":85,"위공무":227,"보유":232,"벡터":159,"》이":131,"》은":258,"복음":190,"》을":87," 리듬":66,"보의":154,"복을":86,"》의":292,"베타":109,"베키":68,"복원":94," 만나":155,"보원":72,"보정":59,"써 ":1207,"본인":182,"보전":215,"보조":194,"복제":80,"보장":241,"산하고":57,"보인":174,"보이":571,"보자":82," 만년":216,"보잉":66,"본의":1265,"위대 ":64,"본이":148,"본은":114,"본을":178,"복잡":213,"본으":94,"류에 ":144,"벤트":72,"번호":560,"부로":440," 많다":296,"베트":571,"보좌":71,"본적":361,"보존":422," 마다":65,"별칭":85,"본제":60," 막대":80,"불렸":246,"부르는":270,"본질":90,"부르":1396,"부를":656,"부른":614,"본주":135,"벨트":79,"보증":59,"범한":75,"범하":94,"복지":390,"법학":195,"불러":105,"불렀":138,"부른다":562," 기름":70,"사자의":62,"에른 ":64,"된다 ":2822,"레 ":617," 국토":265," 기리":96,"렌 ":169," 기록":1008,"높이":655," 될 ":180,"누리":83,"놓은":145,"에르 ":123,"육관광":1111,"지휘관":62," 교회":451,"렘 ":99," 교황":491,"노출":59," 교환":135,"노카":116,"는가":88,"영한 ":59," 교향":137,"사이자":85,"사이의":380,"되던 ":89,"뉴기":78," 귀족":241,"소니 ":75,"농촌":268,"렬 ":143,"노쿠":69," 구하":94," 두 ":1616," 규제":69," 규정":454," 기반":744,"뉜다":143,"려 ":970,"영국령":58," 금속":188,"사이에":1050," 기법":166,"력 ":1905," 기본":560,"련 ":727,"령 ":1058,"의가 ":145," 그와":88,"페인 ":307,"갔다 ":76,"례 ":297,"에피소":110,"느끼":75,"념하":189,"페이 ":59," 구현":181,"분에 ":187," 둔 ":199," 국회":467," 둘 ":80," 그에":142," 군주":331,"네치":59," 그로":78,"영국에":154,"량 ":637,"사이트":392," 기념":453," 그려":163," 관현":152," 그렇":75," 그레":286," 그러":510," 그런":74," 교차":215," 그랜":97," 그래":457,"농산":152," 그라":116," 구조":750," 관해":73," 관할":541," 관한":1386," 관하":68," 국제":2240," 규모":317," 국적":83," 구제":77,"두고 ":439," 군이":85,"념이":269," 군인":411,"념일":61,"노스":368," 공화":1170," 군의":89,"크게 ":346," 기동":58,"대해 ":649," 권익":198,"진행하":112,"노예":123," 기독":683," 기도":110,"사이타":67,"노에":90,"사이클":132," 권위":133," 그린":258," 그리":2688," 궁전":116," 기대":78,"불어 ":253," 그림":284," 기능":764," 광학":73," 기니":64," 그를":80," 글로":188," 그루":89," 근로":105,"감독 ":133,"동물 ":185," 그룹":609,"농수":73,"러 ":2371,"오토 ":64,"덴의 ":130,"놀이":209,"높아":61,"농어":139,"논쟁":109," 구축":257,"농업":544,"웨덴의":119,"노인":60,"논의":106,"녹음":73,"노이":170,"노의":75," 구체":160," 근무":128,"양성 ":103,"설립되":451,"설립된":2612," 된 ":602,"럼 ":613,"럽 ":802,"높은":480,"누르":181,"대학 ":618," 근본":125," 교통":460,"대한 ":2759,"놓여":60,"럴 ":180,"독부 ":84,"네트":660,"외의 ":195,"런 ":372,"네팔":64," 교토":88,"단기":81," 길이":462," 기존":437,"담고":149," 기종":88,"사이를":61," 뒤 ":412,"니는":215,"루이 ":211," 기준":2663," 김일":102,"의거 ":83,"사이며":98,"니다":213,"대개":179,"대가":323,"당과":113,"보통신":129,"대공":201," 김정":92,"대고":184,"당구":102," 기지":96,"대구":662,"대국":94,"대군":106,"대교":257," 깊은":74,"능력":467,"다나":107,"생이 ":83,"판타지":99,"대규":180,"유고슬":66,"애인 ":68,"대까":71,"대기":340,"사위원":70,"봉한 ":64,"액을 ":97,"다는":1787,"루의 ":66," 균형":110,"다니":145,"다다":78,"같다 ":114," 기체":135,"당나":184," 기초":518," 까지":200,"니라":554,"업무 ":115,"단독":80,"로토콜":205,"크고 ":90,"도로가":62,"단된":60,"단되":119,"다드":63," 김천":57,"뉘어":86,"달되":59,"뉴스":481,"담당":568," 드 ":245,"당대":81,"영국의":714,"생의 ":215,"사이드":109,"대는":204,"에만 ":119," 극작":78," 기생":98," 극장":162," 기사":214,"산이다":72," 그의":924," 기상":201,"소는 ":346,"노트":95,"대형 ":188,"도로로":74," 글자":146," 글을":71," 권한":175," 기소":61,"노폴":62,"늘날":414,"누스":263,"눅스":105,"는다":1118,"노프":93,"느님":102," 금융":393,"니가":164," 기술":1634,"부산지":60,"론 ":1033,"산으로":200,"록 ":1898,"로 ":67654," 급제":82,"는데":1842,"니고":130," 금지":145,"눈에":57," 규칙":165,"롤 ":88,"누어":127,"누엘":65,"영화 ":632,"다가":955,"성부 ":74," 기억":140," 기업":903,"롱 ":111," 기여":1107,"롬 ":79," 기아":103,"가나가":58,"단계":343," 기원":1309," 근처":198,"농협":62,"생산한":69,"다고":1243,"생산하":159,"되기도":259,"사용해":88,"사용할":205," 기자":613,"단군":64," 기장":60," 기재":70,"사용했":107," 김영":81,"육과정":69,"사이버":92," 김씨":58,"다국":61,"단과":143,"영된 ":101,"사용하":1482,"사용한":491,"우루스":147,"대비":160,"니아":1877,"다수":306,"단속":75,"달성":181,"니어":177," 딸 ":100,"대부":1072,"다섯":195,"징하는":66,"대백":608,"능을":413,"대방":188," 따 ":65,"니시":132,"능이":137,"는지":249,"사우스":167,"대법":96," 딴 ":76,"대본":115,"대변":64," 꼬리":58,"변화에":59,"대문":243,"퍼시픽":98,"닉스":176,"니스":713,"다에":144,"대수":239,"당시":1347,"다양":1016,"니즘":123,"대시":62,"다와":77,"단어":494,"니지":109,"대신":635,"단에":340,"님이":60,"님의":97,"대승":104,"덜란":394,"보호 ":293,"업하였":82,"대서":179,"당수":72,"대성":249,"더라":88,"당선":166,"《글로":315,"대상":709,"니이":111,"대사":358,"니의":167,"니온":70,"다시":502,"니와":67," 때 ":1805,"다스":163,"니오":102,"단순":280,"니에":124,"니우":69,"당사":230,"단말":68,"도로와":66,"다른":2127,"다르":492,"다를":71,"능성":166,"아어로":59,"다리":327,"룡 ":75,"다마":68,"다만":82,"집합이":107,"도로이":159,"다룬":160,"도로의":196,"다루":444,"달러":146,"니버":155,"달려":57,"집합을":57,"뉴욕":478,"가까운":155,"달라":143,"가까이":69,"사이다":504,"대회 ":303,"지휘하":108,"대되":108,"다란":88," 등 ":2330," 기타":617,"니며":81,"니메":636,"대동":97,"료 ":646,"생을 ":121,"대도":73,"어로는":135,"당되":95,"요시 ":90,"대대":66,"대덕":70,"당된":101,"다비":69,"담배":65," 김해":111,"대만":114," 기후":202,"대립":98,"대리":167,"단법":2075,"대륙":468,"단백":191,"룹 ":318,"대를":566," 기회":105," 기획":174,"늘어":87," 기호":241,"룸 ":70,"뉴질":239,"사용자":630,"간된 ":72,"동방 ":109," 기하":177,"대로":1018,"대량":103,"대략":109,"룬 ":185,"생산자":98,"다목":60,"달린":72,"달리":502,"루 ":753,"倉三三":66,"다면":173,"동단":59,"동당":117,"동대":173,"대출":63,"다테":75,"대칭":171,"되거":99,"데서":86,"리 ":8468,"소년 ":186,"되고":1487,"닌텐":124,"도덕":82,"다카":195,"분야 ":184,"데뷔":278,"다케":114,"도동":111,"생산되":114,"생산된":72,"니티":109,"대책":66,"대체":365,"더스":149,"도리":106,"르네상":84,"링 ":477,"릿 ":94,"사업자":63,"도를":839,"도르":185,"립 ":1307,"더이":67,"대통":1071,"도마":97,"립·":64,"독립":1230,"단하":227,"막 ":535,"단한":192,"동력":113,"도모":729,"마 ":2884,"부에 ":2000,"도메":83,"동량":72,"달한":116,"달하":316,"만 ":5041,"리나 ":165,"표기 ":66,"파키스":153,"린 ":1716,"릭 ":421,"도라":117,"릴 ":239,"리·":102,"음과 ":230,"던에":74,"데시":125,"도록":1047,"도로":1920,"되기":565,"않았다":134,"데스":339,"월드컵":315,"단편":181,"더욱":101,"림 ":455,"다중":115,"어로서":101,"단조":57,"대역":76,"대에":1339,"담은":79,"률 ":308,"닿아":111,"도군":69,"도구":218,"독교":722,"도교":185,"데라":73,"대안":86,"도권":125,"대용":96,"륨 ":85,"대우":165,"당이":352,"델로":83,"단지":227,"대원":153,"사우루":135,"당으":106,"당은":139,"당을":126,"많고 ":57,"대외":71,"당의":341,"대와":275,"동가":358,"대왕":208,"동강":89,"도가":518,"산업의":264,"산업을":71,"다의":253,"다음":663,"댄스":109,"다운":233,"양시 ":144,"달에":108,"양식 ":64,"단이":638,"단일":159,"갖는 ":164,"단장":102,"컴퓨터":1613,"도공":91,"류 ":1253,"달을":122,"달의":59,"륙 ":150,"부와 ":386,"당에":141,"다이":1163,"에드워":105,"단위":503,"단으":253,"단을":267,"단은":441,"단의":275,"부산광":308,"國三三":57,"대지":106,"단체":1326,"니크":67,"데미":171,"데스크":83,"를 ":35910,"대중":546,"사용된":476,"사용되":1174,"동남":213,"아에서":342,"산에서":114,"도달":64,"릉 ":110,"도니":163,"만과 ":66,"컴퓨팅":102,"니터":63,"도는":1874,"능하":401,"능한":354,"름 ":818,"지휘자":123,"덴마":200,"니치":57,"대자":83,"동구":281,"동국":64,"더불":242,"동군":61,"동굴":86,"대장":219,"니카":153,"대의":1701,"대응":252,"동과":336,"대인":254,"대이":136,"사운드":156,"동계":192,"동경":61,"데르":128,"데리":57,"도네":236,"대주":148,"니코":105,"니콘":62,"어려운":65,"니콜":165,"른 ":3003,"더블":67,"도나":71,"유는 ":91,"동기":179,"대조":88,"대적":271,"대전":1323,"르 ":2357,"당주":83,"니케":131,"델리":75,"설명하":178," 가속":74," 간섭":72," 건담":75," 가설":110," 거대":183,"산주의":205," 개봉":160," 가상":296,"안양시":65," 가사":108,"또 ":312," 개별":96," 감소":102,"영토를":59," 강서":86," 경계":464," 것도":74,"꼽힌":72,"꼽히":75,"아우구":84,"나고":178,"날개":106," 감사":72," 가스":186," 결국":129,"여러 ":1385,"나게":61," 가시":92," 거두":92," 가수":406," 결과":470,"나간":63,"나가":628,"않았으":59," 개막":77," 각본":88," 개를":59," 것과":188,"류로 ":186,"리기 ":163," 강릉":100," 가미":74,"끝난":64,"끝나":75," 개방":107," 개발":2267,"개된 ":81," 개미":68," 건너":96,"끄는":125," 개명":89,"복합 ":62,"우승 ":162," 가르":250," 가마":103," 가리":1469,"선수 ":168,"데에 ":162," 가로":154," 갈래":64," 갈라":132,"야에 ":151," 개량":110," 가문":299," 건국":186," 개로":82,"동대문":97,"끌고":66," 건강":182," 가면":65," 강력":160," 갈리":98,"안에서":172,"우스 ":629," 갖는":232,"산지방":80," 감독":595,"약에 ":90," 개념":737,"위로 ":281," 가량":60," 가락":78," 강도":61," 같다":128," 강동":61,"언론인":132,"나머":129,"루아 ":64," 경마":60,"어리그":61,"나며":97,"나면":62," 개최":744," 개척":103,"나리":168," 개체":141," 고등":369,"나마":61," 검사":233," 갖추":158," 객체":126," 검색":137," 갖춘":117,"나무":576," 공동":773,"넓게":76," 가톨":515,"내려":193," 개칭":76,"대체하":94," 골든":60,"나모":58,"낭만":64," 계몽":59,"진흥원":106,"끌어":118,"끌었":93,"남면":62,"내로":74,"나미":178,"나바":64,"속된 ":167,"낱말":206,"내륙":89,"내리":117,"네갈":68," 고려":852,"진흥을":64,"세력을":62," 관구":68,"끼리":100,"내는":669,"남도":1277," 는 ":22667," 관광":330,"남동":614,"진흥에":83,"나라":1940," 가축":63,"낸다":205,"나로":1319," 가치":372," 고대":982," 광고":196,"너가":67,"나를":121,"나르":103,"날로":118,"왕이었":76,"보험 ":71," 건설":517," 경로":93,"냈다":532," 고도":101," 감염":75," 가정":260," 고고":115," 가져":155," 뉴 ":66," 강에":91,"나눈":68," 가졌":75,"나누":202," 가족":215,"여하기":269," 간접":70," 고구":194,"나뉘":181,"성립된":61," 각종":385,"나뉜":158,"변화를":114,"나는":746," 고급":147,"나다":684,"나님":90," 건물":348," 강원":365," 고기":109," 값을":58," 간주":115,"남녀":66," 값이":70,"난다":238," 공간":529," 가지":1815," 가진":647," 공개":359," 강을":88," 각지":78," 감정":108," 강이":197," 강의":193,"됐다 ":189," 공격":386," 같은":1691,"낙동":61," 개월":137," 개원":65," 강점":383,"드》":58,"도바 ":94," 같이":483," 게르":105," 개인":584," 개의":1532," 공과":57," 강제":192," 공공":336," 개장":93," 공국":74," 공군":133,"뀌었":102," 거부":106,"여하고":161," 강조":120," 과거":399,"나들":306,"남단":82,"남대":69,"났다":419," 개정":186," 관계":890," 개조":140," 공기":186," 공급":227,"상이다":365,"가로 ":579,"나급":179," 감시":80," 것들":82,"나기":90," 계곡":100," 개성":96,"변호사":207," 개설":79," 개선":238," 거래":171,"남겼":58,"집행형":59,"리그 ":853,"루어 ":63," 경기":2030,"남군":59,"내각":453,"남구":433," 계급":193," 가야":70," 개신":191," 가와":79," 개시":84," 간에":91,"남극":119,"소기업":149," 계기":111," 가운":1193,"내고":151," 가을":65," 고객":140," 거리":295,"나나":64,"상으로":821," 건립":120,"나노":70,"내기":127," 간의":259," 각자":58," 가장":2276," 경남":74," 가입":175," 가이":129," 공예":66,"립과 ":82," 고종":129," 공업":167,"되거나":99,"내지":117," 고조":84," 공여":67," 공연":289," 곳에":683," 고정":158," 고전":325,"냈으":120,"네바":84," 더 ":942,"남쪽":977," 경찰":296,"롯해 ":76," 《한":67," 곡이":150," 곡은":71," 곡을":68," 고위":306," 고유":247,"아이들":108," 교리":89," 관심":162,"아있는":62,"남지":88," 고원":69," 교류":254,"아이디":58,"육기관":94," 고용":157,"내전":134," 관습":82," 광산":108,"아일랜":478,"놓고":102,"농구":128,"내장":79,"내이":69,"날짜":67,"내의":242,"네마":59," 고양":209,"네르":65," 공식":585," 고안":196," 군도":61,"내용":752,"내외":188," 관세":105,"낮은":183,"나지":103," 국도":176,"농가":60,"났으":129,"남은":84,"내에":828,"남으":73,"내어":79,"남의":129," 군대":254,"남인":67,"남이":161," 경주":328,"남자":215,"남작":57," 구단":114," 경제":1255,"년도":117," 경전":153,"남원":74,"너무":67,"나중":141,"나주":65,"원래는":145,"널리":610,"날의":126," 경쟁":314,"날이":62," 고시":62," 경유":69,"남에":64,"난을":59,"너먼":74,"년대":962," 공사":132," 공산":365," 경인":69," 경우":1814,"남아":651," 결정":636,"남양":87," 겸임":57,"나인":191,"나일":67,"나이":2105," 계열":315,"나의":720," 광범":84,"날에":128,"속기관":448,"동맹 ":104,"나우":78,"속도 ":68," 경영":338," 걸친":86," 국내":570,"기회를":64,"녀는":98," 계약":327,"널로":65,"나와":256,"나왔":84,"나오":543,"낙엽":63," 것처":82,"나온":207,"소규모":61," 결의":95," 고속":345,"나에":147," 거치":92,"나였":70," 광물":68," 고성":109," 곡선":103," 공부":118,"아일보":76," 걸쳐":620,"내셔":215," 겨울":100,"남시":112," 건축":501," 검찰":106,"류를 ":300,"나아":108," 교단":70," 관문":58,"어머니":289," 구글":105," 계승":325," 국기":175," 거쳐":379,"네덜":393," 계속":310,"설립하":135,"남서":500," 대 ":2047,"나시":87,"설립한":221,"나스":130,"남산":76,"마가 ":85," 국경":502," 거창":60,"설립허":405," 국군":59,"널드":63," 개화":61,"안으로":82,"약성경":63," 개혁":224,"대표 ":142,"년까":1214,"남성":246,"넘는":103," 당 ":135," 국가":2932," 구간":223,"년과":139," 경성":105," 결승":157," 강한":138," 강하":79," 공무":329," 강화":298," 고분":81," 관리":1066," 게임":2058," 계산":280," 게이":242," 게오":73," 것으":1465," 개편":301," 것은":475," 것을":1889,"년간":256,"내부":331," 관련":1271,"오는 ":541," 것인":82," 것이":2545," 공립":83,"나서":96,"아이슬":98,"아이스":118,"상청 ":78," 경상":930,"어릴적":114," 관료":212,"년경":335," 건전":249," 교구":126," 간행":78," 공로":79,"어린이":195,"내버":165," 단 ":185," 고문":87," 건조":136,"끝이":62," 거주":394," 공룡":99," 결성":335," 간호":57," 달 ":74," 검은":120,"당한 ":273," 개통":168,"내무":67," 거의":351,"끝에":210,"살이풀":102,"네그":122," 검역":63," 건의":89,"되는 ":3192," 교과":67," 거제":77," 것에":181," 거점":62,"남북":337,"남부":952," 다 ":148,"아인슈":58,"남미":85,"내면":60," 고르":57,"나비":119," 경북":70,"으나 ":1984," 경부":97,"육과학":285," 고리":78," 》은":86," 《아":76," 국왕":338,"노선":512,"년이":209,"년을":193,"념에":64,"년의":324,"년으":59," 구와":86,"녹색":141," 기기":139," 구역":567,"노사":86," 그들":324," 국어":100," 구에":103,"녀의":96,"념을":152,"비가 ":106," 과학":1159," 국장":81,"념으":242,"원래의":69,"평론가":63," 구이":74," 공헌":115," 동 ":488," 구의":119,"여를 ":144," 공항":153," 공학":187,"완전히":129,"략 ":236,"넷을":59," 기관":864," 도 ":370," 근대":279," 기계":313,"농민":122,"랜 ":157," 기갑":57," 그대":262," 기금":68," 공포":138," 구약":88," 기구":396,"단히 ":190,"램 ":396,"컴파일":63,"년에":3786," 골프":64,"랑 ":252,"네의":71,"네임":79,"네이":376,"기호는":57,"노벨":252,"랍 ":91,"람 ":490," 《사":76," 그녀":204," 계획":467," 《삼":92,"노보":62," 그는":841,"랙 ":101,"래 ":1320," 공통":185," 기간":439," 교육":1812,"누구":78,"사카 ":146,"세부 ":62,"노비":106,"사적으":114,"않으며":102,"노부":168,"사적인":86,"넷에":63,"넓은":250," 경향":146,"란 ":2827,"노무":59,"넓이":80," 경험":163,"부분에":132,"넣어":89,"남편":86,"라 ":7177,"널을":66,"널은":82,"락 ":201,"널이":171,"㎢이":539,"노바":67,"노미":136,"네오":95,"너지":586,"남한":59,"남해":125,"농림":676," 구속":101,"왕과 ":60,"랄 ":61,"논문":137,"부분은":122,"부분으":81,"부분을":239,"완전한":90," 군사":494," 관측":187,"부분의":331," 군산":83," 구성":1965,"부분이":237," 견해":86,"나폴":191,"왔으며":92,"네시":339," 광주":506," 근거":256,"네스":338," 근교":75,"노르":399," 교수":480,"소관의":1872," 결합":308,"널에":59,"아제르":103," 과천":67," 관찰":132," 금강":82,"노리":119,"북부에":293," 급격":65,"왕으로":142,"상에서":235," 결혼":171,"논리":281,"넘어":123," 국민":1106," 국방":227,"네상":85,"야의 ":314,"나톨":89,"나토":79," 권력":168," 구미":71," 광장":76," 구별":240," 관직":109,"네소":58,"년부":1645,"약은 ":85,"왕이다":132," 국보":88," 곤충":91," 교사":123,"네수":64,"나파":113,"노란":66," 그가":158,"노래":459,"나트":57," 군벌":59," 권리":410,"약을 ":246,"논란":123," 계통":136,"노력":131," 그것":304," 구분":433,"루살렘":108," 관위":91," 계층":133," 국립":899," 구매":95,"노드":76," 규격":131," 과정":755,"기하학":185,"너스":57," 공중":106," 데 ":719," 공주":130," 관장":217," 궤도":157," 광양":65,"나타":1198," 관점":110,"크가 ":117,"나키":64," 광역":123,"설립자":69," 국무":229,"념물":120," 고체":87,"개국이":87,"롯한 ":236,"약의 ":117,"뜻 ":134," 공용":96," 관악":81," 공원":222," 구로":190,"나카":127," 곳을":76," 곳으":130,"나치":255," 공유":240,"년마":62," 곳이":274," 관여":73," 공을":98," 공의":61," 공익":122," 공인":132,"데이 ":96," 공작":263,"노동":651," 공장":112," 공적":69," 공전":62," 구리":102," 공정":172," 구마":64," 과의":71,"북쪽 ":122,"룡이다":97," 높이":619," 놓은":85," 누르":169," 높은":470,"연맹 ":267,"연합의":90,"유나이":86,"안전성":62," 뉴기":71,"이고 ":1432,"민 ":686," 노출":57,"미 ":1244,"동남아":110,"밀 ":162,"밍 ":299,"및 ":5874," 농촌":225,"떨어":849,"어서 ":645,"바 ":1223,"박 ":148,"루어졌":77,"《뉴스":59,"표된 ":94,"름다운":96,"루어지":209,"루어진":357,"발 ":1144,"반 ":1275,"안전부":66,"도를 ":838," 노트":65,"밤 ":79,"도르 ":69," 느끼":75,"서비스":980,"평양 ":255,"루어져":306,"방 ":1689,"배 ":369,"리그의":168,"리그이":116,"백 ":172,"오케스":66,"약자 ":66,"릭교회":264,"리그에":124," 로 ":1417,"왕국 ":201," 록 ":195,"세서 ":65,"온다 ":69,"붙인 ":79,"약성서":58," 단계":303,"약이 ":77,"인공 ":105," 대가":98," 대개":167," 담고":149,"북아메":178,"서부터":164,"떠한":155,"편의 ":84," 대기":219," 대규":162,"송된 ":57," 대구":602,"연합회":169," 능력":290,"보험자":61,"였다고":86," 대공":148,"였다가":68,"기하는":100," 단독":80,"벌 ":585,"번 ":888,"기한다":67,"르디난":61," 다니":91,"리기도":228," 다다":76,"보호를":80," 당나":182,"버 ":622,"베 ":197,"벤 ":68,"양에 ":120,"였는데":120," 담당":539," 뉴스":181,"법 ":1604,"범 ":366,"편이 ":71,"인과 ":273,"알제리":72,"벨 ":321," 대덕":65,"를린 ":83," 대대":58," 대도":60," 대동":68," 다리":217,"변 ":297,"독립 ":282," 다른":2061," 다르":415,"열린 ":403,"기하고":59,"용어 ":87,"벽 ":98,"문》":144,"별 ":439," 다만":62,"외에도":132," 달라":106," 뉴욕":473," 다루":441," 달러":131," 다룬":160,"병 ":351,"서부의":58,"편을 ":77," 뉴질":235," 단말":62,"서부에":508," 달린":64," 다목":59," 달리":473," 대략":109," 대량":101,"유네스":90,"폴리스":134," 늘어":84," 단백":169," 대륙":393,"르면 ":308," 대만":99,"용에 ":191," 대리":110,"르며 ":194," 대립":97,"볼 ":700," 대부":829,"도모 ":96," 다섯":189," 대본":114,"본 ":2748," 다수":252," 달성":171,"봇 ":74,"여했다":68,"쿠스 ":111," 대비":138,"단한 ":186,"보 ":1353," 대법":85,"가나 ":114," 대변":60,"복 ":311," 니시":68,"또한":786," 대백":573,"람과":66," 대성":143,"위를 ":1049,"라기":109," 대서":110," 대승":78," 단어":482,"람교":71," 다양":968,"래가":61," 당시":1308," 대수":150," 당사":200,"라고":4349,"이가 ":440," 다시":472," 다스":119," 단순":279,"았으며":218,"봉 ":181,"라가":293," 대상":627,"라그":59," 대사":173," 당선":156,"란과":57,"연합군":116,"라과":75," 도교":68,"상적인":119,"블랙 ":57," 도구":194," 대안":79,"라는":3492,"롯하여":102,"라니":63," 다중":111,"포르투":247,"라다":70," 담은":65,"라데":146," 대왕":88,"란다":72," 대외":65," 대우":121,"라도":290," 대원":80," 단지":69," 대신":337,"립공원":182," 다운":92," 댄스":86,"라남":362,"라나":128," 단위":404," 다이":676," 다음":656,"라노":165,"여하는":229," 단일":156," 를 ":1994,"량과":69,"았으나":73," 대주":65," 대중":469,"람들":653," 단체":752," 대지":68," 도달":62,"래된":291,"래되":137,"라라":69," 대응":233," 대의":90," 동계":163,"라드":158," 덴마":189,"뛰어":204," 대장":118," 동굴":66," 더불":242," 동구":140," 더블":62,"랐다":87,"란드":1305," 당주":81," 대전":1030,"라디":509,"래는":286,"상적으":63," 니콜":153," 대조":67," 동기":77," 대칭":110,"여함을":171,"불 ":296," 되고":141,"요일 ":146,"라미":123,"래로":202,"비는 ":92,"분 ":768,"오픈 ":155,"욕의 ":65,"북 ":391,"붙은 ":60,"부 ":7536,"위대한":96,"성립하":64,"라면":117," 동대":115,"라를":184,"송공사":57,"랫동":75,"러가":176,"라리":104,"라마":640," 대체":348,"달한 ":64,"요소를":93,"라르":90," 데뷔":275," 다케":102,"만년 ":186,"랜드":2035,"라루":63," 동남":210,"역학에":87," 도덕":66," 다카":170," 닌텐":122,"라로":150," 만 ":771," 동력":61," 도모":650,"표는 ":100,"사키 ":99,"뜻이":250,"뜻으":193,"뜻은":77,"뜻을":186,"래밍":301,"뜻의":103," 도메":76,"역할을":484," 대통":1037," 독립":1158," 도마":78,"보한다":522,"라비":303,"러나":429,"라브":117,"레고":91," 더욱":100," 단편":179,"라북":263,"래머":71," 데스":111,"렇게":90,"색으로":87," 도로":444," 되기":85,"라보":58,"래를":142,"어스 ":86,"럽과":65,"양사상":138,"인간 ":162,"아즈치":65," 리 ":87,"라바":138,"성리학":82,"럽게":67,"울시 ":92," 대형":216,"란스":62," 대화":129,"란시":124,"왕조의":225," 대회":1040," 동방":166,"선민주":511,"리드 ":197,"령과":63,"령관":126,"레니":104,"레닌":105," 데이":1061,"레네":63," 된다":760,"개국 ":83," 대학":1552," 대하":366," 대한":10310,"러드":105," 동물":531,"라스":508," 두고":421,"상임위":62," 대항":179," 대해":872,"대체로":110,"라시":210,"렀다":179," 맥 ":79,"예로 ":72,"려고":144,"라서":389,"란색":79," 대표":1228,"력과":186,"런던":299," 동맹":199,"레나":119," 되는":598," 동명":90," 두개":57," 달하":98,"왕족으":63,"려가":88,"러다":58," 말 ":208," 데에":168,"융기관":72,"세르비":167," 도미":66,"라이":2502,"라인":656,"려대":69,"라의":696,"러리":161,"로가":256,"러를":61,"라위":80,"란이":133,"란의":103," 도심":76,"란을":119,"람에":161,"랍어":117," 도시":2717,"론가":102,"라자":84," 도스":70,"래시":96,"라와":192,"래식":78,"란에":60,"연합뉴":77,"라오":172,"래스":164,"려는":295,"라운":208,"라우":429,"랜스":139,"랑스":2207,"라엘":229,"라에":374,"레드":242," 도서":212,"라야":78,"뷔 ":108,"여하여":59,"여하였":106," 동북":136," 동부":560,"랑수":68," 또 ":308,"서울 ":354,"동북":139,"동부":1119,"도사":155,"도상":81,"맹 ":398,"도서":352,"독성":71," 나가":269,"도네시":218,"양의 ":498,"도스":130," 나고":67,"도시":3144," 날개":87,"도심":95,"동산":156,"동사":97,"데에":273,"말 ":452,"리는 ":1318,"편에 ":81,"담하":105,"도바":121,"됐다":193,"있게 ":311,"도미":81,"용자 ":266,"동류":60,"되는":3370,"단체가":70,"당하":866,"동맹":284,"대표":1493,"망 ":267,"유니온":66,"동명":97,"두개":63,"원시 ":244,"단히":190,"당했":130,"양자 ":62,"두가":58,"동면":71,"당한":473,"대한":10786,"대하":654,"대학":3157,"유닉스":93,"독부":116,"된다":2991,"설에 ":116,"되던":89,"대해":906,"대항":184,"덴의":130,"데일":69,"데이":1328,"도부":57,"양이 ":144,"붙어 ":106,"맥 ":265,"델이":112,"두고":457,"동물":811,"대행":62,"매 ":354,"되도":63,"록》":64,"대화":239,"임과 ":71,"동방":208,"도비":86,"두교":119,"업무를":406,"대형":256,"맨 ":157,"말기 ":110," 끝난":64," 끝나":75,"대회":1337,"론》":70,"도적":126," 나누":200,"동안":920,"동아":323,"독재":105,"않지만":68," 나눈":68,"독점":82,"머 ":157," 나뉘":181," 나뉜":158,"폴레옹":142,"도전":67,"동양":321,"패키지":72,"도인":180,"독의":116,"도이":817,"도의":1257,"독으":61,"독을":96,"독자":172,"돈을":58,"도입":373,"도자":409,"독이":170,"독일":2061,"도주":98," 남녀":64,"용이 ":226,"도중":100,"돌이":75,"동에":723," 나는":112,"먼 ":217,"동영":106,"동을":1013,"동으":429,"동은":199,"두루":66,"동의":526,"둘러":259,"동이":750,"동인":172,"붉은 ":71,"동일":302,"동작":235,"동자":198,"동장":81,"동원":102,"동위":88,"용의 ":212,"도지":99,"동조":206,"동전":186,"동적":145," 나들":286,"양을 ":259,"페스티":62," 나급":177,"동서":126,"동성":165,"두는":59,"동생":282,"펜실베":90," 남구":129," 내각":396,"운영 ":417,"되며":571,"되면":541," 남겼":58,"분석하":113,"도와":470,"돌아":199,"도에":874,"영향력":151,"도역":63,"도였":83,"도양":84,"도어":105," 남극":113,"가공의":109,"동시":546,"간다 ":126,"로프로":79,"영리 ":121,"유니버":126,"용을 ":583,"도원":152,"도요":90,"데타":127,"도움":144,"용은 ":157,"됐으":67,"돼지":84,"보편적":59," 나무":232,"서와 ":94,"들기":109,"사추세":98,"우의 ":106,"면 ":3592,"예를 ":240,"들고":156,"도쿠":187,"되어":4394,"들과":539,"도쿄":436,"가된 ":579,"되었":8669,"단체로":153," 나머":129,"등급":177," 내륙":67," 낱말":204,"등기":113," 내리":81,"독특":101,"명 ":4495,"등과":273," 내려":165,"등교":82,"몇 ":303,"되자":92,"두산":85," 낭만":59,"료이다":66,"울산광":189,"도청":90,"도체":168,"동진":82,"동지":68,"작가 ":277,"양성하":72,"동중":64," 남동":554,"능하게":61,"메 ":160,"영되었":153,"도착":72," 내는":102,"동차":918,"선에 ":199,"동천":62,"동청":79,"단체를":65,"동체":258,"며 ":20765,"두번":86," 나라":893,"동쪽":1485,"드가":250,"동화":155," 남서":495,"붙여 ":64," 남성":230," 년까":1209,"자가 ":1294,"몽 ":74,"영화를":78," 남산":66,"연방 ":286," 넘는":98,"동하":683,"동한":158,"동해":218,"동했":140,"못 ":69,"언십 ":93,"영화로":104," 년경":335," 년과":115,"몸 ":59,"룹의 ":106,"둥이":68,"드루":67,"들로":549,"소로 ":203,"양성을":74," 나아":105,"드로":556,"유를 ":151," 내셔":136,"드레":194,"있고 ":893,"드러":189," 네덜":389,"드라":851,"드래":93,"디나":115,"디난":62,"유대인":130," 남부":768," 남북":317,"뒤를":89,"드니":128,"드는":706," 끝에":201," 내무":66,"되지":653,"각국의":60," 남미":66,"와는 ":313,"두에":64,"두었":122," 내부":320,"두어":97," 년간":235,"들도":100,"도회":85,"의는 ":204,"도화":58,"세스 ":128,"몬 ":213,"영화는":78," 끝이":59,"돌프":99,"목 ":781,"모 ":847,"영향을":487,"독하":86,"든다":93,"도한":130,"도하":306,"영하고":172,"성북구":63,"때는":184,"데스 ":135," 남쪽":933,"인권 ":61," 내지":88," 낮은":182,"듀서":131,"각각의":117," 남자":211," 내용":717,"상징하":77,"디렉":63,"오후 ":120,"우에 ":227," 내의":129," 날짜":60,"단체이":367," 내전":128," 놓고":87,"단체의":76,"뒤에":153,"소련 ":87," 농구":95," 내장":76,"들면":80," 남양":79," 년대":956,"들목":286,"때까":243," 널리":529,"여러가":94,"가는 ":557," 년도":79," 너무":67," 남원":73,"드벤":58,"분을 ":409,"일곱 ":76," 나중":141," 남은":57," 내에":577,"인구 ":628,"분은 ":160,"드를":373,"드르":92,"드림":70,"서에 ":154,"드리":485," 나온":189," 낙엽":63,"둘째":114," 나오":450,"북서쪽":240," 나왔":80," 나와":88,"일과 ":143,"상태 ":130," 남아":516,"등록":321," 나이":323,"디션":57,"들은":1170,"들을":1666,"등에":962,"떠나":66,"들의":1832,"폴란드":330," 나폴":174,"드이":229,"드인":87,"떻게":123,"록하였":99,"부의 ":953," 논리":244,"성시 ":68,"북서부":257," 넘어":117," 노리":66,"때문":1343,"들이":3059,"들인":129," 노르":359,"드와":268," 년부":1632,"유럽 ":636,"때로":134,"물 ":1678,"드에":481,"드어":129,"등식":95,"드의":964," 노력":128,"대중화":66," 논란":122,"드웨":238,"들여":122,"드워":117,"들었":219,"들에":883,"들어":2018," 노래":446," 노란":64,"롤플레":72," 노드":65,"디부":57,"맡고 ":193,"딸로":82,"능하다":188,"따른":285,"따르":402,"부인 ":190,"디비":83,"리》":59,"오키나":93,"문 ":1427," 나타":1132,"무 ":858,"원소 ":72,"양수산":143," 나치":207,"서양 ":162," 나카":79,"생으로":111,"묘 ":112," 뜻 ":130,"따라":2057,"생이다":99,"린다 ":670,"드시":125," 노동":422,"도록 ":1040,"되기 ":267,"도로 ":981,"따로":85," 년마":59,"용산구":85,"디미":126,"드스":58,"온타리":105,"따왔":76,"디지":599,"따위":130,"따온":72,"디즈":107," 년이":145,"우와 ":60," 노선":481," 년의":255," 년을":99," 녹색":130,"리다 ":103," 년에":3712,"드컵":316,"디젤":71,"디우":62," 누구":77,"디움":88," 농민":87,"디자":541," 노부":118,"디어":563,"디언":175,"디에":99,"유대교":67,"닌텐도":124,"디오":1235,"단편 ":96,"더욱 ":87," 노벨":241,"디아":393,"르만 ":85," 네이":195,"등지":173," 넣어":82," 논문":122,"비나 ":82,"도니아":125," 네오":57,"때부":94," 남한":57," 농림":654," 남해":111,"따서":170,"디스":467," 남편":86," ㎢이":537," 라 ":285,"등을":1777,"등으":538,"등은":87,"듯이":70,"등의":1888,"등이":1018," 넓은":226,"등장":884," 란 ":635," 넓이":75,"데시 ":86," 놓여":58,"분의 ":454,"등한":57,"등학":492,"또는":7080,"앤젤레":101," 네팔":63," 네트":572,"듬해":68," 높아":61," 놀이":123," 농업":387," 농어":113," 논쟁":99,"》를 ":132," 논의":77,"엘리자":71," 녹음":67,"등포":159,"분이 ":204,"르를 ":106,"득하":114," 노예":114,"영하는":250,"때의":171,"에선 ":72,"에서 ":25246,"때에":310,"북서태":59,"원수 ":69,"분자 ":68,"업발전":65,"딸이":133," 농산":100,"이기 ":244,"유로 ":235," 노스":140," 질서":67," 지수":62,"출신":1014,"출시":497,"치가":564," 지시":73," 지식":486,"활용하":92,"폭 ":101,"리미어":109,"치고":191,"포 ":705,"말라위":74,"회장 ":94,"치권":60,"폰 ":320,"치구":161,"협회 ":346,"치기":91,"축에":59,"폴 ":159,"추어":204,"친구":113,"최초":1069," 증진":256,"출연":224,"폼 ":65,"추원":63,"침공":92,"달린 ":60," 지어":146,"카가":116," 진압":74,"달리 ":397," 지었":64," 지역":3302,"축을":74," 직업":172,"축이":59,"축일":68,"카고":81,"추적":79,"총회":148,"추정":272,"출을":84,"축제":166," 지원":890," 직원":79,"출이":71,"출입":201," 지위":222,"출자":57,"출장":65," 지은":141," 집안":60,"출전":170,"홍콩 ":113," 지점":194," 지정":819," 지적":134," 진입":80,"트는 ":279,"추진":396," 직접":507," 직전":63,"치는":396," 지중":131,"츠를":86,"치단":151," 진주":131,"충류":73," 지명":221,"축물":164," 지리":258,"츠가":74,"신성 ":109," 주파":92," 직무":110,"최신":58,"등학교":448,"회적 ":239,"름이 ":380,"름의 ":136,"충무":57," 지방":2170," 지배":541,"출범":212,"단되었":80,"출발":166,"취득":125,"시뮬레":108," 진보":117,"편 ":523,"르시아":205,"총칭":263,"충분":86,"충북":60," 질병":153,"축산":260,"추상":117,"평 ":133,"최종":194," 즉위":118," 중학":70,"축소":72,"출생":339,"최적":97,"추세":127,"폐 ":75," 직선":63," 중화":785,"름은 ":937," 지속":294," 지상":157,"름을 ":720,"리시 ":78,"카마":74,"카리":164,"카를":321,"카르":370,"카로":94,"출판":563,"취지":64,"김일성":79,"말레이":208,"칼라":126,"출한":142,"출할":58,"호텔 ":84,"출하":502,"측에":78,"캐롤":76,"풀 ":129," 지하":383,"츠에":83,"축하":152,"카메":240,"시민들":57,"릭스 ":81," 지표":99,"칼리":211,"푸 ":69,"츠의":100," 진화":199,"풍 ":312,"캐릭":191,"식물의":97," 지휘":383," 직후":72," 질환":60," 집필":59,"회의 ":1094,"스스로":208,"치세":62," 집행":129,"대략 ":95," 집합":390,"츠와":84," 키 ":71,"카미":146," 지향":127," 지형":89," 진행":628,"품 ":726,"기준이":62,"실상 ":131,"치스":72,"치시":115,"비트 ":196,"층을":58,"층의":89,"기준으":386,"층이":72,"캘리":254,"측정":243,"층에":486,"리스 ":961,"흥과 ":58," 진흥":250,"름인 ":66," 킹 ":69,"캄보":77,"화이트":83," 집중":134,"치된":254,"치되":225,"카나":127,"취소":59,"치도":175,"충주":70,"측면":113," 집적":64," 지지":202," 지진":67," 지질":87,"친다":61,"류이다":187,"최하":230,"카데":164,"추측":97,"카니":70,"춘추":91,"추출":65,"획을 ":70," 짧은":155,"춘천":122,"칠레":106," 큰 ":1157,"치로":193,"치료":253,"치러":226,"캐논":62,"최후":86,"카드":366," 지칭":299,"충청":623,"캐나":550," 진출":298,"르지 ":83,"트》":61,"카라":247,"친목":162,"치면":57," 지키":86,"칠리":66,"표 ":478,"취임":66,"치를":548,"침략":84,"다리 ":68,"청소":381,"총독":192," 주민":210,"체성":73," 중립":59,"순히 ":106,"티 ":784,"최고":599," 주변":342,"틱 ":146,"틴 ":360,"차트":146," 정해":170," 정하":119," 정한":85," 제품":480," 좋은":135," 종전":57," 주를":95,"촌동":62," 종족":57," 중랑":60," 종종":129,"창출":92,"초등":129," 제한":242," 정확":274," 주목":103," 중력":134,"청사":253,"천시":356,"초명":74,"천이":116,"착한":88,"착하":100,"쳐서":143,"천의":92,"천을":85," 중복":60,"천으":103," 증가":212,"청에":126," 즐기":62,"최남":61,"철의":57," 중부":577,"파 ":1076," 증거":174,"시리즈":1281,"판 ":692,"천주":138," 주석":95,"다를 ":70,"청원":71," 증권":93,"팔 ":66,"체에":420,"초로":518,"체스":170," 조치":94,"형태이":106,"처에":159,"형태의":265,"천안":97,"최근":299," 조카":75,"천연":139,"등포구":133," 중반":138," 준비":90,"초를":88,"채택":233,"팀 ":383,"처의":89,"처음":1265,"팅 ":469,"창의":108,"쳤다":142,"차지":589,"채용":84,"창작":170,"처벌":87," 전투":1219,"참전":80," 주된":89,"참의":100,"초기":696,"체로":624,"책에":132,"창원":207," 준다":87,"천문":324," 주도":1756," 전통":766,"책의":157," 전파":198,"투스 ":105,"책을":239,"책은":69,"책으":129,"총괄":131," 조에":97,"처분":130,"마르크":179,"책임":299,"창조":274,"책이":259,"스의 ":2137,"참조":109," 조약":551,"체르":60,"체를":704,"천리":76,"천만":67,"참여":643,"찾아":159,"차적":58,"초고":65," 존스":65," 종사":119,"초과":70,"처리":574,"차의":173,"차이":655,"차장":60," 중남":73," 정치":2113," 주는":346," 제출":84,"창업":76,"차종":112,"찰이":62,"초구":256," 주니":71," 전화":182," 전환":128,"초대":489," 좁은":114," 전형":79," 전혀":90,"카이도":140,"마리아":248,"찰청":251,"다만 ":77,"청북":251," 조조":61," 조종":81," 전해":249,"초동":59," 좌우":58," 접해":75," 종이":322,"천사":64," 종의":95," 접하":505," 접한":376," 종을":67," 조지":462," 조직":785," 종으":82," 전후":94," 주로":2214,"튼 ":196," 졸업":314,"트 ":6929," 정통":81," 중단":103," 중대":70," 존재":1242," 조정":209," 조제":62," 전하":166," 전한":60," 저항":140," 조절":103," 적합":91," 조작":128,"틀 ":149," 중동":117,"첫번":86,"칭이다":298,"충돌":185,"초의":700," 집단":362," 주체":106,"초이":60,"초자":71,"출된":104," 지도":570,"체코":190," 지니":158," 지닌":190," 중점":61," 지대":176," 중종":67,"초연":81,"출되":164,"초에":140," 주지":67," 중이":151," 중인":117," 중의":484," 중장":65,"후속 ":76,"체하":137,"체학":60," 질량":159," 주택":112,"페 ":146,"체험":108,"최소":174," 지류":128,"촬영":165,"청하":95,"출력":193,"총재":61,"총장":195," 중추":105,"최상":86,"먹는 ":101,"추리":70,"천황":417,"취급":141,"형태로":346,"촉진":252,"체포":86,"처형":64,"총연":66,"추락":82," 주축":65,"천하":69,"퍼 ":383,"초점":102,"머니 ":100," 주최":206,"철학":918," 증명":166,"천체":227,"컬럼비":62," 지구":803,"추기":89," 조합":232," 종파":171,"챔피":311," 중소":133," 중생":144,"형태를":152,"슨의 ":72,"최되":220,"최된":194," 중서":84,"추구":133," 중성":88," 중세":272,"팬 ":60,"축구":1084," 주식":300,"슨이 ":59,"패 ":76,"청주":162,"출간":124,"체제":657,"다면 ":148,"체적":348,"추고":107,"최대":550,"체의":621,"축가":82,"시설 ":150,"체인":196,"체이":649,"팝 ":104,"천지":81,"창한":58,"청자":73,"청장":193,"체육":1359,"추가":282,"청으":59,"총리":508," 주소":166,"청은":176,"체와":186,"초반":121,"청이":131,"청의":110," 증기":82," 중요":799,"추는":61,"총선":155," 주주":79," 지낸":214," 지내":96," 줄이":91," 준정":80," 지냈":558," 주제":250,"초식":67,"쳐진":69," 지나":284," 지난":146," 중에":696," 중앙":1159," 주장":603," 죽음":141," 죽은":130," 주인":242," 주이":140,"기타 ":345," 주자":62," 주의":999," 집권":84,"률이다":60," 종합":466," 주위":126," 줄여":450," 좌표":69,"쳐져":57," 주요":741," 주와":621," 주연":98," 주었":87," 지금":536," 지급":139," 주에":722," 주어":275,"충격":69," 중시":60," 조화":72," 중심":1728,"척추":104,"형 ":1793,"코토":79,"콘텐":200,"카에서":101,"협 ":123," 차별":95,"코트":155,"코틀":235," 창립":241," 체계":535,"코퍼":63," 체결":226,"쿠시":66,"쿠스":228," 청구":123,"크는":102," 채무":154,"크다":86,"키가":93," 차량":299,"징이다":166,"말리아":59,"쿠바":94,"크고":102,"크게":351,"황제로":69,"크가":121," 차례":291,"현 ":2291,"혁 ":104,"혀 ":208,"코타":86,"징으로":70,"크기":368,"대륙 ":89,"케팅":130,"컴퓨":1719,"험 ":357," 채널":298,"쿠르":111,"스와 ":613,"칭으로":286," 찾는":68," 창달":98," 창단":225," 창당":93,"대를 ":566,"컨트":120,"코어":137,"코에":118,"리비아":152," 채권":172," 차남":67,"지중해":127,"커피":96,"코이":72,"코의":222,"컴파":63,"허 ":115," 차단":59,"헌 ":139,"쿠라":165,"태는":61,"킬로":125,"대만 ":63," 첫번":85,"키르":123," 처분":74,"타디":124,"타로":108,"크스":277,"쿼크":68," 초대":479,"타라":76,"택되":100,"키며":125,"효 ":88,"타는":77," 차종":107," 창업":69,"크바":228," 초고":57," 찾아":157," 천만":60," 참여":607," 차이":388," 처리":445," 책이":152," 책임":221," 창조":192," 총괄":120," 책으":80," 참조":105," 채용":77,"회 ":3813," 창작":141," 처벌":80,"획 ":208," 창의":90," 참전":79," 차지":583," 창원":193," 참의":90," 초기":674,"타니":105," 천문":270,"크레":166,"크로":1143,"활 ":172,"클래":142,"클라":364,"크루":160,"타고":165,"타공":116,"지질학":58,"통칭은":57,"키나":206,"화 ":3719," 창설":237,"크래":193," 찰스":137,"크라":447,"화·":76," 청동":62,"환 ":439,"지지하":61,"킨다":751,"크메":76,"태계":75,"클리":189,"클린":94,"니메이":622,"타난":144,"타나":395," 차원":250,"타내":438,"타낸":182,"클럽":362,"클레":211," 창시":139,"클론":67,"클로":182,"키는":1068,"크를":175,"탐구":65,"태가":129,"크리":684,"황 ":673,"크림":80,"크립":110,"혼 ":107,"홀 ":76," 청나":165,"코프":157,"호 ":2171,"키고":232,"코하":57," 철도":572,"타가":60," 첨단":85,"쿠오":85," 청년":105,"키기":265," 차세":58,"홈 ":112,"시리아":214,"면과 ":135,"르에서":63,"순한 ":97,"플 ":168,"리아 ":2068,"코노":61,"까지를":69,"코네":66,"리안 ":121,"픈 ":178,"콩고":162,"커버":63,"프 ":1611,"코나":75,"측하":71,"담당한":59,"담당하":386,"대로 ":879,"켰다":167,"카지":59,"커뮤":174,"치체":194,"칭으":286,"치지":83,"칭을":179,"칭은":479,"카와":268,"리야 ":76,"카오":100,"침입":91,"캐스":57,"카운":74,"칭이":493,"카우":76,"컬러":63,"츠키":72,"컬럼":77,"카의":270,"코가":63,"카자":100,"카이":616,"카인":59,"신라의":85,"취하":134,"칙을":131,"칙으":83,"치의":242,"치이":165,"친위":80,"치인":905,"칙이":149,"케도":119,"친일":133,"치적":263,"카에":232,"지털 ":477,"카야":118,"치주":107,"치에":313,"카스":306,"칙에":97,"치와":131,"카시":93,"치원":65,"후부터":65,"케다":64,"커다":69,"카사":70,"리어 ":186,"컫는":618,"치안":73,"치아":129," 참고":71," 창건":80," 창간":97,"쿠데":107,"향 ":296,"리엄 ":215,"쿠니":115," 참가":722,"콘스":196,"코시":67,"리얼 ":67,"술한 ":81," 차관":105,"코스":429,"치인이":484,"치인으":223,"콘서":84,"케도니":118,"리에 ":892,"행 ":946,"황제이":83,"해 ":11775,"핵 ":98,"캠퍼":91,"쿠가":151,"케이":822,"케인":158,"항 ":503,"마스 ":131,"컵의":85,"코미":140,"코믹":87,"합 ":1352,"함 ":501,"현하는":126,"한 ":36846,"학·":96,"할 ":5085,"컵에":64,"칭호":106,"카프":65,"학 ":3682,"하 ":1115,"침해":108,"핑 ":85,"스어 ":438,"코리":211,"코르":181,"콜로":109,"칭한":198,"칭하":436,"콜롬":91,"필 ":124,"친환":81,"코로":88,"까지는":225,"리오 ":289,"스에 ":397,"콜라":224,"케스":103,"카페":78,"치하":2020,"치학":71,"치한":3549,"치해":358,"치했":87,"현하기":80,"콩고 ":134,"피 ":342,"픽 ":726,"카트":104,"핀 ":359,"까지도":76,"기초로":124,"기초를":61,"코드":673,"커스":115,"코딩":85,"카타":138," 언론":305,"중종":67," 알아":113,"진다":650,"진단":77," 안에":305," 않아":113,"황제 ":355,"지대":330," 않았":277," 안양":112," 에디":95,"중점":70," 어려":133,"중적":79,"지니":319,"지닌":190," 에드":185," 어렵":70," 예금":57,"지는":2060,"지능":93,"즈를":119,"중이":356,"중인":249,"중장":67,"중재":63,"주지":232,"중을":67,"중의":646," 에도":489," 액션":106,"주최":210," 안정":204," 안전":386," 얼마":78," 열대":176,"호작용":139," 아제":99,"즈미":73," 않을":60," 않으":216," 않은":394,"주체":150,"집단":449," 연대":172," 안의":57," 어머":279," 야생":70,"중지":63," 아이":1133," 역대":77," 아인":68," 아일":388," 어릴":143,"진동":81," 어린":266,"직된":74,"지되":322,"지정된":110,"지정되":305," 아우":255,"지도":837,"만들기":94,"지동":62," 아울":60,"지라":98," 않지":68,"만들고":94," 에르":95," 양성":269," 아직":134," 였다":83," 양산":93,"증명":181,"다르게":104," 야스":61," 아즈":91,"즈베":96,"주축":66," 앞에":89," 아주":105," 옮겨":85," 열도":76," 알제":77,"지를":1015,"지르":60,"비주얼":58," 여러":1622,"지류":134,"질로":116," 양식":231,"진료":73,"지리":373,"때에는":117,"지름":79," 영등":165,"질량":179,"주택":185," 완공":67,"중추":123,"마드리":66,"지로":949," 엘리":185," 엄밀":69,"질랜":239," 업무":536," 옛날":72,"률이 ":74," 영동":66," 오다":74," 오늘":444," 여름":113,"주특":163,"리랑카":66," 아침":58," 약자":169," 아카":249," 왕국":656,"친위대":72,"직무":110,"주파":110,"비즈니":135,"치이다":129," 왕가":158,"진리":60,"지원하":329,"지막":450,"지마":92,"지만":2443,"쿄 ":369,"지명":245,"진이다":61," 연료":112,"신문》":123," 열렸":185,"지며":169,"지면":175," 예로":96,"진으로":71," 압축":113,"주한":124,"지부":157,"휘는 ":146,"주하":399,"진보":157,"률의 ":82," 액체":118," 오디":174,"지배":563,"지방":3019," 열리":279," 아케":110," 열린":474,"지바":88," 여명":78," 연맹":288," 온도":178," 여부":76,"쿨 ":70,"즈에":211,"준화":118,"째로":481," 외계":79," 에서":1916," 영문":107," 안토":103," 양주":57,"즈와":76," 외교":366," 아키":249," 예루":104," 양의":74,"질병":167," 양자":305,"률을 ":89,"칙이다":82," 연방":722," 양재":71,"쿠 ":497," 예를":204," 아테":125,"리브 ":93,"주화":87," 아토":61," 왔다":158," 올랐":110,"지상":185," 엑스":155," 언어":1410," 알파":121,"지선":61,"중화":873,"즌이":138," 양쪽":62," 얻어":102,"직선":85," 예방":102," 아폴":70,"다루는":196," 어원":87," 얻었":76,"지션":130," 오르":201," 오른":92,"지속":297," 억원":58," 오류":88," 영미":82," 오랫":76," 완도":63," 오래":309," 아트":82," 외국":347," 오랜":130," 온라":297,"중학":110," 아파":129," 아티":99," 어업":104,"칙으로":83,"즉위":118,"다룬다":88,"중해":135," 올라":148," 에스":395,"즈이":155,"지사":210,"즈의":362," 안티":91," 여성":671,"지스":206," 여섯":126," 없었":105," 연산":188," 역설":57,"즘의":66," 없어":111,"진수":64,"즘이":67," 약칭":414," 역삼":92," 아프":573," 역사":1519,"지수":116,"질서":165," 오리":271," 연쇄":64," 여수":102," 연속":241,"진시":95," 언제":60," 요구":281," 예비":61," 알프":80,"증을":98," 올림":799," 얼음":64," 올리":108," 차 ":1230,"지식":562,"지시":133,"능을 ":412," 얻은":80," 업적":116,"통적인":164," 없이":247," 여신":124," 역시":116," 없으":149," 에어":174,"지점에":130,"증진":435," 에이":242," 예산":87," 애플":267,"지어":207," 암호":144,"지아":300," 올바":113,"지야":80," 오버":65," 영상":317," 에우":58,"진영":77," 오브":259,"진에":166,"지와":387," 책 ":74,"직업":192,"직에":115,"지역":3831,"지연":62," 예선":234,"지었":74,"진압":79,"지에":1070,"지오":59," 채 ":79,"지였":87,"지인":168,"지이":710,"직의":93,"직을":212,"직으":106,"지의":930," 연애":57,"집안":61,"지은":150,"진은":66,"진으":71,"직자":136,"직임":89,"직이":307,"즈치":65,"직접적":93,"지자":110," 예수":291," 예술":486,"직원":124,"지원":1263,"진왜":117,"질에":101," 연안":287,"직위":91,"지위":252," 엔진":327,"질의":280,"질이":274,"징역":61,"켰다 ":152,"진정":61,"진을":324," 여왕":102,"진의":113,"집에":83,"투르크":97,"진이":164," 연예":76,"지적":171,"진입":88,"지점":270,"지정":864,"직전":64,"직접":511,"질은":90,"질을":426,"집을":67,"진주":148," 오세":84," 업체":175," 연재":197," 영양":101," 월간":68," 연장":152,"집이":101," 원격":57," 영어":930," 역을":64," 역은":61,"뉴욕의":60," 여의":113,"지주":81,"질적":241," 오사":151,"지중":143," 역임":393," 역이":108," 여자":305,"치체 ":79,"집적":68," 외래":64,"징이":263," 영역":323,"지질":112,"징을":98,"지지":438,"지진":90," 영업":143,"징으":70," 예언":71,"호이다":121," 여주":68,"니버스":58," 옆에":57,"집중":149," 왕복":62,"닉스 ":124," 연주":271," 오스":1097," 영웅":113,"황의 ":111,"큐 ":96,"쪽과":149,"수행 ":60," 용도":92," 월까":163,"짧은":155,"지청":89,"맞대고":167," 영조":60," 왕비":129,"황을 ":121," 예전":119," 예정":308," 영주":76," 운동":905," 외무":89," 영지":58," 완성":200,"수한 ":277," 오염":68,"진출":340,"지칭":300," 열차":200,"지컬":96,"크 ":3097,"니스 ":252,"통적으":123," 요리":491,"황이 ":66,"큰 ":1169," 요르":61," 엔터":268," 오이":81," 연출":58,"다르다":167,"클 ":181," 외부":231," 어항":59,"만든다":72,"만드는":271," 오전":103," 우라":85,"지키":149," 천 ":124,"큼 ":96," 에티":97,"까지의":267," 왕실":92,"지털":569,"수학 ":153,"통치 ":72," 위기":77,"딸이다":74,"주광":202,"주관":327,"정주":71,"주국":154,"준공":69,"주군":206,"지정하":64,"지정한":88,"주교":442,"제조":448," 쓰는":224,"재한":349,"재학":69,"재하":725,"조부":69,"제정":539,"주공":78,"제적":455,"주고":191,"재했":212,"재해":152,"족보":60,"제의":631,"주가":248,"장했":136,"정전":83,"정적":273,"주간":164,"제일":134,"제임":217,"제작":1329,"제자":224,"주거":121,"정조":73,"종목":228,"제이":524,"제인":138,"전지":147,"전직":85,"정일":58,"정인":93,"맞닿아":98,"정자":73,"접전":71,"접적":132,"장해":59,"장하":1342,"장한":379,"장학":77,"현한 ":91,"제와":162,"제외":408,"적지":100,"잡한":94,"정으":195,"저지":133,"자흐":77,"정을":810,"정은":146,"정이":736,"정의":966,"제어":265,"점유":74,"점은":112,"제에":429,"점을":418,"점으":208,"칼 ":114,"정원":147,"제연":82,"점의":91,"전주":277,"종류":648,"제였":72,"점이":420,"자협":82,"전제":91,"칸 ":384,"제안":211,"장편":92,"르와 ":76,"조물":104,"재판":339,"족문":173,"종료":106,"제약":76,"자회":144,"전자":1283,"작해":97,"작했":259,"조명":72,"카 ":2034,"적절":91,"절을":58,"전쟁":1436,"정에":737,"절이":80,"전적":194,"젊은":111,"종로":421,"기한 ":75,"주년":107,"존속":102," 아가":58,"정체":133,"중기":285,"정청":74,"주나":75,"접촉":83,"조세":77,"조성":326,"정책":908,"정착":170,"조선":2884,"중구":359,"중국":2218,"져있":131,"조상":99,"중교":61,"조사":870,"점차":84,"중계":60,"줄기":211,"중간":227,"전철":111,"전체":673," 쪽 ":114,"절차":197,"전청":59," 쓴다":97,"전차":161,"주기":300,"정직":60,"정지":148,"제주":546,"주권":127,"재화":72,"재활":72,"조약":652,"조에":276,"족에":140,"조어":71,"조업":97,"전파":285,"중단":108," 아나":248," 아날":71,"조와":122,"존에":63,"전통":832,"주도":1871," 않기":58,"주된":119,"전투":1249,"만들었":181,"주되":65,"만들어":1188,"제출":94,"주는":689,"죄를":91," 알고":262,"주니":101,"주당":264," 악기":149,"중남":73,"준다":217,"제천":67,"졌으":236,"존스":69,"종사":195," 않고":534,"정치":2288,"접하":574,"접한":492,"토콜 ":80,"종의":527,"전후":101,"조지":513,"조직":975,"종으":458,"종은":82,"종을":142," 아돌":57," 아동":142,"정할":108,"제품":561,"정하":1154,"정한":1132,"정해":250,"컵 ":410,"종자":67,"좌우":61," 안동":112,"종이":791,"접해":436," 야구":716,"적화":77,"전혀":91,"절하":80,"절한":80,"르에 ":62," 약간":124,"젝트":419," 아니":980," 아닌":443,"조종":82,"제트":78,"전했":92,"조조":79," 않다":148,"주로":2465,"좁은":114,"전화":322,"전환":157,"컬 ":194,"주력":61," 않는":847,"족주":88,"전형":115,"존의":272,"저항":165,"적하":72,"헨티나":186,"조이":169,"족의":411,"조인":125,"족이":405,"조작":149,"족인":57,"전할":66,"전한":509,"전학":81,"전하":663,"종에":80,"전함":71,"전해":286,"적합":98,"조절":138,"조적":99,"조제":92,"조정":332,"존재":1248,"커 ":224,"정통":92,"졸업":318," 아내":168,"중대":89,"중도":73,"족을":151,"족은":109,"중동":130,"조의":562,"족으":212,"또는 ":7073,"주민":357,"제휴":62,"중립":69," 아라":177," 아랍":266," 아래":375," 양국":63,"제후":83,"조치":133,"주변":352,"즈가":129,"켓 ":162,"중랑":61,"종종":130," 안드":171,"제하":242,"제학":350,"종족":62,"정확":287,"제한":327,"정화":73," 아드":72,"주를":291,"전히":177,"종전":66,"좋은":148,"제프":122," 아들":897,"주문":90,"켄 ":72," 애니":636,"제회":58,"중력":144,"주목":108,"케 ":324,"중부":615," 아무":102,"즐기":62,"증거":195,"중복":64,"증가":223," 알리":168," 없고":94," 아버":489," 앙리":58,"증권":184,"치에서":60,"주선":105,"주석":120," 아미":102," 얼굴":67," 언급":141," 아바":62,"죄의":58," 쓰여":83," 쓰였":116,"주사":146," 아름":145," 아르":573,"켜 ":348," 알려":1676," 알렉":314," 알레":71,"조카":85," 앤드":80," 아메":328," 압력":91,"준비":133,"중반":143," 아마":238,"식별 ":61,"다루고":124," 아리":130,"즈는":180,"중서":88,"지개":84,"지가":490,"중성":112,"즈니":258,"지각":64,"중세":273,"중소":176,"종특":81,"지게":172,"조합":512,"조항":62,"조하":271,"조한":146,"족한":81,"족하":252,"종파":173,"지고":1085,"족행":61,"코 ":1075,"지관":81,"직공":120,"존하":237," 어느":236,"지구":953,"진공":59,"진과":118,"콘 ":142,"스부르":91," 여개":62," 여객":163,"조화":108,"중시":81," 야마":192,"중심":1840,"증기":111,"주소":193," 알바":142," 쓰이":700," 쓰인":357," 아부":59," 에게":145," 아브":60,"주시":655,"주식":354," 아비":83,"중생":157,"집이다":61,"준의":154,"준을":139,"준이":188,"준인":62," 연기":182,"중앙":1401," 암석":66,"주자":204,"주일":76," 암살":118," 아스":164," 어디":65,"주재":60,"준으":443," 아시":766,"주장":609," 연극":159,"지나":378,"중에":1098,"지난":146,"지낸":215,"줄이":100,"지내":104," 에는":69," 어떤":681," 어떠":156,"주전":67,"주적":67," 어떻":123,"주제":335,"지널":67,"지냈":559,"준정":82,"즈로":101,"주주":795," 영국":2073,"중요":802,"지노":57,"주연":137,"지기":214," 아서":83,"주에":945," 여겨":280," 얻는":95,"콜 ":173,"주얼":72,"주었":136," 앨범":615,"지금":541,"지급":150,"질과":85,"주어":317,"진구":106,"좌파":64," 아사":106," 아산":69," 연계":84," 연결":746," 양력":106,"준에":93,"주와":720," 언덕":79," 안산":100,"주였":57,"줄여":450,"종하":70,"좌표":82," 에너":453," 연관":129,"증대":108," 연고":210,"주요":747,"질적인":82,"죽음":150,"죽을":61," 여기":344,"죽은":134," 없다":375,"주인":347,"주이":578," 어드":76,"주의":4317,"집권":101,"콩 ":169," 없는":546,"주위":137,"종합":594," 연구":2349,"통 ":1329," 이오":58,"찬가":157," 이온":105,"지에서":319," 자신":748," 이와":206," 이외":199," 정당":373,"차관":122," 일어":792," 이용":1530," 일에":1863," 이웃":64," 적도":79," 절대":86," 의존":77," 전도":66,"톰 ":68," 전동":120,"톱 ":100," 이야":437," 제네":68,"차가":214," 이어":589," 이에":430," 이었":171," 이전":899," 장수":124," 위해":3054," 위험":192,"창간":101," 있었":1191," 일으":392," 일을":310," 인재":83," 잠시":62,"짧은 ":150," 이정":57," 있어":761," 이제":64," 제도":983," 인접":485,"지역번":77," 인정":430," 이종":59," 일자":88,"참고":72,"급하는":96," 위협":73," 일이":219," 장식":99,"창건":81,"증진을":113," 정도":1045," 이유":297," 인용":64," 이익":269," 장소":242," 재산":268," 일요":83," 이자":142," 유통":251," 이의":67," 제대":57," 잠수":90," 위한":1962," 일원":183," 위하":1580,"참가":738," 재생":127," 이수":74," 전남":74,"다섯 ":151," 인쇄":158," 원형":97,"스미스":64," 일생":60," 저널":82," 재무":111," 이스":433," 이슬":305," 인수":172," 이승":76," 익스":106," 응용":360," 제기":143," 유체":74," 원활":65," 이성":104," 인사":173," 인상":58," 제고":88," 제공":975," 접근":267," 정권":212," 정기":77," 일상":122," 제국":1197," 정규":377,"증진에":72," 원하":87," 의장":114," 자생":67," 장비":172," 작사":165," 유치":74," 자살":101," 자산":102," 일시":89," 임시":200," 작성":314," 작센":73," 의정":119," 자세":74,"트남 ":220,"다목적":58," 전달":242," 인스":61," 위키":130," 위탁":113,"식물 ":196," 재배":113," 이시":95,"톤 ":252," 잠비":60,"토 ":1338," 인식":217," 의원":243," 유출":60," 종교":1217," 이치":73," 적분":68,"급하고":62," 장점":70,"회에 ":290,"채널":346," 재임":96,"기호 ":76," 전반":229," 일체":59," 재위":670," 정리":561," 인체":78," 인천":505," 장의":150," 정립":87," 정복":93," 재직":117," 정보":1417," 제반":57," 이탈":1113," 일컫":636," 일컬":82," 재즈":82," 자체":292," 입출":70," 은하":175," 제목":256,"찾는":69," 전부":159," 전북":64," 재정":153," 일치":69," 은행":189,"창당":94," 잡지":202,"창달":122,"창단":248,"기타공":108,"채권":223," 잡아":60," 작은":643," 전류":87,"차남":68," 잎은":103,"매를 ":89," 조각":203," 자유":815," 작위":102,"찾기":70," 자율":74," 인증":117," 작용":292," 인지":119," 자원":213,"비이다":74,"창군":88," 있으":3188," 전례":131," 있을":254," 전력":146," 입자":250," 이진":78," 이집":402," 입장":142," 있음":85," 이지":96," 자연":687," 이즈":59," 잭슨":67," 일종":701," 전략":271," 일제":542," 임의":128," 작업":288,"쪽과 ":149," 자에":59," 인조":152," 전라":664," 이중":112," 일정":464," 인종":139," 이주":143," 조기":59,"차단":60," 전문":804," 유효":82," 조금":94," 자주":201,"차는":139," 있지":409," 유형":175," 임진":126," 작전":169," 저명":67," 자전":132," 유행":117," 장애":251,"대부 ":69," 장안":62," 장악":76," 유한":96," 유학":142," 점령":153," 조건":224," 자이":125," 제사":70,"천국":78,"천구":94,"천군":186,"첨가":59," 이해":327," 이행":101,"화예술":214," 이하":307," 정수":130,"창립":248," 인해":475," 인한":143," 인하":140,"참모":66," 일하":99," 인형":68,"차별":151," 정신":352," 정식":444," 이후":1760," 전압":65," 적어":66,"청과":62,"체가":469,"청구":177," 제시":244," 전에":217," 일환":93,"체결":240," 전역":168,"체계":709," 입학":80,"체고":109," 적용":417," 조류":83," 작품":1113,"체국":70," 조리":61," 전용":143,"채무":169," 적은":107," 전원":79,"신들의":66," 저자":149," 저작":244," 적이":69," 저장":326," 전의":63," 점에":156," 정부":1251," 자치":673," 정비":99," 인텔":209," 인터":1102,"차량":357," 층 ":246,"막부 ":71," 전사":114," 전산":106," 장착":83," 저서":110," 의해":2065,"차로":318," 의한":371," 의하":461," 의학":175,"차례":334,"시민 ":74," 전세":104," 전설":193,"름에 ":102,"차르":58," 저술":147,"차를":208," 의회":263,"착륙":65," 전송":205,"지역으":204,"지역을":380,"지역은":111,"카이 ":111,"지역의":387,"지역이":326,"지역인":66," 정사":64," 전승":126," 점성":173," 전신":162," 전시":258,"투 ":527," 장치":478," 정상":182,"천광":247," 접속":105,"스박스":60,"창설":240," 제주":484," 주기":199,"청동":74," 전차":91," 주권":84," 준공":68,"찰스":137,"체는":221," 정지":85," 재화":72,"화에서":184,"체되":102,"채소":57," 줄기":140," 중간":217," 전철":72,"지역에":787," 절차":120," 전체":567," 중구":353," 중국":2024,"체들":133,"차에":128,"르의 ":305," 정착":154," 조선":2644," 정책":576," 조세":64," 조성":287," 점차":84,"창시":143," 조사":590," 조상":79,"처럼":463,"차원":316," 존속":100," 주년":103,"처를":60,"초가":64,"카의 ":270,"차와":65," 접촉":74," 정체":105," 중기":271," 장편":91,"리메이":69," 칸 ":70," 제안":202," 전제":81," 젊은":107," 종로":405,"신문 ":168,"지어졌":61," 전쟁":1259," 적절":82," 전자":881," 저지":85,"차선":57," 제외":403," 점이":100,"청나":170," 종류":641,"청남":319," 전주":245," 정원":86," 칼 ":70," 점을":70," 제어":219," 점유":66," 종료":104," 재판":231," 제약":63," 자회":101," 제이":81," 종목":202,"찰서":86,"천동":110," 주가":75," 주간":132," 전직":83,"체나":63,"비에트":309,"차세":59," 정의":672," 접전":68,"청년":158," 제조":389," 주교":176," 주고":100," 제정":501," 주관":308," 재학":57,"처드":110,"첨단":94," 재해":66," 제임":214," 제일":119," 제작":1250," 제자":112," 주거":104,"철도":871,"탁 ":81,"타 ":1864," 용산":140," 오키":113," 영향":784,"탄 ":632," 유니":282," 유닉":93," 온타":105," 연호":83," 외에":213,"진흥":630,"징하":82," 유네":90," 요시":226,"지위를":75,"킹 ":248,"회사의":138,"지휘":406," 오케":84,"비잔티":171,"진화":280," 역할":582,"회사인":94," 여행":159,"회사이":255,"직후":76," 역학":81,"집행":234," 윈도":635," 연합":775," 유나":92," 요소":324,"질환":102,"집필":60,"집합":497,"집하":97,"진행":633,"코가 ":60,"지형":108,"킨 ":405," 운반":62,"진하":250,"진한":63,"진해":69,"비치 ":261,"는지 ":96," 왕조":583,"회사에":86," 왕족":171," 요새":71," 원리":213," 오카":66,"킬 ":155," 위대":99,"질학":58," 유기":176,"집트":409," 왕위":174,"직하":135,"직한":63,"직할":115,"지할":102," 왕으":89,"지함":108,"지하":1289,"지한":165,"키 ":1509," 왕자":123,"지향":165," 왕이":223," 영토":326," 왕의":63,"지했":204,"환으로":121," 완전":315," 육군":269,"지표":121," 원래":602," 우리":336," 유가":72," 예측":113," 와이":160," 에피":148," 유고":73,"리소 ":81," 월드":600," 우르":62," 첫 ":814,"루트비":99," 자국":94," 운전":103," 있기":213," 이나":121," 율리":81," 잉글":370," 의도":111," 유명":895," 우정":89," 작곡":845," 이끄":118," 이끌":202," 임기":78," 임금":138,"진왜란":116," 윤리":120," 자격":186," 우익":62," 총 ":839," 유리":168," 작가":611," 입구":69," 자가":81," 운용":154," 일까":724," 있고":843,"화인민":476," 있게":303," 원시":110," 용인":92," 워싱":115," 인기":260," 운영":1278," 인근":199," 위반":87," 우에":75," 오후":126," 이기":80," 유로":181," 원수":138,"화재로":72," 인구":3560," 일곱":88," 인권":151," 원소":289," 유럽":1117," 유러":115," 인공":238," 유래":578," 오호":60," 윌리":269," 용어":934," 이곳":157," 원산":126," 이고":250,"회원 ":168," 초 ":138," 일간":93," 이것":480," 인간":752," 오피":88," 오프":61," 오픈":259," 요인":73," 왼쪽":64," 오하":61,"회사를":67,"매되었":349," 위를":178,"능이 ":86,"택 ":158,"태 ":322," 우승":675," 오페":308,"회사로":118," 운송":76," 우수":237,"탕 ":82," 위로":69," 울산":328," 월부":254,"탑 ":86," 영화":1571," 우선":79," 유동":58,"컫는다":300," 유도":157,"화재단":118," 오토":147," 유대":297," 의거":134,"탈 ":268," 의견":96," 육성":259," 음반":525," 자동":798," 유성":164," 이래":213," 의무":187," 작동":93," 이라":1915," 이란":1010," 위에":358," 이러":460," 이런":125," 이렇":64," 우크":191," 인력":88," 의미":1870," 유신":72," 이로":113," 이론":891," 요크":70," 이때":111," 있다":14657,"칭이 ":130," 원주":160,"쪽은":318," 있는":7503,"활약한":126,"활약하":64,"쪽의":188,"화유산":156," 잇는":267," 이들":580,"쪽으":3081," 이듬":68," 있던":474,"터 ":8679," 인디":276," 의료":229,"턴 ":549," 있도":441," 자는":478,"털 ":563,"활약했":89," 육상":128," 장남":113," 웨일":79," 유산":69," 웨이":59," 유사":324," 장관":274," 이다":3516,"칭은 ":476," 위상":193," 장교":115," 음력":494," 장군":295,"칭을 ":179,"쪽에":725," 위성":197," 원인":186," 읽는":58," 원작":227," 원자":518," 이동":421," 음료":60," 움직":247," 일대":282," 장기":194," 유비":58," 인도":1080," 원제":62," 원정":83," 요코":84," 자녀":61," 원조":65," 유물":109," 우주":613," 이념":113," 요청":100," 자극":96," 자금":128," 웹사":127," 우즈":92," 으로":1449," 자기":443," 웨스":246,"지이며":179," 울주":85,"화이다":369," 월에":788,"화재가":70," 이는":558," 육지":73,"시되었":188," 전기":671," 재료":157," 유지":523," 전까":100,"회사가":85," 장르":269," 자발":83," 의식":186," 자바":143," 잘못":97,"지원을":145," 전국":513," 적극":94,"시되어":63," 이산":64," 이사":315," 이상":1002," 익산":65," 정교":161," 위치":5975," 제거":141," 자본":218," 장면":76,"회와 ":238," 음악":1252," 전개":206," 유입":69," 자매":61," 의사":412," 유인":76," 유일":468,"직으로":106," 임무":131," 일반":1861," 자리":455," 이복":68,"신도시":92," 자를":83," 자문":64," 입법":102," 일부":2106," 전공":90,"직이는":74," 장로":61," 운행":339," 운항":58,"커다란":64," 음식":283,"직이다":99," 유전":388," 유적":194," 일본":4755," 일명":82," 유엔":66," 인물":662," 인문":59," 유역":93," 자란":59," 자라":124," 인명":72," 자랑":66,"템 ":507," 음성":147,"기후 ":77," 임명":212," 인민":184," 유용":63," 이번":134," 이베":69," 이벤":57,"시드니":63," 이민":78," 우편":108," 이미":324," 이바":343," 워크":74," 자료":390," 이름":3638," 이른":205," 이르":661," 이를":700," 일로":82," 위의":84,"텐 ":76," 재단":468," 이뤄":69," 일렉":96," 이룬":137," 이루":1409," 위원":421,"테 ":299," 일련":190," 원칙":300," 이며":915,"지이다":426," 일리":90," 위임":72," 인류":278," 요한":197," 입력":181,"카와 ":236,"텔 ":308,"우가":342,"앙행":163,"용과":94,"암호":151,"올바":113," 수술":59," 수신":86," 순수":111,"仕 ":99,"에의":112,"창 ":189,"예상":58,"애플":275,"예산":117,"에이":482,"염색":75,"업이":475,"업인":321,"기의 ":1762,"업자":222,"없이":431,"여신":129,"었으":2299,"었을":161,"업으":181,"업을":673,"업은":134,"연수":157,"없으":154,"업의":671,"영사":61,"업적":191,"오버":82,"영상":486,"에우":80,"리아는":57,"어지":702,"역시":1578,"현존하":104," 수소":95,"어진":2055," 수송":124,"압하":71," 순서":114,"찬 ":123,"언제":60,"요구":295,"양체":81,"연세":57," 승격":131,"알프":91,"열사":59,"예비":145,"와라":117,"어족":218,"역소":73,"양천":58,"안하":96,"올림":844,"얼음":64,"착 ":90,"안한":115,"어졌":507,"올리":188,"올린":122,"어져":637,"찰 ":199,"에어":186,"연쇄":70," 수상":426," 수산":175," 수사":159,"여수":112,"에야":80,"단법인":2067,"연속":265,"연소":68,"기상청":109,"업용":63,"요건":96,"역삼":95,"역상":157,"어인":161,"어이":939,"아프":916,"어있":255,"글이다":95,"역사":1691,"어의":702,"오리":350,"얻은":80,"차 ":2442,"업연":100,"여성":713,"연산":224,"人 ":246,"없었":109,"여섯":133,"역설":57,"업에":293,"없어":112," 승객":70,"언이":107,"악하":95,"여서":479,"언을":82,"약칭":420,"아하":63,"역의":628," 수영":134,"오사":185,"역임":393,"역인":112,"여자":435,"역이":801,"스타 ":243,"연을":133," 싱가":97,"화에 ":525,"약하":110,"약한":190,"언츠":61,"연의":96,"오세":131," 수요":109,"연이":74,"업체":378,"업청":73,"연장":227," 수용":208,"월간":108,"영양":129,"연재":221,"약했":96,"영어":955,"열을":131,"스탄 ":326,"원격":59," 수원":209," 좀 ":59,"여졌":92,"열의":161,"영업":166,"원경":141,"용노":84,"영에":132," 손해":107,"연예":123," 소형":113," 존 ":356,"열에":85,"엔진":374,"약품":127," 심각":57," 수업":58,"역으":485,"여의":138,"역은":412,"역을":746," 수여":189," 시기":380," 소프":898,"예술":941,"예수":361,"여야":90,"연애":59,"연안":304," 소피":59," 시공":71," 속해":183," 송파":169," 소행":123,"역에":1144,"우기":66," 속하":1012," 시계":86," 속한":669," 신경":196,"여왕":122," 조 ":468,"어촌":137,"우고":127,"예선":249,"오브":295,"책 ":401,"채 ":187,"앙회":62,"용기":122,"왜란":118,"우구":91,"업지":61,"업진":68,"었지":266," 시가":100," 시각":159," 시간":720,"영리":199,"양으":132,"양을":259,"언스":130,"아키":326,"예루":109,"후로 ":162,"양의":505,"아타":75,"아크":78," 제 ":4289,"예로":129,"만이 ":196,"기자 ":326,"어스":174,"오디":190,"액체":118,"于 ":68," 수많":217," 정 ":183," 수립":238,"압축":117,"온도":198," 수를":81," 수리":128," 성향":66,"와나":75,"양에":292,"여명":94,"연맹":487," 점 ":68,"아케":128,"열린":478,"열리":280,"오도":95,"어선":74,"어서":782," 쉽게":163,"亀 ":88," 세포":385,"아침":62,"亂 ":1513,"왕국":706,"온다":87,"아카":282,"약자":201,"많은 ":1265,"약이":262," 수록":335,"약을":246,"약은":85,"어사":104,"야이":202,"약의":117,"왕과":64,"스턴 ":192,"오다":102,"약으":104,"야의":315,"오니":86," 수렴":58,"여를":144," 선형":142,"여름":122," 센트":165,"오늘":448,"오는":554,"기장 ":96,"연료":154,"열렸":185,"스터 ":402," 전 ":1060,"연령":60,"왕가":164,"에밀":59," 손자":147,"에미":96,"어원":140,"亳 ":89,"오류":90,"올로":60,"억원":67," 숭배":60,"오르":366,"오른":100,"지하기":153,"오를":110,"요가":94,"예보":65,"어와":363,"언에":58,"왔다":418,"예방":135,"티드 ":85,"아폴":74," 수비":88,"양쪽":63,"알파":123,"얻어":102,"얻었":76,"올려":58,"어업":225,"어에":445,"만을 ":299,"오로":122,"안티":93,"올라":211,"에스":534,"엑스":201,"어오":76,"어온":57,"언어":1505,"올랐":113,"영미":83,"지하고":206,"오랫":76,"완도":69,"아티":246,"온라":299,"염병":62,"아파":201,"어야":172,"양지":59,"기인 ":130,"외곽":60,"양주":113,"외국":418,"오래":309,"아트":145,"리아를":70,"오랜":130,"외교":422,"오라":68," 수반":64,"亞 ":1949,"여부":101,"외계":90,"에서":29088,"안토":110,"영문":119,"에선":73,"아테":131,"아토":68,"양재":76,"역번":77,"연방":786,"언십":167,"양자":317,"만의 ":176,"양이":303,"예를":245,"와는":313,"어리":167,"어린":285,"어를":713,"모가 ":127,"오가":148,"어류":77," 소수":212," 셋째":71,"악원":61,"양부":117,"협의회":158,"야생":75,"안을":183,"안으":82,"아자":83,"악이":91,"아있":148," 소스":183,"아일":569,"아인":232,"악의":207,"역대":111,"아이":1321,"어링":63,"어릴":143,"악을":150,"아의":1952," 서태":96,"약성":129,"아제":124,"않은":399,"않으":216,"오고":97,"않을":60,"안이":117,"연대":266,"안의":235,"어머":290,"앙아":113," 수단":217," 선택":204,"연도":64,"역되":83,"안정":303,"안전":674,"여되":60,"에라":85," 수는":94,"앙에":77,"얼마":78,"열대":208,"어라":65,"권한을":66,"액션":116,"였기":64,"때의 ":171,"실시되":64,"실시된":74,"어려":133,"아어":558,"스크 ":410," 선출":244,"아야":80,"에디":101,"않았":277,"안양":115," 소셜":77,"아와":401,"알아":118,"아오":102,"예금":73,"어렵":70,"에드":190,"아에":642," 소설":770,"않아":117," 생활":496,"어로":1502,"악에":82,"佇 ":72,"화와 ":320," 설치":696,"아웃":101,"아울":62,"아우":283,"안에":740," 소송":210,"언론":352," 소속":1527,"영된":120,"영되":313,"애자":58,"업무":727,"액을":97," 속에":242,"애인":203,"글자를":64,"양수":197,"기술과":58,"엄밀":70," 선포":61,"업발":66,"오나":76,"엘리":216," 소유":309,"완공":68,"여래":59,"영등":168,"디자이":77,"디자인":463,"양시":233,"양식":325,"앤젤":102," 소장":152," 속이":74," 센터":199,"기술개":69,"여러":1623," 속의":125,"약에":115," 서해":142,"카에 ":110,"야에":433," 소재":587,"연되":60,"옮겨":85,"아주":160,"앞에":101,"열도":82,"알제":77,"오기":78,"에로":64,"였는":131,"엘라":90,"야스":153,"아즈":110," 수도":1216,"았으":301,"였다":6029,"야시":57,"아지":116,"아직":137,"양사":193,"양산":105," 속씨":88,"였던":503," 소아":74,"어버":79,"양상":57,"다시 ":463,"니와 ":61,"않지":68,"에르":318,"시즌 ":224,"에른":140,"에리":86,"앙정":74,"양성":389,"에만":120,"영동":84,"옛날":72," 산하":461,"씨식":95," 자 ":216," 소멸":81," 서적":93,"막을 ":84,"야로":143," 사항":165," 선의":80," 섬에":254," 사하":60," 상트":68,"아사":140," 섬이":161,"아산":86,"스키 ":291,"야마":570," 섬의":117,"기술로":69," 산화":93," 상표":91,"대륙의":64," 잘 ":546," 성우":86," 생태":163," 세에":95," 사후":156," 섬을":79," 섬으":146,"여개":65,"여객":267," 선종":67," 사회":2075,"야를":102," 섬유":63,"여가":61," 설정":173," 살해":171,"어는":597," 선조":133,"리아가":58,"단백질":180,"어느":238," 선전":63," 사형":76," 선정":248," 쇼군":110,"알베":57," 선양":102,"쓰인":360,"쓰이":716," 선언":226,"아부":73,"에게":2384,"안보":81,"양도":65," 상태":747," 일 ":16662,"알바":146,"르토 ":64,"양동":61," 서양":207,"었고":896,"애를":72," 소련":332,"막의 ":105," 석유":97," 소리":267," 소말":61,"어내":101,"아비":128,"어낸":69," 서유":66,"아브":61,"어나":672,"어날":73,"어난":835,"었기":138," 솔로":142,"어났":456,"업기":117," 서울":3544,"머리 ":75,"안시":66,"었던":889,"어떻":123,"투에서":133,"였고":684," 성직":123," 성질":259,"에는":3705,"었다":9042,"연금":63,"아시":1288,"금융기":75,"연극":189," 성주":57,"어떤":681,"어떠":156," 세종":300," 소비":642," 세조":70,"암석":66,"연기":258,"염기":67,"마을 ":150," 서초":356,"영국":2099,"에도":1265,"씨의":120,"영과":63,"에다":73,"어도":167," 세우":109," 세운":200,"언덕":81," 성인":182," 세워":312,"양력":120," 성장":260,"역과":296,"연계":123," 상하":185," 선진":141,"연결":758," 세웠":103,"연고":218,"안성":60," 상품":255,"얻는":95," 소방":94,"여겨":282," 세와":139,"앨범":671,"아서":237," 성은":94,"얀마":118,"안산":110," 성의":77,"없는":620,"여금":57,"에노":70,"어드":104,"어들":198," 상호":668,"여기":352,"업단":115,"기적 ":104,"었는":201,"없다":384," 샌프":82,"암살":118,"아스":346,"어디":66," 상황":261," 수가":104,"마의 ":282,"연과":73," 성전":89,"연관":142," 성적":226,"에너":561," 장 ":243," 세의":435," 서쪽":905,"대륙에":112," 세이":184," 세인":106,"연구":3821," 사찰":82,"았던":129," 은 ":18128,"암동":115," 을 ":2159,"애니":672," 소녀":88," 상징":242,"양계":70," 소년":140,"양경":128,"양과":174,"양군":100,"양국":72,"양구":62,"비아의":150,"아들":1116,"야기":519," 서북":81," 서부":519,"아드":146,"때에 ":170," 상주":72,"아디":57,"았다":1000," 서브":58,"안드":183,"길이 ":175," 서비":842,"금으로":71," 서사":93,"실제 ":183,"俘 ":76," 생존":104,"아레":72," 석사":65," 사카":84," 세부":97,"아로":119,"알라":103,"앤드":86," 속도":241," 의 ":5102,"치인 ":144,"기술서":144," 성분":85," 읍 ":79," 성북":85,"디오에":59,"아라":308,"아랍":275," 소니":105,"아래":399,"압력":96," 서식":301,"리에서":329,"승용차":65," 선수":1292,"아마":286,"아목":89,"알리":180,"아몬":59," 사태":68,"아메":712,"알려":1678,"알레":75,"알렉":317,"아리":224," 소득":100,"아름":151,"어가":540,"어간":77," 서술":85,"아르":723,"아를":253,"직할시":78,"아바":91,"언급":141," 이 ":6364,"앙리":61,"쓰였":116,"얼굴":69,"아미":126,"지하였":117,"업과":191,"업관":61,"없고":95,"아버":569," 인 ":395," 생체":57,"업계":106," 센서":58,"양대":68,"지》":67,"르트 ":344,"어권":118,"니어 ":84,"아무":106,"아문":73," 성서":95,"기술부":292,"길을 ":64," 산타":90,"업가":98,"쓰여":83,"형적인":66," 세상":123," 위 ":236,"악기":342," 상수":101,"안구":75,"안군":96," 상속":67,"알고":264,"아기":73,"시스템":1332,"심이 ":111," 섬들":62,"안과":128,"아군":73,"니오 ":65," 성동":57," 세대":321,"실시간":101,"않고":536,"악구":59,"아과":121," 산스":84," 삼성":325," 성당":140," 세는":67," 웹 ":345,"악과":60," 사용":5046," 생산":1061," 사운":155," 사우":191,"기술적":76," 사원":114,"아날":73,"아나":434,"아내":271," 산업":792," 살아":158," 살았":134,"시스코":114,"았고":97," 사업":732," 산악":85,"지함을":85,"슈퍼 ":89," 서로":499,"진행된":77,"진행되":197," 상승":71,"않기":58,"심의 ":122," 소규":60," 생식":58,"아는":197,"기술연":67," 삶의":108," 삶을":67," 살인":124," 상에":106," 상업":212,"아누":93," 설립":4416," 서명":79," 사정":82," 사제":64," 소관":1915," 사적":136," 사전":183,"기술을":263," 산이":64,"기술의":232,"아노":202," 사장":102," 사자":61," 사이":2278," 소개":178,"기술이":179,"기술인":74," 사유":70," 생성":251,"기술자":91,"애국":68,"급으로":81," 손꼽":71,"안되":84,"안된":112,"기존 ":131," 선보":66,"즈》":67,"안동":130," 성모":102," 색을":60,"侶 ":207," 세르":235,"야구":985," 서버":233,"아돌":57," 상임":95," 선발":106,"심을 ":205," 선박":128,"아동":169,"앵글":61,"안데":62,"애나":90," 산지":91," 상의":104,"않다":149," 상을":58," 성립":280," 상이":114," 상인":70," 상위":92,"않는":850," 삽입":61," 사진":217," 상으":64," 성리":78,"지하철":230," 상원":72,"기술에":58,"악단":271," 세로":127," 소금":58," 세력":190,"아닌":450,"아니":1250," 설명":374," 상용":62,"약간":124,"아다":74,"말은 ":132," 사무":2313," 사물":92," 설계":434," 선교":139," 선구":63,"지한다":100," 서기":255," 새로":744," 새롭":78," 상륙":76," 상류":70,"리아어":250,"리아에":188," 섬과":100,"목과 ":70," 사법":159," 성격":204,"말을 ":157,"스주의":80," 성경":194," 세가":201,"통틀어":103,"트리 ":144," 성공":441," 성과":102," 세계":3678,"스코 ":228,"치적 ":191," 서남":105," 원 ":160," 센고":139,"지하는":209,"쓰는":237,"쓰다":206,"니아 ":1248," 월 ":22165,"많이 ":589," 세균":89,"쓴다":98," 세기":1685," 생리":73," 생명":334,"쪽 ":908," 샤를":130," 서대":93," 성남":123," 사상":928,"르체고":106,"캄보디":75," 생물":516," 산소":61," 선도":76," 산성":63,"집트의":91,"악가":125,"실이 ":60,"비영리":167,"아가":452," 세네":79,"화의 ":697," 사실":480," 성능":96," 사도":134," 외 ":86,"슈팅 ":70,"진하고":72," 생기":166," 생긴":156," 살던":66,"倉 ":985,"토해양":108," 상당":502," 상대":501,"캘리포":248,"말이 ":72,"회사 ":324,"지했다":169,"뉴질랜":239,"측정하":101,"메라 ":83," 사람":2374," 사랑":216," 사라":147,"쓰고":114,"화재 ":280," 사령":113," 사례":65,"기준 ":2089," 사망":418,"기술하":75," 용 ":77,"리아와":111," 사립":104," 사마":97," 사막":116," 사르":73,"확인 ":117," 선고":68," 서구":220,"리아의":735,"투아니":93," 우 ":320," 선거":866,"쓰기":124," 산맥":264," 산림":264,"말의 ":116,"적이":892,"저작":265,"저자":156,"적인":4818,"亂並":388,"전위":69,"亂丘":135,"전으":231,"전은":327,"亂三":545,"저장":344,"적자":77,"전의":505,"정안":94,"亂丁":320,"점에":478,"전을":821,"적재":58,"자하":69,"전인":95,"전이":516,"져서":63,"작하":761,"작한":580,"작품":1198,"조를":342,"조르":59,"조리":96,"전용":189,"적은":2124,"적으":6892,"칭 ":682,"전원":97,"적의":174," 쓰기":94,"적을":427,"임했":179,"저우":183,"당시 ":1027,"침 ":97,"따왔다":64,"절에":116,"적용":431,"환의 ":69,"조류":112," 쓰고":102,"리우스":221,"전에":1678,"제시":329,"일환":97,"임한":108,"임하":316,"전역":201,"입한":122,"입학":90,"입하":329,"인형":87,"조로":212,"적에":131,"적어":75,"전압":72,"이후":1816,"잔티":172,"並國":285,"칠 ":70,"정식":676,"정신":481,"이화":58,"일한":420,"정시":83,"일하":307,"친 ":511,"정수":173,"乙倉":109,"이해":346,"인프":61,"이행":148,"인하":333,"칙 ":237,"인한":241,"인해":494,"치 ":2632,"신인 ":126,"이프":354,"제사":194,"이한":134,"이하":446,"三大":142,"신이 ":258,"접속":115,"이풀":105,"정성":106,"정서":149,"장치":620,"전신":167,"환을 ":105,"전시":500,"乙乙":117,"정상":286,"乙之":271,"之倉":297,"일파":102,"자키":58,"종대":66,"乙亞":103,"전승":143,"정사":185,"점성":174,"乙亂":105,"자크":65,"乘三":61,"이퍼":110,"乙並":232,"재청":67,"전술":58,"족들":119,"乙丁":307,"시절 ":80,"저스":73,"乙丘":178,"乙三":410,"三國":301,"인트":215,"전소":133,"이팅":121,"저수":94,"이파":70,"전송":216,"저술":150,"의회":639,"이티":216,"之亂":405,"명단 ":58,"之亞":451,"이틀":169,"이트":1360,"전세":108,"신장 ":61,"조된":63,"전성":138,"조되":83,"전설":222,"전선":133,"之丁":1040,"之三":2090,"之丈":89,"망을 ":100,"之両":59,"之並":1657,"之丘":553,"之丙":209,"之且":109,"장착":83,"전산":136,"之丹":143,"전사":228,"저서":111,"의해":2089,"之之":1269,"의한":468,"의학":321,"의하":736,"之乙":257,"의할":59,"제부":107,"자치":1144,"정비":150,"확장 ":96,"인텔":213,"이토":133,"인터":1169,"층 ":466,"丹倉":60,"조달":91,"응하":231,"조는":153,"이터":1189,"정부":1875,"정벌":59,"정법":122,"자체":347,"丹乙":84,"정변":61,"재즈":85,"丹之":209,"丹並":154,"제반":61,"정보":2086,"이크":941,"이클":251,"정복":111,"재직":118,"재지":325,"쟁으":65,"쟁은":76,"僅 ":60,"쟁을":248,"쟁의":208,"이타":167,"이탈":1138,"쟁이":241,"丹亞":73,"제법":87,"은하":190,"측 ":145,"제목":268,"이케":58,"츠 ":974,"리이다":317,"잡지":250,"화제 ":72,"조나":82,"쟁에":206,"일치":88,"은행":538,"이코":123,"리잡고":88,"丹三":207,"丹丘":102,"丹丁":217,"입출":70,"정받":96,"비스를":298,"並倉":230,"일컬":82,"일컫":636,"재의":598,"並人":80,"장점":74,"中三":72,"종과":75,"실을 ":195,"제리":117,"종교":1302,"장조":63,"이치":249,"재자":79,"並亂":444,"전보":64,"傭 ":180,"재이":59,"재임":98,"並亞":687,"재일":59,"적분":127,"정무":57,"이카":88,"제명":84,"재정":215,"이커":104,"전북":82,"전부":292,"中並":57,"中之":85,"장을":941,"인체":87,"장은":773,"장으":586,"정리":695,"両之":103,"인천":533,"졌다":865,"장인":245,"丟之":69,"両三":99,"장이":1191,"젤레":109,"장의":447,"정립":97,"両並":87,"並丹":89,"일체":116,"並並":1269,"並乙":240,"전반":248,"丘倉":118,"스케 ":67,"실은 ":1893,"並之":1226,"장자":107,"並丁":729,"제를":766,"並丘":363,"융합":89,"재위":678,"제르":165,"並両":95,"並三":1954,"並丈":68,"종결":57,"三倉":449,"丘之":421,"丘丘":278,"자주":224,"丙丁":90,"丘並":322,"丙三":80,"화적 ":138,"丘亂":138,"僅丁 ":58,"丘乙":185,"丙之":212,"있지":448,"재연":67,"제로":721,"조기":91,"丘亞":147,"실의 ":102,"잡이":62,"유효":82,"丟並":76,"조금":122,"이천":64,"재에":108,"丟丁":65,"전문":1050,"유해":57,"장애":383,"장악":78,"장안":65,"丁倉":187,"자전":175,"자적":159,"유행":121,"자재":65,"작자":143,"자자":71,"작이":256,"조건":316,"유하":391,"유학":156,"유한":279,"점령":156,"장에":759,"임진":131,"유형":215,"전면":62,"제라":64,"작전":209,"丘三":684,"丘丁":429,"임즈":102,"저명":67,"정렬":62,"은퇴":57,"三侶":71,"족과":104,"丈三":117,"잎은":109,"三丈":107,"丈並":101,"三万":69,"三丁":1471,"자원":529,"三三":4055,"三丘":745,"인지":345,"三丟":89,"三丙":67,"三並":2154,"三両":110,"인증":178,"丈之":100,"三丹":134,"작용":550,"三之":2117,"三乘":139,"三乙":351,"자인":870,"자이":2068,"작의":72,"三亂":531,"작으":448,"자의":1247,"작은":702,"잡아":77,"작을":166,"三亞":989,"전류":94,"조개":72,"자음":68,"三人":96,"자율":111,"작위":138,"조각":242,"조가":162,"자유":977,"자였":253,"임이":597,"자연":787,"리위원":62,"자열":60,"丁丘":425,"丁且":87,"임의":297,"작업":333,"입은":77,"자역":86,"입을":113,"작에":70,"丁丈":69,"임을":405,"자에":659,"丁丁":864,"제들":91,"丁三":1278,"전략":331,"丁丹":114,"임은":109,"임으":241,"자어":57,"丁並":785,"일제":561,"이중":126,"丁乙":272,"일정":485,"임위":64,"인종":158,"丁之":1054,"이주":163,"으키":165,"으킨":137,"이징":189,"丁亞":282,"이집":416,"이진":103,"이지":1231,"입장":148,"있음":88,"丁亂":313,"丁人":80,"전례":156,"있을":258,"있으":3281,"자와":521,"입자":336,"전력":195,"丈丁":89,"잭슨":68,"이즈":350,"임자":75,"입이":70,"일종":722,"정되":1028,"이잔":109,"정된":594,"식을 ":714,"재생":142,"이재":61,"이익":326,"이이":176,"재산":389,"이인":77,"장소":328,"황에 ":67,"유통":346,"일요":87,"이자":2950,"인의":1113,"위해":3093,"인이":4001,"인으":806,"인을":537,"임에":183,"인은":257,"일원":193,"위하":1705,"위한":2059,"식은 ":203,"장성":72,"이유":337,"인용":176,"졌고":82,"익을":208,"제대":96,"정동":479,"이의":934,"잠수":99,"이은":66,"제단":60,"정도":1147,"인원":74,"이종":60,"일자":116,"인접":487,"인정":511,"인적":116,"위협":78,"인조":157,"전라":669,"장시":86,"장식":115,"임워":63,"취 ":74,"잠시":62,"기지 ":76,"인재":122,"이제":109,"제도":1306,"있어":778,"이정":63,"인자":89,"이점":63,"장수":156,"이전":987,"통합하":160,"이저":329,"인인":120,"이족":65,"이조":77,"제되":75,"일인":105,"일이":470,"일의":940,"위험":212,"일을":556,"일은":174,"일으":424,"있었":1211,"자수":84,"이야":497,"제네":71,"전되":64,"절도":60,"이어":1308,"이언":277,"이었":2244,"이에":1970,"익에":79,"신설되":74,"의존":91,"전도":170,"이아":356,"전동":176,"이안":76,"캐릭터":185,"이외":210,"정당":438,"유키":92,"이용":1588,"이우":80,"일어":991,"장사":59,"시인 ":178,"일에":2143,"이웃":70,"제는":261,"이였":67,"인어":137,"이올":125,"이온":234,"이오":499,"식의 ":484,"인에":349,"이완":207,"자신":773,"유클":61,"이와":378,"자식":84,"의지":73,"일신":97,"일시":120,"일스":114,"잠비":104,"파는 ":76,"인시":91,"인식":243,"유출":66,"의원":853,"활을 ":172,"위키":154,"인스":118,"위탁":115,"재배":144,"인슈":60,"응을":89,"제나":96,"절대":92,"적도":104,"임시":210,"작센":85,"의제":61,"작성":335,"의정":233,"의적":274,"자세":81,"자성":62,"임스":290,"전당":60,"전대":71,"전달":281,"의장":161,"자생":114,"음주":74,"의자":305,"유치":96,"작사":221,"장비":214,"의인":546,"자산":166,"자살":104,"자사":95,"의의":352,"일상":129,"시작 ":73,"제국":1585,"일생":67,"시설이":123,"원한":148," 집 ":170,"원하":678,"쟁력":155,"식이 ":173,"이소":58," 신흥":72,"비스이":77,"정기":592,"제교":76,"을이":57,"이세":85,"제고":109,"이센":174,"인상":83,"제곱":73,"제공":1150,"정규":416,"이션":1407,"음에":319,"접근":281,"정권":313,"점기":433,"이선":105,"시설을":69,"인사":262,"兌 ":199,"이성":133,"익스":143,"활의 ":71,"입사":58,"이승":80,"원후":60,"이식":83,"이시":344,"의와":146,"이슈":60,"제기":237,"유체":83,"음의":177,"원활":70,"원회":1095,"임상":62,"이슬":422,"이스":2082,"仕三":62,"육청":92,"음이":197,"인수":210,"원형":177,"인쇄":185,"음으":564,"음은":101,"의에":273,"음을":324,"응용":379,"저널":109,"음원":65,"재무":115,"일성":102,"이수":87,"전남":92,"의약":116,"이순":57,"재로":240,"저기":73,"대백과":604,"잘못":97,"적극":95,"출 ":296,"치의 ":225,"점검":69,"장르":283," 시행":352,"육지":116,"재료":225,"유지":641,"시장 ":205,"전기":888," 신학":305," 시험":291," 지 ":95,"의식":267,"자바":152,"자발":97," 시호":361," 진 ":93,"점과":85,"人三":93,"전까":209,"을에":58,"자베":74,"장면":96,"자본":288,"제가":451,"제강":74,"음악":1495," 질 ":78," 신호":310,"정계":61,"정경":76," 실행":293,"칙을 ":131,"재를":220,"이사":565,"이산":85,"정과":206,"스카 ":184,"정관":93,"충 ":115," 신화":415," 실험":263,"정구":335," 실현":162,"이상":1108,"위치":6047,"제거":152,"익산":65,"정교":193,"일반":1994,"자리":1002,"익보":67,"이보":83,"이복":70,"유의":257,"임무":144,"일방":62,"유인":88,"之大":89,"유일":471,"입문":63,"자매":75,"의사":510,"육의":120,"마스터":68,"육을":218,"인보":77,"유자":93,"의상":66,"유입":79,"까운 ":156,"전개":214,"이부":78,"육자":126,"의성":63,"일보":361,"일본":4937,"유적":246," 실패":143,"유전":485,"전거":106,"추 ":144,"이븐":59,"율을":155,"이브":495,"음식":352,"축 ":318,"이블":337,"운항":73,"율이":70,"亞倉":61,"이비":217,"장로":122,"운행":351," 식품":226,"전과":411,"전공":113,"일부":2152,"전광":273,"우호":59,"춘 ":196,"신은 ":98,"자문":126,"입법":132," 심판":95,"작물":136,"율적":242,"유주":119,"전국":582,"위주":70,"심에 ":61,"신을 ":369,"之國":69,"之圓":61,"이묘":288,"자랑":69,"인명":89,"유역":120,"이므":100,"자로":1208,"인물":819,"인문":93,"유에":59,"유엔":67,"자력":167,"일명":83,"음성":162,"亞丁":182,"亞三":599,"음서":80,"亞丘":99,"자루":62,"워크":714,"이바":376,"유와":57,"亞並":511,"자료":546,"울특":2233,"이미":360,"亞之":492,"이민":84,"우편":143,"자를":1003,"용해":337,"자르":81,"용했":139,"육원":57,"용하":2610,"亞亂":216,"용할":380,"용한":877,"이베":186,"亞亞":176,"이벤":65," 시티":84,"유용":65,"임명":214,"인민":1273,"이버":362,"이번":163,"위원":1545,"亂乙":88,"의병":59,"일로":231,"재는":563,"亂之":408,"이뤄":69,"일렉":99,"亂亞":162,"亂亂":108,"일련":190,"장동":67,"이마":124,"위의":342,"신의 ":935,"위이":229,"이맥":82,"위인":79,"인류":317,"이름":3683,"이를":1128,"이른":205,"이르":700,"재단":793,"이리":104,"입력":182,"요하":229,"이머":65,"요한":1121,"이먼":60,"이메":59,"디지털":568,"이며":7197,"위임":83,"위자":61,"장된":112,"장되":154,"인리":94,"인먼":269,"비스타":71,"위조":60,"자라":247,"재되":117,"자란":69,"원칙":340,"은색":62,"이면":165,"이명":60,"亂倉":143,"일리":688," 신체":155,"외하":104,"외한":225," 스포":456," 신청":73,"매사추":92,"육상":138," 시초":66,"장남":121,"우치":86," 스펙":67," 스페":757,"웨일":116,"장난":59,"유산":310,"유사":363,"웨이":486,"자대":65," 시청":126,"쟁과":63," 丘 ":87,"있도":442,"자니":97,"입된":112,"입되":233,"마쓰다":198,"의를":445," 스파":150,"자는":1092,"일드":67," 스티":145,"원지":101,"있던":494," 스트":337,"인디":287," 스튜":250,"인들":571,"워진":166,"의료":334,"요크":80,"이때":111,"있다":15164,"원주":176,"위스":240,"재까":179,"이디":118,"있는":7991,"우체":68,"의로":182,"으므":160," 즉 ":662,"메리 ":61,"유신":98,"이루":1453,"일러":233,"이룬":139,"우크":207,"위와":98,"의미":1879,"일랜":486,"인력":158,"자들":1135,"위에":756,"이론":1040,"이로":415,"이렇":64," 스프":81," 시카":80," 스피":206," 스핀":57,"의무":269,"의문":59,"이런":131,"이러":633,"통하여":478,"이라":4666,"이란":1468,"이래":223,"작되":526,"작된":385," 並 ":184,"음반":546,"자동":1079,"최 ":64," 실천":136,"작동":101,"유성":172,"육성":326,"장경":65," 신조":74,"이는":2179," 슈팅":70,"장관":476,"이다":44715,"재개":63,"장과":268," 실제":432,"이니":195,"재가":173," 시조":152,"원예":81,"우지":75,"원에":608," 싱어":64,"장갑":60,"월에":803,"장거":57," 스코":288,"잡고":156,"울주":88,"으로":39730,"자기":738,"웨스":286," 신인":71,"움이":79," 신이":79,"움을":181,"이노":91,"요청":103," 신의":77," 신장":97,"비슷한":239,"유발":57," 스케":164,"비슷하":194," 시절":186,"우즈":100,"유민":79,"웹사":130," 신자":91," 시점":66,"이네":70," 시인":309," 시이":157,"유무":68,"이너":235,"통해서":112,"유물":138," 시의":190,"작권":131," 실용":67," 시장":413,"자극":108," 스카":114,"자금":194,"시상식":63,"우주":734," 시작":1908,"이념":153," 스톡":57," 스토":195,"투이다":152," 실질":132,"자녀":65,"인되":81,"원조":101,"인된":61,"웨어":1107,"이듬":68,"이들":778,"잇는":270,"이드":728,"움직":247,"워졌":78,"음료":81,"일대":304,"깊은 ":79,"자나":141,"왕후":204," 三 ":313,"원전":1057,"유비":60,"장기":260,"원정":112,"요코":91,"인도":1254,"원제":94," 스테":207,"원의":775,"용차":86,"원인":277,"위성":291," 스키":157,"원이":1024,"으면":282," 스타":592,"으며":8023,"읽는":62,"원자":600,"원작":230," 스탠":103,"원장":376,"이도":263," 싸움":60,"이동":495,"인데":229,"울지":66," 심의":80," 슈퍼":229," 丁 ":138," 신주":59,"위상":207,"장교":142,"재건":66," 시즌":547,"음력":497," 심장":68,"위생":71,"이던":150,"이더":241," 십자":179,"원으":778,"인다":456," 스크":137,"장군":389,"원을":809,"원은":649,"이데":100,"육부":79,"형태 ":63,"일군":61,"원수":199,"유롭":69,"원숭":77,"三爲":60,"우에":529,"오후":131,"이기":1185,"유로":412,"이그":62,"일과":149,"인권":206,"용이":398,"용인":137,"임과":78,"운영":1427,"용의":233,"워싱":117,"용은":159,"용으":300,"용을":584,"인기":282,"인근":202,"위반":100,"우와":70,"유래":580,"인공":464,"용에":213,"인격":64,"용어":1083,"윌리":271,"초 ":560,"원생":66,"요제":75,"일간":105,"일가":59,"일곱":97,"인구":3663,"유럽":1343,"冲 ":93,"유러":115,"원소":347,"오호":62,"촌 ":246," 실시":523,"인과":324,"이끌":202,"자고":60,"우저":126,"이끄":118,"의도":237,"유명":908,"우정":123,"작곡":859," 썼다":61,"윤리":162," 시와":120,"임금":151,"자격":236,"옹호":75,"임기":171," 시외":158,"의된":97,"대성 ":58,"이내":59,"의되":83," 시위":129,"운전":120,"자국":131,"자군":113," 신용":132," 실업":107,"율리":85,"작과":77,"잉글":396,"울의":68,"이나":3192,"있기":222,"이남":57,"유를":151,"있고":900,"일까":746,"자간":58,"운용":176,"자가":1369,"우유":59,"울에":84,"위법":67,"원시":421,"용자":756,"있게":320,"유류":81,"의는":204,"일기":79,"우이":219,"우익":68,"우자":69," 시에":386," 신앙":144,"입구":92,"입국":115,"치에 ":239,"작가":798,"유리":178," 신약":73,"총 ":953,"우의":129,"월부":255," 스위":277,"우수":283,"운송":99," 시사":57," 중 ":2659," 시상":122," 시설":392," 신사":98,"운수":104,"시의 ":1040,"오페":337,"우스":1158,"리칸 ":115,"위로":336,"의거":140,"용소":61,"우선":90,"영화":1822,"활성화":218,"의견":100,"리카 ":773,"유동":91,"원부":65,"유도":196,"리적으":85,"용수":83,"외전":91,"울산":345," 스웨":362,"리적인":105,"으나":1988,"이가":479,"울시":173," 승용":68,"오픈":264,"요인":96,"욕의":65," 심사":67,"오프":166," 시스":1156,"요일":287,"이거":210,"인가":135,"인간":782,"이것":484,"오피":231,"이게":62,"오하":85,"왼쪽":64,"원사":88," 실수":85,"이고":1474,"원산":135,"이곳":157," 승인":135,"원상":70,"우승":695,"우시":59,"오폴":57," 신성":183," 신설":178," 신속":77,"위를":1049," 시민":365,"오카":257," 식민":417,"원리":261,"여하":917,"여한":139,"여할":326,"여함":202," 스스":212,"요새":77,"왕족":171,"왕조":659," 심리":249," 신문":265,"위대":223," 시뮬":113," 식물":383,"위는":290,"스이다":194,"융기":85,"윈도":643," 식별":121,"오케":99,"쳐 ":1031,"연합":1184,"요소":392,"유나":103,"연하":111,"연한":93,"여행":192,"요성":113,"여했":135,"역할":607,"역학":339,"역한":78,"역하":120," 亞 ":77," 신분":107," 주 ":4010,"매우 ":477,"통합되":76,"요시":396,"오클":62,"리이며":65," 수행":872," 수학":787,"연호":88,"메니아":86,"외에":406,"유네":90,"倉亂":100,"육대":57,"오토":172,"예프":66,"외의":195,"유대":321,"倉亞":80," 순환":84,"영향":799," 줄 ":89,"유닉":93,"용성":58,"유니":298,"의가":147,"온타":106," 신비":72,"倉丁":326,"영한":96,"영하":577,"유는":91,"倉並":271,"倉丘":124,"倉三":482," 수호":59," 준 ":71,"음과":236,"용산":154,"오타":75,"倉乙":106,"오키":160,"倉之":304,"월드":684,"첩 ":70," 식량":97," 신라":319,"우를":179,"우르":146,"첫 ":815,"업협":85,"유가":172,"우리":506,"웠다":116,"원들":183,"오지":91,"맡은 ":78,"울러":57,"업한":67,"업하":195,"대사 ":83,"우루":219," 시라":58," 亂 ":146,"웨덴":355,"유고":84,"육과":405,"육관":1166," 신뢰":95,"체 ":1944,"청 ":1596,"예측":116,"와의":292,"와이":323,"와인":57," 시로":87,"업화":69,"빛의 ":78,"카스 ":79,"에피":155," 시마":63,"회민주":65," 쇼핑":60,"원래":605,"빛을 ":75," 술탄":78,"위나":89,"유권":118,"육군":281," 시리":1297," 시를":88,"완전":346,"칙에 ":86,"유구":70,"영토":332,"왕이":422,"왕의":270,"스위스":188,"원로":84,"왕을":61,"왕으":142,"운반":68,"왕자":127,"리자베":66,"육기":102,"유기":217,"온천":62," 시모":72,"왔으":124,"니의 ":167,"왕위":174,"오염":119,"요로":94,"우디":104,"메르 ":60,"언트":67,"우드":176,"오에":131,"오와":86," 시도":132,"열차":260," 스몰":57,"운드":310," 승려":122,"디즈니":97,"요르":77," 乙 ":95,"위가":175,"왕성":75,"스이며":63,"侶三":70,"외버":131," 신도":90,"오이":168,"오일":61,"엔터":311," 스미":84,"요리":555," 시드":98,"연출":61,"대상 ":99,"오의":95,"위공":239,"오전":108,"왜성":61,"위계":74,"용량":87,"어항":124,"원대":91,"온의":63," 승리":259," 순천":93,"어하":99,"어학":198,"후반 ":84,"외부":238,"원도":356,"에트":351,"위구":57,"우라":154," 수출":183,"척 ":91,"처 ":416," 수치":83,"우려":58,"왕실":105,"에티":108,"원동":67,"천 ":830,"요미":57,"어휘":60," 죄 ":83,"우로":109,"위기":195,"철 ":398,"워드":249,"연적":84,"원고":58,"치와 ":115,"열이":89,"영역":375,"언컵":95,"외래":67,"원과":233," 종 ":214,"화시키":67," 수익":76," 수의":96,"실에 ":74,"원구":83,"원국":135,"여주":182," 수입":181,"옆에":62," 순위":121,"예언":76," 수장":78,"원군":252,"영원":61,"영웅":130,"오스":1498,"연주":311," 수정":210,"옥스":58,"몽골 ":105,"였으":1734,"오시":78," 丹 ":77,"왕복":96,"였을":67," 싱글":369,"여지":119,"여진":185," 시나":74,"영을":122,"영의":146," 시내":231,"영이":82,"영자":87," 숙종":91,"영장":73,"양한":780,"양학":62,"양하":218,"우는":273,"월까":163,"양항":61,"용도":148," 수준":219," 슬라":77,"예인":65," 실내":91,"예의":63,"용된":671,"용될":69,"영조":63,"왕비":137,"용되":1573,"예전":122," 숫자":146,"와서":75," 수집":187," 수직":64," 之 ":340,"운데":1232,"예정":321,"우도":237,"영주":89,"완성":213,"울대":190," 슬로":136," 스리":80,"운동":1815,"외무":92,"어트":94,"대문구":151," 스마":121," 시대":2063,"였지":104,"영지":83,"어파":69,"소시":75," 분쟁":188," 붉은":115,"소스":310," 부정":201," 분자":245,"세청":93," 부인":212,"셋째":71,"소수":273," 부작":91,"수다":87,"수단":483,"세츠":103,"시와 ":384," 브로":98,"티나 ":145," 붙여":234," 브레":111,"선택":248,"름에서":87,"서태":158," 붙어":133,"손실":63,"단의 ":266,"수는":372," 브라":642," 부족":243,"송사":95," 브랜":223,"션으":79," 불안":63,"션을":118,"션은":114,"소사":75," 분야":1053," 부여":249,"쟁 ":829,"선출":248,"썼다 ":65," 비극":78,"생했":81,"생하":591,"생한":515," 북아":293," 북위":59,"성체":67," 부위":68,"설치":714,"수나":99,"소속":1553,"소송":393,"신에 ":117,"명과 ":133,"속성":78,"소셜":82,"션의":93,"소설":947,"생활":791,"션이":221," 분열":80,"생화":64,"따온 ":72," 부착":61,"선포":63,"소위":58,"단은 ":440,"소와":122,"트라 ":199,"속인":60,"속이":290,"소자":103,"소장":374,"손으":98,"속작":76,"소재":625,"석하":208,"서해":154,"석학":150,"손이":173,"소유":337," 부천":92," 부처":87,"속으":235,"소의":301,"속은":58,"진화 ":77,"속을":100,"기에는":229,"소이":246,"속의":608,"소인":65," 비디":406,"센터":804,"수도":1289," 블로":143," 블록":76,"술대":62," 분지":73,"술단":60,"수동":96," 블랙":148," 블라":159,"시오 ":93," 브루":131," 부지":65,"단을 ":267,"속에":468,"수들":238,"소에":318,"소아":88,"속씨":93,"수되":71," 붙인":76,"서트":83," 블루":149," 북쪽":939," 브리":239,"성학":57,"성한":344,"성하":1173,"수를":679,"성했":93,"점 ":566,"컫는 ":311,"접 ":423,"술로":114," 비롯":537,"트남의":86,"수리":211,"성향":92," 비례":62,"수립":264,"정 ":3475,"수많":217,"수면":90,"성화":282,"정·":70,"세한":64," 부터":293,"수목":78,"제 ":8681,"수라":68," 빌딩":89,"송에":109,"저 ":691,"선하":86,"적 ":6488,"손자":185,"디스플":113,"속적":207,"선형":177,"센트":222,"적·":123,"화민국":208,"설하":120,"설한":95,"세트":80,"전 ":5853,"대부터":165,"수론":65,"수록":388,"수로":616,"절 ":333,"수렴":66,"송이":144,"송의":131,"송을":189,"설화":59,"세포":573,"선후":58,"쉽게":176,"형식의":79," 분파":90,"형식으":115," 비밀":142,"시에 ":1035,"다이 ":78,"스과":112,"져 ":1995," 분포":280," 빠르":144," 빠른":99,"수비":112," 부품":80,"술부":294,"숭배":68," 부하":57,"형식이":60,"젠 ":160,"젤 ":96," 부통":85,"디스크":171,"술문":89,"수반":73,"수법":94,"스웨덴":355,"단위 ":102,"식에 ":147,"스가":801," 본질":83,"다음 ":231,"의 ":113266,"기업의":151," 불렸":246,"기업이":229,"속도":891,"선생":91," 법학":135," 불러":104,"서서":57,"선사":107," 복지":133," 불렀":138,"르이며":70,"사카":280,"세부":108,"기업인":182,"석사":85,"행하고":204,"생존":118,"서사":106,"응 ":113," 번호":380,"소니":139,"소닉":71,"소는":346,"성분":130,"읍 ":503,"성북":87,"사추":98,"성부":135,"다의 ":251,"생자":65,"음 ":1500," 별칭":84," 베트":372," 보좌":58,"생이":317," 본적":119," 보존":342," 보조":161,"생의":222,"생을":123,"행하기":192," 복제":75,"사촌":66,"등장한":143,"생으":111,"등장하":542,"치아 ":63," 본인":73,"설비":81," 보전":117,"을 ":57193," 보장":178," 복잡":211,"사천":61,"사찰":89,"화방송":96," 복음":136," 보이":420," 보인":139,"소년":531," 보잉":63,"소녀":133,"상징":246," 보유":223," 벡터":143,"은 ":53620,"생에":69," 복원":82,"소나":91,"서비":984,"상주":112," 베타":95,"서브":58,"리사무":72,"성문":74,"인 ":17705,"서양":389,"성시":131,"이 ":37893,"성수":74,"성술":118,"센서":66,"생체":62,"익 ":246," 북미":97,"송된":69,"송되":126,"세상":147,"세서":262,"산타":97,"성서":193,"사토":62,"호에 ":574,"선스":81,"성사":84,"성산":69,"선시":239,"사태":109," 부문":169,"서스":92," 불리":901,"서식":307," 불린":584," 부모":106,"행하는":526,"기업에":73,"사키":131,"르웨이":214,"서술":88,"사쿠":75,"소들":74,"소드":129,"소득":173," 분리":348,"선수":1423," 부르":974," 부른":608,"상청":115,"소되":63,"속되":249,"속된":176," 분류":697,"설정":185,"섬유":95,"사회":2727," 부상":120," 보통":720,"선종":75,"설적":60,"선조":162," 부산":765,"살해":175,"투자 ":68,"자·":93,"세아":63,"잔 ":168,"상품":332," 북서":591," 부설":61," 본토":83,"섬이":172," 분산":111," 부서":58,"성원":193,"상표":111,"산화":189,"성운":59,"섬의":133,"섬으":166,"생태":212,"성우":110,"세에":183,"사후":160,"섬을":86,"성요":67,"잘 ":553,"소멸":82,"서적":136,"성애":87,"사항":240,"선인":123,"사했":72,"선이":566,"사하":732,"사학":226,"선을":465,"섬에":271,"선은":242,"선의":737,"사할":112,"사한":280,"서장":59,"선으":205,"상트":78,"선전":130,"사형":99,"쇼군":122,"선정":259,"설이":415," 병합":69,"성어":114,"설을":222,"작 ":890,"산한":104,"산학":93,"산하":736,"설의":132,"성에":448,"자 ":9649,"설은":95,"솔로":157," 변형":122,"소를":405,"임 ":1301,"서울":3628,"입 ":284,"선왕":86,"서원":70,"설에":180,"도가 ":497,"서인":123,"석의":89,"서이":286,"석을":172,"소말":61,"석이":169," 변호":184,"서유":74," 변화":441,"잉 ":170," 변환":220,"서의":944,"석으":73,"소리":483,"석유":108,"서열":68,"소로":258,"석에":88,"세스":264,"서예":61,"출하였":98,"선양":152,"소련":350,"출하여":68," 불법":159," 부분":688,"일 ":19527,"상태":852,"인·":87," 북부":662,"서에":300,"기에서":318,"선언":288," 보컬":132,"서와":99,"선에":397," 변하":73," 복합":146,"술교":71,"송법":108,"수기":70," 보한":520,"션에":87,"서초":359," 비공":72," 비교":314," 보험":236,"선총":96," 보호":689,"등장인":96,"소비":693,"세조":81,"수교":103,"후기의":231,"리와 ":419,"수권":213,"세종":317,"성지":76,"성질":285,"성직":128,"술관":133,"술과":123,"장 ":5509,"세이":380,"세의":524,"서쪽":1399,"세자":103,"세인":151,"성종":71," 보편":88,"상호":734,"샌프":83,"상화":104,"상황":295,"술개":70,"재 ":2451,"성주":100,"상회":64,"술가":133,"세와":166,"캐롤라":68,"소방":114,"성으":264,"성은":337," 부속":114,"성을":1294," 분석":366,"성의":584,"술회관":61,"사히":61,"성인":258,"성이":936,"성자":131,"세운":225,"세우":158,"세워":323,"성장":335,"속버":59,"세웠":108,"선진":160,"상한":79,"상학":60,"상하":394,"대부분":788,"상해":61,"기여를":92,"수가":629,"소보":57,"상했":97,"성전":187,"성적":290,"석기":155,"기여하":360,"상류":71,"상륙":81,"새롭":78,"스에서":445," 미합":61,"서기":467,"새로":765,"기여함":193," 미하":64,"기여할":296,"산문":69,"산물":335,"호와 ":151," 시 ":1062,"성가":64,"사바":60,"선교":176,"설계":483,"사물":97,"사무":2780,"울 ":554,"설과":91,"선구":92," 배치":124,"성경":276,"성계":81,"웃 ":62,"성격":206,"성공":519,"시안 ":86,"성과":536,"웅 ":112," 본래":266,"사본":71,"세가":270,"사보":77,"시아 ":1643,"사법":297,"움 ":309," 신 ":151," 바티":91,"섬과":108," 번역":439,"세계":3906,"산부":140,"워 ":326," 벌어":349," 발트":81," 베스":190,"성구":134,"성군":196,"사부":61,"세균":108,"월 ":22349," 발표":766," 번의":314,"달에 ":101,"상법":81,"세기":1777,"서남":114,"성기":125,"센고":142," 보르":102,"카메라":190,"원 ":4524," 복리":66,"현청 ":126,"서는":3206," 법원":151," 보물":126,"상북":422,"상부":76," 본명":394,"근처에":117," 벌이":59," 벌인":98,"생리":85," 볼리":57,"진흥 ":62," 버전":294," 보면":65," 벗어":103," 번이":131,"선대":74,"생물":828,"산사":62,"사선":118,"사서":100," 버지":75," 배포":140," 법인":125," 밝혀":97," 발현":62,"사사":122," 법의":69," 법이":73,"사상":1612," 번주":318,"성남":125,"서대":130," 변수":131,"생명":423," 베어":58," 발행":329," 범위":193,"샤를":135,"산소":74," 범죄":367,"선되":118," 베이":535,"세네":84," 법조":68," 번째":1969," 방해":63,"산성":191," 방향":321,"스앤젤":97,"선도":157," 번지":619," 법정":244," 보병":96,"사소":200," 병사":60,"다운 ":138,"사성":112," 법적":136," 발효":85,"서도":675,"성단":63,"성당":248,"성대":78,"삼성":344,"산스":90,"사슬":60," 부과":61," 불가":312,"성능":133," 본부":184,"사실":538,"사시":168,"설되":275,"설된":124,"사스":150," 범주":66," 밝히":70," 북구":110,"산식":630,"산시":419,"리적 ":251,"웹 ":348,"세는":97,"성도":116," 북극":76," 불과":64," 부근":222,"상속":91," 불교":744,"성동":166,"세대":442,"섬들":63,"성된":741," 불구":96,"성되":956,"상수":192," 분기":121,"위 ":2320,"성들":103,"상스":90,"윈 ":68,"상승":79,"셔널":254,"상식":83,"상시":144,"상실":57,"린이 ":101," 붕괴":168," 보상":64," 복사":102,"산악":97,"사업":1551,"사에":878,"행한다":126,"통합 ":160,"서로":775,"사연":96," 본사":229,"사였":94,"사와":428,"산업":1568,"살아":160,"선로":99,"통해 ":1561,"집합 ":96,"살았":134,"산에":325," 병역":76," 복소":94," 본선":116,"사용":5124,"생산":1237,"때문이":153," 별자":112,"사우":425,"사운":168,"서류":82,"설로":162,"사원":206,"생생":58,"사위":127," 보수":175,"댄스 ":74,"소가":271,"사유":116,"생성":266," 복수":110,"서를":347,"사자":349,"사장":277,"사인":290,"사이":3510,"립에 ":79," 보스":263,"사일":246,"사의":845,"서만":132," 병원":123,"서리":63,"소개":184,"사정":140,"서명":92,"산자":217," 봉사":58,"산재":60,"소관":1922,"사제":90,"산인":85,"산이":328,"사절":60,"사전":1026,"서면":90,"사적":555,"산의":351,"산으":200," 법칙":215,"스어로":96,"산은":127,"산을":359,"윤 ":93,"카르타":63,"삶의":108,"살인":141,"사조":84,"세라":64,"살이":176,"삶을":67,"상업":234,"상에":642,"상어":65,"설립":4441,"때문에":1177,"육 ":627,"유 ":819,"소금":62,"율 ":154,"세력":252,"설명":378,"소규":61," 부대":178,"생식":87,"생시":83," 부담":83,"속기":527,"산주":225,"상위":159,"삽입":62," 부동":119,"상용":93,"기업청":60," 분당":67,"소기":175,"세로":166,"상원":88,"선민":529,"상이":873,"상인":149,"서버":242,"상자":197,"상임":117,"선발":112,"선박":143," 보안":191,"상은":243,"상으":822,"성리":100,"사진":268," 북동":561,"사지":81,"성립":287,"파가 ":58,"상을":1272,"상의":1384,"세를":145,"세리":64,"송공":59,"상적":276,"산지":293,"상장":64,"비의 ":135,"세르":275,"선보":70,"색이":139,"송국":244,"린의 ":67,"서부":1232,"서북":82," 보여":231,"색을":143,"성모":113,"색은":70," 부등":76,"색으":87,"융 ":140,"색의":117,"손꼽":71,"뿐이":69," 밀양":57,"사고":593," 방사":170,"사관":271,"사과":105,"와 ":15664,"옹 ":166," 바스":71,"사건":1923,"사거":86,"사격":73," 바실":65," 미야":70," 베네":192," 미얀":92,"사가":957,"사각":96,"통치하":66," 미쓰":88," 변경":370,"대법원":73," 발사":235,"출하기":61," 발생":1103,"삼고":63,"산기":92,"기이다":399,"대신 ":324," 방식":744," 밑에":65," 뮌헨":76,"사기":229,"수행한":79,"상가":172,"수행하":444,"산구":164," 방송":1132,"살고":132,"단에 ":234,"산권":82,"산군":133,"삼각":154,"기원전":1034,"산광":498,"완 ":175,"산과":197," 밀집":64,"니즘 ":74," 바위":64,"사냥":61,"사나":120,"상급":60," 반영":94,"상국":58,"출하는":157," 밖에":125," 받았":408," 민중":86," 받아":431," 민주":647,"상공":144,"상관":120,"상과":358,"왕 ":1238," 민족":808,"상경":57,"다와 ":69,"삼국":365," 밀접":73,"통한 ":448,"상계":62," 배열":80," 벨라":91," 발족":205," 보기":59,"사대":81," 별도":115,"생과":60,"사단":1910,"사다":97," 보급":405,"통칭하":65," 발전":1652," 법률":682,"생겨":142,"사는":701,"생겼":60,"현으로":89," 백악":117," 본관":550," 변동":57," 방영":369," 밝은":60," 발음":225," 본격":104," 방어":109," 방언":173,"생각":316," 보관":104," 받을":65," 받은":244," 본거":85," 보고":251," 법령":81," 발원":164," 반응":269," 방안":58," 보건":205," 밖의":74,"단어 ":74,"까지 ":3943," 바이":697,"산동":187," 방정":183,"살던":66," 받지":79," 법무":126,"산된":107,"산되":209," 미카":72," 미치":120," 백인":62,"사들":245," 백작":125,"기초 ":68,"상남":484," 방위":104,"행하였":97,"행하여":85,"산당":204,"산대":62,"사도":176," 배우":373,"산더":62,"외 ":526,"사동":76,"사되":110," 베르":258,"생긴":160,"사된":69,"생기":186," 베를":141,"상동":61,"상도":117,"등으로":538,"비전 ":429,"산드":170," 백제":157," 보내":142," 봉기":67,"상당":532,"상대":588,"상담":89,"니스트":163,"삼동":102,"는지를":90," 방지":187,"살라":75," 보도":103,"사례":68,"사령":195,"사로":662,"생대":183,"살렘":109,"사료":78," 보는":142,"사라":234," 미터":113,"사랑":297,"사람":2438,"술하는":60,"요 ":955,"욕 ":325," 미토":58,"리의 ":865," 보다":233,"니스탄":150," 승 ":122,"우 ":2451,"살리":87,"석과":66,"사모":61," 바탕":449,"서관":272,"님의 ":89,"선거":1124,"설가":221,"산맥":321,"산림":320,"운 ":2130,"선과":230,"서구":357,"선고":72,"산면":109,"상록":72,"생들":178," 배출":120,"욱 ":152," 별명":121,"서가":119,"사르":183,"사를":1012,"산리":59," 버스":279,"생되":69,"생된":72,"사망":432," 방출":92," 보드":68,"사리":79,"사마":121,"사막":121,"용 ":1999,"메달 ":69,"사립":113,"혹은 ":1399,"당은 ":139,"실베이":80,"호의 ":145," 온 ":216,"수학자":299,"수학의":99,"집트 ":224,"수학적":106,"째 ":1900,"니이다":60," 옛 ":292,"카를로":81,"당을 ":126," 영 ":87,"마에 ":93,"림을 ":114,"당의 ":340,"기원후":57,"집 ":514," 연 ":60,"짐 ":75,"트를 ":420,"당이 ":130,"림의 ":63,"징 ":234," 열 ":74,"수행을":57,"신흥":75,"립을 ":177,"확보하":72,"짜 ":61," 생각":309,"단순히":106," 생겼":60," 생겨":141," 사는":188,"현재는":456," 사단":1779," 왕 ":308,"출판사":141," 상관":89," 삼국":254," 살고":132,"당사자":199," 삼각":141,"릴적 ":113,"동가 ":129," 와 ":1259," 삼고":59,"현재까":179,"대와 ":262," 사기":64," 사가":107,"리스에":76,"리스어":391,"대왕 ":100,"수학에":150," 사고":438,"리스의":233," 사건":1669,"스하":127,"시칠":59,"시카":195,"스피":342,"스핀":66,"승팀":125,"즉 ":662,"즈 ":1704,"시코":429,"시켜":325,"시켰":170,"실천":166,"길이는":187,"스플":201,"스프":195,"시청":223,"스퍼":73,"스펙":70,"스페":888,"시초":70,"스포":707,"신청":95,"스폰":57,"신체":167,"스투":75,"심지":489,"스튜":256,"스트":3813,"스틴":60,"스틱":113,"스티":592," 양 ":88,"스파":404,"실질":136,"스톡":64,"스토":637,"스테":623,"스템":1334,"스텔":113,"스터":863,"스턴":325,"스톤":109,"시지":134," 약 ":1207,"스크":1207,"현재에":63,"십자":249,"심장":74,"시즘":60,"시즌":581,"시즈":65,"신주":76,"심이":158,"싸움":90,"스탠":109,"스탄":838,"스탈":89,"심적":69,"층의 ":88,"스타":1367,"스키":554,"슈티":64,"슈팅":76,"카리브":78,"시조":180,"실이":117,"신전":61,"신적":108,"신정":80,"스코":803,"슈트":99,"스쿨":82,"심으":693,"심을":206,"심의":204,"슈퍼":245,"싸여":64,"신조":82,"실적":80,"스쿠":71,"실제":435,"스칼":83,"신으":438,"스카":534,"스칸":67,"시장":721,"실용":73,"신의":975,"당선되":96,"식재":59,"스캐":63,"신은":100,"단순한":93,"심에":93,"신을":369,"시인":445,"시이":748,"식의":488,"식을":715,"식은":204,"식인":80,"식이":641,"시작":1913,"시자":111,"현재의":485,"스케":361,"실은":1894,"신장":127,"식적":310,"실의":105,"싱어":70,"실을":195,"신이":763,"신인":167,"시점":75,"신자":135,"시정":103,"시적":140,"시절":216,"름으로":597,"실현":165," 역 ":190," 여 ":231,"실행":302,"신화":440,"실험":314,"신호":329,"질 ":802,"식회":208,"신해":58,"실하":58,"시호":371,"진 ":4958,"시했":60,"시행":387,"등지에":113,"시한":333,"식하":203,"식한":134,"마쓰 ":58,"지 ":12819,"직 ":904,"신한":74,"시험":488,"신학":397,"신하":183,"심판":171,"달성하":68,"시하":616,"시픽":100,"식품":996,"실패":146,"다중 ":70,"름이다":364," 뿐만":102,"싱턴":122," 에 ":3968,"층을 ":58,"시판":68,"시티":207," 뿌리":139,"시트":81,"기장에":74,"치시 ":58,"리스도":198,"증 ":222,"승한":65,"기장을":58,"신탁":73,"슷한":239,"슷하":194,"즘 ":268,"승하":152,"시킬":102,"시키":987,"시킨":292,"시타":80,"담은 ":79," 어 ":61,"기장이":86," 억 ":226,"전》":368,"대에 ":921,"호선의":73,"즌 ":240,"시뮬":120,"신문":591,"심리":312," 빅토":126,"식민":428,"말에 ":88,"시바":74,"시민":455,"시미":57,"스스":259," 비판":173,"시베":62," 비트":267,"식별":124,"수함":92,"수한":297,"수학":984,"수하":240,"수행":909,"실베":102," 비평":80,"시부":72,"수필":57,"순한":104,"수형":93,"신부":105,"신분":132,"주 ":6421,"스앤":101,"신비":78,"머니이":60,"이》":70,"수호":86,"준 ":2588,"술하":154,"술한":115,"수화":58," 비해":209," 비행":271,"승을 ":297,"줄 ":149,"스어":694,"스에":917,"순화":57,"순환":168,"기존의":250,"시라":107,"신라":377,"식량":124,"시로":1329,"승부":68,"실록":97,"실로":87," 쓴 ":317,"신뢰":98,"시를":363,"시리":1561,"시마":348,"시립":76,"술탄":80,"쇼핑":78,"림수산":539,"신망":70,"시모":119,"실리":112,"스속":105,"층에 ":431,"식물":650,"식문":64,"독교 ":326,"승전":168," 알 ":152,"실시":535,"시아":3207,"시안":117,"다수의":139,"트로 ":289,"닿아 ":81,"시온":61,"시오":180,"썼다":75,"시와":405,"신에":201,"신약":75,"식에":220,"비아 ":592,"시어":65,"기적인":70,"시에":1534,"신앙":167,"기적으":76,"신용":161,"식으":607,"시의":1064,"시위":145,"시우":69," 앤 ":149,"실업":129,"실에":130,"시외":223,"슈타":211,"스위":294,"순히":106,"스웨":430,"스오":59,"스와":739,"심부":90,"술회":66,"슨의":72,"직한 ":59," 뻗어":76,"시설":711,"슨이":67,"신사":180,"스의":2139,"중 ":3559,"도권 ":73,"식사":62,"시상":135,"스이":308,"시사":106,"스인":78," 빌헬":87,"신속":78,"지할 ":97,"스주":85,"승에":60,"지한 ":61,"신설":186,"신선":60,"실상":172,"신성":225,"시시":71,"실수":92,"승을":297,"승인":162,"승자":99,"신시":65," 안 ":111,"승용":69,"습을":167,"습이":87,"시스":1777,"심사":156,"丙 ":228,"소하":122,"소한":93,"속하":1183,"시계":147,"丘 ":1912,"속한":740,"소행":127," 비스":147," 비슷":450,"시게":81,"소피":62,"지하 ":71,"족 ":952,"신경":249,"손해":112,"니아와":58,"송파":188,"만에 ":232,"속해":225,"丟 ":282,"식경":89,"시공":102,"丞 ":58,"튜디오":194,"스도":241,"식과":187,"식공":81,"조 ":2368,"丑 ":151,"스는":657,"달의 ":59,"지칭한":98,"지칭하":168,"호주 ":71,"송통":78,"형이다":110,"丕 ":102,"소프":1375,"且 ":206,"니아의":174,"습을 ":166,"시간":1006,"시각":172,"시가":359,"스니":152,"수요":138,"심리학":178,"신기":142,"수와":199,"싱가":102,"丫 ":62,"르크 ":449,"마와 ":59,"송하":166,"술연":115,"좀 ":61,"수원":294,"술에":154,"형으로":179,"수용":253,"신교":225,"両 ":166,"소화":114,"시권":58,"수아":82,"존 ":728,"시국":65,"니아에":65,"신과":128,"신고":75,"소형":129,"수영":176,"수였":72,"並 ":3956,"시기":468,"수여":200,"수엘":64,"수에":273,"수업":92,"리즘 ":90,"심각":57,"달을 ":122,"승격":131," 분화":88,"수사":246,"수산":1050,"수상":476,"소통":90,"트럴 ":117," 북한":208,"스기":80," 빌보":65," 분할":95," 분해":71,"승객":82," 부호":199," 부활":95,"수술":79,"수수":82," 비상":102,"丈 ":353,"순수":115,"스노":76,"三 ":5345,"출판되":65,"시스 ":159,"리지 ":202,"소포":62,"수시":75,"수신":110,"수성":148," 부흥":64,"수소":134,"스나":102,"丁 ":3345,"식민지":360,"万 ":91,"순서":137,"수송":152,"술사":85,"술서":149,"당에 ":75,"리스트":199,"스미":145,"스바":64,"스박":60,"리스티":104,"시드":120,"시된":222,"식되":65,"신도":198,"스몰":61,"승려":122,"乙 ":1163,"슬링":138,"슬림":73,"乘 ":269,"시되":344,"리스토":113,"시도":203," 빛을":61," 빛의":72,"식문화":60,"죄 ":281,"단이 ":202,"비에 ":63,"스부":93,"수치":89,"단일 ":104,"스볼":110,"乩 ":76,"수출":221,"스베":93," 빼앗":59,"진출하":105,"순천":97,"신들":162,"승리":273," 비율":114,"숙종":94,"스럽":73,"스러":103," 비잔":182,"술적":188,"스레":59,"수주":83,"수준":267,"좌 ":100," 비용":109,"시나":175,"술의":455,"싱글":400,"술을":417,"술은":76,"술인":130,"시내":295,"스라":342,"술이":263,"술자":98,"丹 ":433,"수장":102,"술원":71,"리즈 ":556,"수적":127,"싸고":92,"수정":259,"맥스 ":80,"종 ":2005,"수의":777," 비영":167,"수익":107,"수이":764,"순위":140,"수입":226,"수인":135,"수자":76,"스마":263,"시대":2951,"스만":162,"머니는":107,"스리":201,"시다":76," 비즈":134,"시는":274,"슬로":221,"때부터":94,"스를":979," 비주":67,"之 ":4501,"수직":77,"수지":162,"수집":212,"숭이":78,"숫자":148,"슬러":133,"파구 ":139,"슬레":59,"스로":529,"시노":86," 비전":65,"슬람":295," 비정":120,"슬란":124,"슬라":250,"실내":104,"빌보드":64,"그의 ":1128,"즘의 ":66,"수인 ":81,"마크 ":189,"극을 ":92,"는다 ":996,"기사 ":106,"수상하":96,"수상했":86,"술서기":141,"지방에":438,"교향악":94,"지방을":71,"지방으":60,"특수 ":78,"지방자":116,"지방이":59,"지방의":262,"국토해":108,"니고 ":121,"카미 ":64,"힌두교":117,"증을 ":98,"노쿠니":65,"만큼 ":89,"수적 ":58,"싸고 ":90,"파로 ":96,"지식 ":88,"는데 ":1814,"주하고":96,"술은 ":76,"분포하":147,"술을 ":417,"술의 ":445,"지배하":161,"싱글 ":166,"지방행":148,"지방해":72,"메리카":560,"메리칸":121,"근에 ":191,"리튼 ":69,"칠리아":60,"리트 ":176,"특별시":2267,"그와 ":129,"념하기":58,"술이 ":63,"모두 ":601,"특별법":73,"국토관":71,"지방과":88,"지방검":64,"숙종 ":62,"리티 ":77,"특별지":138,"주파수":89,"마지막":447,"특별자":254,"떠한 ":154,"술적 ":124,"파를 ":146,"누어 ":109,"모든 ":1110,"빠르게":93,"圓 ":266,"그에 ":214,"지방국":73,"國 ":227,"지방법":71,"기록하":192,"기록한":116,"파리 ":176,"비스 ":391,"특별히":77,"머스 ":117,"질서 ":65,"츠의 ":100,"특별한":118,"스로 ":388,"지막으":64,"중해 ":78,"르헨티":187,"신교 ":109,"급이 ":64,"림축산":107,"급을 ":162,"기반의":108,"기반을":124,"기반으":258,"급은 ":65,"금이 ":60,"급의 ":111,"기법이":65,"지리학":71,"즈의 ":361,"지사 ":62,"지면서":85,"리키는":517,"기술 ":470,"충청남":311,"리킨다":654,"지상 ":78,"판매 ":90,"수영 ":75,"트비아":70,"수에 ":166,"시기 ":87,"금은 ":161,"수와 ":188,"리키며":63,"금을 ":242,"주특별":162,"다가 ":862,"티브 ":148,"금의 ":358,"중화 ":71,"충청북":246,"금융 ":121,"國之":115,"國亞":57,"리카의":183,"國丁":85,"國三":298,"國並":202,"구팀이":62,"圓三":73,"리카에":152,"트비히":100,"립트 ":57,"명되었":154,"술에 ":87,"수산부":104,"수원 ":77,"수산물":73,"즈와 ":65,"마찬가":135,"교회의":291,"리프 ":97,"교회와":67,"교회에":135,"몇몇 ":106,"메모리":266,"리케인":119,"리케이":107,"지류인":60,"급에 ":117,"기서 ":119,"리한 ":169,"수산식":513,"리학 ":218,"치러진":143,"근의 ":141,"금에 ":58,"트어 ":82,"리핀 ":247,"극장 ":74,"수의 ":736,"글을 ":102,"트에 ":193,"최후의":62,"출할 ":58,"지리적":89,"패로 ":61,"다고 ":1194,"출한 ":110," 피부":85,"스는 ":657,"부터의":66," 행동":333," 허가":248," 하류":58," 했던":64," 하루":107," 했다":544,"리즈에":127," 표현":714," 필립":80," 필리":448," 필름":96,"부통령":87,"단과 ":106,"지로서":70," 해당":773," 한때":92," 합동":61,"리즈의":173,"리즈이":119," 하드":309,"르크스":130,"冲之":64," 함대":59,"질랜드":239," 필라":63," 핀란":212," 할당":112,"시가 ":252," 한다":3550," 하다":597,"트로닉":61," 하늘":148," 하는":2411," 하느":107," 丹並":115," 丹丁":139," 한성":74," 丹三":149," 丹丘":70," 丹之":113," 현과":87," 피아":207,"르키나":72," 학생":355," 학살":107," 학사":67,"트라이":124," 並倉":88," 並之":464," 並乙":106," 필수":58," 丘倉":66," 항복":59," 해발":149," 해방":139," 並亂":164," 並亞":126," 並丁":313," 並丘":167," 합병":171," 並三":570," 並並":376,"단계 ":74," 丘乙":71," 三倉":199," 丘之":178," 丘並":131," 하부":75," 丘丘":138," 丘丁":182," 丘三":312," 행렬":75," 항만":73," 丁倉":83," 한반":214," 하버":79," 한민":80," 해리":88," 한번":60," 항목":84," 三丘":352," 합류":148," 三三":1459," 三並":676," 학문":432,"매주 ":79,"규정하":103," 丈三":77," 三丁":609," 三亞":219," 합리":91," 三之":750," 헝가":248," 三乙":140,"트랜스":130," 三亂":164," 하며":678," 하면":179," 丁丘":176," 丁三":472," 丁丁":355," 丁並":314," 학명":174," 할리":61," 丁亞":83," 丁亂":112," 丁乙":148," 丁之":391," 해에":93," 함으":81," 해양":438," 해안":258," 한정":80,"비롯한":246,"비롯하":108,"화하여":111,"비롯해":85," 해운":73," 향상":440," 해외":278," 하지":445," 합작":67," 해와":61," 합의":125," 하위":142," 학위":90," 행성":260," 하원":92,"화학자":72," 행사":339," 하우":120," 하와":84," 피지":78," 핵심":157,"트로이":97," 한자":374," 한일":97,"화학적":86," 현대":825," 프톨":67," 하인":90," 함양":74," 학자":250,"째로 ":479,"리크 ":66," 허리":151," 하이":338,"환하는":65," 해서":99," 해석":322," 하여":729," 하에":107," 하였":775," 하얀":72,"립적인":63," 학습":168," 행복":66," 학술":377," 피에":140,"즈에 ":111," 항성":196," 함수":391," 해산":87," 필요":634," 해상":198," 항상":88," 합성":230,"르크의":62,"시간 ":432,"중추원":62,"화합물":130," 확대":221," 피해":312," 회계":74,"트레이":130,"트레일":500," 협력":288," 황금":95," 혁명":479," 합쳐":178," 헤비":59," 혼동":64," 해체":141," 해주":60,"늘날에":73," 하천":129,"기부터":151," 행위":568,"부터는":174," 했으":125," 호는":364," 피터":73," 행정":2058," 협동":102," 헤르":204," 화가":164," 홈구":160,"노폴리":62," 헌법":409,"규정에":101,"늘날의":100," 헨리":126,"틀랜드":245," 倉 ":57," 해전":102," 허브":61," 헬리":60," 환경":782," 호남":99,"僅丁":77," 현실":117,"僅三":105,"캐나다":542," 형성":527," 확률":198," 항해":59,"속해 ":143," 혁신":98," 형상":83," 형사":105," 협상":60," 학회":76," 형식":446," 화물":115," 해협":157," 후계":64," 화면":108,"속한 ":330,"지부 ":95," 확립":183," 헤이":198," 한편":88,"구하여":62," 호로":200," 형법":118," 활동":1538," 학파":104," 한해":58," 현상":583,"화하는":131," 효과":357," 하프":69,"티노폴":57,"티누스":77," 황도":62,"傭三":85," 호르":78," 허용":108," 홀로":66," 확산":127," 화석":129," 화성":179,"림청 ":130,"확하게":91,"카를 ":215," 홍수":68,"카데미":148," 형이":88," 향하":60," 현지":86," 협정":151,"립운동":226," 화산":224," 형제":214," 현청":128," 확실":69,"화하기":61," 활성":221," 효력":75," 호에":514," 활발":97," 확보":146," 행해":125,"화하고":69," 행하":123," 현의":154," 협약":108," 혈액":72," 현에":71," 홍보":159," 획득":133," 후기":424," 혐의":64," 회로":165," 호수":187," 현존":112," 협의":101," 호스":85," 현재":2800," 현장":98," 호선":451," 호세":57," 확정":107,"최하는":107," 확장":327," 환자":90," 홈즈":59," 형태":1027," 후반":207,"구하는":390,"소형 ":88," 휘는":138," 황제":690," 후보":221,"리즈는":127,"는다는":74,"리코 ":60," 호칭":116," 혼인":73," 혹은":1388,"부호 ":101," 회복":73,"리즈로":71," 호주":106," 호조":68,"倉倉":133,"수아 ":63," 활약":340," 훈련":135," 화재":138," 확인":346," 활용":295,"신과 ":111," 회사":809," 화이":94,"기본적":189,"마에서":71,"리지널":66,"식과 ":176,"분할 ":73," 효율":259," 홈페":62," 혼합":144,"丘驿":62," 호환":88," 후에":392,"출판 ":83," 효소":84," 회원":584," 홋카":126," 회의":273," 휴대":208," 호텔":130,"주한 ":63,"담고 ":141," 홍콩":226," 회장":211," 협회":248," 후속":211," 후손":130,"구하고":183," 회전":155," 희곡":57," 후지":163," 흘러":172,"수소 ":62,"스나 ":83,"모델 ":116," 화합":132," 화학":486," 화폐":85," 후원":123," 倉丁":148,"주최하":113," 倉並":114," 倉三":242," 倉丘":63," 倉亂":57," 倉之":119," 힌두":143,"니다 ":190,"대개 ":139," 히데":85,"즈베키":65," 황후":99," 흐르":180," 황해":115," 흐름":133,"당과 ":104,"마치 ":141,"기원 ":60,"북한 ":74," 후쿠":159,"트리스":63,"지배 ":66," 히로":126," 倉倉":67," 회화":73,"지방 ":781,"대가 ":240," 희망":65," 히브":111,"트리아":442," 흰색":64," 희생":96,"니는 ":214," 후한":109," 흡수":98,"부한 ":73," 흑인":105,"명령 ":61,"흐르는":105,"그이다":93,"리처드":110,"당구 ":75,"치를 ":548,"·연구":60," 히스":59,"치단체":145,"극작가":87," 힘을":80,"기와 ":326,"망원경":111,"트리트":107," 휘하":73,"맡았으":76,"집단이":82,"흘러드":76,"만으로":117," 흑해":77,"대교 ":83,"빠른 ":100," 흔히":425,"류하는":80,"류하다":77,"르투갈":235,"능력 ":85," 히트":60," 히틀":63,"기여 ":85,"명나라":109,"기에 ":1427," 힙합":219,"근에서":110,"류하고":65,"기업 ":244,"막으로":89,"대고 ":174,"기억 ":70,"마이다":107,"맡았다":163," 之三":810,"말이다":630," 之丁":474," 之丹":65," 之並":680," 之丘":236,"마이클":102," 之亂":157,"마이크":612," 之之":450," 之乙":108," 之亞":129,"술문화":87," 三國":102," 乙丁":159," 乙三":188," 乙丘":109," 乙並":99," 之倉":147," 乙之":125," 乙乙":65,"를테면":61," 乙倉":62," 並國":241,"치되어":106,"치되었":68," 亂丁":147," 亂丘":69," 亂三":239,"국회의":347,"수법인":62," 亂之":174," 亂並":156," 亂倉":78,"그에서":63,"구협회":61,"근에는":98,"마이오":85," 亞之":103," 亞亂":72," 亞三":197," 亞丁":62," 亞並":142,"대구 ":108,"구현하":65,"모는 ":61,"학자":2335,"한의":189,"현대":875,"함에":145,"한을":120,"학의":956,"하이":710,"학을":385,"학으":130,"하의":429,"학은":215,"하자":244,"학이":346,"함양":88,"하임":58,"하인":110,"하일":70,"프톨":69," 통상":134,"학적":904,"기념일":61,"할을":489," 터키":401,"한이":100,"합에":109,"한자":411,"한일":104,"행사":447,"하우":219,"하원":98,"피지":85,"핵심":159,"호간":219,"호가":153,"행성":432,"학위":158,"허리":158,"학원":440,"하위":156,"항을":212,"하지":1949,"항으":97,"해왔":62,"혔다":58,"합작":74,"해와":166,"그래픽":309,"합이":240,"합의":328,"함이":112,"한지":68,"협동":167," 통신":479,"해운":88,"그레이":201,"그래프":117,"무관 ":85,"향상":599,"합적":124,"항이":169,"헬레":69,"해외":283,"항의":92,"한제":218,"해안":395,"현동":109,"한정":88,"프트":1666,"호국":61,"항에":121,"합으":111,"합은":87,"합을":202,"함으":765,"함은":90,"함을":479,"해에":225,"해야":257,"해양":758,"현된":68," 태화":59,"퓨터":1617,"부천시":57,"할시":83,"항성":207,"피의":87,"해산":95,"함수":560,"필요":647,"해상":245,"해살":124,"피에":185,"행법":63,"픽에":161,"피오":64,"학습":221,"행복":77,"하시":85,"슬로바":89,"합성":289,"항상":88,"해수":92,"그려져":89,"하얀":74,"퓨팅":102,"항시":79,"하에":362,"헤드":71,"학연":123,"하였":7094,"학에":1132,"하여":10590,"한에":57,"하와":112,"해시":144,"할아":61,"해석":435,"해서":1485,"핀의":74,"해병":58,"그러한":104," 털이":65,"필수":60,"픽스":83,"항복":61,"해발":152,"해방":192,"피스":241,"합병":195," 토머":69,"합법":65," 토마":98,"확히 ":61,"지역과":116,"학술":418,"피어":124,"피언":426,"하수":77," 테이":155,"피아":520,"현과":109," 태풍":365,"한성":103," 탐험":69,"향력":154,"호하기":67,"한사":58,"한산":83,"학생":582,"해부":71," 태평":280,"학상":204,"학살":146," 테오":77,"학사":169,"프와":64,"헝가":249,"항만":156,"합류":148," 텍사":129,"문과 ":115,"프에":98,"한문":65,"함마":70,"합리":119,"해로":105,"하므":81,"학문":497,"하며":3518,"하면":1454," 타타":70,"호하고":60,"마포구":144,"할린":58,"하모":62,"학명":176,"할리":69,"권에서":136,"한불":58,"행렬":102,"피소":115,"하부":85," 텍스":81,"구지방":63,"학부":176,"스리랑":67,"해리":93,"한번":67,"해를":394," 테스":96,"합물":165," 토론":158,"항목":94,"프의":110,"한반":216,"한민":7437,"하버":84,"표하":378,"해당":812,"필리":478,"필립":81,"필름":113,"해도":129,"표했":61,"표한":304,"파르트":58,"신라 ":149,"표현":736,"하라":255,"해되":60,"하려":361," 토대":84,"했다":3819,"했는":102,"하로":70,"프스":170,"했던":889,"비디오":466,"하루":140,"하리":63,"판매되":66,"히는 ":130,"행동":388,"하마":145,"하르":159,"하류":64,"허가":742,"하를":74,"문가 ":75,"피부":86,"기념하":175,"행된":216,"행되":505,"하느":121,"하는":18789,"필드":112,"효율적":195," 태어":821," 테러":91,"하늘":174," 태양":417,"했고":365,"하다":2005,"행과":61," 터미":91,"학대":110," 타지":75," 탑재":107,"하던":522,"한다":14560,"하도":295," 텔레":470,"매한 ":208,"해남":60,"했기":61,"할당":116,"한데":57," 통계":268," 테르":57,"행기":130," 통과":189," 테마":80,"표팀":149,"합뉴":77,"기록 ":133,"핀란":235,"하드":336,"호하는":60,"함대":93,"피로":70,"필라":72,"기로 ":619," 태조":124,"파리에":66," 태종":83,"한때":92,"합동":105," 토너":70,"티베트":129,"함된":182,"함되":256,"해는":67,"합된":94,"합되":136,"품종":97,"프를":84,"플로":271,"합과":70,"함과":93,"풍이":93,"플레":847,"플러":120,"합격":100,"함경":91,"풍으":73," 탑승":57,"한글":194,"플랫":190,"플랜":61,"플래":146,"해결":279,"합금":58,"항구":135,"플루":90,"항공":848,"프리":1512,"프린":151,"합군":122,"대기 ":87,"해가":156," 타이":816," 타인":112," 타자":72," 타임":92,"한나":105,"하나":4082,"품질":176,"해군":428,"함께":1510,"근로자":82," 타원":89,"플리":188," 탄자":80,"학년":63,"그리고":1096,"하노":64,"피드":122," 탄생":197,"표지":57,"표준":828,"푸에":75," 탐사":100,"품안":66," 탄소":90,"시로 ":1233,"하고":10067,"학계":119,"그룹의":105,"학과":608,"학관":65,"프라":535,"프란":258,"풀이":93,"한계":93,"글로벌":433,"하거":696,"하게":2062,"그룹이":170,"한강":205,"품에":167,"그루지":65,"하계":214,"프레":585,"한국":5662," 태생":107,"품을":440,"품은":147,"품으":223,"하기":4401,"프로":4269,"품의":327,"품이":502,"플라":427,"학기":729,"프랑":2551,"학교":2885,"하구":63," 테니":98,"프랜":72,"프랭":62,"후부":73,"호칭":116,"그랜드":67," 팔라":87," 팔레":125,"군인으":72,"효소":123," 티베":152," 투표":249,"현하":338,"현한":123,"군인이":191,"황이":118,"황의":113," 파란":59," 파라":163,"시대의":878,"휘는":146,"후보":250," 특수":377,"황제":796,"구조를":175,"형태":1105," 특성":245,"후반":218,"황을":121,"환의":69,"환이":100,"화적":211,"환자":123,"화점":66,"화제":218,"화정":132,"홈즈":59,"시를 ":363,"활을":172,"확정":119,"활의":75,"황에":133,"구조물":73,"무가 ":97,"화유":179,"확장":333,"괄하는":86,"환을":105,"환으":121,"화재":932,"화장":67,"활용":342,"확인":373,"화인":552,"회사":1398,"화이":520,"화의":717,"회주의":311,"훈련":219," 파동":83,"화와":331,"그레고":75,"떨어져":174,"화예":218,"그래머":64,"헨티":187,"화연":58,"후로":193,"화원":71,"활에":69,"파소 ":63,"활약":341," 특별":638,"호조":94,"호주":113,"화에":724," 판단":139,"황실":61,"그러나":356,"호작":139,"호의":161,"혹은":1401,"호이":192,"떨어지":62,"떨어진":577,"그래밍":301,"휘관":62,"혼인":75,"회복":162,"확실":95," 파나":61,"현청":128,"규모의":148,"관하여":88,"호와":168,"화시":180,"관하였":59,"호에":620,"회민":65,"국제적":222," 트리":201,"효력":77,"리핀의":59,"형질":59,"활성":267,"화소":62,"스마트":110,"교차로":174,"화석":141,"화성":207,"리학의":82,"홍수":94,"시마 ":242,"형적":101,"형제":253,"화산":351,"리학에":160,"화사":143,"리하여":91," 트로":120,"확산":137,"화상":154,"형인":57," 트랙":87," 트랜":212,"현지":87,"협정":206,"향하":118,"협조":69,"회를":455," 트레":142,"형의":233," 트라":148,"형이":378," 파괴":164,"형은":85,"형을":227," 판결":111,"형으":179,"협의":275,"호스":99," 파견":97,"혐의":73,"회로":482," 통화":141," 투쟁":64," 투자":238,"현종":57," 투입":65,"현존":113,"호수":201,"리학자":290," 통합":613," 통해":1669," 통하":497,"구조에":62,"메인 ":87," 통한":430,"형에":86,"현장":128,"현재":2814,"카드 ":151,"호세":67,"현을":152,"현의":222,"호선":457,"현이":155,"협약":154,"행형":63,"치로 ":163,"현으":89,"활발":97,"호사":248,"행해":164,"행했":102," 투어":114,"확보":154,"티아 ":137,"행할":139,"행한":306,"행하":1296,"트에서":297,"화방":117,"혈액":74,"홍보":199,"티안 ":64,"현에":128,"화민":221,"확립":194,"헤이":247,"합회":170,"해한":72,"해하":221,"후계":66,"판사 ":69,"화면":122,"해협":171,"형식":491,"화물":206,"리하고":119,"현악":203," 통틀":103,"획득":137,"후기":490,"시대를":133,"리하기":81,"험을":187,"학회":466,"험자":75,"험의":59,"화로":327,"험이":169,"함한":517,"함하":555,"혁신":147,"협상":84,"형사":139,"합한":173,"함해":71,"합하":407,"현실":137,"형상":96,"형성":570,"항해":93,"확률":208,"화를":1063,"회는":1632,"항하":173,"판매하":166,"회당":58,"회담":74,"호를":436,"황도":75,"홀로":69,"호르":135,"험에":93,"하프":78,"효과":428,"홀름":57," 통칭":251,"한하":72," 통치":299,"그램이":267,"학하":70,"그램의":101,"하학":186,"현상":661,"그램을":190,"그램으":79,"헌정":58,"해튼":63,"할하":144,"할한":336,"한해":67,"리하는":212,"화되":254,"화된":293,"화동":78,"시대부":79,"활동":1928,"학파":157,"필하":71,"형법":133,"호로":363,"리한다":63,"형벌":57,"허용":114,"한편":89,"기념물":120,"추진하":98,"글라데":64,"화는":234,"회가":354,"향을":646,"다는 ":1779,"향으":228,"향의":75,"하키":105,"향이":127,"피하":88,"피해":356,"회계":133,"형문":163,"화도":69,"회관":224,"화당":76,"확대":271,"관할한":325,"관할하":116,"황금":99,"혁명":621,"행중":61," 통일":365,"합쳐":178,"피트":60,"헤비":60," 투르":130,"화나":80,"향에":72,"협력":477,"합체":119," 토지":194,"향악":104,"해체":142," 통제":86,"했지":130,"혼동":64,"행을":299,"행으":73,"해진":265,"해지":305,"행의":136,"행위":930,"헤미":57,"했을":154,"했으":992,"화기":123,"하천":174,"하철":238,"망한 ":84,"지지 ":191,"해주":158,"호대":71,"행정":2568,"징을 ":98,"호는":1131,"관현악":157,"피터":77,"실로 ":59," 통영":63,"치료 ":66,"행이":179,"행자":83,"시대에":456,"합중":92,"헨리":128," 테크":122,"해자":124,"해있":127,"해의":187,"화강":75,"헌법":468,"홈구":160,"화가":521," 토양":84,"헤르":222,"향신":67,"화권":68," 大丁":58," 大三":77," 大並":205,"화국":2106,"행에":142,"환경":1224,"글랜드":374,"호남":102,"화교":105,"허브":67,"해져":64,"했었":83,"헬리":65,"해졌":152,"해제":83,"화관":60,"해적":58,"해전":114," 토요":69,"헬름":103," 파티":73," 폭력":128," 파트":83,"황후 ":99," 포맷":119,"최초의":614," 포르":340," 패턴":71,"흥에":88," 펜실":91," 폴란":330," 페스":58," 포로":65,"술이다":157,"흑인":107,"질적 ":91," 폭발":156," 표기":452," 페어":66," 편성":112," 폴리":129," 퍼져":67,"틴어 ":259,"흥을":81,"흥원":108,"히스":77,"히어":69," 페이":330," 평생":57," 페리":59,"회화":87," 패의":57,"후쿠":167,"히로":187,"회학":141," 페루":67,"시내버":159,"집을 ":67," 페르":414,"평가 ":122,"휘자":123,"지식을":78," 평등":60," 특허":114,"브리어":86,"흐스":60," 포도":92," 편리":65," 특히":654,"트이다":286,"흰색":64,"니라 ":509," 파키":145," 퍼시":104," 파크":139,"후한":126," 평면":83," 판타":104,"히브":114,"희생":100,"흡수":105," 포드":63,"지스터":88,"후원":128,"호흡":62,"확한":140,"확하":150,"화합":170,"화한":180,"화학":716,"화하":463,"훈장":68,"후인":57,"후이":122," 파스":91,"후의":318," 평가":365,"환하":122,"화협":57,"활하":69,"흘러":172," 파악":100,"확히":75," 평균":159,"북쪽은":67," 패션":82,"북쪽으":560,"후지":177,"활화":61,"히데":106,"힌다":88," 팀이":267," 팀인":83," 팀은":59," 팀을":65,"부터 ":5567,"황해":119,"흐르":181,"흐름":139,"히는":131,"북쪽에":130,"황후":208," 파워":88,"비를 ":208," 파울":70,"브리지":101," 포괄":107,"힌두":145," 폭격":62," 파이":306," 파일":459," 파장":70,"희망":76,"멕시코":351,"면에 ":269," 판정":70," 파르":82," 파리":324,"호쿠":61," 판매":505,"획에":68,"화체":1138,"회에":827,"회와":251,"호크":61,"홋카":126," 패러":89,"티에 ":60,"퍼드 ":93,"회원":649,"호텔":166,"스볼 ":93,"흥과":58,"획을":70,"회의":1793,"휴대":208,"회이":521,"회장":306,"협회":1182,"획이":86,"홍콩":229,"흥군":61,"회전":178,"희곡":60,"회적":302,"후손":130,"후속":211," 특유":59," 특이":78,"회주":311,"수이자":73," 특정":747,"단계에":81,"효율":286," 특징":490,"히고":71,"홈페":65," 패배":83,"호하":246,"호협":62,"혼합":151," 파생":136,"호화":96,"호환":91,"화폐":97,"후에":722,"황태":64,"브리튼":77," 하기":275," 프로":3860,"스러운":81,"지적 ":62," 한국":5417," 프레":355,"지속적":117,"슬란드":102," 학교":399," 프랜":67," 프랑":2466," 프라":205," 프란":161," 한계":75," 하고":784," 하계":203," 하게":69," 한강":168," 하거":107,"부지방":64,"메시지":94,"무기 ":82,"뉴스 ":176," 표준":763," 푸에":67," 학년":60," 함께":1504," 해군":342," 한나":93,"지정 ":159,"출연하":62," 하나":3925," 품질":108," 항구":132,"모로코":75," 해결":238,"직접 ":361,"추정된":67," 품종":76,"추정되":104," 항공":685," 프리":592," 프린":124," 플루":58," 플러":58," 합격":78," 플레":499," 플로":151," 플라":322," 플래":123," 플랫":188," 한글":177," 함경":88,"림픽에":158,"질을 ":426,"슬라브":70," 평화":277,"슬라비":71," 포크":98," 표시":264," 포털":64,"질은 ":90," 포터":82," 풍부":90," 폭탄":71,"홈페이":65,"그리스":1462,"질의 ":262," 풋볼":90,"티의 ":76,"힙합":222," 포항":151,"출입국":71," 포함":1756," 피고":86,"수주의":71,"지식경":85,"블로그":77,"기능이":91,"수준의":104," 포트":118,"립하여":100,"질이 ":162,"립하였":147,"힌다 ":87,"기능을":346,"그림을":66,"흔히":426," 펼친":93,"싱글이":108,"트웨어":808,"기독교":722," 포지":92,"히토":70,"직의 ":93,"지인 ":141,"히코":61," 포유":87," 펼쳐":96,"흑해":78,"립하는":77," 폐지":323,"스라엘":216," 표면":218," 포인":78,"마트폰":75,"비로 ":77,"중화인":472," 평택":82,"립하고":77,"권으로":128," 푸른":60,"히틀":64,"히트":99,"트워크":561,"립했다":63,"티움 ":158," 편이":112," 편의":114," 편입":97,"뉘어 ":79," 평안":87,"힘을":86," 평양":179,"립허가":405,"진은 ":66,"문구 ":138,"물과 ":174,"진을 ":324,"지션은":60,"슬람교":71,"휘하":198,"권익보":58,"물관 ":160,"목록이":78,"후에는":149,"진의 ":108," 편찬":115,"기를 ":1415," 포스":152," 평원":63," 편집":205,"진이 ":64," 철학":533," 처형":61,"키타":74,"직을 ":211," 추락":80,"브라이":58,"브러리":89,"태지":103," 초점":101," 체포":79,"탈출":64," 촉진":190,"타카":106," 취급":129,"흥 ":176,"토대":96," 천황":402,"키텍":134,"토니":210,"기반 ":179," 촬영":150,"타케":96," 총장":96,"희 ":216," 출력":112,"브라우":133,"브라운":81,"지의 ":915," 체험":72," 최소":174,"타크":164,"터스":138,"시기에":129," 최상":86,"터미":267,"후에 ":504,"탑재":111,"지은 ":141,"테레":67,"태양":433,"테러":113,"태어":822,"태에":207,"테르":345,"통계":363,"술연구":104,"통과":270,"테리":169," 초에":92,"태의":337,"테마":94,"타지":184,"탕으":335,"탁집":59,"텔레":541," 체코":189,"터베":257,"중화민":210,"테면":61,"브라질":214,"흐 ":135,"대교구":66,"태자":84,"태이":177," 초연":67,"토노":77,"태종":105,"태조":138,"토너":74," 충돌":170,"터이":208,"터장":63,"토리":469," 취득":122,"터의":386,"토마":125,"대는 ":203,"토머":72,"턴의":58,"통로":60," 총칭":263," 충분":75,"톨릭":545,"톨리":110,"토모":60,"모델이":91,"털이":89,"통령":1141," 축산":110," 추상":113,"태평":463," 최적":94,"토미":114,"테오":100," 출생":337," 최종":192,"회원국":118,"출시한":118," 축소":69,"투갈":235,"태풍":371,"탐험":74,"템에":113,"테일":72,"테인":310,"테이":563,"타타":84,"화체육":1124,"키프":58,"텍사":130,"통되":70,"틀어 ":87," 최신":57,"히 ":2784,"리투아":94," 출발":163,"즌이다":79,"힌 ":149,"터에":367,"탄티":148,"토로":115,"힐 ":59," 출범":202,"텍스":122,"토론":166,"테스":290,"터와":150,"톨레":83," 편 ":84,"힘 ":69,"토르":148,"토를":102,"터널":153," 처음":1260,"터내":78," 팀 ":177,"스》 ":220,"시된 ":202," 채택":232,"붙여졌":67,"회원의":67," 천연":128,"크이":135,"크의":348," 최근":299," 천안":91,"태를":373," 청원":63,"회이다":450,"지원 ":253,"터는":441,"치도 ":124," 판 ":94,"수엘라":63," 최남":61," 초명":73,"모니터":62,"키스":403,"질에 ":69,"터넷":668," 청사":77,"탈리":1166,"탈린":65,"후 ":3176,"타마":167," 초등":93," 창출":78,"타르":237,"타를":77,"타리":335,"터가":166,"키보":78,"키백":58,"금속 ":93," 차트":125,"태로":481," 최고":577,"타미":69,"크와":139,"타바":73,"구축하":85," 청소":291,"붙여진":80,"크어":57,"크에":279,"마케도":118,"모리 ":253,"훈 ":123," 총독":86,"터로":173,"타에":65,"타운":164,"타우":94,"홋카이":126,"택시":93,"키지":131,"탄에":62,"타와":67,"텐도":125," 척추":95,"휘 ":79,"탑승":57,"트와 ":207,"탄자":83,"토관":72,"탄의":170,"탄을":70," 총선":154,"터를":399,"토가":60,"터리":174,"타워":123,"타원":94,"타입":74,"크톱":69,"타임":197,"타자":78,"시도 ":60," 초식":67,"타의":139,"타일":144,"타인":408,"타이":1114,"키아":237," 추가":264," 체육":101,"테네":224,"탄소":127," 최대":527,"키에":115,"타스":72,"탐사":115," 초반":121," 천주":117,"블라디":122,"슬링 ":88," 총리":306,"모를 ":205,"탄생":209," 팝 ":93,"테나":69," 추기":61,"즈이다":127,"키의":171,"태생":110," 챔피":295," 천체":219," 청주":153," 출간":122," 체제":509,"키와":61,"모델로":73," 추구":126,"키우":65," 축구":957,"테니":137,"트는":279,"리히 ":247," 측정":234," 캘리":251," 층에":435,"통틀":103,"토해":114," 캄보":74,"트니":100,"토프":60,"진에 ":121,"퇴적":60,"대규모":179,"트남":408,"투스":187,"튜디":195," 캐릭":178,"빌딩 ":490," 칼리":148,"토크":67," 카메":218," 풀 ":69,"수이며":80,"통치":346,"통칭":251,"대구지":67,"트가":392," 카리":88,"지와 ":314," 카르":178," 카를":260,"교환 ":84,"토콜":205," 출판":450,"히고 ":66,"특성을":91," 침입":81,"능력이":74,"능력을":155," 카운":60,"국철도":85,"파나":80,"파냐":96," 카자":80," 카이":174,"티드":127,"귀족 ":88,"트럭":83,"트럴":128,"트럼":73," 친위":73,"트레":777,"수원시":104,"티노":156," 취하":75,"트롤":86,"트로":845,"싱가포":89," 친일":132,"틀란":68,"틀랜":270,"마추어":90,"티누":78,"트루":135,"틀러":85,"트르":93,"트를":421,"치된 ":243,"트릭":104,"트리":1178,"통행":63,"파가":72,"통하":582,"통한":472,"립한 ":329,"통해":1678,"통합":684,"투자":326,"투이":162," 카스":160,"투입":66,"통화":178,"파견":103,"분으로":162,"투쟁":105,"판관":57,"파구":159,"트랙":134,"트랜":257,"지역 ":878,"트라":796,"트란":76,"트랄":57,"니며 ":81,"판결":150,"파괴":182,"티나":260,"직에 ":77,"분이다":91,"수이다":549,"투아":129," 커다":65,"투어":153,"투에":168,"통신":860,"토양":96,"수여하":88," 추진":344,"텐츠":220,"트인 ":57,"터테":274," 출전":165,"통상":199," 출입":97,"투는":161,"브랜드":212," 추정":261," 총회":98,"토시":94,"토스":227,"터키":426," 축제":131,"텍처":131,"지에 ":707," 출연":182,"토성":62,"림픽 ":413," 침공":92," 최초":1056," 폴 ":107," 친구":98," 폰 ":187,"수용소":59,"통부":57,"트의 ":617,"회에서":510,"중학교":87,"투기":161,"템이":180,"템을":168,"템은":65,"템의":139,"술에서":64,"태화":59," 출신":971," 출시":471,"지어 ":59,"통문":80,"택하":130,"근무하":84,"증진 ":102,"교황 ":314," 카라":126," 친목":158,"대구광":218," 침략":81,"토착":58," 취임":66,"통제":163," 최후":85," 카드":233," 캐논":60,"모로 ":86," 치료":200,"투명":71," 칠레":103,"토지":226," 캐나":542,"통은":64,"통을":190,"통일":475," 충청":610,"통의":266,"통이":170," 치러":226,"통적":314,"투르":163,"투를":79," 춘추":67," 추측":96,"교회 ":398,"송하는":91,"통용":58,"구체적":132,"투로":114,"大之":149," 춘천":113,"大亞":171,"통영":82," 추출":59,"통에":86,"大丁":104,"大丘":81,"大並":265,"토의":195,"大三":116,"터페":234,"토에":143,"토어":58,"토요":82,"테크":171,"뉴스》":133," 충주":65," 측면":110,"최초로":360,"판서":64,"파소":76,"티안":75,"티아":321,"판소":126," 항 ":96," 케이":278,"파수":93,"티야":82," 캠퍼":62,"퍼드":118,"티에":140,"파스":130,"티오":173," 해 ":409,"틴어":370,"파시":83,"평가":559,"스를 ":979,"확한 ":138,"티움":195,"티의":76,"팀에":70,"평군":70,"평구":64,"패션":100,"평균":190,"파악":100,"퍼런":57,"부여하":82,"팀은":106,"파에":127,"팀을":101,"팀이":414,"팀인":106,"패스":68,"폐기":68,"머지 ":99,"퍼레":61,"특수한":100,"팀으":74,"속하는":814,"판에":167," 콘서":79,"파와":71,"파워":96,"속한다":406,"파울":88,"파의":210,"파이":647,"파인":105,"파일":554," 코스":197,"포가":72,"시는 ":274,"판이":166," 콘스":180,"폭격":74,"판의":82,"판은":76,"판을":143,"기록되":116,"판으":77,"파장":76,"페란":60,"페라":351,"포괄":108,"즈에서":95,"편되":118,"지아 ":174,"포구":341,"판정":86,"송파구":154,"트페":72," 쿠데":103,"후속작":75,"페르":483," 컨트":101,"대까지":71,"트폰":76,"페루":70,"시간에":90,"시간이":97,"티칸":62,"특한":83,"시간을":87,"명명되":59,"페리":114," 코어":59,"평동":57,"패의":75," 컴파":63," 커피":78,"특허":119,"비드 ":116,"평등":101,"특히":654,"스니아":124,"편리":65," 컴퓨":1671,"출생하":68,"포니":304,"화학 ":222," 쿠르":73,"평론":89,"포되":112,"포도":114,"화한 ":163,"포동":68,"퍼시":110,"파크":221,"퍼스":194,"포드":131,"분에서":63,"평면":121,"판타":113,"파키":163,"특별":3191,"파는":76," 커뮤":155,"퇴하":73,"판단":150,"부이며":90,"판되":77,"기록을":88,"기록은":61,"기록이":62," 코나":66,"파도":65,"파동":100,"트비":181," 콩고":150,"수집 ":85,"파라":208,"파란":62,"티모":92,"틸리":74,"티미디":76,"만화 ":211,"특성":272,"트사":71,"팔레":130,"티미":122,"북으로":70,"파르":244,"파를":146,"티벌":59,"티베":160,"투표":309,"특수":392,"파로":128,"팔라":113,"특정 ":405,"트어":154,"패러":91,"티븐":77,"티브":220,"부이다":121," 카타":66,"판매":556," 코드":377,"파리":365," 친환":78,"특유":61,"트이":390,"트의":618,"특이":82," 카페":68,"트인":71,"트워":614,"트웨":825,"송통신":78,"트와":228," 카트":59,"틀어":112,"트에":514,"패로":64,"맞추어":57,"티시":93,"티스":235," 칭호":106,"다란 ":85," 코리":125," 코르":132," 칭하":80," 콜로":74,"트족":57," 콜롬":89,"틀을":58,"특정":766," 침해":88," 함 ":107,"판사":210,"슬람 ":141,"파생":140," 코미":128," 코믹":74,"특수법":62," 할 ":828,"틀을 ":58," 한 ":3539,"패배":83,"특징":490,"펙트":82,"페트":58,"펼친":93,"포지":121," 회 ":430,"푸르":142,"풀로":95,"다른 ":2094,"말해 ":85,"분야로":104,"포의":126,"펼쳐":96,"페테":81,"포유":91,"표를":238,"품들":89,"비교하":63,"포인":100,"포이":65,"포자":65,"표면":243,"평택":84,"휴대용":67,"프가":223,"포츠":546,"회의에":88,"푸른":64,"회의원":323," 킬로":101," 키르":89,"리포니":249,"포터":121,"포털":72,"풍부":92,"폭탄":88,"교통의":80,"포크":112,"표시":333,"기본 ":174,"스도의":64,"평화":337," 키보":71,"편하":134," 쿼크":66,"풋볼":91,"품부":596," 후 ":926,"협회는":600,"출시된":71,"출시되":154,"풍속":64,"표이":142,"치가로":67,"포하":234,"포함":1770,"포한":64," 터널":91,"프는":77,"표의":64,"표율":67,"뉴욕 ":303,"푸아":98,"비교적":115,"표적":496,"피고":92,"포항":188,"식경제":82,"표에":93,"포트":180,"폭포":71,"먼저 ":125,"푸스":101,"당나라":170,"추진 ":78," 크기":356,"후의 ":318,"포르":483,"패턴":74,"포를":110,"표가":57,"팔레스":104,"분야이":162,"파하":69,"분야의":248,"만한 ":99,"포맷":122,"치는 ":382,"패키":72,"분야에":384,"티스 ":63," 크고":91,"폴란":333,"페스":133,"펜실":91,"폴로":79,"소프트":1324,"폴레":162," 현 ":1849,"면서 ":1800,"파티":108,"다룬 ":72,"파트":241,"몰도바":68,"포로":194," 크게":351,"폭력":166,"포럼":115," 쿠바":79," 國三":150," 國並":101,"팽창":61,"스만 ":143,"패하":101,"후인 ":57,"북아프":61," 코트":97,"리트어":69,"평생":67,"츠를 ":86,"구할 ":67,"시대 ":1109,"페이":806," 코퍼":58,"페인":767,"소행성":117,"페어":82," 콘텐":143,"마케팅":128,"표기":489,"마쿠라":73,"폭발":174,"퍼져":67,"폴리":363,"편성":139,"식공룡":68,"판하":95,"팩트":77," 형 ":90,"시다 ":61,"편적":65,"표된":100,"표되":128,"편입":100,"평야":69,"평양":609," 홈 ":107,"편으":97,"편을":77,"평안":88,"편의":170,"편이":180,"치가이":174,"표는":100,"품과":60,"편에":104," 호 ":622,"주하는":151,"보호하":179," 크다":72,"표로":306," 클리":72,"폐지":328,"편찬":136,"명령어":128,"포에":131," 클로":116," 탐구":62," 크리":494,"펑크":69," 크루":115," 클럽":310,"분야를":77," 클레":98," 클라":269," 크로":292," 클래":126,"출신의":366," 크레":128,"출신이":151,"편집":254,"투표를":67,"평의":64," 크라":154,"부에서":328,"출신으":183,"평원":75,"속하며":146,"포스":282,"포시":139," 타고":80,"폭스":71,"줄여 ":63,"테리아":58,"국시리":95,"최초 ":67,"탁집행":59,"현대자":68,"현대의":80,"주요 ":619,"한제국":216,"현대에":59,"프트가":61,"터베이":229,"국시대":174,"학자이":807,"학자인":136,"면으로":111,"람과 ":57,"면이다":122,"태이다":143,"테르부":65,"행정 ":844,"중부에":219,"죽을 ":57,"목이 ":67,"허리케":119,"죽은 ":131,"주의 ":2545,"구조 ":121,"목의 ":117,"교에서":366,"그녀의":76,"계획을":62,"계획이":79,"피터 ":60,"목소리":65,"통계학":58,"계획에":64,"추어 ":149,"호는 ":1131,"그램 ":342,"관한 ":1431,"학자로":168,"규모 ":208,"호간의":155,"라기 ":58,"국제 ":1037,"행성이":82,"종합 ":162,"념이다":176,"학자들":180,"행사하":73,"목은 ":112,"기나 ":97,"목을 ":213,"농업 ":98,"모의 ":211,"념으로":242,"통계청":58,"하인리":70,"준의 ":153,"년으로":59,"중앙 ":206,"교육자":122,"면적은":1793,"목적 ":106,"교육을":199,"교육의":108,"치구 ":58,"탕으로":335,"합이다":98,"준을 ":139,"함으로":764,"향에 ":59,"교이다":212,"해양수":137,"합으로":111,"그대로":248,"주인 ":62,"해안에":90,"해양부":103,"그룹 ":318,"화나 ":70,"중에 ":471,"군주 ":60,"지나 ":148,"지난 ":127,"혁명 ":188,"노이 ":65,"프트의":82,"프트웨":808,"노선을":63,"노선의":63,"노선이":141,"권에 ":140,"터스 ":74,"치고 ":176,"그로 ":130,"교육과":397,"출범하":69,"교육기":98,"해양경":119,"준인 ":60,"구스타":61,"준이 ":89,"텔레비":412,"무라 ":94,"학적으":169,"노의 ":74,"협력 ":130,"학적인":134,"지널 ":58,"태어났":310,"태어난":296,"태어나":175,"학에서":938,"敎之":110,"공항 ":89,"구성된":325,"구성되":572,"맨해튼":63,"하여야":74,"공한 ":83,"공학 ":155,"출이 ":60,"할아버":61,"라고 ":2752,"태양계":61,"구원 ":202,"지낸 ":207,"년에서":224,"카고 ":57,"물건을":96,"화국 ":933,"출을 ":84,"하에서":122,"최적화":72,"환경 ":270,"먼트 ":231,"하였는":106,"행에 ":116,"즈로 ":87,"터미널":258,"경하였":58,"학연구":99,"태에서":98,"국왕 ":169,"하였다":4731,"하였던":143,"추세츠":96,"물관이":96,"헬름 ":83,"구와 ":470,"군에 ":299,"모아 ":105,"해석학":116,"해석하":67,"하였고":606,"중생대":120,"중요 ":61,"중서부":70,"라가 ":204,"행을 ":299,"구성하":492,"주식회":205,"중을 ":67,"국적 ":77,"행의 ":135,"학으로":130,"공회 ":118,"군인 ":129,"그녀는":86,"묘로 ":171,"모여 ":116,"중의 ":536,"목에 ":210,"탄자니":77,"축을 ":74,"학이다":126,"군이 ":366,"국세청":71,"타이완":189,"행이 ":113,"프톨레":68,"타인의":82,"행위 ":176,"군의 ":818,"하우스":121,"했을 ":143,"축산식":105,"타이베":77,"금까지":91,"카가 ":78,"면에서":220,"과학 ":369,"중소기":146,"학위를":104,"국장 ":61,"군을 ":273,"해진 ":173,"군은 ":187,"지는 ":2020,"메탈 ":76,"국이 ":616,"구성요":67,"하와이":79,"국인 ":365,"군사적":69,"추원 ":57,"구성원":169,"구장 ":97,"타이틀":140,"즈를 ":119,"종특별":81,"국의 ":7793,"구인 ":59,"日三":105,"구소는":106,"하였으":1353,"중인 ":239,"즈니스":133,"총칭이":130,"구의 ":1000,"국을 ":477,"년에는":218,"국은 ":385,"중성자":58,"조하는":89,"하철 ":179,"토관리":71,"퓨터의":102,"향상 ":127,"항이 ":78,"퓨터에":131,"국왕이":80,"신하여":63,"해외 ":140,"항의 ":71,"출생 ":118,"해서는":187,"신학자":96,"시험이":69,"국으로":324,"명을 ":535,"명은 ":635,"공하여":84,"공하였":61,"구원은":154,"구이다":327,"필요로":66,"시행하":82,"합이 ":96,"구역은":158,"구역으":111,"타이거":62,"구역이":121,"명의 ":949,"주시 ":444,"기까지":238,"공하기":71,"합의 ":217,"공하고":126,"군에서":97,"합은 ":87,"명이 ":605,"명인 ":101,"합을 ":202,"신호를":88,"공하는":288,"敎 ":92,"최종 ":111,"항을 ":212,"식회사":205,"주변의":60,"하지 ":1309,"매하는":108,"해와 ":164,"무는 ":91,"주변에":81,"공한다":129,"합성어":91,"메이션":621,"퓨터를":66,"필요하":96,"필요한":311,"즈는 ":180,"헨리 ":107,"식품의":90,"농수산":67,"메이저":161,"시한다":59,"관하는":129,"시하는":199,"식하는":102,"구장이":90,"구장은":60,"구장으":111,"테면 ":61,"메이지":127,"지가 ":477,"즈니 ":71,"과학에":60,"태조 ":87,"과학원":110,"시행되":95,"과학적":147,"교토 ":66,"과학의":105,"과학자":114,"중세 ":186,"그라드":91,"국제명":67,"메이크":70,"교통 ":183,"공화정":72,"구치 ":63,"과학기":696,"화가 ":316,"국이다":140,"해살이":124,"국인들":59,"공화국":2091,"구축 ":59,"시하였":95,"함수의":80,"또한 ":786,"해의 ":186,"무관으":57,"물고기":88,"지게 ":159,"군이다":165,"공화당":68,"군으로":160,"헌법 ":117,"규모가":68,"시호는":324,"국제교":61,"국제공":130,"출발하":59,"합에 ":76,"테르 ":63,"한의 ":141,"현대 ":369,"조한 ":117,"곡하였":67,"해부학":57,"면서도":79,"족한 ":72,"한이 ":81,"조합 ":90,"통계 ":83,"향력을":65,"통과 ":82,"학적 ":572,"권의 ":269,"태생의":62,"말하는":177,"면은 ":81,"면을 ":202,"말한다":3380,"종파 ":71,"기관을":79,"기관으":991,"기관의":141,"기관이":951,"지고 ":1032,"한자 ":153,"기구로":81,"권은 ":114,"기관에":108,"권을 ":623,"할을 ":488,"태의 ":331,"만화가":103,"학은 ":215,"그를 ":132,"하의 ":427,"높은 ":477,"면이 ":103,"학상을":72,"말하면":59,"말하며":226,"기능 ":112,"하이 ":171,"학의 ":951,"교육청":88,"기는 ":947,"글로 ":110,"모모야":63,"학을 ":385,"면의 ":154,"학이 ":90,"피아노":101,"진과 ":113,"그림 ":81,"지구 ":303,"그린 ":169,"높이 ":126,"하자 ":138,"출신 ":245,"네치아":57,"함에 ":123,"한을 ":120,"피아니":63,"치가 ":290,"놓은 ":145,"학자 ":830,"기니 ":77,"면적 ":89,"신화에":220,"중심 ":210,"해야 ":228,"구에서":361,"신화의":72,"명에 ":142,"해양 ":65,"피언컵":95,"진구 ":92,"주얼 ":63,"그들의":150,"그들은":74,"질과 ":83,"함은 ":90,"함을 ":479,"해에 ":167,"타지 ":89,"구역상":152,"실행하":64,"국에서":1555,"주에 ":640,"지기 ":88,"기도 ":3458,"항에 ":88,"피에르":97,"권이 ":170,"기관차":146,"만화이":72,"농산물":130,"테니스":103,"프트 ":483,"구약성":69,"국에는":66,"국어로":84,"피언십":167,"모바일":151,"주와 ":707,"현동 ":88,"해안 ":100,"기구이":161,"준에 ":58,"증가하":70,"초점을":59,"뿐만 ":208,"퓨팅 ":60,"터에서":152,"중요성":72,"주주의":702,"관으로":1430,"관이다":925,"관이었":166,"탄티노":86,"국사 ":69,"과적으":61,"지냈으":100,"과정이":135,"과정을":292,"높이는":372,"과정에":270,"중앙행":163,"중앙회":62,"하여 ":10358,"학에 ":189,"누르고":122,"준정부":80,"하에 ":228,"관장하":182,"명칭으":130,"명칭은":335,"명칭을":111,"명칭이":208,"핵심 ":64,"군사 ":206,"중의원":106,"광역시":1449,"구성 ":124,"해시 ":75,"구밀도":162,"호가 ":138,"행성 ":102,"지니고":81,"투갈 ":67,"지로 ":816,"중요하":63,"중요한":537,"츠가 ":73,"국무총":119,"하위 ":107,"국민당":74,"텍사스":130,"학원 ":257,"네트워":601,"태풍 ":215,"구소 ":210,"주지방":89,"농어촌":104,"중이다":171,"학생들":151,"국민경":58,"지만 ":2429,"지마 ":65,"농업인":62,"지막 ":351,"한불교":58,"퓨터 ":987,"뉜다 ":141,"견한 ":100,"항상 ":79,"지리 ":83,"광주 ":85,"목으로":232,"공으로":88,"목이다":93,"피소드":110,"공원이":117,"질로 ":92,"지대에":91,"함수 ":148,"토미 ":72,"고지로":66,"교수 ":144,"지를 ":1014,"곳으로":142,"공용어":70,"촉진하":68,"결한 ":67,"구려의":58,"곳이다":155,"지니아":101,"해서 ":1198,"핀의 ":74,"철학자":224,"목적이":96,"목적으":2374,"목적은":73,"목적을":89,"관에서":127,"메트로":85,"타크래":128,"무부 ":116,"고쿠 ":157,"털이 ":79,"문》 ":124,"지되었":235,"관위는":85,"지면 ":61,"지며 ":169,"과이다":71,"톨릭 ":174,"천황의":64,"공유하":89,"지도자":328,"통령 ":409,"국립공":185,"턴의 ":58,"학명은":70,"모야마":65,"니가 ":122,"족행위":60,"진다 ":599,"출력 ":84,"물리 ":92,"결하는":245,"지도 ":237,"구분하":130,"지구에":121,"함마드":68,"근대 ":136,"노프 ":58,"곡한 ":151,"지금까":89,"기계 ":100,"토리 ":100,"기고 ":87,"교적 ":222,"현과 ":107,"교수로":84,"학문이":118,"학문적":57,"지관리":66,"기관 ":423,"지닌 ":149,"근거하":73,"존하는":140,"하므로":81,"한민국":7350,"피아 ":143,"터의 ":386,"문대학":65,"족하였":143,"직공무":113,"노카미":82,"누스 ":182,"합류하":76,"기구 ":245,"주어지":59,"주어진":139,"교수이":104,"지금의":259,"토니아":73,"늘날 ":214,"멀티미":78,"학술 ":98,"합리적":59,"지금은":121,"눅스 ":72,"헝가리":248,"토르 ":81,"픽에 ":123,"토를 ":102,"키텍처":131,"천황 ":220,"하버드":67,"한반도":215,"터와 ":146,"학습 ":59,"문명 ":78,"지기도":75,"구에 ":582,"국어 ":241,"·철학":275,"지구의":118,"모양을":68,"모양으":92,"테스 ":76,"중심부":67,"주었다":103,"모양이":89,"모양의":161,"주에서":249,"기기 ":100,"구역 ":205,"국에 ":586,"토대로":59,"목에서":71,"중심지":446,"직된 ":71,"촉진 ":60,"중심의":73,"중심으":672,"중심이":78,"한민족":78,"주의는":98,"줄여서":375,"계획 ":143,"주이다":406,"뉴기니":78,"무로 ":104,"모스크":232,"프스키":67,"주의를":168,"축물 ":62,"피스 ":81,"교에 ":115,"국방부":74,"터에 ":207,"종합적":78,"국민에":61,"권력을":67,"주이며":69,"허가된":536,"주요한":65,"토로 ":68,"국문화":83,"해발 ":137,"명으로":376,"해방 ":60,"집단 ":101,"명이다":422,"행되고":89,"국방송":84,"국민의":235,"행된다":79,"행되는":98,"명이며":67,"모습을":123,"교와 ":209,"주인공":208,"토너먼":71,"국불교":141,"중앙아":113,"무를 ":833,"중앙정":74,"하르트":89,"지냈다":412,"행동을":107,"권리를":141,"교사상":96,"행되었":179,"중에서":493,"주장한":106,"주장하":234,"구분된":68,"구분되":71,"기간 ":297,"주의에":98,"교육 ":543,"기가 ":609,"주의와":98,"준이다":67,"준으로":442,"통과하":60,"구별하":80,"주의자":203,"주의인":510,"그는 ":921,"주의적":180,"광주광":201,"하면서":761,"주의의":142,"물론 ":117,"물로 ":459,"무대신":61,"학살 ":67,"교의 ":1022,"명칭 ":96,"중에는":97,"그것은":65,"그것을":99,"주제로":77,"학생 ":143,"근거로":57,"丘乙 ":101,"실제로":191,"문을 ":285,"문은 ":97,"丙之 ":191,"현악단":131,"념물 ":77,"전한 ":445,"구를 ":601,"전할 ":64,"문서를":72,"三倉 ":159,"초에 ":110,"과사전":636,"챔피언":309,"丘之 ":172,"무장 ":114,"승팀 ":85,"경제자":60,"丘亞 ":97,"경제의":97,"경제적":182,"군대를":57,"三丁三":180,"三丁丁":115,"템이다":123,"무소는":58,"丘亂 ":62,"무의 ":132,"문서는":80,"화성 ":63,"스케이":155,"중기의":177,"조정 ":98,"젝트 ":155,"물을 ":636,"三並亞":103,"물은 ":154,"三並亂":75,"三並並":197,"화상 ":61,"三並之":157,"三並三":347,"三並丁":93,"확립하":58,"체코 ":66,"공작 ":150,"러나 ":375,"토에 ":57,"三三並":435,"三三之":337,"三三亂":104,"三三亞":275,"절한 ":64,"三三丘":91,"三三三":746,"三三丁":204,"三丁並":115,"三丁之":138,"정치가":329,"공이 ":75,"경제부":95,"三丘三":78,"추구하":83,"三三倉":73,"문서에":61,"무소장":62,"통신 ":286,"문이 ":99,"공을 ":239,"계이다":139,"스코틀":228,"문서이":58,"문자 ":261,"시코 ":197,"공의 ":248,"래되었":95,"三之並":215,"三之之":161,"문의 ":316,"三之亞":63,"공유 ":71,"三三國":62,"관에 ":201,"심으로":693,"시켜 ":262,"三之丁":129,"三之三":285,"공산주":198,"십자군":103,"화산 ":89,"졌으나":61,"과와 ":58,"공사의":74,"곳의 ":66,"못한 ":89,"노래 ":87,"조선민":527,"곳을 ":106,"곳은 ":97,"회를 ":455,"丁倉 ":81,"중국어":136,"스타리":76,"중국에":167,"시즌이":135,"형성하":139,"경쟁력":153,"명하였":122,"전》 ":217,"뜻의 ":103,"몬테네":93,"공원 ":236,"래밍 ":212,"국령 ":69,"협정 ":78,"구로 ":407,"해하는":84,"스타디":113,"뜻은 ":77,"뜻을 ":186,"스크바":214,"과에 ":283,"조사연":59,"무와 ":69,"스크리":94,"스크립":98,"硏之":94,"문에 ":1313,"결정하":131,"구려 ":72,"라루스":57,"丁並之":61,"정책을":139,"丁並並":65,"랜드의":362,"스토니":68,"정책의":92,"丁並三":108,"정책이":65,"정책에":70,"랜드에":119,"형의 ":232,"뮤니티":87,"존의 ":270,"스테르":112,"남쪽으":574,"남쪽은":77,"丁三亞":60,"丁三之":151,"경으로":205,"丁三並":143,"丁三三":197,"공산당":201,"丁三丁":74,"계열의":107,"스터미":113,"丁丁之":67,"丁丁三":77,"丁丁丁":59,"광범위":81,"합회는":84,"조선총":95,"스크톱":69,"스타일":126,"스타인":141,"형이 ":118,"스탄의":136,"냈으며":111,"남쪽에":112,"족의 ":403,"경우에":367,"뮤니케":86,"丘並 ":120,"조선시":218,"丘丘 ":120,"겨진다":96,"족을 ":151,"족은 ":109,"중국인":65,"중국의":313,"조의 ":556,"丘三 ":214,"丁之之":73,"중교통":58,"족이 ":130,"조사하":74,"형을 ":227,"丘丁 ":189,"조선의":232,"조선인":72,"丁之並":120,"丁之三":108,"출된 ":86,"조선왕":60,"조선에":59,"형은 ":84,"무원 ":354,"계에서":550,"물에 ":244,"나중에":137,"내에서":352,"정할 ":104,"스템에":108,"제품 ":138,"스테이":248,"형성된":99,"형성되":118,"並亞 ":397,"정한 ":1015,"태풍으":59,"태풍이":71,"공연 ":73,"경우를":91,"통상 ":58,"스템의":137,"스템이":178,"스템을":165,"스템은":65,"계약을":87,"정치학":71,"고종 ":91,"민국 ":4370,"터키 ":238,"중남부":58,"고슬라":66,"합하여":263,"럽과 ":63,"명하고":104,"시킨 ":207,"국내에":69,"시킬 ":95,"스타크":130,"곳에 ":630,"럽게 ":67,"종사하":78,"남이다":68,"丘三三":90,"주니어":77,"丘三之":57,"丘三並":57,"회로 ":295,"함하여":108,"경우는":71,"국내외":132,"스탄티":147,"접해 ":411,"경우도":213,"스토리":150,"三倉三":63,"종이 ":160,"슷한 ":237,"공업 ":91,"전투는":153,"심지는":190,"제프 ":99,"템에서":59,"경찰 ":105,"초의 ":683,"명하며":58,"호수 ":60,"경우가":270,"전투기":110,"고전 ":139,"스튜디":195,"결정되":69,"실질적":115,"났으며":113,"함한다":221,"고속버":59,"란드에":64,"란드어":81,"주도로":122,"전통문":78,"투는 ":161,"무에 ":90,"테이션":199,"명하다":316,"투갈어":68,"주도는":958,"명하는":145,"란드의":272,"주를 ":291,"래로 ":181,"전히 ":176,"테인먼":266,"함하는":169,"경에서":129,"테이블":95,"三丘驿":62,"좋은 ":139,"무역 ":89,"三亞三":128,"三亞並":101,"三亞之":123,"내용은":87,"내용을":238,"내용으":63,"스파냐":94,"내용의":62,"내용이":162,"곡을 ":163,"곡은 ":123,"좁은 ":114,"함하고":175,"고속도":557,"주로 ":2407,"고의 ":280,"철학 ":391,"고자 ":296,"곡이 ":62,"전화 ":176,"형에 ":66,"곡의 ":107,"심지이":98,"험이다":74,"람들이":226,"람들의":90,"검찰청":131,"람들은":61,"람들을":90,"고유 ":58,"민간 ":90,"람들에":76,"현재 ":1569,"스트로":176,"並丁 ":256,"스트를":69,"並三 ":685,"렇게 ":88,"것처럼":82,"모할 ":63,"스트리":632,"졌으며":172,"학회는":214,"스트라":255,"전혀 ":90,"스트레":553,"並並 ":551,"종의 ":525,"호세 ":58,"ος ":121,"교류 ":167,"접한 ":137,"공부하":58,"스티안":65,"並丘 ":162,"종을 ":142,"현이 ":70,"종은 ":81,"스파이":76,"호선 ":244,"정치적":249,"민과 ":61,"並之 ":482,"조지 ":208,"조직 ":160,"정치인":881,"교를 ":330,"미국 ":2327,"통문화":79,"현의 ":217,"효과적":73,"스티븐":77,"할한다":328,"현을 ":152,"할하는":82,"並乙 ":122,"스티벌":59,"스파르":60,"행형 ":62,"현상이":157,"래를 ":142,"현상을":242,"텐츠 ":92,"並亂 ":230,"스트이":111,"스트의":82,"협약 ":74,"실시하":164,"제작자":87,"권리 ":62,"문신 ":143,"제자유":65,"경찰청":120,"곳에서":166,"스템 ":494,"노동자":160,"스텔 ":62,"노동조":80,"주당 ":171,"천주교":125,"격한 ":87,"톨리아":98,"효과를":107,"라면 ":101,"관악구":58,"재하였":61,"널은 ":82,"스톤 ":59,"뛰어난":130,"널을 ":66,"호사 ":85,"재하지":105,"통령을":141,"통령의":87,"통령으":73,"통령이":192,"제적인":115,"제적으":88,"그가 ":220,"제작하":177,"제작한":315,"라데시":106,"준다 ":198,"라마 ":280,"주광역":200,"러가 ":71,"미가 ":133,"초명은":71,"경찰서":86,"거하여":108,"제주도":96,"교사 ":69,"제조업":81,"전통 ":182,"넓은 ":249,"행한 ":180,"주도 ":249,"행할 ":135,"정이었":81,"장하며":59,"시아의":577,"시아와":80,"시아어":195,"넣어 ":72,"장했다":79,"시아에":205,"的 ":81,"접전을":65,"나타나":260,"나타난":144,"접적으":61,"나타내":437,"나타낸":182,"곡이다":130,"호르몬":66,"시에는":136,"라디미":108,"곡으로":120,"고있다":120,"제이다":258,"스트 ":1046,"체육관":1157,"현에 ":78,"홍보 ":87,"라디오":334,"재하고":117,"제외한":225,"정의한":63,"정의하":162,"제작되":129,"제작된":176,"장하였":134,"제외하":103,"장하여":85,"고유의":69,"정치 ":296,"식에서":64,"스틱 ":69,"교류를":138,"정적인":117,"재하는":271,"태평양":418,"재한다":193,"시에서":270,"체에서":108,"주는 ":678,"토스 ":122,"활동하":431,"활동한":114,"재했던":158,"고이다":107,"관심을":87,"종목에":75,"너지 ":209,"총리대":58,"청으로":59,"총리를":116,"제정되":152,"제정된":104,"국민 ":136,"제임스":214,"활동했":136,"후기 ":150,"죄를 ":91,"무선 ":97,"해협 ":57,"물리적":166,"시외버":130,"족에 ":107,"三之 ":901,"고용노":84,"三乙 ":170,"三乘 ":99,"조에 ":202,"시청 ":67,"줄기는":57,"활동을":468,"형식 ":59,"화물 ":67,"활동에":80,"총선 ":59,"三三 ":1345,"투기 ":72,"네스 ":139,"라로 ":118,"템의 ":139,"三丁 ":581,"고위공":230,"활동이":95,"조와 ":117,"토론토":96,"물리학":446,"전체의":66,"三丘 ":326,"시외전":76,"템은 ":65,"템을 ":168,"문서 ":147,"슈타인":136,"톨레마":65,"무소 ":98,"최대의":181,"三並 ":896,"三人 ":61,"화되어":83,"래된 ":286,"형문화":146,"텍스트":85,"져있다":81,"화되었":81,"쳐진 ":60,"고양시":85,"공식적":231,"시이다":491,"테스트":133,"활동과":61,"식으로":605,"식이다":352,"三亂 ":228,"고양이":81,"시작된":195,"시작되":382,"터이다":170,"三亞 ":422,"체이다":555,"청장은":97,"시이며":121,"스카르":62,"명한 ":534,"신으로":438,"년마다":62,"丁丹 ":61,"피해자":88,"관의 ":2170,"丁並 ":336,"丁乙 ":118,"주관하":162,"체제의":76,"관인 ":84,"제정한":62,"관이 ":275,"丁之 ":446,"신이다":266,"체제에":91,"공주 ":71,"시인이":151,"추기경":60,"과정 ":135,"궤도 ":71,"토마스":59,"최되었":107,"시장에":144,"제주시":75,"전투 ":320,"토리아":108,"丁丘 ":202,"라를 ":184,"주된 ":92,"시작으":155,"丁丁 ":409,"신이며":66,"丁三 ":412,"노동당":62,"丁人 ":68,"조약 ":210,"확률 ":66,"최되는":68,"경제학":303,"화를 ":1060,"모토 ":158,"과의 ":595,"시장을":66,"시장이":77,"체제를":101,"스카이":59,"회는 ":1632,"랜드 ":1148,"톨릭교":272,"구대회":70,"국립 ":152,"청주시":71,"계적인":187,"계적으":250,"시작하":474,"시작한":212,"시작해":80,"시작했":235,"경주시":80,"축구단":96,"시적으":65,"체적인":105,"丁亂 ":154,"체적으":123,"노동부":61,"신이자":75,"국대학":78,"식적으":162,"전체를":82,"제주특":160,"丁亞 ":110,"논리 ":71,"관을 ":436,"식적인":111,"피해를":133,"관은 ":726,"토머스":70,"大之 ":76,"중부 ":251,"공룡이":97,"제하는":65,"정해진":101,"개편되":114,"국내 ":265,"트가 ":377,"관련된":425,"건전한":206,"권과 ":96,"걸친 ":83,"경영 ":97,"大丘 ":63,"之之三":178,"之之丁":97,"之之並":118,"之之之":104,"네스코":91,"네시아":285,"험의 ":58,"정하여":167,"정하였":105,"험을 ":187,"구나 ":75,"고속 ":76,"경에 ":256,"발된 ":162,"결을 ":132,"험이 ":59,"정하지":57,"미로 ":169,"제품이":89,"제품을":86,"화로 ":269,"之丁並":63,"之丁之":91,"之丁三":123,"之丁丁":66,"량과 ":57,"나폴레":142,"거주하":225,"결정 ":73,"결성한":67,"경상남":479,"것이며":93,"최고의":169,"大亞 ":63,"乙亞 ":60,"조직의":65,"조직으":61,"조직을":68,"조직이":140,"것이라":157,"계약 ":89,"최대 ":229,"체의 ":618,"之並之":139,"之並並":158,"之並三":216,"之並丁":69,"之並亞":199,"함한 ":296,"之丙之":157,"논란이":57,"발견한":90,"발견하":88,"체인 ":128,"게오르":73,"之三丘":62,"것이다":1291,"之三三":426,"之三丁":121,"之三之":190,"之三並":196,"합한 ":160,"것으로":1506,"之三亞":92,"래는 ":286,"정하고":231,"격이 ":107,"것에서":61,"체제 ":143,"乙之 ":116,"정하기":94,"乙丘 ":89,"정하는":363,"정한다":104,"격의 ":76,"조지아":231,"반도 ":306,"乙並 ":132,"건축 ":91,"접한다":355,"검역소":69,"종으로":458,"미널이":72,"가하였":118,"가하여":102,"격을 ":325,"乙乙 ":66,"종이다":450,"라남도":362,"之倉 ":121,"체적 ":96,"추고 ":107,"접하며":306,"해체되":61,"향으로":228,"접하고":189,"노르웨":212,"문제에":105,"처에서":63,"전형적":62,"결성되":75,"결성된":112,"축구 ":742,"최근에":153,"족주의":88,"학회 ":138,"조직된":71,"년에 ":3322,"乙丁 ":151,"乙三 ":190,"문제로":78,"최된 ":172,"받는 ":236,"넷을 ":59,"견을 ":57,"문제를":243,"발견되":256,"발견된":167,"교관이":68,"반대 ":73,"거이다":64,"네의 ":71,"가하고":96,"채택되":89,"라도 ":249,"협력을":97,"물이나":96,"네상스":84,"문자를":85,"계승 ":114,"바다 ":113,"주민들":79,"통신사":68,"물이다":498,"문제가":87,"노벨 ":164,"걸쳐 ":536,"효과 ":100,"고리즘":197,"가했다":70,"건이다":462,"교는 ":208,"현상 ":62,"大並三":80,"건으로":192,"주소 ":90,"통신망":69,"했지만":129,"빌헬름":85,"험에 ":74,"나톨리":87,"체스터":79,"大亞之":73,"문이다":346,"정확하":95,"정확한":116,"문으로":196,"가하는":151,"식품부":594,"고려의":79,"무장관":67,"무원이":83,"무원으":224,"행정부":79,"나파소":72,"처음에":146,"천으로":103,"라드 ":121,"네수엘":63,"채택하":69,"가포르":89,"증권 ":60,"시하고":125,"행정동":192,"물에서":66,"뮬레이":141,"년부터":1634,"군과 ":241,"고려시":129,"거에서":68,"행정기":403,"비행기":106,"국군 ":60,"노래이":97,"제하여":61,"터페이":229,"노래를":60,"호를 ":436,"제학자":107,"미디 ":96,"격에 ":63,"거쳐 ":338,"랐다 ":84,"란드 ":706,"죄의 ":57,"못하는":67,"향악단":90,"문에서":86,"행정안":64,"처음으":371,"구글 ":68,"한편 ":73,"라노 ":78,"터키의":77,"민공화":988,"화된 ":280,"민국의":2300,"기》 ":71,"민국에":562,"했으나":251,"스페인":683,"스페이":72,"해진다":88,"행위를":267,"통을 ":190,"교로 ":167,"통은 ":64,"해지는":107,"못하고":66,"네이버":142,"했으며":734,"행으로":73,"통이 ":84,"스펙트":61,"통의 ":259,"고에 ":101,"주민 ":65,"고와 ":63,"並亞三":75,"並亞並":57,"시티 ":116,"학파 ":61,"미국의":1693,"미국이":72,"미국인":172,"노스 ":128,"계승하":58,"농림수":538,"미국에":434,"활동 ":273,"행위에":64,"건축가":79,"스페란":59,"형법 ":64,"호로 ":311,"並三國":84,"건축물":157,"투로 ":104,"並之之":99,"격으로":151,"並之並":167,"並之三":173,"並之丁":59,"농림축":109,"행위이":57,"행정구":264,"並並之":99,"並並亞":75,"並並並":118,"並並三":168,"전투에":151,"並丁三":78,"並丁並":60,"並丁之":93,"계적 ":102,"전투이":155,"강화하":64,"並三丁":85,"초를 ":88,"並三三":352,"並三並":166,"구기관":173,"並三之":182,"확대 ":72,"並三亞":95,"丹之 ":65,"스피드":93,"주도하":91,"화교류":59,"시칠리":59,"식품 ":76,"처음 ":669,"처의 ":89,"丹丁 ":93,"민경제":59,"국과학":73,"라는 ":3491,"민당 ":69,"조약으":67,"경주 ":115,"조약이":138,"민국과":113,"국도 ":142,"라고도":1545,"환경에":149,"並倉 ":90,"해주는":74,"미니 ":62,"통일 ":78,"전통적":268,"전투를":62,"종종 ":128,"환경을":119,"전투로":106,"환경의":58,"비해 ":202,"스포츠":528,"국기는":74,"싱턴 ":94,"터테인":265,"화국에":206,"제학 ":83,"제한 ":74,"천을 ":85,"주도이":258,"회관 ":166,"공식 ":315,"천의 ":86,"공신 ":59,"스프레":81,"화국이":115,"화국의":592,"쳐서 ":141,"스플레":121,"투를 ":79,"민간인":66,"방과 ":134,"착한 ":79,"시카고":77,"물질 ":102,"미국과":130,"논리학":71,"시한 ":262,"三國 ":87,"향이 ":94,"모하고":162,"구는 ":2663,"관리를":117,"국가의":292,"국가이":133,"년을 ":193,"경쟁 ":61,"향의 ":74,"협동조":95,"합중국":79,"국가와":63,"전하였":96,"년이 ":104,"노선 ":97,"하키 ":77,"모하기":104,"래가 ":59,"향을 ":645,"년의 ":319,"식한 ":96,"존재했":183,"존재하":508,"존재한":228,"헤르체":107,"헌법에":75,"관리소":120,"홈구장":160,"화가이":84,"관리사":94,"게임은":64,"게임을":126,"게임으":157,"게임이":455,"게임의":112,"게임에":95,"미는 ":124,"계속되":62,"고비나":106,"시코의":88,"계의 ":803,"경제 ":436,"철의 ":57,"전해지":88,"청에 ":72,"구단 ":75,"목표로":175,"회가 ":352,"게이트":71,"공모함":59,"전했다":59,"之亂 ":185,"스피어":79,"관리자":123,"논리적":58,"널이다":102,"발굴 ":71,"시켰다":116,"화는 ":234,"공무원":718,"之亞 ":205,"관리청":88,"녀의 ":96,"之之 ":481,"화국과":90,"토의 ":187,"국경을":303,"해졌다":113,"스하키":63,"관리하":241,"시픽 ":95,"문신이":114,"구관으":65,"之乙 ":132,"구광역":218,"체에 ":291,"향상과":135,"받고 ":270,"관련이":94,"之丁 ":427,"경우 ":678,"주변 ":114,"계에 ":486,"之三 ":666,"시키는":366,"항으로":97,"시킨다":73,"슷하게":59,"하지만":557,"之丘 ":282,"之且 ":96,"것이었":89,"계열 ":117,"실행 ":66,"졸업하":144,"之並 ":569,"너지를":107,"발과 ":93,"고스 ":58,"국가가":96,"경상북":406,"국가기":78,"노미야":60,"신호 ":86,"전하는":152,"국가대":143,"항이다":64,"개편하":94,"계와 ":138,"초등학":97,"전하고":83,"전하게":65,"관련하":58,"관련한":66,"국가들":151,"무실은":1845,"므로 ":457,"즈가 ":125,"념을 ":152,"실험 ":62,"시험 ":132,"게임기":80,"총리 ":123,"물의 ":727,"경을 ":557,"국가로":150,"경은 ":67,"물이 ":315,"청은 ":173,"조이다":111,"국가를":123,"청소년":337,"체와 ":151,"구개발":124,"관료이":65,"경의 ":225,"국가보":77,"비히 ":100,"받게 ":57,"향상에":76,"공사 ":223,"경이 ":113,"청이 ":90,"통에 ":62,"총독부":113,"문제 ":176,"향상을":130,"무슬림":67,"시키기":187,"청의 ":110,"빅토리":101,"족으로":212,"결승전":133,"시키고":183,"미널 ":87,"구간이":72,"광부 ":1095,"족이다":137,"국가에":207,"향상시":75},"n_words":[4985886,5984351,3260836],"name":"ko"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/lav b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/lav new file mode 100644 index 000000000..ce5ff7ed1 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/lav @@ -0,0 +1 @@ +{"freq":{"ūci":182,"ūdu":26,"ūdr":44,"ūdo":28,"ūde":716,"ūda":90,"D":3059,"E":2166,"F":1831,"G":1835,"A":5495,"B":3355,"C":2145,"L":4567,"M":3974,"N":1829,"O":1507,"H":1820,"I":2327,"J":1801,"K":4616,"U":852,"T":4509,"W":365,"V":3715,"Q":38,"P":4759,"S":5447,"R":3339,"Y":65,"X":234,"Z":1747,"f":8161,"g":29438,"d":58295,"e":131519,"b":30435,"Fed":124,"c":22500,"a":237698,"n":95937,"o":88352,"l":73126,"m":69285,"j":43124,"k":78380,"Fel":22,"h":5764,"Fen":23,"i":199506,"w":553,"v":49552,"u":101354,"Fer":33,"t":118682,"s":178123,"r":127678,"q":293,"p":52161,"z":35062,"y":1297,"x":396,"²":54,"Fil":64,"í":35,"Fin":30,"Fir":23,"é":81,"ç":26,"ä":65,"â":42,"á":40,"ü":91,"ö":83,"ó":42,"Fiz":28,"ē":27728,"Ē":143,"Ā":409,"ā":76597,"Č":300,"č":1638,"ı":70,"ķ":3799,"Ķ":255,"Eze":42,"Ļ":56,"ļ":8048,"Ģ":128,"ģ":3732,"Ī":133,"ī":34346,"Ģer":28,"Ģeo":39,"Ģen":28,"ş":30,"ņ":7202,"Ņ":124,"ō":55,"Ž":134,"ž":4793,"Š":1043,"š":16459,"Ū":37,"ū":7903,"Equ":185,"Eri":30,"Ern":25,"Eur":70,"Eir":595,"́":38,"Ele":79,"Eks":36,"Eko":28,"μ":50,"ν":83,"End":31,"ο":116,"ι":60,"κ":31,"λ":61,"δ":42,"ε":43,"η":40,"α":118,"β":23,"γ":49,"ί":37,"Emi":22,"Eli":48,"ω":27,"Ent":23,"ό":36,"σ":41,"ς":97,"ρ":66,"π":29,"φ":23,"υ":22,"τ":47," l":9777,"ь":65," m":8646," n":13651," o":3224,"я":84," h":1222," i":26578," j":3868," k":23420,"ы":62," d":13444," e":3216,"х":31,"ц":23," f":3413," g":7521,"ч":56,"р":268," a":22507,"с":262," b":8086,"т":170," c":4249,"у":116," y":33," x":65," z":3907," u":13570," t":13126," w":93," v":19041," q":33," p":25406," s":20595," r":6772,"HK ":23,"Ūde":29,"Л":28,"К":30,"Н":52,"М":37,"О":27,"Б":29,"А":26,"В":29," J":1795," K":4607," H":1796," I":2309," N":1813," O":1473," L":4536," M":3956," B":3324," C":2058,"Р":35," A":5469,"С":193," F":1822," G":1815,"Ф":23," D":3031," E":2156,"л":187," Z":1739,"к":221,"й":81," Y":64," X":228,"и":382,"п":57,"о":387,"н":271,"м":85," S":5368,"г":53,"Ger":28," R":3325,"в":222,"б":51," Q":37," P":4729,"а":390,"Geo":50," W":350,"з":76," V":3691,"Gen":23," U":847,"е":335," T":4452,"д":133,"šža":24," ā":501," Ā":409," č":467," Č":299," Ē":143," ē":282,"HL ":22," ž":311," Ž":134," Ū":37," ū":565," Š":1042," š":2083," Ļ":56," ļ":329," ķ":663," Ķ":254," Ī":131," ī":702," Ģ":128," ģ":1094," Ņ":120," ņ":41,"י":25,"Gan":49,"Gal":115,"Gam":34,"Gau":47,"Gar":70,"Gai":64,"Fut":176,"و":37,"ي":53,"ل":68,"م":47,"ن":33,"د":35,"ب":27,"ة":22,"ا":101,"س":25,"ر":50,"Frī":41,"šūn":142,"Flo":40," А":25," Б":28," В":29,"Fra":343," К":29,"Fri":44," Л":27," М":37," Н":52," О":26,"Fre":87,"A ":493,"For":93," α":37,"F ":117,"Da":634,"Cu":37,"Cl":54,"Co":292,"Cr":43,"Ce":347,"Ch":135,"Ci":209,"G ":59,"Ed":95,"Eb":22,"Du":106,"Dz":229,"Do":208,"Dr":103,"De":400,"Di":679,"IP ":41,"Fe":227,"H ":468,"Fa":110,"Ez":43,"Eu":85,"Ev":42,"Ex":29,"Er":98,"Eq":185,"Et":48,"Es":44,"En":123,"Em":90,"Ei":677,"El":193,"Ek":93,"Eg":26,"Ge":158,"Bā":56,"Ga":460,"I ":434,"Fu":230,"Fr":536,"Fo":212,"Fl":70,"Fi":194," о":23,"B ":133," Р":34," С":176," Ф":23,"II ":185,"C ":377," с":29,"Av":74,"Au":759,"Ar":519,"At":405,"As":243,"D ":170,"Ba":1010,"Az":34,"Af":50,"Ag":51,"Ah":37,"Ab":147,"Ac":82,"Ad":148,"Am":328,"An":739,"Ap":260,"Ai":200,"Ak":154,"Al":535,"Hit":49,"His":22,"Bu":240,"Br":526,"Ca":279,"E ":106,"Bi":333,"Be":447,"Bo":341,"Hil":23,"Bl":116,"Him":40,"Hip":27,"Kv":49,"Ku":433,"Kl":267,"Kr":1045,"Ko":785,"Gā":24,"Le":274,"Li":1187,"N ":114,"La":2106,"Lu":187,"Ly":26,"Lo":258,"Me":656,"Hā":28,"Dž":311,"Mi":487,"O ":256,"Ma":1352,"My":39,"Hē":35,"Mu":257,"Mo":497,"Ni":163,"Ne":339,"Na":331,"P ":315,"Hel":44,"Hei":53,"Nu":37,"No":488,"Ok":85,"Ol":289,"On":42,"Og":53,"Oh":28,"Od":50,"Jā":93,"Hen":52,"Of":29,"Ob":41,"Her":113,"Gi":68,"Gl":88,"Gr":518,"Go":173,"IA ":51,"Gu":165,"Gv":31,"Bē":72,"J ":48,"Ha":442,"He":346,"Hi":235,"Ho":305,"Bī":48,"Hu":55,"Cē":86,"K ":99,"Ib":23,"Id":25,"Dā":72,"Ie":161,"Ig":193,"Im":77,"In":597,"Ik":26,"Il":62,"Dē":23,"Iv":35,"Is":56,"It":130,"Ir":159,"Ja":606,"L ":193,"Iz":255,"Je":180,"Jo":238,"Hab":30,"Ju":235,"Hal":59,"Hai":24,"Ka":1308,"Han":77,"M ":140,"Ham":27,"Har":76,"Ki":234,"Hav":40,"Ke":175,"Mū":173,"Ur":133,"Up":46,"Un":191,"Uk":57,"Ul":29,"Ug":37,"Pā":146,"W ":36,"Tu":367,"Nī":78,"Tr":348,"Lū":27,"To":528,"Th":183,"Ti":330,"Tj":24,"Te":412,"Ta":1094,"V ":507,"Bēr":58,"Grī":41,"Sy":41,"St":811,"Sv":222,"Su":204,"Wo":58,"Wi":99,"Wa":68,"Rā":30,"We":47,"Vo":206,"Pī":38,"Vu":40,"Vi":1349,"Vl":38,"X ":140,"Va":795,"Ve":528,"Pē":222,"Uz":97,"Lā":40,"Pu":149,"Pr":574,"Ps":29,"Gus":31,"S ":509,"Pe":330,"Kā":157,"Pa":1460,"Gui":25,"Pl":246,"Po":522,"Pi":543,"Ph":56,"Gul":51,"Os":199,"Ot":132," ا":37,"Ov":28,"Op":65,"Or":179,"R ":242,"šņu":59,"Jē":211,"Nā":75,"Se":449,"Sc":140,"Si":396,"Sh":52,"Sn":22,"Sm":71,"Sl":112,"Sk":318,"Mī":29,"Sp":308,"So":292,"Ru":198,"Jū":171,"Mē":139,"U ":122,"Sa":1320,"Grā":24,"Re":684,"Mā":133,"Ri":309,"Rh":25,"Ro":567,"Lī":215,"Qu":25,"Lē":28,"T ":118,"Ra":377,"Gre":140,"Gri":112,"Gra":91,"Vī":58,"b ":1431,"Gru":54,"Gro":39,"a ":45978,"Sē":77,"Tā":889,"Yo":26,"Tē":78,"Sī":40,"Z ":47,"Rē":60,"Sā":102,"Pū":23,"Rī":858,"Gol":28,"Got":33,"Vā":356,"Vē":122,"Za":126,"Ze":604,"Zi":554,"Tī":49,"Zo":72,"Zu":34,"God":26,"Rū":43,"Zv":222,"šķā":29,"i ":20844,"aē":38,"gd":52,"ge":675,"bā":1878,"ga":11955,"gb":23,"Ing":34,"Inf":36,"fl":161,"fg":38,"ff":54,"aā":32,"fi":2006,"šķē":67,"fs":184,"fr":742,"ač":195,"fu":915,"ft":143,"Int":119,"fo":1630,"Ins":32,"j ":431,"aķ":196,"gz":413,"bē":351,"Ir ":43,"cā":282,"he":981,"aļ":2174,"ha":893,"gn":346,"gm":103,"gl":1302,"gk":23,"aģ":126,"gi":1023,"gh":75,"gg":39,"gv":152,"gu":2538,"gt":345,"gs":1978,"gr":3115,"šķī":179,"aī":165,"go":1269,"dt":34,"du":3460,"dv":153,"dy":39,"dz":8558,"g ":378,"Ima":40,"ea":831,"eb":2145,"ec":2362,"ed":5035,"de":6326,"dd":61,"dg":22,"di":7508,"dh":33,"dk":50,"dm":437,"dl":81,"do":4137,"dn":387,"dp":40,"ds":1737,"dr":2632,"ew":72,"ex":66,"eu":138,"ev":3202,"ey":101,"ez":2104,"fa":698,"h ":326,"Inc":26,"Ind":290,"fe":924,"eh":574,"eg":1917,"ef":579,"ee":260,"el":8559,"ek":9435,"ej":1682,"ei":6080,"ep":1928,"eo":1018,"Imp":27,"en":17231,"em":12435,"et":9035,"es":13667,"er":13266,"cb":46,"ca":1325,"e ":9104,"bv":92,"by":23,"bs":478,"br":1873,"bu":2780,"bn":90,"bo":2478,"bp":134,"bj":321,"bk":204,"bl":923,"bi":5030,"bb":37,"bd":41,"be":3600,"da":13240,"f ":227,"cy":80,"cu":688,"ct":320,"cs":106,"cr":118,"co":534,"cp":28,"cm":65,"ck":210,"cl":78,"ci":9940,"ch":496,"ce":3798,"cc":58,"c ":1617,"Zī":28,"az":1867,"ay":138,"ba":7096,"d ":1260,"at":15301,"as":46560,"ar":22107,"šķe":37,"ax":44,"aw":25,"av":4016,"au":11606,"šķa":58,"ak":5105,"al":13877,"ai":16755,"aj":4377,"ao":99,"ap":6109,"šķi":792,"am":7193,"an":13591,"ac":1971,"ad":7331,"aa":123,"šķu":61,"ab":3333,"ag":2079,"ah":438,"ae":799,"af":317,"nu":3766,"nt":6816,"ns":6634,"ič":143,"nr":301,"hī":43,"np":87,"no":13676,"nn":366,"nz":252,"ny":68,"iē":45,"nv":1299,"oe":196,"jā":6443,"of":937,"Dān":37,"oc":1480,"od":5344,"oa":231,"ob":1666,"Dār":22,"om":4560,"on":9439,"ok":3012,"ol":6437,"oi":175,"gš":291,"iģ":203,"oj":3579,"og":1772,"oh":231,"Iga":176,"ot":8233,"m²":53,"gū":417,"os":7017,"ov":1717,"ou":258,"op":3592,"oo":225,"or":8642,"iķ":475,"r ":23056,"ox":43,"jē":253,"ow":104,"oz":1358,"oy":26,"pd":241,"pe":2624,"kā":9200,"pg":761,"gž":90,"pa":12196,"pb":92,"iļ":351,"pc":59,"pl":2446,"iņ":2232,"pm":337,"pn":123,"po":2922,"ph":171,"pi":8931,"pj":212,"pk":534,"lo":5141,"ln":1238,"eņ":1120,"lm":668,"ll":864,"ls":6050,"dū":151,"lr":53,"fī":68,"lp":774,"lv":2188,"lu":3183,"lt":2348,"lz":417,"ly":68,"gē":101,"o ":13523,"md":123,"ma":11255,"mb":1027,"dž":490,"mg":152,"me":8257,"mf":62,"hā":197,"mk":81,"ml":84,"mi":7529,"eš":2372,"mj":254,"mn":294,"mm":568,"mp":1937,"mo":3385,"mt":1499,"ms":4163,"mv":67,"Iek":27,"mu":4579,"hē":85,"mz":26,"Ied":23,"Ier":30,"p ":1187,"Ies":23,"na":11100,"nb":173,"nc":1308,"gļ":378,"nd":3610,"ne":6367,"nf":496,"iā":1355,"ež":1461,"ng":2033,"nh":159,"ni":10637,"nj":103,"nk":1409,"nl":178,"nm":119,"jv":54,"jt":24,"ju":6450,"jr":40,"eč":136,"bū":646,"js":1745,"jp":49,"dī":2457,"jn":108,"jo":2718,"jl":29,"jk":33,"ki":2861,"eģ":460,"kh":87,"kg":105,"fā":86,"ke":1430,"kd":52,"kc":519,"kb":27,"ka":21595,"m ":14604,"fē":229,"ky":24,"cū":51,"ks":6047,"kt":4783,"ku":9917,"kv":498,"ko":8251,"kp":53,"eī":44,"kr":3493,"kk":49,"kl":2204,"dņ":25,"km":1006,"kn":291,"li":12111,"lh":104,"lk":789,"lj":234,"le":5914,"ld":1879,"lg":521,"lf":344,"gā":2261,"la":14259,"eļ":2084,"lc":198,"lb":519,"n ":12333,"eķ":397,"hr":242,"hs":176,"bī":818,"ht":159,"hu":177,"hi":1019,"hn":345,"ho":773,"hl":97,"aņ":799,"hm":55,"id":6988,"ic":1972,"ib":840,"ia":987,"ih":374,"ig":1651,"if":662,"dā":3118,"ie":43851,"hy":49,"cē":786,"k ":3032,"cī":1751,"iq":24,"ir":20819,"is":22114,"it":6916,"iu":210,"iv":1914,"dē":1715,"ix":47,"ii":76,"aš":1551,"ij":18002,"ik":8262,"il":7272,"im":5227,"in":12037,"io":3152,"ip":1361,"je":2277,"jd":65,"až":1131,"eā":550,"ji":2430,"iz":8191,"l ":908,"ja":18785,"xi":24,"pš":285,"rģ":265,"pū":149,"rī":5569,"xt":23,"rē":1505,"ww":72,"z ":3167,"ož":188,"sā":1658,"nž":71,"wi":65,"oš":2487,"šīs":96,"šīr":28,"wo":40,"šīn":152,"ws":45,"vv":135,"vz":34,"y ":470,"wa":100,"pļ":34,"rā":7122,"we":66,"vl":36,"vm":57,"oņ":431,"vj":161,"vk":55,"vi":15879,"nš":154,"vg":67,"vu":1511,"vr":110,"vs":665,"nū":52,"vp":135,"pī":487,"vn":277,"vo":2198,"šīb":168,"uz":3239,"ux":47,"pē":3898,"uv":1138,"uu":163,"ve":6316,"vd":128,"vc":24,"oļ":231,"va":13478,"oķ":34,"x ":250,"oģ":891,"ui":330,"mš":154,"uj":549,"uk":2577,"ul":3970,"ue":159,"pā":3136,"uf":42,"ug":2904,"lž":37,"uh":49,"oī":103,"ur":8826,"mū":945,"us":8406,"ut":3554,"um":10369,"un":12883,"uo":66,"up":1299,"ty":109,"tz":181,"tu":9581,"tt":1263,"tw":38,"tv":2682,"ub":1129,"ua":219,"ud":1801,"uc":777,"w ":104,"to":9558,"tn":1900,"tm":416,"tl":676,"lū":587,"ts":7290,"tr":9995,"oč":89,"nī":2204,"tp":327,"tg":235,"tf":75,"te":8645,"td":205,"tk":771,"tj":107,"ti":16287,"lš":164,"th":431,"v ":977,"šī ":103,"tb":1541,"tc":58,"ta":17648,"su":2355,"sv":864,"ss":1501,"kū":96,"st":22568,"sy":29,"sz":152,"sw":23,"nē":1546,"sl":2038,"sk":10907,"sn":958,"sm":2964,"sp":4072,"so":1970,"sr":95,"nč":276,"mī":785,"sd":451,"sc":379,"sf":321,"nā":8240,"se":3495,"sh":197,"sg":86,"sj":78,"si":5921,"kš":1455,"rz":732,"u ":34678,"sa":11922,"sb":260,"rr":239,"rs":5613,"jū":1021,"rt":4290,"ru":7404,"rv":1310,"Cēs":56,"mē":2975,"ry":160,"lī":4107,"rp":1821,"ro":10142,"rn":1729,"kņ":114,"rm":3278,"rl":568,"rk":1664,"rj":126,"jš":27,"ri":15479,"rh":439,"rg":2074,"iž":275,"mā":4269,"rf":127,"re":6968,"rd":2322,"rc":590,"kļ":994,"rb":2090,"ra":18562,"t ":6209,"lē":2235,"qu":266,"kī":37,"iš":513,"lā":5128,"s ":99264,"kē":55,"pz":438,"pt":1346,"pu":3008,"pv":476,"pp":139,"jī":54,"pr":4678,"ps":1123,"zī":3820,"zā":1002,"IX ":48,"šģi":28,"zē":1137,"už":113,"uš":785,"IV ":42,"tš":221,"uļ":295,"uņ":333,"vī":926,"tū":1454,"vā":2847,"tļ":184,"uģ":166,"rž":79,"zz":61,"sū":160,"Bīb":25,"vē":3474,"tņ":104,"uā":341,"Hor":54,"zg":379,"zi":7929,"rš":1224,"zb":206,"Hou":27,"zc":577,"zd":606,"ze":4296,"za":1506,"Hom":27,"Hon":23,"Hok":34,"Hol":58,"zv":1734,"uē":34,"rū":541,"zs":1624,"uč":23,"zr":375,"zu":648,"zt":460,"zo":976,"zn":964,"tī":5903,"zp":657,"zk":332,"zj":64,"zm":1200,"zl":791,"yg":24,"ye":62,"tā":11917,"rļ":24,"yc":58,"yd":22,"ya":64,"rķ":279,"sē":2104,"tē":2602,"yt":35,"ys":126,"yr":30,"sī":1152,"yp":31,"yo":86,"yn":43,"ym":26,"rņ":171,"yl":66,"yi":22,"Arg":44,"Arh":40,"Are":22,"Ard":29,"Ara":25,"Arm":42,"Ari":31,"Šīs":37,"Apv":89,"Apo":23,"Atk":35,"Atl":83,"Atr":91,"Ato":22,"Ast":53,"Ata":28,"Asi":33,"Aso":76,"Art":56,"Avo":25,"Aut":94,"Aus":451,"Aug":149,"Alū":46,"Arā":51,"šēj":249,"zš":91,"zū":24,"zņ":392,"Šķi":29,"Atš":29,"Bak":26,"Bal":501,"Ban":57,"Bab":25,"Baz":45,"Bar":119,"Bas":49,"Bau":40,"Abr":31,"Act":23,"Ada":38,"šā ":313,"Adr":25,"šād":125,"šāk":184,"šām":60,"šās":183,"šāv":22,"Afg":26,"Aiz":104,"Aka":34,"Ala":26,"Alb":79,"Ale":93,"Alf":40,"Alt":55,"All":36,"Alp":29,"Ame":197,"Ama":49,"Šī ":93,"Ang":135,"Ana":95,"And":123,"Ant":228,"Ann":55,"Ar ":101,"ОН ":57,"Bul":41,"Bur":79,"Blū":22,"Bru":49,"Brī":92,"² ":53,"Brā":30,"Cal":37,"Cam":27,"Car":39,"Cau":23,"Can":86,"Cap":22,"CH ":201,"Bez":37,"Ber":134,"Ben":73,"Bel":45,"Bie":67,"Biz":31,"Šād":55,"Bil":27,"Bir":42,"Bio":33,"Blo":34,"CP ":24,"CO ":32,"Bla":25,"Bre":53,"Bra":125,"Bro":55,"Bri":92,"Bol":40,"Bon":23,"Bor":50,"Bos":71,"Bov":25,"Der":41,"Des":26,"Dei":40,"Del":44,"Dem":45,"Den":34,"Deg":23,"Dan":52,"Dar":42,"Dat":63,"Dau":261,"Dab":33,"Chr":32,"Cit":38,"Cir":22,"Cil":47,"Cel":26,"Cen":195,"Cet":27,"Cer":41,"Cha":50,"Cor":106,"Com":69,"Col":30,"Con":48,"FA ":41,"ģip":59,"ģin":756,"ģio":352,"ģit":52,"ģis":449,"ģim":77,"ģij":982,"Dze":94,"Dzi":93,"ģi ":28,"ģer":123,"ģel":28,"ģeo":161,"ģen":236,"Edv":25,"Edu":28,"ģa ":65,"Dzī":27,"āg":215,"Daž":59,"āf":379,"āc":3184,"ād":3136,"āb":862,"āp":472,"ām":4331,"ān":2529,"āk":5743,"āl":5581,"āj":3661,"āv":1981,"āt":4781,"ās":7161,"ār":6698,"āz":697,"Dib":24,"Dis":48,"Din":26,"Āb":22,"Dig":22,"Ād":23,"Āg":35,"Āf":113,"Die":362,"Āz":143,"Ār":50,"Div":37,"ā ":23455,"Dub":30,"ür":23,"ая ":29,"ģu ":60,"СН ":64,"Dra":31,"Dob":31,"ES ":40,"Don":29,"Dom":61,"OH ":75,"Nea":33,"ēģ":190,"Nei":26,"Net":40,"Ner":49,"Nep":30,"Neo":28,"Ēģ":41,"Nat":30,"−":111,"īdi":166,"īdr":32,"īds":186,"īdu":170,"īda":185,"īde":154,"Nin":27,"Nik":51,"ēž":23,"īci":383,"ūšu":22,"īca":276,"ūša":102,"īce":148,"ībn":58,"ēš":773,"ībi":22,"ību":1222,"ībv":37,"īd ":59,"ībe":36,"ība":3544,"ēļ":376,"New":31,"ēķ":56,"ēņ":27,"īcā":40,"ībā":960,"īgi":496,"īga":1676,"īgu":405,"īgo":298,"īgs":407,"īdz":1603,"īla":22,"Nam":26,"īgā":813,"īle":67,"īli":124,"Nac":121,"īka":42,"īkl":241,"īko":106,"īks":151,"īja":305,"ģu":81,"īji":84,"īju":700,"īdī":105,"īm ":246,"ģi":2798,"ģe":601,"ģa":66,"īdā":112,"īcī":70,"Ģe":106,"āļ":238,"āņ":597,"āč":113,"Či":48,"Če":124,"Ča":35,"Ču":25,"či":150,"če":516,"Īri":58,"ča":247,"āš":567,"āž":93,"No ":69,"ē ":2668,"Īsl":26,"čo":33,"čs":42,"ču":562,"ēz":349,"ēt":4896,"ēs":1279,"ēv":258,"čū":27,"Čī":26,"OS ":28,"ēm":2242,"ēn":867,"ēk":1496,"ēl":2212,"ēr":3544,"ēp":82,"Nov":61,"ēc":1136,"ēd":833,"Nor":163,"ēj":4209,"ēg":174,"Nos":50,"Not":22,"ēb":25,"Nok":22,"Ēr":64,"Nob":33,"ķe":541,"ķa":229,"ķu":510,"ķs":30,"ķo":78,"Odi":27,"ķi":1644,"ļ ":195,"Ogr":36,"Jān":51,"ļa":2291,"ļi":696,"ļk":39,"ļj":32,"ļe":71,"ļd":32,"ķā":31,"Ķī":170,"ļr":180,"ļs":48,"ļl":36,"ļo":646,"ķē":171,"ļu":2107,"ļv":154,"Ļe":28,"Oke":30,"ķī":541,"ļķ":37,"ļī":23,"ļģ":54,"ļē":91,"PA ":36,"ļā":656,"ļš":133,"ļū":169,"ļļ":89,"ļņ":176,"ņv":39,"ņi":716,"ņk":42,"ņj":25,"ņo":260,"ņn":28,"ņu":2226,"ņs":60,"ņr":139,"Ņu":43,"ņa":1766,"ņb":29,"ņd":47,"ņe":432,"Otr":101,"Ovi":22,"ī ":3304,"ģē":120,"ģī":39,"Jēk":140,"Īs":48,"Īr":60,"īb":5893,"Jēz":37,"īc":960,"īd":2819,"īj":1202,"īg":4125,"īl":317,"īk":663,"īn":1786,"īm":2002,"īp":453,"īr":757,"īt":3369,"īs":1871,"īv":3050,"īz":500,"ģīt":31,"Oli":250,"ı ":35,"Jāņ":29,"īģ":38,"īč":97,"īņ":368,"PS ":25,"īļ":122,"īš":592,"Ope":52,"Org":41,"Ost":30," −":67,"Osk":35,"Osm":120,"Ķe":55,"š ":1382,"Ple":55,"Pla":145,"Pil":83,"Paš":73,"Pit":22,"Pir":196,"QL ":27,"Pie":153,"Pha":28,"ģēt":22,"ģēr":24,"Kār":70,"ģēl":37,"šī":572,"šģ":28,"Per":109,"šļ":41,"Pet":30,"Pen":59,"Pek":25,"Pel":45,"šķ":1261,"Šī":134,"Kā ":42,"šā":893,"šē":273,"Šķ":45,"Šā":65,"Paz":31,"Pat":54,"Pas":386,"Par":468,"Pav":27,"Pau":41,"Pad":103,"Pan":44,"Pap":26,"Pal":61,"Pak":46,"šg":29,"še":180,"šd":202,"ša":5315,"šo":571,"šp":217,"šm":110,"šn":89,"šk":157,"šl":112,"ši":1623,"šv":170,"šu":2014,"št":354,"šs":357,"šr":148,"šz":36,"Še":104,"Ša":199,"Šo":132,"Ši":163,"Št":29,"Šv":81,"ņš":324,"Ņū":40,"ņģ":77,"Prū":54,"ņē":348,"ņķ":245,"ņā":297,"Prā":22,"Pro":228,"Pri":121,"Pre":78,"Pra":58,"Pol":274,"Pos":25,"Pop":24,"Por":59,"žr":80,"žs":96,"žu":691,"žn":24,"žo":773,"že":338,"ža":902,"žk":75,"žm":27,"ži":613,"Ža":46,"Ži":23,"Že":35,"RS ":104," ال":23,"ž ":41,"žū":26,"žņ":118,"žī":67,"žģ":48,"žā":790,"SA ":43,"Rad":110,"Rai":35,"Rag":24,"Rak":35,"ū ":140,"šņ":106,"Ūd":31,"šž":26,"šū":152,"ūg":56,"ūd":971,"ūc":206,"ūz":629,"ūs":815,"ūt":957,"ūv":256,"ūp":130,"ūr":2415,"ūk":417,"ūl":106,"ūm":112,"ūn":373,"ūš":146,"ūž":54,"Isl":22,"Irā":62,"Iva":31,"Izv":72,"Izr":29,"Itā":112,"Jac":27,"Jav":26,"Jau":217,"Jap":129,"Jan":40,"Jam":45,"Jag":28,"Ja ":27,"Jel":80,"Jer":41,"Jor":27,"Jon":25,"ア":23,"Joh":102,"KS ":29,"Jug":32,"Jup":83,"Jur":42,"Jum":22,"Kad":24,"Kab":22,"Kai":30,"Kam":79,"Kal":190,"Kap":52,"Kan":182,"Kau":72,"Kat":99,"Kas":57,"Kar":357,"Kaz":79,"Ker":28,"Ken":34,"Kem":29,"Kei":25,"Kir":46,"Kin":77,"Kij":27,"Kli":34,"Kle":26,"Kla":44,"Klu":132,"Kon":195,"Kom":112,"Kol":59,"Kos":58,"Kor":100,"Kop":106,"Kod":29,"Kok":40,"Kre":35,"Kra":70,"Kri":714,"Kro":35,"Kru":113,"Krā":28,"Kul":67,"Kur":259,"Kva":27,"Let":23,"Leo":37,"Lej":26,"Led":38,"Lau":64,"Lak":51,"Lai":103,"Lag":34,"Lat":1556,"Lar":29,"Lap":25,"Lam":24,"Lan":56,"Lab":56,"ML ":46,"Lib":28,"Lie":695,"Lim":30,"Lin":97,"Lit":29,"Liv":157,"Lut":24,"Luk":24,"Lud":28,"Lug":27,"Lor":22,"Lon":64,"Lok":22,"ūs ":24,"ūpn":62,"ūra":1491,"ūt ":294,"ūsd":328,"ūnā":49,"ūrs":28,"ūru":316,"ūrv":45,"ūrm":32,"ūrn":45,"ūrg":22,"ūri":123,"ūks":153,"ūku":78,"ūka":36,"ūko":44,"ūma":25,"ūli":71,"ūmu":36,"ūna":154,"ūns":22,"ūnu":55,"ūni":45,"Mek":48,"Mei":30,"Men":40,"Mel":144,"Mer":74,"Met":75,"ūtā":37,"Med":58,"Mez":22,"ūzi":561,"Džo":145,"ūzu":22,"ūtī":135,"Džu":25,"Dže":88,"ūsi":58,"ūsm":68,"ūsu":37,"ūst":237,"ūta":126,"ūte":28,"Man":129,"Mal":86,"ūti":73,"Mam":22,"Mar":393,"ūto":32,"Mas":145,"ūtn":56,"Mag":45,"ūts":52,"Mad":99,"Mak":70,"Mai":65,"ūtu":111,"Mac":23,"īzā":35,"īzē":29,"ūvi":42,"Maz":108,"Mat":72,"ūve":114,"ūrā":242,"īvā":296,"ītī":76,"īzi":177,"īze":130,"ītē":23,"Mod":95,"Mol":50,"Mon":122,"Mos":23,"Mor":85,"Mot":31,"Moz":28,"NS ":43,"īvī":139,"Mež":62,"īvē":41,"Mih":26,"Mik":53,"Mie":24,"īrā":42,"Mic":50,"īvn":200,"īvm":36,"īvp":28,"īvo":1046,"īvu":146,"Mir":23,"īvs":154,"Mil":64,"Min":133,"īva":467,"īve":148,"īvi":298,"ūvē":84,"ītā":552,"NO ":49,"īz ":81,"īsā":29,"īlī":22,"īrs":118,"īru":139,"īri":268,"īsa":30,"īnā":148,"īmē":659,"Mur":22,"Mus":124,"īra":120,"īt ":399,"ītu":205,"īnī":56,"ītr":41,"īts":565,"ītn":23,"īto":115,"īti":392,"īst":852,"īss":36,"īmī":130,"īsl":28,"īsk":119,"īsi":181,"īkš":28,"īte":151,"īta":808,"īne":41,"īni":507,"īno":33,"īns":285,"īnu":169,"īme":446,"īmi":343,"īmj":45,"īmo":31,"īmu":34,"īms":40,"īna":462,"īkā":26,"īs ":468,"ījā":106,"īpa":426,"Sāk":57,"Rēz":54,"XX ":24,"кий":32,"Wor":39,"Wil":32,"Win":29,"War":28,"Vul":29,"Vor":36,"Vol":134,"Viņ":206,"Viļ":33,"Vis":230,"Vit":48,"Vla":36,"ču ":517,"Zaļ":27,"Zie":391,"Zin":62,"Zil":29,"Zel":41,"Zem":525,"之":22,"Tēr":50,"三":24,"на ":32,"Tā ":634,"Tāl":53,"Tās":150,"Sēr":28,"Sēl":24,"Rīg":820,"Svē":102,"Sys":26,"Sve":45,"Spē":56,"Sul":33,"Spā":87,"Str":115,"Stu":53,"Sti":60,"Sto":87,"Sta":349,"Ste":80,"Teh":22,"Tec":22,"Tem":25,"Teo":25,"Tei":33,"Tel":43,"Tam":51,"Tan":40,"Tas":583,"Tar":26,"Tau":65,"Tai":63,"Taj":81,"Tak":27,"Tal":71,"Sko":119,"Sku":25,"Ska":110,"Sim":41,"Sil":58,"Sig":27,"Sir":32,"Sin":63,"Sid":28,"Sie":22,"Sib":28,"Nāc":29,"Ser":100,"Sen":122,"Sel":26,"Sem":34,"Sek":22,"TV ":22,"Spa":42,"TS ":22,"Spi":27,"Spe":35,"Spo":27,"Soc":53,"Sol":25,"Som":114,"Son":25,"Slo":56,"Smi":29,"TP ":38,"Mēr":47,"Mēn":64,"Jūr":108,"Jūl":32,"SV ":351,"Run":31,"Rum":56,"Rub":29,"Sai":29,"Sah":30,"Sak":57,"Sam":35,"Sal":189,"Sac":23,"Sab":29,"Sae":27,"Sad":27,"Sco":41,"Sci":36,"Sch":39,"Sav":262,"Sat":49,"Sau":200,"Sar":143,"Sas":60,"San":93,"ови":22,"Mār":46,"Māk":28,"SI ":51,"Res":30,"Rie":159,"Rau":22,"Rec":23,"Red":33,"Rei":58,"Ren":27,"Rep":321,"Rob":99,"Rod":49,"SR ":106,"Ros":76,"Ron":23,"Rom":176,"SS ":24,"Līg":32,"Līd":101,"čūs":27,"Reģ":30,"SO ":60,"Pēc":116,"Pēt":62,"Vai":65,"Vel":97,"Ven":119,"Vei":37,"Vec":107,"ски":39,"ска":25,"ско":22,"Vas":82,"Van":50,"Val":406,"Var":89,"Vaš":22,"Vid":291,"Vie":179,"Vir":65,"Vil":141,"Vik":70,"Vin":38,"Ver":44,"Ves":70,"Ukr":55,"Ung":47,"Uni":125,"Urs":73,"Mūz":68,"Mūs":71,"Ērg":30,"Uz ":28,"Čīl":23,"ēcī":76,"ēdā":27,"Trī":27,"ēj ":73,"ēgu":33,"ēgt":73,"ēkl":37,"ēko":23,"ēki":215,"ēku":376,"ēkt":35,"ēks":180,"ēm ":819,"ēka":504,"ēji":561,"ēju":643,"ējs":400,"ējr":35,"ējp":24,"ējo":477,"ēl ":109,"ēdē":151,"ējd":44,"ēja":1223,"ēmu":365,"ēma":558,"ēmi":221,"ēli":303,"ēlo":171,"ēln":72,"ēls":126,"ēlu":113,"ēla":172,"ēle":379,"ēc ":930,"ēci":41,"ēdu":26,"ēdz":296,"Pāv":29,"Pār":113,"ēda":98,"VI ":40,"ēde":49,"ēdi":142,"Ter":125,"Tet":23,"ēvs":32,"ērē":61,"ērā":124,"ērķ":215,"ēsē":144,"The":138,"ērī":91,"ēsā":29,"ēze":148,"Tib":26,"Tie":134,"ēsī":28,"Tim":41,"ētā":792,"Tir":25,"ēzi":135,"ērš":71,"ētī":178,"ēzu":41,"ēvē":143,"To ":233,"ēne":214,"ēni":174,"ēna":102,"ēns":137,"ēnu":91,"Top":34,"ējā":633,"Tor":80,"Tom":55,"Tos":31,"ēkā":56,"ēr ":112,"ējī":33,"ēpo":30,"ēlā":185,"ēs ":404,"ēt ":252,"ēlē":492,"Nīd":49,"ēra":721,"ērb":56,"ērd":31,"ēre":37,"ēmā":142,"ēri":669,"ērk":23,"Tro":39,"ērn":117,"ērp":23,"ēro":293,"ēlī":53,"ērt":389,"Tri":83,"ērs":217,"ērv":101,"ēru":97,"ēmē":83,"Tre":69,"ērz":31,"Tra":108,"ēnā":38,"ēkš":30,"ēsl":23,"ēsu":45,"ēst":566,"ēnē":31,"ēte":130,"ēta":1832,"ētn":71,"ēto":79,"ēti":598,"ētk":66,"ētu":414,"ētr":34,"ēts":396,"Tur":208,"Tuv":48,"Tuk":33,"Tul":26,"šdz":152,"šde":24,"ši ":834,"šel":77,"ša ":338,"šas":321,"šau":228,"šah":27,"šai":236,"šaj":205,"šam":126,"šan":3757,"ēģi":168,"Šve":65,"šte":79,"šta":234,"šst":29,"šum":55,"šus":57,"švi":22,"šve":23,"šva":72,"špa":34,"škā":87,"špi":125,"šos":132,"šot":31,"Ēģi":41,"špu":29,"šs ":266,"šre":66,"šru":52,"šsa":28,"šu ":1883,"šla":74,"šme":77,"вич":26,"šo ":346,"šni":32,"šno":38,"šie":334,"šif":27,"šin":270,"šim":31,"šis":80,"ēļa":42,"ēļ ":153,"ēķi":49,"švā":48,"šze":25,"ēļu":170,"bju":45,"bje":249,"biz":35,"bis":145,"bit":116,"bio":155,"bir":59,"bik":26,"bil":410,"bin":496,"bij":2367,"bo ":36,"blo":48,"ble":47,"bli":610,"bla":73,"bku":154,"bok":22,"bol":1514,"boj":283,"bni":61,"bež":545,"bs ":212,"biļ":23,"bpi":124,"biņ":28,"bon":217,"bor":108,"bot":84,"bos":35,"bov":23,"be ":419,"bam":32,"ban":81,"bak":69,"bal":1602,"bai":173,"baj":47,"bag":46,"bac":26,"bad":23,"baz":174,"bau":36,"bat":100,"bas":2875,"bar":192,"azī":447,"bi ":165,"bei":323,"bed":22,"ber":482,"ben":195,"bel":118,"bek":85,"bez":361,"bes":245,"bet":713,"bib":56,"bie":860,"brū":72,"− ":42,"buļ":79,"−C":44,"ca ":396,"car":55,"cas":201,"cat":29,"cau":337,"can":76,"cab":38,"cam":74,"cal":52,"ce ":431,"cba":35,"blē":52,"bri":385,"bro":61,"bra":298,"bre":171,"bu ":1529,"blī":48,"bru":342,"bsk":33,"bso":54,"bse":25,"bst":77,"bur":350,"bul":250,"bun":25,"bum":299,"bud":74,"but":64,"bus":88,"boļ":39,"bva":41,"brā":110,"brī":410,"aka":880,"am ":2221,"ake":96,"akc":136,"aki":53,"aji":783,"ajo":724,"ajs":38,"adī":860,"aju":73,"adē":277,"aiz":832,"al ":300,"aja":469,"aje":41,"aij":61,"aik":1200,"ail":137,"aim":532,"ain":809,"aip":45,"acī":139,"air":752,"ais":4315,"ait":1125,"aiv":51,"aig":508,"adā":819,"aie":25,"aid":426,"aic":101,"aib":25,"ahi":35,"ahs":67,"aht":36,"abī":81,"ahr":22,"abē":108,"aha":93,"agl":88,"abā":487,"agi":39,"agr":218,"ags":92,"agu":84,"agn":169,"ago":152,"ajā":2224,"anv":34,"anu":718,"anz":65,"ano":394,"ann":140,"ant":1775,"ans":674,"anr":123,"ane":123,"ang":611,"anh":30,"ani":1185,"anj":22,"ank":275,"anl":23,"ap ":332,"ana":3035,"anc":401,"and":1589,"amu":130,"amm":408,"amo":175,"amp":185,"ams":603,"ami":532,"ahā":45,"adž":91,"ame":775,"amb":217,"ama":1351,"ao ":25,"alv":1226,"alu":519,"alt":791,"als":1977,"alp":208,"alo":1383,"aln":628,"alm":121,"all":272,"alk":231,"alg":97,"ali":1208,"alc":61,"ald":1013,"ale":584,"alf":96,"agā":163,"ala":1330,"alb":172,"Šaj":103,"an ":784,"aks":1610,"akr":121,"Šar":24,"aku":213,"akt":789,"ako":151,"akn":91,"akm":124,"akl":47,"aba":1096,"abe":95,"abi":630,"abl":44,"abo":176,"abp":131,"abr":109,"abs":116,"abv":34,"abu":136,"ae ":655,"aca":38,"aau":77,"ad ":480,"ac ":37,"afr":25,"aft":53,"afi":105,"ai ":5352,"aga":835,"age":107,"ael":27,"aei":29,"ah ":32,"afa":26,"ado":609,"adr":151,"adl":29,"adn":49,"adm":304,"adi":802,"ade":142,"adz":161,"ads":379,"adu":517,"ack":35,"aci":939,"ach":47,"ace":507,"ada":1586,"act":88,"acu":34,"azn":207,"azm":31,"azo":137,"azi":230,"arš":263,"azu":55,"atī":1487,"azs":68,"atē":140,"aze":46,"aza":217,"azd":25,"atņ":23,"avē":54,"avā":267,"arž":51,"arī":2864,"arē":195,"az ":62,"asā":83,"asī":143,"asē":82,"Šob":33,"atā":330,"aye":23,"auž":79,"ba ":1526,"azā":276,"atū":468,"auņ":57,"avī":79,"atš":186,"auš":105,"at ":261,"alē":137,"arh":312,"aiž":27,"arg":217,"amā":271,"are":686,"ard":512,"arc":143,"akļ":72,"arb":1417,"ara":2574,"arp":1342,"aro":671,"arn":121,"arm":206,"arl":146,"ark":821,"arj":66,"ari":685,"aru":580,"Šie":27,"arv":25,"amē":73,"alī":910,"arr":34,"ars":430,"art":883,"au ":159,"asa":1301,"ary":36,"anā":994,"asf":22,"akš":415,"asi":550,"ash":28,"asc":35,"ase":553,"aso":90,"asn":297,"amī":170,"asp":375,"ask":709,"asm":50,"asl":59,"ar ":6199,"apb":88,"apa":727,"Šep":43,"akā":218,"ape":72,"apd":220,"aiļ":41,"apj":56,"api":222,"aph":30,"apg":734,"aiņ":241,"apm":273,"Šei":27,"apl":157,"apk":491,"apo":44,"app":36,"apr":520,"aps":483,"apt":349,"apu":118,"apv":358,"apz":415,"as ":38125,"alā":492,"aiš":99,"ava":1146,"ax ":25,"auz":73,"auv":33,"aut":1629,"avs":157,"apī":65,"avr":23,"avo":299,"avp":76,"anš":45,"avi":843,"ave":232,"ay ":49,"Šo ":72,"avv":82,"avu":357,"arā":580,"av ":331,"atb":314,"ata":845,"asu":217,"ast":3489,"ass":194,"anč":183,"anē":182,"asv":32,"atm":195,"atn":153,"atk":493,"atl":205,"anī":82,"atr":1790,"ato":1405,"atp":124,"ate":661,"atf":33,"Šis":89,"atc":32,"atd":107,"ati":895,"atj":54,"atg":171,"ath":38,"auc":511,"att":979,"ats":614,"alū":32,"atv":2153,"atu":973,"atz":132,"aul":1187,"aum":53,"aun":922,"aup":26,"aur":568,"aus":1232,"aud":1114,"apā":234,"aug":1739,"auj":444,"auk":1608,"Vēs":43,"Vēr":24,"ος":59,"ος ":59,"ς ":97,"ν ":22,"Zvi":157,"Zva":55,"α ":62,"Vār":66,"Vāc":268,"ēša":752,"Н ":147,"ий ":35,"ич ":26,"jeb":1453,"jer":106,"jek":399,"jel":23,"jen":64,"jet":57,"jev":88,"eān":337,"eāl":99,"eāt":94,"ji ":637,"aža":89,"aži":139,"ažk":37,"ažo":204,"ažr":77,"ažu":75,"ļģi":26,"jad":67,"izē":509,"jas":8640,"jau":557,"jap":53,"jar":34,"jak":65,"jan":85,"jam":931,"dēš":109,"jai":593,"izņ":119,"izš":65,"jda":46,"jni":88,"jol":22,"jon":751,"jom":89,"jot":574,"jos":350,"jor":71,"js ":1627,"dīb":475,"dīc":65,"jiņ":29,"jpu":34,"ск":94," zī":183,"jis":272,"jie":1464,"то":24,"ст":46,"jko":24,"jo ":387,"ažā":482,"itm":69,"itl":241,"itr":232,"inī":182,"itp":32,"ito":983,"itu":694,"itt":30,"its":171,"ity":36,"imš":47,"isk":6070,"ism":951,"isl":163,"iso":147,"isn":115,"imī":127,"isp":195,"iss":145,"inč":41,"isu":253,"ist":3658,"isv":78,"inē":330,"ita":561,"ite":695,"ith":30,"iti":844,"ilš":47,"inū":22,"ivs":26,"ivr":48,"ipī":32,"ivp":30,"ivo":171,"ivv":36,"ivu":117,"irā":703,"inž":48,"ius":102,"iur":38,"ium":46,"ipē":33,"iva":204,"ivd":29,"dē ":186,"ix ":38,"ivi":487,"inš":34,"ivj":45,"ivk":27,"ive":291,"ipr":208,"ipo":63,"ipu":70,"ips":96,"ipt":115,"ipi":127,"igž":89,"ipl":132,"cīb":793,"cīg":288,"ilā":148,"is ":8439,"ion":1944,"iop":23,"ašī":283,"ior":31,"igū":45,"ios":84,"iot":138,"ijā":2772,"iog":37,"iok":51,"iol":177,"iom":40,"ipa":229,"ikā":1450,"ipe":167,"iov":23,"ir ":14672,"imē":165,"iru":216,"irs":599,"irt":236,"ilī":94,"irr":24,"iro":905,"irm":929,"irn":124,"irk":171,"iri":558,"isi":459,"ikš":84,"ish":36,"inā":3097,"ise":117,"isc":158,"isb":151,"isa":605,"irz":314,"cīt":112,"cīn":190,"cīj":23,"cīk":97,"imā":119,"ire":99,"irg":402,"irb":90,"ira":259,"ird":185,"irc":39,"it ":228,"ilē":113,"cīz":63,"itū":160,"ivī":107,"izā":483,"dēļ":202,"ja ":7647,"itā":1332,"irī":150,"dēs":22,"dēt":124,"dēv":144,"dēj":602,"dēn":29,"dēm":188,"cīņ":106,"dēl":80,"isā":208,"irē":31,"iz ":254,"ivā":236,"itļ":164,"izz":43,"izu":55,"izv":798,"itī":222,"izr":274,"izs":752,"izt":200,"izp":558,"izo":166,"izn":131,"izm":1077,"izl":692,"izk":139,"izj":45,"irš":41,"izi":513,"izg":245,"ize":159,"izd":376,"izc":301,"izb":41,"iza":170,"itē":104,"isī":84,"eģi":394,"kij":77,"kil":129,"kia":33,"kie":620,"eģe":52,"kin":233,"ļās":38,"kip":24,"kir":36,"kis":66,"ļām":48,"keā":336,"km ":504,"kga":63,"ki ":1566,"kgr":28,"kaļ":69,"kaķ":31,"kho":57,"kaņ":374,"kej":204,"kel":71,"ken":50,"kes":27,"ker":86,"ket":457,"ļā ":507,"fāt":30,"ke ":111,"kci":508,"kdi":30,"kra":920,"kre":163,"klē":111,"kt ":222,"eīn":30,"klā":396,"ksa":250,"kse":83,"kmē":88,"ku ":2253,"kro":296,"klī":65,"kru":265,"kri":985,"koz":38,"kov":64,"kot":513,"km²":49,"kos":513,"kor":259,"kop":1110,"koo":61,"kon":1216,"kom":1199,"kol":578,"kok":286,"koj":143,"koh":29,"kog":34,"koe":27,"kod":306,"ks ":1859,"kme":260,"kne":183,"klu":183,"kls":75,"ko ":1627,"kle":136,"kla":494,"klo":153,"kli":573,"ļēj":87,"dīš":155,"još":397,"jus":320,"jum":2601,"jur":89,"jvi":27,"jsi":45,"būv":217,"būs":22,"būt":380,"eču":47,"ju ":3050,"dīg":518,"dīj":452,"dīn":38,"dīt":668,"dīz":28,"jra":36,"eče":56,"kaz":48,"kav":162,"kat":1010,"kau":385,"kar":1806,"kas":6913,"kap":301,"kan":621,"kal":1136,"kam":395,"kaj":1054,"kak":37,"kai":2823,"kad":430,"kab":198,"ka ":3723,"juš":280," Ga":455," Bā":54," Ge":158," I ":103,"guļ":52," Fo":211," Fu":230," Fr":535,"ļš ":124," Fi":190," Fl":70," Ha":441,"aķu":37," He":345," Bē":72,"aķi":22,"guš":31," J ":40," Go":172,"aķe":127," Gr":516," Gu":162," Gv":31," Gi":68," Gl":86," Ig":193," Dā":72," Ie":156," Id":25," Ib":23," K ":22," Cē":86," Hu":54," Bī":48," Ho":304,"ha ":116," Hi":232," Je":179," Ja":604," Iz":255," Iv":35," Dē":23," Ir":159," Is":56," It":130," Im":77," In":594," Ik":26," Il":59,"ham":85," M ":45,"han":159,"hai":42," Ka":1303,"hal":100," Ke":174,"hau":35," Ki":234,"har":152,"has":51,"hat":24,"aļ ":30," Jo":237," Ju":233,"hae":23," N ":55," La":2100," Le":272," Gā":24," Li":1175," Kl":266," Ko":784," Kr":1044," Kv":49," Ku":433," Ma":1344," O ":55,"aļu":335," Mi":483,"aļv":40," Dž":308," Me":654," Hā":28,"he ":281," Lo":254,"aļa":796," Ly":24," Lu":187,"aļi":184," Ne":334," P ":63,"а ":100," Na":328," Ni":163,"cā ":43," Mo":496," My":39," Mu":257," Hē":35,"hek":42,"hel":84,"hei":58," A ":102,"С ":41,"het":54,"her":196,"heo":49,"hen":64,"hem":51,"cāk":136,"cām":35,"hi ":25," B ":49,"cās":52," C ":203," Ap":260," Am":327," An":736," Ak":149," Al":533," Ai":198," Ag":50," Ah":36," Af":50," Ac":82," Ad":148,"aļā":556," Ab":144," Ba":1003,"aļē":89," D ":68," Az":34," Av":74," Au":758," At":403," As":243," Ar":519," Be":444,"hie":34,"hid":182,"hic":23,"hib":51," Bi":327,"hip":128,"hin":98," Bl":114,"him":44,"hil":44," Bo":338,"hij":70," Br":524," Bu":238,"his":79,"hit":143,"aļķ":22," E ":56," Ca":270," Ce":344," Ci":203," Ch":131," Cl":40," Cr":39," Co":292," Cu":37," F ":24," Da":629," Di":673," De":398," Dr":102," Do":202," Dz":227," Du":106,"hn ":22," Eb":22," Ed":95," El":193," Ek":92," Ei":676," Eg":26," Et":48," Es":44," Er":98,"hlo":75," Eq":185," En":121," Em":90," Ez":43," Ex":28," Eu":85," Ev":42," Fe":226,"aņa":180," Fa":110," H ":140,"aņd":30,"gma":49,"go ":413,"gme":45," Rī":858," Pū":23,"glu":49,"glo":94," Sā":102,"gls":48," Z ":22,"gle":241," Rē":60,"gli":344,"gla":305," Wo":56," Wi":95," We":44," Rā":30," Wa":65,"й ":60," Rū":43,"gog":33," Zu":31,"god":68," Zv":222," Zo":72,"aģē":26," Tī":49," Ze":604,"gno":38," Zi":551,"gni":35,"bāš":52," Za":124," Sī":40," Tē":78,"gna":34," Yo":26," Tā":889," Sē":77," Vī":58,"gs ":1150,"glā":76,"о ":42," Vē":121,"н ":27,"gol":71,"gon":119,"gos":60,"gor":256," Vā":354,"got":83,"gov":43,"gu ":870,"gnā":78," a ":72,"р ":25,"glī":122,"gro":67,"gru":596,"gra":755,"gt ":56,"gri":552,"gre":213,"aīs":153,"gtu":35," R ":37," Jē":211," Ov":27," Os":199,"gto":46," Ot":132," Or":178,"gts":50," Op":65," Po":516," Pl":245,"gum":401," Pi":541," Ph":55,"gul":224," Kā":157,"gua":28," Pe":329,"gub":86," Pa":1447,"gud":66,"gst":733,"gnē":109,"gsn":33," Nu":37," No":486," Ol":289," Ok":85," On":42," Oh":28," Og":53," Od":50," Jā":93," Of":27," Ob":41,"gta":111," Ra":371,"д ":27," Lē":28," Qu":23,"goš":45," Lī":215," Ro":565," Re":681,"grā":671," Ri":308," Rh":25," Mā":133," S ":101,"guv":148,"gur":196," Pr":570," Ps":28,"gus":188," Pu":147,"gun":194,"gvi":84," Lā":40,"gva":31,"bēr":112," Sy":39,"grī":79,"bēt":95," Sv":220," Su":203," St":793," Ta":1092," V ":48," Tj":24," Th":177," Ti":329," Te":399," Tr":346," Lū":27,"ļūt":29,"ļūs":33," Nī":78," To":521," Mē":139," Jū":171," Ru":196,"ļūd":92,"grē":114," Sa":1313," U ":30,"е ":61," Sh":52," Si":395," Sc":134," Se":442," Nā":75," So":290," Sp":307," Mī":29,"bēj":25," Sk":316," Sl":112," Sm":70,"bēm":82," Sn":22," Pē":221,"grū":45," Uz":96," Va":790," X ":41,"и ":54," Ve":526," Vi":1347," Vl":38," Pī":38," Vo":205," Vu":40," Tu":361," W ":26," Pā":146," Ug":37," Uk":57," Ul":29,"gzd":28," Un":191," Up":44," Ur":133,"gzn":376," Mū":173," ja":682,"cēš":42,"iak":26,"ь ":24,"iam":59,"ial":119," iz":4946,"ian":220,"ias":27," je":1511,"iat":108," im":336," in":1344," ik":136," il":190,"ic ":183," dē":302," iv":22," is":92," it":111," cī":105,"iag":25," ir":14600,"ibl":76," ka":7945,"ibi":285,"ibo":30," m ":158,"ibr":57," ki":241," fā":22,"ibu":58," ke":72,"iaz":26," jo":407," dī":55,"id ":25,"iba":66," bū":407,"ibe":125," ju":119," bē":90," ha":132," he":218," aģ":61," gl":287," gr":1494," go":110," gu":155,"ia ":270," gs":71," cē":148," id":175," dā":101," ie":4455," ig":94," hi":297," hl":48," ho":304," bī":86," hr":108," ht":33," hu":35,"iet":4005,"iev":1792," ni":63,"iez":227,"iel":3446,"iem":8120," ne":2383,"ien":7676,"iep":380," na":986,"ier":1197," p ":50,"ies":2658,"iee":100,"ied":2745,"ieg":992,"iek":4508," mu":445,"iej":39,"iea":35," mo":718,"iec":1164," mm":35,"ieb":72," ok":512," ol":76," on":40,"dāv":49," og":135,"ifo":180,"dām":160," of":307," jā":140,"dān":30,"ifs":22,"dās":334,"dāt":198,"dār":218,"ifr":46," ob":243,"dāf":28,"ife":75,"dāl":53,"dāj":251,"ifi":245," nu":108," no":9749," gā":212," le":458,"icr":40,"ics":32,"ict":31," li":2852,"icu":63," n ":74,"ico":88,"ick":37," eļ":37,"icl":22," la":3298," kv":261," ku":4521,"ici":543," cū":37,"ich":68,"ice":118,"ie ":1698," km":554,"ica":238," kl":531," kr":1914," ko":4523," me":1393,"idz":312," dž":28,"idu":626," mi":1711,"ids":336,"я ":56,"idr":632,"ido":1694,"idp":27,"idm":53," ma":1802,"idn":29," lu":115,"idi":317," lv":27,"ide":638,"idd":33,"ida":1167," lo":437,"dā ":1681," af":23," ag":155,"aša":197,"idā":226," ab":209," ac":105," ad":392," am":414," an":722,"aši":302," ap":4517,"ašn":47," ai":846," ak":503,"ašl":70," al":593," av":171,"ašs":53," au":2262,"ašr":63,"icī":260," ar":6236,"ašv":86," at":4655,"ašu":167," as":496," d ":35," ba":1482,"idē":338,"il ":50,"ija":12639," bi":2895,"ije":54," be":1390,"iji":165," bo":133," bl":146,"idī":348,"ijs":425," bu":382,"iju":1715," br":766," ca":410," e ":62,"im ":312,"ika":3320,"ige":58,"iga":284,"ii ":23,"igl":56,"igm":40,"igh":40,"igi":68,"igu":73,"igs":27,"igr":58,"igo":33,"ign":102,"ij ":163,"igz":407," b ":53,"iha":58,"ihi":54,"ihs":70," Zī":28,"iho":104,"ibī":64,"ik ":182,"icē":211," c ":63," er":23,"imo":88,"imn":195," et":118," es":227,"ims":83," en":251," em":85," ep":55,"imp":593,"idž":50,"imf":36," ei":45," el":849,"ime":522," ek":494," ef":77,"imi":811,"ieš":1802," fe":288,"ip ":24,"inc":281,"ind":539,"ina":1252," fa":282," ez":655,"imt":1282,"imu":237," ev":61," fu":829,"inn":34,"ino":729," fr":351,"ļļu":39,"inr":24,"int":1230," fo":740,"ins":796,"inf":318,"ašā":181,"ine":633," fl":69,"inh":61,"ing":589,"iež":570,"inj":23," fi":803,"dāš":37,"ini":1119,"ink":89," ge":43,"cī ":27," bā":233,"ioa":45," ga":5014,"iod":270,"ļļa":40,"inu":278,"inv":33," i ":44,"iko":225,"ikn":25," cm":50,"ikm":90,"ikl":215," co":68,"iki":144,"ikg":62," ce":962," ch":25,"ike":59,"ikd":24," ci":2295,"ila":297,"ilb":52," da":4272,"in ":197,"ieķ":378,"ikv":30," cu":46,"ikt":677,"iku":1045,"ikr":195,"iks":380," do":494,"ilp":256,"ilo":443,"ill":168," dr":234,"ilk":121,"iln":265,"ilm":237,"ieņ":198,"ilh":58,"ilg":175," de":1205,"ilj":175,"ili":579,"ild":409,"ilc":81,"ieļ":23,"igā":206," di":3087,"ile":125,"ima":242,"imb":308,"ч ":32," g ":36,"io ":204," eb":89," du":128,"ilz":47,"idū":60," dz":3456,"ils":2044,"ilt":346,"ilu":127,"ilv":752,"ль":27,"hs ":112,"bīg":65," sū":56,"bīd":30," vē":1059,"ми":22,"bīb":430,"ло":25," vā":1227," tī":340," zo":142,"ла":30," zu":23,"ле":23," rū":113,"ли":29," zv":544,"hok":186,"hol":226,"hom":35,"hon":30," za":193,"ко":45,"hos":37," ze":740,"hot":32," zi":2010,"hop":25,"hor":75,"ка":54," tē":247,"ки":52," sī":84,"hni":146," sē":228," tā":1796,"hno":151,"aņu":241," pū":63," rī":133,"aņe":35,"hme":29,"ин":34,"aņi":61," ww":36,"ий":38," sā":685,"ич":34,"aņo":46,"ри":31,"ро":53,"ра":42,"ре":36,"htt":39," zā":53,"hst":50,"ос":22,"ор":37,"ол":32,"aņģ":36,"ов":87,"hu ":43,"ое":22,"aņē":59,"нс":22,"но":31,"hro":158,"aņā":78,"ни":29,"hri":23," tū":103," vī":192,"ht ":30,"на":44,"bīr":30,"bīt":96,"bīs":120,"bīn":33,"cēt":118," ru":206," jū":849," mē":678," u ":116," sa":6813," nā":219," sf":46," se":1483," sc":42," si":1753," sh":33," sn":112," sm":289," sl":596," sk":1357," mī":111," sp":2239," so":351,"ве":29," qu":23,"ви":41," lē":170," t ":61,"во":24," ra":2342," kļ":152," re":2229," mā":826," ri":726,"cēn":32," kņ":49,"cēm":41,"cēl":179," ro":913,"cēj":228," lī":2107," pu":1266," pr":3156," ps":120," s ":86," lā":230,"ļņu":56,"ва":29," os":114," gū":38," ot":330,"ļņi":27,"hum":50," op":221,"ав":30," or":1147,"ан":46,"ļņa":76," jē":154,"ал":24," pe":651,"cē ":120," kā":2571," pa":8411,"ар":38," pc":24," pl":1389,"ая":29," po":1148," pi":5908," rā":73," x ":60," va":7044," ve":2127," pē":1285," uz":2903," vo":159," pī":83," vu":52," vi":7158,"ес":31,"ер":46,"ен":52," tv":38," tu":790," mū":750," ut":55," ur":52," up":232," un":10091," ug":66," pā":1765," ta":1745," st":3025," kū":39," sv":412," su":879," nī":29," tr":1203," lū":49," to":1082," th":155," ti":3365," te":2144,"aāt":29,"fi ":28,"fes":176,"fer":133,"feo":25,"fed":168,"ņi ":361,"feb":35,"fen":84,"fek":185,"fel":37," Ča":35,"ņin":63," Či":48,"ņie":244," Če":124,"fga":33,"faz":23,"fas":28,"ezī":69,"far":40,"fan":93,"fak":97,"fal":45,"fai":36,"ņbr":28,"fab":102,"ņem":387,"ņda":33,"fe ":34,"ņos":47,"ņot":124,"ņoj":49," Čī":26,"evē":231,"evī":174," ēz":45," ēt":31,"ņra":135,"fa ":173," Ēr":64,"ņs ":24," ēd":44," ēr":63," ēk":65,"esē":107,"esī":292,"erņ":62,"etā":683," Ču":25,"ez ":111,"erē":156,"erī":393," če":400,"ņji":23,"erģ":206," ča":23,"esā":195,"ezv":29,"ezu":188,"evā":40,"eza":38,"ezd":35,"etē":183,"ezm":33,"ezn":141,"ezo":141,"ezp":31,"etī":89,"erū":27,"ezt":29,"eze":817,"ezg":53,"erš":24,"ezi":201,"ezk":125,"etb":351,"eta":734,"ete":624,"eti":845,"elš":89,"eth":26,"etn":170,"etl":29,"esp":338,"emī":84,"esn":43,"eso":286,"est":937,"ņoš":22,"esu":212,"enč":28,"esr":33,"ess":340,"enē":213,"esv":35,"ev ":24,"epā":130,"emš":50,"eto":1378,"enī":969,"etr":698,"ets":222,"ett":58,"etu":1584,"etv":168,"ew ":38,"eve":83,"eva":376,"evo":146,"evn":29,"evi":1543,"enš":59,"eut":31,"eus":24,"ex ":26,"erā":709,"evu":397,"evr":24,"evs":91,"ey ":55,"epe":71,"ekā":290,"epi":258,"epj":76,"eph":37,"er ":1104,"epa":258,"eot":23,"egū":271,"eos":34,"eor":322,"ņu ":2105,"eom":53,"eol":176,"eop":39,"eon":61,"elā":1125,"es ":8988,"ept":197,"eps":32,"epu":444,"epl":47,"epo":71,"epr":190,"erk":66,"erl":157,"eri":2539,"erg":167,"ere":536,"emā":318,"erf":37,"ekļ":537,"erc":178,"erd":99,"era":1626,"erb":238,"et ":1093,"elē":112,"esk":278,"esl":110,"esm":388,"enā":1113,"ņus":89,"esi":374,"ekš":656,"esc":24,"ese":289," Ēģ":41,"esa":337,"erz":36,"ery":29,"erv":331,"eru":391,"emē":508,"ņve":32,"err":36,"elī":103,"ert":417,"ers":1648,"ern":467,"erm":855,"erp":67,"ero":595,"eki":366,"ekl":427,"ekm":150,"ekn":62,"eko":416,"ekr":305,"eks":1397,"ekt":1750,"eku":811,"ekv":109,"en ":402,"elb":111,"ela":1449,"eld":81,"egā":92,"elf":85,"ele":1367,"eli":980,"elj":22,"elg":122,"elm":98,"eln":210,"elk":50," Ģe":106,"ell":209,"elo":182,"elp":198,"elu":464,"elv":59,"els":567,"elt":409,"elz":306,"eo ":63,"emb":176,"ema":412,"edž":46,"emg":143,"ehā":103,"eme":2607,"emd":28," ģe":323,"emn":25,"emo":348," ģi":768,"emi":389,"emj":71,"emt":133,"emu":60,"emp":493,"ems":89,"ep ":41,"ene":1004,"eng":203,"enb":97,"ena":2039,"end":388,"enc":397,"eno":1358,"enp":40,"enm":45,"enn":52,"enk":331,"enl":88,"eni":1040,"enu":734,"env":1058,"ens":2464,"ent":2847,"ehī":26,"enr":79,"enz":110,"egš":47,"eog":110,"eof":26,"ejā":89,"eod":60,"egl":203,"ego":210,"ege":31,"egi":29,"eaģ":26,"egr":83,"egs":36,"egt":159,"egu":482,"egv":44,"ehn":276,"eho":29,"ecā":200,"ehi":58,"ek ":1542,"eib":23,"eic":317,"ecē":53,"ecī":715,"eis":229,"eir":180,"eim":142,"eil":42,"ein":253,"eih":26,"eik":735,"eie":54,"eid":2544,"eig":207,"edā":218,"eja":808,"el ":113,"edē":86,"eiz":614,"eit":215,"eiv":56,"ejs":177,"ebū":23,"edī":123,"ejo":81,"ejn":76,"eji":80,"eke":31,"ekc":120,"eka":402,"em ":6412,"eju":260,"ejv":23,"gaž":22,"git":41,"gis":49," īs":256,"gin":40,"aģe":63,"gie":240," īp":415,"aģi":37,"ght":32," Īr":60," Īs":47,"gaļ":93,"bās":254,"bāt":57,"bāz":178,"gi ":519,"bāj":44,"bāl":44,"bāk":295,"bān":43,"bām":208,"gen":244,"ger":118,"ges":34,"gel":54,"gej":38,"bā ":646,"ge ":89,"gab":646,"gad":2505,"gai":779,"gas":1682,"gar":786,"gau":305,"gat":362,"gav":387,"gaj":108,"gam":98,"gal":1339,"gan":1451,"ga ":1326,"frī":26," ķē":68,"aēl":30," ļo":206," Ķī":169,"frē":39," ļa":118,"žņu":81," ķī":292,"Ņuj":43,"fut":631," Ļe":28,"fta":36,"fun":189,"ft ":61,"fra":303,"fre":65,"fri":213," Ķe":55,"fu ":37," ķi":28,"fro":69,"aču":132," ķe":273,"for":1089,"fos":41,"fot":77,"fon":280,"fol":75,"ņak":24,"ņam":33,"ņas":543,"ņaz":78," ņe":38," Ņu":39,"fs ":175,"ņai":51,"ņa ":1018,"fle":24,"fla":25,"fli":29,"flo":42,"fic":294,"fig":49,"fij":235,"fil":435,"fik":181,"fin":189,"fir":37,"fis":214,"fiz":287,"da ":3140,"de ":574,"dac":25,"dab":346,"dak":25,"dal":823,"dai":150,"dag":58,"dae":523,"dat":711,"das":2562,"dar":1471,"dap":69,"dan":60,"dam":271,"dau":771,"dda":35,"cul":28,"cum":72,"cty":34,"cto":75,"cti":74,"cte":48,"cus":46,"cyo":60,"ceļ":571,"cle":31,"co ":36,"ciā":742,"cog":76,"con":50,"col":50,"com":55,"cor":52,"cop":28,"cot":97,"ciņ":28,"cs ":85,"ct ":32,"cro":67,"cu ":436,"cea":28,"ch ":124,"cer":171,"ces":699,"cet":115,"cen":1090,"cep":69,"cek":125,"cem":35,"cel":374,"ced":32,"ci ":164,"cha":72,"cia":105,"ck ":59,"cie":767,"che":97,"chi":53,"cho":24,"chn":24,"civ":69,"cij":3939,"cik":179,"cil":946,"cim":32,"cif":53,"cir":29,"cis":561,"cit":901,"ciu":34,"cin":303,"cio":768,"cip":250,"cm ":47,"cke":32,"cka":44,"ed ":130,"eba":49,"ebe":168,"ebi":87,"ebk":175,"ebo":22,"ebr":247,"ebs":44,"eak":105,"ean":79,"eal":83,"ear":51,"eas":36,"eap":54,"dzī":2001,"eat":203,"eau":46,"eb ":1292,"dzā":72,"dzē":373,"ea ":66,"efi":131,"efo":131,"efa":30,"efe":198,"ei ":338,"ega":166,"efs":31,"eej":99,"een":27,"edi":335,"ede":1042,"eda":646,"edz":1195,"eds":41,"edu":254,"edo":120,"edr":685,"eck":45,"ech":44,"eci":633,"ece":209,"eca":89,"ee ":59,"ecu":116,"ect":70,"ecp":24,"eco":62,"drī":349,"dz ":1238,"doš":285,"drā":113,"dy ":22,"dvi":33,"dve":34,"doņ":93,"dur":107,"dus":742,"dva":54,"duš":31,"dzv":49,"dzs":170,"dzu":124,"dzo":52,"dzn":78,"duā":33,"dzi":2913,"dze":1097,"dza":294,"dor":118,"don":402,"dom":421,"dol":232,"dok":188,"dow":29,"dov":34,"dot":762,"dos":455,"diņ":89,"dpo":22,"ds ":1372,"dmi":319,"dne":44,"dni":257,"diā":75,"dob":64,"dod":87,"doe":23,"doj":533,"dnī":68,"dun":24,"dum":173,"dul":78,"duk":158,"dug":33,"dub":73,"dua":23,"duc":94,"dri":640,"diž":52,"dra":350,"dre":139,"du ":1832,"dro":640,"drs":87,"dru":292,"dsi":206,"dsk":23,"dsm":48,"daļ":1548,"dic":163,"dia":195,"dib":246,"der":1382,"des":875,"det":70,"dev":375,"deb":147,"dea":22,"ded":49,"dec":38,"def":128,"deh":29,"deg":170,"dej":161,"dei":89,"del":244,"dek":100,"den":1101,"dem":139,"dep":138,"deo":95,"di ":661,"deļ":51,"dko":25,"dma":88,"do ":341,"deņ":285," Āz":143,"div":810,"diu":34," Ār":50,"dim":118,"din":621,"dio":398,"dip":35,"dir":59,"dis":577,"dit":40,"die":2511," Āf":113,"dif":53," Āg":35,"dig":41," Ād":23," Āb":22,"dij":481,"dik":129,"dil":24," ār":250," āt":154," āp":26,"daž":632," ād":29,"ižu":32,"rgu":304,"raļ":69,"rhe":62,"raķ":99,"rha":55,"rhi":273,"rbī":529,"māz":34,"raē":35,"māt":506,"iža":92,"rga":943,"jš ":26,"ri ":1063,"ižk":30,"rgi":83,"iže":26,"rge":111,"rbā":31,"rgs":168,"rgo":78,"ret":778,"res":696,"rev":103,"reu":25,"rez":384,"rfa":28,"māc":507,"māj":191,"māk":627,"māl":154,"mām":145,"mān":158,"rfo":45,"mār":102,"mās":220,"rdu":246,"rds":349,"rg ":40,"rdz":219,"reb":22,"rea":246,"ree":37,"ref":132,"rec":144,"red":582,"rei":822,"rej":271,"reg":233,"rem":185,"ren":387,"rek":208,"rel":259,"rer":29,"reo":23,"rep":144,"mā ":1508,"rda":365,"kļu":259,"rct":35,"rdo":96,"rdn":63,"rdi":228,"rde":305,"re ":399,"ņām":78,"ņās":22,"rbu":231,"rbs":88,"rco":80,"kļo":52,"kļi":136,"rci":226,"rch":63,"rce":59,"rca":34,"kļa":421,"rax":25,"raz":76,"rd ":116,"rap":69,"rar":28,"ras":4121,"rat":1049,"rau":810,"rav":242,"rbi":268,"rbo":531,"rba":232,"rbe":87,"raj":717,"lēš":123,"ņā ":197,"rai":643,"rah":53,"rag":283,"ran":1071,"ram":1238,"ral":520,"rak":1567,"rab":128,"raf":152,"rad":1141,"rac":100,"rpt":521,"rpu":97,"rpr":64,"rpp":23,"rpo":72,"rs ":2853,"rpe":30,"rpa":43,"riķ":45,"riņ":229,"rpl":24,"rpi":90,"rkā":93,"ror":63,"ros":500,"rot":765,"rom":435,"ron":900,"roo":23,"rop":1052,"roz":140,"rou":41,"rov":266,"rob":624,"roa":30,"rod":1744,"roc":512,"lī ":122,"roj":521,"roi":35,"riģ":56,"rol":216,"rok":423,"rof":236,"roe":58,"rog":545,"rno":46,"rns":56,"rnu":187,"rp ":573,"rgļ":35,"rna":307,"rež":135,"riā":400,"rne":333,"rni":347,"māš":32,"rmk":26,"māņ":51,"rmo":304,"rms":203,"kņu":24,"rmu":139,"ro ":308,"kņa":79,"rma":773,"rme":418,"rdž":57,"rmi":499,"reš":174,"rls":24,"rlo":32,"rli":126,"rgā":217,"ižā":28,"rld":35,"rle":24,"rla":201,"rn ":84,"rku":265,"rkt":251,"rks":248,"kļū":96,"rkn":35,"rko":61,"rki":73,"reģ":361,"rkl":58,"rke":63,"rka":377,"rbū":24,"reč":45,"rdī":30,"rja":44,"reā":83,"raž":305,"rje":48,"riz":128,"rdē":22,"rip":74,"rio":330,"rit":1293,"ris":2568,"riv":81,"riu":29,"rih":80,"rig":98,"rij":2366,"raš":66,"ril":99,"rik":885,"rin":683,"rim":290,"ria":161,"rib":107,"ric":188,"rid":231,"rie":3740,"rif":114,"rdā":161,"rk ":63,"roš":448,"mēd":92,"rož":23,"rsā":44,"mēj":294,"mēm":78,"mēl":71,"mēn":131,"mēs":84,"mēr":1231,"mēt":199,"rsē":59,"rtā":193,"rpā":40,"rud":44,"ruc":33,"rur":31,"roī":36,"rup":644,"run":357,"rum":1852,"ruk":350,"ruz":42,"rpē":106,"rus":878,"rut":84,"rva":432,"mē ":626,"rvi":327,"rve":210,"rvs":22,"līč":64,"roņ":62,"rvu":63,"ry ":107,"rsk":108,"rsl":46,"jūl":25,"rsi":451,"rkš":28,"rso":354,"rsp":142,"rsm":215,"rsn":57,"jūd":35,"rsd":23,"rsa":148,"rse":69,"rnā":130,"rta":1012,"jūt":39,"rst":685,"rss":51,"jūr":881,"rnē":53,"rsv":73,"rsu":128,"rtl":32,"rtn":59,"rto":248,"rnī":124,"rte":168,"rth":30,"rti":792,"rts":333,"rtr":97,"roč":76,"rtu":328,"līm":186,"līn":460,"riš":83,"līj":172,"līg":392,"līc":164,"līd":1562,"līb":213,"rt ":437,"līz":66,"līv":121,"līt":444,"rri":36,"rre":54,"rmā":762,"rra":96,"ru ":2726,"rmē":77,"rlī":45,"sab":330,"sac":442,"sad":310,"sag":154,"sai":857,"mēš":100,"saj":138,"sak":466,"sal":1082,"sam":248,"sbi":144,"rzī":41,"sap":162,"san":223,"sau":2277,"sat":285,"sas":1660,"sar":747,"sav":1100,"saz":48,"sa ":1042,"mēģ":49,"rsū":33,"rvē":141,"ruš":59,"ruņ":155,"rze":250,"ruā":39,"rza":50,"rtē":197,"līš":88,"rvā":75,"rzs":23,"rtī":278,"rzi":284,"saņ":59,"sho":31,"shi":22,"si ":826,"kš ":48,"sga":35,"nāv":198,"nāt":1807,"nās":1024,"sgr":33,"saī":148,"siz":24,"saž":44,"sie":635,"sid":107,"kšd":149,"sic":34,"sib":36,"kša":264,"sia":56,"sk ":23,"kšt":50,"sit":335,"kšu":53,"sir":69,"sis":1127,"kšs":52,"kšp":164,"sip":27,"sin":756,"kšn":32,"sio":148,"sil":229,"kšl":23,"kšm":75,"sim":594,"sij":423,"sik":99,"kšk":106,"sih":129,"sif":65,"sig":89,"nā ":1513,"sda":48,"sdi":356,"sbu":40,"se ":542,"sca":22,"sce":66,"sci":117,"sch":88,"sco":39,"sev":271,"ser":334,"ses":362,"set":54,"sfa":26,"sez":117,"sh ":43,"nāj":705,"nād":289,"nāc":166,"sfo":68,"nār":126,"nāl":1149,"nāk":422,"nām":427,"sdz":22,"sei":104,"seg":72,"sed":36,"sec":62,"sep":119,"sen":630,"sem":62,"sel":189,"sek":324,"sej":83,"spu":61,"spo":584,"siņ":49,"kšņ":49,"spr":198,"skā":2459,"spe":377,"spl":61,"spi":604,"kšķ":38,"spa":151,"sot":106,"sov":22,"sol":116,"som":91,"son":503,"sor":227,"sos":35,"sod":41,"sof":59,"kšģ":28,"soj":40,"soc":383,"su ":834,"smē":44,"nču":194,"sjū":46,"slī":114,"kšž":25,"smā":173,"nča":33,"sra":53,"st ":664,"slē":278,"mīt":118,"mīn":84,"mīk":32,"mīl":44,"mīg":202,"slā":344,"mīb":243,"mīd":29,"ss ":875,"sli":399,"slo":148,"slu":68,"sfē":192,"sla":592,"sle":81,"ski":1153,"sko":1104,"sks":400,"skr":170,"sku":481,"ska":4650,"ske":410,"sno":53,"kšē":181,"sns":27,"sna":41,"nāš":340,"sni":516,"sng":29,"sne":180,"kšā":24,"smo":229,"shē":40,"sms":242,"smu":340,"so ":75,"sma":1140,"smi":429,"seš":62,"sme":291,"soš":166,"nēt":549,"nēs":72,"nēm":160,"nēj":281,"nēz":87,"stā":3123,"sze":116,"suā":44,"stē":996,"stī":1710,"svā":52,"sse":108,"ssa":247,"sso":61,"ssk":34,"ssi":62,"ssv":26,"kūv":24,"smī":51,"ssp":22,"snē":32,"ste":1133,"sta":3898,"stm":49,"stn":212,"sto":1125,"stp":85,"sti":2606,"stl":22,"stv":62,"stu":1969,"str":3208,"snī":38,"sts":1496,"sud":63,"sub":69,"spā":202,"sug":619,"sul":139,"sum":128,"sup":49,"sun":42,"sus":127,"sur":82,"spē":1745,"suv":25,"nē ":308,"sva":373,"sve":113,"svi":110,"soņ":53,"spī":75,"nēš":36,"tai":828,"taj":702,"tak":124,"tal":256,"taf":30,"tag":177,"tab":171,"tac":309,"tad":222,"tbi":216,"tba":91,"tav":303,"tau":931,"tat":537,"tas":3364,"tar":1920,"tap":52,"tan":395,"tam":934,"tce":25,"te ":724,"tbo":1157,"tbr":38,"tdi":61,"tda":95,"svē":166,"suņ":88,"stū":113,"svī":41,"ta ":6165,"ozā":24," št":206," ši":160,"pa ":730," šo":253," ša":314,"iķu":54," še":87,"iķi":331," Šv":81,"iķa":30," Št":29,"iķe":39," Šo":131," Ši":163," Še":104,"ovī":25," Ša":199,"ovē":187,"osū":27," Šķ":45,"pdr":26," šā":147,"iļu":60," Šī":134,"kā ":4239,"iļi":22,"pci":27," Šā":65,"iļa":27,"pe ":174,"par":3884,"ozī":528,"pat":548,"pas":2092,"pav":354,"pau":149,"paz":430,"pba":51,"pac":124,"pad":181,"paa":70,"pab":25,"pag":415,"pak":786,"pal":445,"pai":59,"pap":138,"pam":682,"pan":195,"pc ":24,"iļā":27,"paļ":30,"pha":38,"paņ":40,"phi":54,"pga":664,"kāz":22,"pi ":142,"pgr":35,"kād":424,"kāb":641,"kāc":170,"kāp":196,"kān":152,"kāt":32,"kās":1168,"kār":1333,"paā":29,"kām":189,"kāl":251,"kāk":39,"kāj":89,"pea":50,"pec":223,"ped":72,"pdz":192,"pen":158,"per":1152,"pet":33,"pes":264,"pei":23,"pel":224,"pek":146,"peļ":35,"pla":1300,"pli":106,"pgā":32,"ple":241,"plo":77,"plu":29,"pka":321,"pko":110,"pja":69,"iļņ":141,"pjo":49,"pju":63,"pie":4300,"pig":22,"paš":762,"pij":105,"pil":2275,"pin":133,"pio":305,"pir":966,"pis":387,"pit":151,"poz":106,"por":630,"pop":247,"pot":153,"pos":221,"poj":154,"pog":70,"pon":210,"pok":25,"pol":767,"pod":51,"ps ":241,"ppu":25,"ppl":37,"piņ":42,"pkā":95,"iņu":475,"iņs":42,"iņo":51,"kāņ":216,"iņi":157,"iņj":22,"pme":52,"pma":68,"iņa":746,"po ":65,"gžņ":89,"pni":63,"pne":24,"psu":31,"pst":387,"iņķ":170,"pta":564,"pse":42,"ņķo":49,"ņķi":80,"psi":158,"psk":78,"ņķa":92,"pso":28,"ptu":237,"ptv":61,"pub":494,"pte":121,"pti":177,"pto":59,"pnī":27,"plū":201,"plē":184,"pra":501,"jīg":32,"plā":202,"pmē":120,"pru":34,"psa":72,"pu ":321,"pmā":37,"iņā":150,"pri":1091,"pre":942,"pro":1797,"plī":101,"poš":65,"pož":46,"prē":65,"prī":60,"psē":31,"pur":145,"pmū":26,"pus":720,"put":341,"pum":233,"pun":290,"ņģē":37,"iņš":323,"pul":349,"poļ":35,"pva":35,"pvi":404,"prā":125," Ņū":40,"ptū":22,"pzi":58,"ptī":28,"prū":42,"ņģe":27,"pzī":361,"lā ":1304,"lār":401,"lās":590,"lāt":209,"lām":367,"lān":215,"lāp":55,"lāj":219,"lāk":1056,"lāg":85,"lād":144,"lāc":180,"lāv":61,"lāz":36,"iša":70,"iši":31,"išu":56," Ži":23," Že":35," Ža":46,"lāč":85,"lāš":22," ža":153," že":29," žu":96,"lāņ":65,"išķ":223,"išņ":36,"ņēm":347,"qua":27,"lē ":420,"quu":124,"que":29,"qui":79," šī":215," šķ":525,"lēd":76,"lēc":25,"lēm":141,"lēn":178,"lēk":87,"lēl":48,"lēj":178,"lēg":138,"lēs":295,"lēt":383,"lēr":42,"lēp":64," šū":130," Ūd":31," ūd":556,"ra ":3874,"ežo":374,"ngo":130,"ngi":47,"eži":331,"ngl":303,"ngv":61,"ežu":144,"ngu":183,"ngr":212,"ngt":36,"ngs":108,"ni ":1261,"nge":139,"eža":263,"nga":229,"ncē":85,"nha":38,"nhi":24,"nhe":54,"neg":80,"nej":92,"nei":201,"nel":264,"nek":293,"nen":247,"nem":97,"nep":336,"neo":76,"ner":698,"net":418,"nes":1590,"nev":218,"ndz":31,"ng ":184,"nea":224,"neb":55,"nec":44,"ned":153,"nfi":27,"nfo":273,"iān":89,"iāl":1004,"nfl":40,"nfr":48,"nez":35,"iāc":169,"nfe":88,"nci":571,"gļi":38,"nce":476,"nch":29,"nca":32,"ne ":1014,"nbu":52,"ndu":273,"ndr":359,"nds":68,"ndo":248,"ndi":727,"nde":437,"nda":780,"gļu":239,"nak":85,"nal":235,"nam":315,"nan":170,"nar":136,"nac":383,"nad":66,"nae":90,"naf":23,"nag":57,"nai":923,"naj":193,"nab":23,"nbe":61,"nd ":206,"nav":456,"nau":117,"nat":306,"nas":3073,"naz":22,"na ":4384,"muļ":23,"muš":43,"hēm":45,"mtā":193,"ntā":395,"nsē":48,"noš":193,"ny ":39,"nvi":1034,"nux":29,"nve":133,"nva":62,"nuk":32,"nul":25,"num":139,"nus":295,"noī":26,"nto":950,"ntu":416,"nts":925,"ntr":875,"nti":950,"nth":28,"nta":799,"nte":768,"nsu":59,"nsv":36,"nsp":162,"nso":88,"nst":540,"nss":27,"nkū":25,"nsf":27,"nse":131,"nsg":24,"nsi":192,"nsl":44,"nsk":554,"nsa":85,"nu ":3157,"nmē":32,"iču":24,"ičs":33,"nrs":66,"iči":25,"nri":78,"iča":38,"nra":85,"nt ":98,"hīd":23,"nkā":234,"niņ":82,"ns ":4213,"noc":58,"nod":505,"noa":58,"nob":42,"nog":200,"nof":35,"nok":292,"nol":424,"noj":304,"nop":85,"nom":610,"non":115,"not":1518,"nos":1301,"nor":435,"nov":804,"noz":696,"npa":23,"niķ":23,"nne":83,"nna":118,"ngļ":211,"nno":31,"nni":41,"nme":24,"nma":29,"iāņ":39,"ežģ":48,"neš":108,"ndž":62,"ežī":26,"ežā":198,"ngā":136,"nn ":32,"nla":94,"neļ":30,"nle":25,"no ":5915,"nke":26,"nki":45,"nkc":180,"nka":173,"nku":121,"nko":53,"gļū":52,"nks":81,"nkt":272,"nkr":126,"nja":39,"ndī":35,"njo":28,"nij":1586,"nig":62,"nif":36,"ndā":228,"nie":3147,"nid":123,"nic":83,"nia":73,"nk ":29,"niz":488,"ndē":98,"niv":242,"nis":2463,"nit":151,"nir":27,"nio":28,"nip":37,"nim":128,"nin":84,"nik":329,"nil":57,"ogs":183,"ogr":713,"ogu":116,"ogi":122,"ogl":96,"ogo":65,"ogn":46,"oga":163,"obā":56,"ņš ":323,"obī":23,"ocē":27,"oho":29,"ohn":25,"oha":113,"odē":120,"ois":41,"oin":31,"ocī":54,"odā":459,"iģi":165,"iģe":27,"ok ":31,"gša":114,"oju":1293,"odī":31,"ojo":586,"oji":109,"oje":183,"oja":1186,"ol ":51,"oce":578,"och":26,"oci":581,"ock":58,"oco":46,"obs":66,"obu":91,"oca":32,"ode":548,"odi":313,"odo":337,"odn":41,"ods":132,"odr":212,"ocy":51,"jā ":4204,"of ":167,"oda":2367,"oel":45,"oef":31,"oei":29,"oen":27,"odz":39,"odu":575,"jām":1042,"jān":27,"ofi":331,"jāj":22,"jās":923,"ofs":60,"oft":50,"ofo":72,"ofe":168,"jād":51,"jāb":32,"ofa":27,"nzē":40,"oal":24,"oak":87,"oba":54,"od ":93,"obo":33,"obr":164,"obl":72,"obj":208,"obi":154,"obe":704,"nsī":306,"ntē":146,"ة ":22,"nza":50,"nzi":41,"nzo":53,"ntī":340,"nvā":46,"ntū":58,"otā":1010,"orķ":25,"orī":50,"opš":220,"jēj":29,"osā":36,"jēd":148,"orē":91,"ows":32,"ovā":78,"gūš":56,"ozu":30,"otī":57,"ozo":189,"oze":115,"ozi":143,"oza":288,"otē":115,"orņ":38,"otu":305,"oti":1556,"oth":36,"ote":602,"ott":59,"olū":125,"ots":723,"otr":369,"onī":135,"oto":694,"otn":222,"onē":180,"ost":506,"gūt":168,"osu":40,"ota":947,"osi":149,"osk":156,"ose":88,"osf":203,"onā":1526,"osp":73,"oss":48,"gūs":114,"gūr":45,"osm":456,"osl":225,"oso":109,"orā":211,"owe":22,"ovi":389,"ovg":31,"opī":120,"ovs":143,"opē":176,"ox ":29,"jē ":37,"ova":643,"ove":137,"opā":322,"oun":55,"ous":25,"our":37,"out":44,"opm":30,"opo":347,"opi":253,"opl":68,"ope":301,"okā":278,"oph":40,"opa":835,"os ":3856,"opu":475,"opr":71,"opt":86,"ops":93,"ojā":198,"or ":99,"oot":22,"oor":77,"ork":107,"orl":52,"orm":1086,"orn":222,"oro":248,"orp":128,"olī":129,"orr":39,"orc":49,"okļ":89,"ord":492,"ore":247,"omā":452,"orf":64,"org":872,"orh":26,"ori":1689,"osa":935,"ort":723,"ors":691,"orv":185,"oru":295,"omē":208,"orz":33,"ory":23,"olā":244,"ot ":1449,"m² ":52,"orb":148,"ora":653,"olē":98,"olb":29,"ola":1498,"old":135,"on ":659,"oli":1155,"oll":82,"olk":110,"olf":57,"ogā":71,"ole":441,"olg":32,"ols":417,"olt":46,"olm":107,"oln":31,"olo":1146,"olu":413,"ogē":50,"oka":339,"om ":55,"oki":85,"okh":49,"oke":542,"okr":192,"oks":506,"oko":208,"okl":145,"okm":47,"okt":89,"oku":309,"ona":1194,"ond":224,"ogļ":73,"onc":136,"onf":111,"one":173,"ong":158,"oni":1530,"onk":159,"onn":56,"ono":626,"onr":30,"ons":1271,"ont":491,"onu":567,"onv":60,"gšē":65,"ony":39,"onz":36,"oma":1047,"ome":546,"omb":95,"omi":730,"omm":51,"omj":98,"omp":487,"omo":191,"omt":26,"omu":284,"oms":200,"op ":56,"la ":3657,"eķu":303,"kuļ":50,"ktū":291,"kuš":110,"eķi":82,"le ":615,"eļd":25,"lce":40,"eļe":30,"eļa":635,"lci":93,"eļi":128,"eļv":32,"eļu":421,"eļo":286,"eļr":165,"gā ":654,"lde":303,"lda":256,"ldo":68,"ldn":139,"ldi":101,"ldv":22,"ldu":71,"lds":71,"ldr":27,"lab":686,"lac":74,"lad":63,"lah":38,"lag":32,"laj":474,"lai":2379,"lak":285,"lan":766,"lam":314,"lap":246,"lar":131,"lat":1524,"las":2361,"lau":462,"lav":247,"lay":44,"laz":38,"lba":32,"ld ":81,"lbe":128,"lbu":171,"lbr":107,"kvi":68,"kve":97,"kva":316,"kuu":25,"kut":36,"kmū":49,"kus":576,"kur":4124,"kup":73,"kun":181,"kum":1594,"kul":627,"kuk":32,"kuj":25,"koš":92,"krā":588,"koņ":106,"kta":560,"kte":51,"knē":45,"kss":117,"kmī":26,"ksp":156,"ksu":120,"kst":1947,"ksk":31,"cūk":37,"ksi":433,"kso":59,"ksn":205,"ksm":118,"ksl":373,"ktr":699,"kts":634,"ktu":492,"kti":662,"kto":408,"ksī":103,"ktē":73,"kuģ":144,"krū":64,"ktī":473,"ksā":78,"krē":127,"ktā":172,"krī":67,"fēr":208,"ksē":49,"lpo":192,"liņ":107,"lps":165,"lkā":113,"lpe":42,"lpi":52,"dū ":66,"ls ":2358,"lpu":76,"lok":186,"lon":250,"lom":194,"lop":98,"lor":215,"lod":1255,"loc":172,"log":309,"loj":39,"liģ":139,"lpa":98,"los":267,"lot":233,"lov":125,"loz":171,"lno":58,"lnk":23,"lni":256,"lne":55,"lob":58,"lnv":34,"lnu":164,"lns":198,"eņo":30,"lmi":75,"eņi":138,"lme":73,"eņe":150,"eņb":28,"lma":269,"eņa":350,"gāļ":23,"lna":214,"lmu":99,"eņu":143,"eņr":134,"lms":33,"ltk":80,"lti":424,"ltn":68,"lto":53,"ltr":29,"lts":217,"lnī":100,"ltu":221,"lud":54,"luc":32,"lub":111,"lug":36,"lpā":54,"lsi":33,"lkš":22,"lsk":140,"lsm":135,"lsn":30,"lso":131,"lsp":34,"lss":53,"lst":1735,"lsu":49,"eņķ":69,"lv ":26,"lta":371,"lte":188,"lkņ":24,"lmā":69,"lu ":1807,"eņē":35,"lnā":79,"lse":64,"dūd":48,"lsa":85,"lt ":35,"lhe":59,"eļā":42,"lgu":44,"lgs":36,"lgt":25,"lgr":44,"lgo":65,"lbā":28,"lge":25,"li ":1126,"gāz":197,"lga":178,"gār":144,"lfr":22,"gās":198,"gāt":113,"gān":110,"gāj":129,"gāk":229,"gāl":68,"gām":215,"gāc":40,"gād":124,"lfa":193,"lez":112,"lev":95,"les":1626,"let":176,"ler":213,"leo":70,"lep":67,"lem":358,"len":329,"lek":1222,"lei":141,"lej":190,"leg":36,"lef":47,"led":254,"lec":71,"lea":23,"lfī":26,"lls":27,"ldū":50,"llu":78,"lo ":480,"lla":140,"lle":160,"lgā":68,"lli":182,"leņ":73,"llo":82,"lko":184,"lku":31,"lks":97,"lka":119,"lke":27,"lki":33,"eļš":95,"leģ":37,"lkl":39,"leč":51,"ljo":123,"ldī":542,"eļļ":42,"lje":30,"ll ":123,"lja":61,"eļņ":24,"lit":895,"lis":1779,"lir":22,"lip":94,"lio":99,"lin":517,"lim":573,"liz":308,"ldē":33,"liv":35,"lic":208,"lid":326,"lia":94,"lib":49,"lik":929,"laš":379,"eļģ":25,"lij":964,"lig":100,"lie":3537,"lif":131,"ldā":34,"ma ":2997,"mac":23,"mai":882,"maj":174,"mak":194,"mad":68,"mag":255,"map":23,"lzī":23,"mar":276,"mas":1459,"mal":305,"mam":184,"man":1880,"maz":508,"mat":1537,"mba":149,"mbl":29,"mbi":138,"mbe":47,"mbr":158,"mbo":287,"me ":570,"mbu":166,"mda":33,"mde":27,"mdo":23,"med":310,"meg":22,"met":1247,"mes":1625,"mer":791,"mem":29,"mel":157,"men":1391,"mei":147,"meh":105,"mek":209,"mez":28,"hār":41,"mfo":25,"hān":110,"lva":502,"lve":648,"lvi":41,"luk":23,"loģ":845,"lup":35,"luo":34,"lum":401,"lut":87,"lus":425,"lur":30,"loī":24,"ly ":28,"loš":29,"loņ":26,"lvo":84,"lvu":57,"lož":83,"ltā":300,"gēn":73,"lsē":1122,"lzi":33,"lza":40,"lzc":242,"lsī":24,"lvā":83,"ltī":58,"lzs":43,"lvē":725,"ltū":225,"mpi":549,"mpe":254,"mpr":55,"mpo":156,"miņ":109,"mpl":189,"mpu":71,"mps":29,"mpt":22,"ms ":3789,"mog":37,"moc":27,"mob":84,"mod":286,"mon":399,"mop":26,"mok":98,"moj":43,"mom":24,"mol":217,"mor":220,"mos":1307,"mot":190,"mpa":147,"ešķ":123,"miķ":31,"mmā":27,"mmē":68,"msa":67,"mu ":2868,"mt ":26,"mtu":58,"mts":51,"mti":48,"mug":77,"mpā":152,"mss":33,"mst":25,"msu":24,"msk":121,"mte":23,"mta":1054,"mvi":24,"moš":35,"mur":78,"mus":558,"mut":78,"mui":109,"mul":121,"mum":318,"mun":151,"mpē":250,"muz":106,"maņ":208,"džu":100,"džs":35,"mga":146,"dža":84,"mi ":937,"maģ":28,"dži":70,"dže":114,"mju":201,"ml ":23,"mje":32,"min":1418,"mio":29,"ešo":30,"mil":392,"mir":718,"ešs":32,"mis":1428,"ešv":29,"mit":475,"ešu":1242,"miz":31,"mic":35,"eša":400,"mig":64,"mie":997,"ešd":35,"mid":33,"mik":313,"mij":472,"maš":145,"eši":317,"mo ":301,"meņ":339,"meļ":1113,"džā":37,"mko":36,"mm ":35,"mni":192,"mna":27,"ešā":114,"mež":103,"mmu":74,"mma":291,"mme":33,"vī ":36,"tšķ":209,"uņi":48,"uņo":84,"uņu":131,"tūt":53,"tūr":1186,"tūk":66,"tūc":93,"vīn":52,"vīt":70,"vīr":237,"vīg":77,"vīd":56,"vīb":202,"vīz":153,"vē ":134,"īču":22,"īča":67,"sūt":95,"vēl":461,"vēk":693,"vēj":244,"vēc":27,"Čeh":54,"vēs":501,"vēt":425,"vēr":790,"vēn":31,"vēģ":76,"Čik":22,"uļo":37,"uļv":73,"uļu":71,"uļi":36,"uļa":32,"vēš":46,"tļa":51,"tļu":59,"tļi":52,"tļo":22,"vā ":578,"vāj":43,"vāc":471,"vāl":70,"vāk":140,"vān":38,"vām":138,"vār":1021,"vāt":107,"vās":151,"vāv":76,"ržu":43,"uģa":52,"uģi":59,"uģu":36,"tņu":72,"ča ":145,"zra":210,"zru":92,"zjū":39,"tīd":188,"zlā":29,"tīb":1094,"zs ":189,"tīt":1190,"tīs":433,"tīv":934,"tīr":77,"tīk":237,"tīn":159,"tīm":268,"tīg":275,"tīj":350,"zte":106,"zti":66,"ztu":134,"čem":249,"ztv":96,"čet":144,"znī":263,"čer":57,"zsa":231,"rūd":56,"znā":215,"zmē":101,"zu ":183,"rūt":48,"zst":360,"rūs":59,"zsv":33,"znē":22,"zsl":25,"zsk":600,"rūk":50,"rūn":90,"rūm":55,"zsp":47,"rūp":88,"zva":673,"zvi":325,"zve":584,"či ":69,"zul":164,"zum":137,"zpē":51,"zus":63,"čie":24,"zsā":72,"tīņ":237,"zrā":47,"tīģ":32,"zzi":39,"zuā":39,"īģe":36,"tīš":166,"zvē":121,"rūš":31,"čs ":40,"zgl":134,"zga":142,"rš ":626,"zi ":317,"uār":73,"uāl":181,"zaļ":79,"zgu":59,"zef":34,"zej":232,"zdz":26,"zeb":60,"zdo":186,"uāc":50,"zes":430,"zen":285,"zem":1268,"zel":450,"zek":170,"zer":903,"ze ":308,"zce":422,"zbr":68,"zda":107,"zde":234,"zci":73,"zab":39,"īļu":88,"zai":49,"tēš":90,"zah":57,"zam":111,"zan":24,"zak":23,"zar":328,"zau":128,"zav":27,"zas":275,"zat":43,"zod":22,"zob":42,"tī ":235,"zos":43,"zot":69,"zor":28,"zop":22,"zom":26,"zon":281,"zol":154,"zof":144,"ziļ":81,"ziķ":104,"zpa":78,"zpr":45,"ال":32,"zpl":262,"ziņ":261,"zkā":32,"zpi":173,"zo ":48,"zma":918,"zme":35,"zmi":84,"zna":38,"zmu":41,"zno":68,"zne":198,"ršā":79,"zni":156,"zbū":81,"zka":34,"zkl":48,"zkr":193,"zla":642,"zgā":25,"zli":78,"zeļ":55,"zeņ":47,"rša":176,"zie":1720,"zid":135,"zij":625,"rši":100,"zin":1174,"zim":1926,"zil":123,"zik":669,"ršo":29,"zio":48,"zcī":73,"ršr":51,"zir":324,"zis":229,"zit":58,"ršu":90,"ziv":58,"tē ":318,"yst":46,"rņā":31,"sīk":51,"sīj":64,"sīm":27,"sīn":31,"sīs":28,"sīt":105,"sīv":85,"sīb":502,"sīd":98,"sīg":56,"tāž":25,"yon":65,"sī ":32,"tēģ":40,"īņā":28,"za ":232,"āža":23,"āžu":50,"īņu":254,"īņa":76,"sīļ":23,"tēk":46,"tēl":335,"tēm":821,"tēn":44,"tēj":348,"tēt":204,"tēs":73,"tēv":63,"tēr":175,"tēz":37,"īša":499,"īšu":52,"tā ":2912,"tāc":148,"tād":527,"tāk":538,"tāl":1306,"tāj":1760,"rķu":27,"rķe":31,"rķi":179,"yla":29,"tāļ":48,"rņa":66,"rņu":41,"tāš":25,"tāv":1332,"tāz":22,"tāp":79,"tām":538,"tān":411,"tās":1054,"tāt":740,"tār":419,"rīz":162,"rīn":188,"rīj":40,"rīk":162,"rīl":26,"rīv":387,"rīs":243,"rīt":190,"rīg":665,"rīb":593,"rīd":236,"rīc":210,"pūt":23,"sāļ":43,"rī ":2361,"rīš":55,"pūš":30,"sē ":157,"sēj":316,"sēk":27,"sēm":89,"sēn":52,"sēd":44,"sēs":30,"sēr":135,"sēt":1211,"ožu":58,"oža":54,"sāt":137,"sās":67,"sār":68,"sāp":24,"sān":37,"pš ":215,"sāc":43,"sāj":28,"sāk":643,"sāl":103,"sām":92,"ožā":27,"pšu":22,"rģi":226,"pša":33,"rģe":23,"rēķ":47,"sā ":333,"rēš":122,"rē ":110,"ww ":36,"āļu":173,"āļi":45,"www":36,"rēt":449,"rēs":31,"rēm":93,"rēn":56,"rēj":380,"rēk":33,"rēl":48,"rēd":88,"rāļ":69,"rāņ":44,"ošā":198,"rāš":23,"ws ":30,"ošī":35,"wor":28,"rā ":1557,"pļa":22,"rāk":869,"rāl":881,"rām":402,"rān":164,"rāg":38,"rāj":67,"rāc":432,"rād":816,"rāf":309,"rāb":117,"wer":27,"nže":53,"rār":31,"rāp":24,"rāv":135,"rās":553,"rāt":492,"rāz":74,"ošs":181,"ošu":115,"oši":415,"ošo":147,"oša":1342,"vze":33,"vvē":32,"āņi":41,"āņu":468,"vuš":26,"āņa":65,"war":33,"pīt":24,"pīr":89,"pīn":23,"pīl":42,"viš":195,"pīg":88,"pīd":81,"pīb":56,"vs ":473,"vri":37,"vst":90,"vsk":63,"vu ":956,"vus":141,"vmū":35,"vum":201,"vuk":61,"vul":71,"vva":94,"voš":86,"pīļ":68,"āša":527,"via":49,"nša":32,"vio":33,"vir":905,"vik":41,"vil":371,"vin":313,"vig":52,"vij":2101,"vic":31,"vid":1832,"vie":6969,"viz":69,"nšu":53,"vit":157,"nšt":29,"vis":1620,"vji":56,"vju":71,"vo ":339,"oņa":59,"veš":46,"oņi":162,"oņu":145,"viā":31,"vna":31,"vni":238,"vič":61,"vod":34,"voj":423,"vol":130,"vok":149,"von":248,"vor":27,"vot":667,"vos":64,"vpa":23,"viļ":118,"vpi":79,"viņ":404,"vpr":25,"vaņ":38,"vaļ":151,"vi ":493,"vgo":31,"ver":992,"ves":531,"vet":45,"vej":30,"vei":2843,"ven":961,"vem":34,"vel":158,"vek":42,"ved":123,"vec":250,"oļu":172," − ":35,"vda":91,"uzņ":254,"ve ":176,"val":3215,"vak":43,"van":198,"vam":39,"var":1672,"vat":135,"vas":1579,"uzē":26,"vab":47,"vad":1354,"vai":3704,"vaj":267,"pēļ":144,"va ":982,"mūž":31,"uvē":31,"uvā":81,"uzv":164,"uzl":72,"uzk":39,"urš":530,"uzi":73,"uzg":36,"uze":128,"uzt":192,"uzs":479,"uzr":64,"utī":62,"uzm":28,"utē":47,"uzb":144,"uzc":22,"uzd":109,"utā":171,"usī":47,"pēt":433,"usē":169,"usā":96,"pēd":188,"pēc":941,"pēj":691,"urģ":36,"pēm":32,"pēl":736,"pēk":384,"pēr":307,"urī":204,"urē":196,"uz ":1335,"urā":908,"umš":52,"uum":27,"upā":104,"upē":50,"ux ":33,"uus":124,"uvi":141,"uvo":31,"uva":357,"uve":337,"upī":23,"uvu":135,"usl":182,"usm":71,"usj":49,"usk":104,"mūk":26,"ukš":120,"usi":609,"unā":343,"usd":32,"use":127,"usa":206,"mūz":468,"usz":100,"usv":36,"usu":107,"ust":2158,"mūs":296,"uss":395,"mūr":69,"umī":24,"uso":49,"mūn":33,"utn":283,"uth":28,"uti":652,"ute":201,"uta":279,"utb":797,"utt":67,"uts":90,"utv":22,"utu":102,"uto":580,"utr":30,"unī":25,"us ":3775,"ulā":424,"oīd":99,"ulē":350,"ut ":97,"urb":65,"ura":1608,"urd":30,"urc":141,"umā":913,"ure":246,"urg":216,"uiž":110,"urj":22,"uri":851,"url":46,"urk":327,"urn":303,"uro":291,"urp":107,"ulī":38,"urs":344,"urt":245,"uru":1149,"urv":97,"umē":24,"urz":200,"unz":34,"ugš":195,"ujā":42,"uor":22,"upa":461,"ur ":573,"upj":23,"upi":127,"ukā":121,"upe":293,"upo":29,"upu":109,"ump":111,"ums":2443,"umu":2190,"umt":47,"umv":39,"umi":1048,"umk":31,"pāņ":98,"umm":30,"uml":29,"umo":1060,"umn":30,"uma":1511,"umb":191,"umd":66,"ume":317,"udž":74,"unt":48,"uns":163,"unr":34,"unv":30,"unu":158,"unl":25,"unk":486,"uni":663,"uno":67,"ugļ":37,"unc":25,"und":348,"una":264,"ung":150,"une":47,"up ":25,"uks":271,"uku":836,"ukt":791,"uko":36,"ukl":91,"uki":42,"ukc":69,"um ":175,"uka":140,"ulv":63,"ulu":136,"ult":666,"uls":122,"ulp":39,"ulo":29,"ulm":42,"ull":58,"ulk":243,"uli":203,"ulg":48,"ule":823,"ulf":35,"ugā":140,"ulc":29,"uld":110,"ula":397,"ulb":50,"un ":9898,"uid":83,"oģe":28,"udā":23,"oģi":861,"uil":24,"uis":38,"ucē":126,"ķa ":175,"mša":94,"uji":27,"ujo":73,"udē":94,"ul ":24,"uja":223,"ubā":54,"ugi":71,"ugo":30,"ugl":76,"pār":1984,"pās":27,"uga":887,"ugu":553,"ugs":799,"uha":22,"uj ":134,"uco":23,"pā ":453,"uda":124,"ude":104,"udi":282,"ķir":550,"ķis":433,"ķin":48,"ubs":106,"ķij":62,"ķim":24,"ubu":76,"ķie":106,"ķid":184,"uca":88,"ue ":35,"uce":66,"uci":96,"uer":36,"pāc":26,"pān":369,"pām":68,"pāj":65,"udu":86,"āču":68,"udr":142,"udo":32,"ug ":37,"udz":752,"uel":29,"ķet":39,"ķes":25,"ķer":270,"ķen":35,"ķel":35,"tuš":25,"ua ":31,"tzī":84,"uar":51,"ual":31,"uan":35,"ubi":59,"ubj":31,"ubl":522,"ube":111,"uba":77,"uag":22,"uc ":316,"ķi ":217,"tvā":37,"tzi":22,"tuā":134,"ttī":266,"trū":52,"ttē":198,"tza":38,"ttā":196,"nīš":44,"tyl":39,"tvē":108,"ķu ":470,"ty ":51,"toņ":39,"tve":395,"toļ":81,"tvi":1976,"tva":158,"tur":1909,"tus":646,"tuv":673,"ķo ":45,"tul":280,"tuk":47,"tun":72,"ķeš":66,"tum":1336,"tub":43,"tud":188,"tuc":22,"tug":34,"tpū":25,"trī":313,"trē":132,"two":22,"toš":435,"trā":1294,"nīc":430,"nīd":58,"nīb":728,"ts ":6404,"nīj":53,"nīg":331,"nīt":121,"nīs":25,"nīr":102,"nīn":27,"nīm":63,"tlē":35,"tre":229,"tt ":106,"oča":27,"tra":1972,"tri":1251,"oči":28,"trs":398,"tru":1883,"tro":2406,"tlī":43,"tu ":4075,"tmē":32,"tsa":92,"tse":174,"lūc":74,"lūd":44,"lūg":25,"lūk":137,"tsk":152,"tsl":24,"lūp":24,"tsp":162,"tsv":27,"tsu":24,"lūt":49,"tst":123,"lūs":138,"lūz":46,"tnē":293,"tta":34,"tte":67,"tti":291,"ttl":22,"tto":22,"tnī":27,"ttp":39,"ķus":35,"tma":80,"to ":1892,"tms":32,"tmo":123,"tml":23,"tmi":87,"tni":753,"tne":504,"tp ":39,"tna":35,"tns":112,"tnu":123,"tno":42,"tof":38,"tod":192,"toc":137,"toj":671,"tog":69,"nī ":207,"tob":116,"tov":52,"tos":547,"tot":998,"toz":23,"tom":540,"ton":588,"tok":294,"tol":346,"tor":2083,"top":326,"tpe":28,"tkā":47,"tpi":87,"tiķ":219,"tpa":63,"tpl":32,"tiņ":164,"tpr":24,"tij":940,"til":601,"tik":1958,"tif":82,"tie":4403,"tig":30,"tir":195,"tit":273,"tis":2277,"tin":593,"tim":104,"tip":378,"tio":312,"tia":75,"lša":104,"tic":277,"tid":70,"teā":78,"tju":24,"tiz":110,"lšu":27,"tiv":158,"tja":44,"tki":59,"tkl":212,"tko":27,"tkr":96,"tku":37,"tka":280,"tli":341,"teņ":82,"tla":152,"tgā":22,"tle":76,"tem":480,"ten":587,"teo":285,"tep":65,"tei":672,"tej":47,"tek":587,"tel":542,"teg":123,"teh":268,"teb":48,"tec":92,"ted":53,"tfo":35,"th ":68,"tet":45,"tes":1146,"ter":2575,"tgr":47,"ti ":2942,"tga":132,"tač":123,"tho":40,"the":191,"thi":29,"taļ":38,"tha":41," α ":31,"āpa":64,"āpe":142,"ākā":884,"āpi":34,"ājē":32,"ār ":34,"ājā":201,"āno":72,"āns":365,"ānu":327,"āre":82,"āmā":78,"ārg":36,"āra":470,"ārb":33,"ākļ":103,"ārd":904,"ārm":72,"ārn":280,"āro":74,"ārp":114,"āri":461,"ārk":89,"ārl":118,"āt ":234,"ālā":1101,"āpu":44,"āps":37,"ās ":6616,"āld":44,"āgā":35,"āle":181,"āli":1326,"āla":1215,"āks":485,"ākt":61,"āku":495,"āko":642,"āki":268,"āka":1716,"ām ":3525,"ājs":680,"ābū":29,"ādī":293,"āju":1139,"āji":502,"ājo":89,"ājp":22,"āni":891,"āna":615,"ānd":34,"āmu":42,"āms":160,"āmi":68,"āma":396,"ālu":633,"āls":579,"ālo":317,"ārē":202,"āsā":40,"āpš":36,"ārī":93,"āvu":149,"žās":33,"ārā":289,"žād":455,"žāk":194,"žām":34,"ātē":54,"āze":265,"ārš":275,"āzi":216,"āzu":50,"zšķ":85,"ātī":67,"ātā":439,"ārņ":54,"āv ":562,"žā ":38,"āta":627,"āst":95,"āsu":62,"ātn":541,"ātr":318,"āto":42,"āte":469,"āti":825,"ārz":92,"āsa":252,"ālī":22,"ārr":75,"ārs":844,"ārt":1313,"āru":144,"ārv":488,"ānā":124,"āsi":27,"ākš":30,"āvd":67,"āva":113,"āpē":74,"āvs":30,"āvo":161,"āvj":71,"āvi":182,"āve":205,"āts":679,"ātu":408,"Āzi":142,"āfi":261,"āfr":63,"āfs":37,"āga":57,"āgs":41,"āgo":45,"āj ":38,"ābē":84,"ācē":37,"āk ":1029,"ādā":677,"ācī":199,"ādē":157,"āja":844,"āje":33,"ābi":54,"ābj":26,"ābe":514,"āba":24,"āca":27,"ābu":87,"āci":2513,"ācb":31,"āda":636,"ācu":337,"ādn":33,"ādo":104,"āde":246,"ādi":416,"āds":129,"ādu":390,"ļin":31,"ļie":252,"ļi ":260,"zņe":149,"ļda":25,"ļav":42,"ļau":478,"ļai":47,"ļas":391,"ļam":83,"ļa ":1215,"āzē":88,"zņē":241,"žīm":24,"žģī":37,"ātņ":41,"āvē":149,"āvā":189,"āvī":87,"AU ":30,"":23,"zēš":55,"BA ":99,"ķī ":22,"ļot":251,"ļos":305,"ļiņ":134,"ļoj":28,"ļri":165,"Ķīn":125,"ļu ":1814,"zīš":29,"ļsk":34,"ļve":81,"ļvi":28,"ļum":33,"ļus":125,"ļuv":123,"ķēr":58,"ķēn":27,"ķēd":39,"ļoš":38,"Žan":29,"zīs":345,"zīt":108,"zīv":1468,"zīl":49,"zīj":29,"zīm":1070,"zīd":65,"zīc":55,"zīb":324,"zīg":242,"AP ":26,"zāc":457,"zā ":57,"ža ":310,"zāk":210,"zāl":65,"zām":26,"zān":65,"zās":75,"žku":26,"zē ":172," С ":34,"žis":66,"ķīd":71,"ķīr":23,"ķīs":84,"žie":84,"ķīn":49,"ķīm":271,"žos":33,"žot":153,"žor":51,"žkā":37,"Āge":33,"žon":63,"žoj":249,"Āfr":113,"zēl":36,"zēj":212,"zēm":74,"zēt":500,"zēs":27,"zēr":47,"žni":23,"žo ":82,"žas":293,"žag":66,"žai":25,"žan":122,"žam":29,"ži ":383,"žer":29,"žes":28,"žet":61,"žei":43,"žel":23,"žen":74,"uža":37,"užu":32,"žus":34,"žur":90,"žoš":80," Н ":25,"žs ":70,"žre":77,"žu ":492,"ušā":109,"ušu":56,"ušo":68,"uši":230,"uša":268},"n_words":[2106271,2428959,2036825],"name":"lv"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/lit b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/lit new file mode 100644 index 000000000..3f3e0526e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/lit @@ -0,0 +1 @@ +{"freq":{"ūdu":237,"ūdo":102,"ūdi":671,"ūda":331,"D":8684,"E":5566,"F":3594,"G":7812,"A":19441,"B":11003,"C":5201,"L":15923,"M":12432,"N":7515,"O":2898,"H":3427,"I":6943,"J":8588,"K":17851,"U":3005,"T":11425,"W":951,"V":11358,"Q":106,"P":20146,"S":16914,"R":10122,"Y":441,"X":1264,"Z":1079,"f":17928,"g":102928,"d":143421,"e":363311,"b":73275,"c":39025,"Fed":229,"a":700709,"n":341806,"o":414082,"l":214716,"m":192290,"j":140065,"k":242084,"h":15703,"i":803156,"w":1450,"v":137211,"Fer":122,"u":266546,"t":305542,"s":495974,"r":352720,"q":282,"p":146221,"z":20490,"y":92511,"x":937,"ūgn":67,"ūgi":136,"":175,"²":445,"Fil":257,"Fin":83,"í":134,"é":265,"ä":96,"á":197,"à":65,"ü":86,"ú":64,"ö":70,"ó":158,"ė":94567,"ę":9237,"ā":164,"ą":20880,"Č":1561,"č":23545,"ī":70,"Į":732,"į":24134,"ō":147,"ų":90375,"Ž":2451,"ž":44691,"Š":7077,"š":70424,"Ū":76,"ū":25506,"Fal":71,"Far":66,"ūbr":365,"Fab":73,"Eri":121,"Est":230,"Eti":120,"Eur":1489,"Ekv":92,"Ele":243,"Eko":63,"μ":79,"ν":128,"ο":198,"ι":119,"κ":65,"λ":109,"ε":95,"α":204,"Ent":76,"σ":88,"ς":168,"ρ":114,"π":65,"τ":94,"ь":90," l":18168," m":39544," n":26364,"я":147," o":7927," h":2325," i":50039," j":10300,"ы":100," k":69096," d":33767," e":11412,"ц":67," f":7201,"ч":71," g":24899,"р":400,"с":408," a":48847,"т":349," b":21159,"у":184," c":5176," y":9991," x":101," z":358," u":9812," t":37056," w":140," v":43820," p":74653," s":59667," r":27511," J":8568," K":17825," H":3382,"Gel":228," I":6930," N":7489," O":2834,"Geg":68," L":15878," M":12380," B":10949," C":5111,"Ged":147,"С":93," A":19385," F":3572," G":7762," D":8642," E":5548,"л":327,"к":381," Z":1072,"й":180," Y":439,"и":579," X":1253,"п":122,"о":721,"н":471,"м":156,"г":113," S":16766,"в":327,"Ger":157," R":10064,"б":111," Q":106,"а":757," P":20081,"з":104,"Geo":114," W":927,"Gen":295," V":11305,"е":519," U":2992,"д":172," T":11383," ą":118," č":811," Č":1561," ė":303,"Gla":64,"Gib":75,"Gin":94,"Gil":90,"Gir":131," ž":11466," Ž":2446," ų":74," Ū":76," ū":618," Š":7067," š":19822," Į":722," į":17189,"šų ":222,"Gan":127,"Gal":319,"Gam":189,"Gaj":89,"Gau":103,"Gar":244,"Gai":76,"Gab":77,"ي":99,"ل":106,"م":65,"ن":73,"ب":63,"ا":149,"ر":65,"šūn":177,"Flo":97,"Fra":186,"Fri":67,"Fre":105,"A ":1074,"For":525,"F ":250,"Da":2187,"Cu":139,"Cy":71,"Cl":158,"Co":831,"Cr":212,"Ce":857,"Ch":1267,"Ci":314,"G ":220,"Ed":144,"Dv":187,"Du":605,"Dz":157,"Dy":151,"Do":667,"Dn":85,"Dr":666,"De":900,"Di":2059,"Fe":543,"H ":197,"Fa":428,"Eu":1613,"Ev":98,"Ex":73,"Er":363,"Et":189,"Es":386,"En":323,"Em":143,"Ep":87,"Ei":125,"El":573,"Ek":234,"Eg":301,"Ge":1133,"Ga":1414,"I ":1579,"Fu":220,"Fr":454,"Fo":751,"Fl":218,"Fi":559,"B ":521," С":93,"II ":866,"C ":1065,"Av":215,"Au":2682,"Ar":1944,"At":910,"As":631,"D ":380,"Ba":3819,"Az":731,"Af":806,"Ag":282,"Ab":409,"Ac":198,"Ad":552,"Am":1804,"An":2621,"Ap":788,"Ai":520,"Aj":72,"Ak":583,"Al":1985,"Bu":1123,"Br":1448,"Ca":774,"E ":242,"Bi":838,"Be":1548,"Bo":1206,"Bl":293,"Him":100,"Hip":99,"Kv":191,"Ku":1466,"Ky":76,"Kn":86,"Kl":830,"Kr":1957,"Ko":2668,"Le":2735,"Li":7587,"N ":208,"La":2652,"Lu":489,"Ly":250,"Lo":724,"Dū":73,"Me":1902,"Dž":420,"Mi":1792,"O ":471,"Ma":4741,"My":151,"Mu":533,"Mo":1998,"Ni":720,"Ež":273,"Ne":1803,"Na":1866,"P ":639,"Hel":151,"Ny":218,"Nr":561,"Nu":901,"No":779,"Ok":221,"Ol":265,"Om":89,"On":141,"Ją":106,"Oc":104,"Od":117,"Of":81,"Hen":73,"Ob":214,"Her":326,"Gi":594,"Gl":239,"Gr":2248,"Go":422,"Gu":450,"Gv":487,"Gy":327,"J ":126,"Ha":879,"He":851,"Hi":517,"Ho":543,"Hu":227,"Hy":110,"K ":521,"Ib":64,"Id":102,"ा":68,"Ig":304,"Im":227,"In":1584,"Ik":112,"Il":691,"Aš":111,"्":69,"Iv":75,"Is":624,"It":425,"Ir":401,"Ja":1783,"L ":366,"Dė":112,"Iz":149,"Ji":1102,"Je":435,"Jo":1434,"Bū":168,"Ju":1787,"Hal":105,"Ka":7199,"M ":415,"Han":93,"Ham":121,"Har":160,"Ki":1470,"Hav":88,"Ke":841,"Us":82,"Mū":111,"Ut":266,"Ur":330,"Uo":118,"Up":176,"Un":265,"Uk":462,"Ul":82,"Ug":88,"W ":71,"Ty":98,"Tv":72,"Gyv":237,"Tu":954,"Tr":1269,"To":1061,"Th":580,"Ti":954,"Te":1633,"Ta":3988,"V ":1768,"Sy":113,"St":1651,"Kū":349,"Sv":277,"Su":2454,"Wo":154,"Wi":274,"Wh":63,"Wa":211,"We":128,"Vy":520,"Vo":1251,"Vi":4324,"Vl":71,"X ":603,"Va":2935,"Ve":1368,"Uz":69,"Gva":257,"Gvi":230,"Iš":781,"Jį":73,"Pu":558,"Pr":4041,"Ps":108,"Kė":213,"S ":1115,"Pe":1585,"Gua":94,"ėžt":110,"Pa":7638,"Gud":68,"Pl":1104,"Po":1535,"Pi":2755,"Ph":112,"ėži":636,"Os":252,"Ot":63,"Op":146,"Or":562,"Jė":115,"R ":1502,"Se":1883,"Sc":300,"Si":1578,"Sh":180,"Sn":82,"Sm":286,"Sl":299,"Sk":1024,"Sr":63,"Sp":553,"So":1804,"Ru":2114,"Jū":181,"Ry":867,"Mė":156,"U ":260,"Jų":127,"Sa":3106,"Re":2289,"Ri":771,"Ro":1443,"Lė":71,"T ":426,"Ra":1932,"Gre":184,"Gri":532,"Gra":983,"Vė":216,"b ":435,"Už":349,"Gru":297,"Gro":162,"a ":85927,"Sė":67,"Yo":68,"Yr":183,"Z ":96,"Są":373,"Gol":68,"Sū":95,"Tė":65,"Za":514,"Ze":220,"Zi":68,"Zo":74,"Rū":230,"aė":112,"i ":72374,"fy":103,"gd":980,"ge":8770,"ga":24984,"Inf":65,"fl":318,"fg":67,"ff":102,"fi":4585,"fr":1236,"ač":2434,"fu":1782,"ft":398,"fo":4629,"Int":267,"Ins":77,"j ":778,"bę":413,"bė":6516,"gy":5384,"gz":596,"he":3549,"ha":2884,"gn":1795,"gm":391,"gl":2484,"bą":398,"gi":19462,"gh":277,"gv":1056,"gu":4898,"gt":1721,"gs":555,"gr":11904,"gp":278,"go":7511,"du":8502,"dv":2782,"dy":7581,"dz":385,"g ":2674,"ea":3623,"eb":2049,"ec":2366,"ed":9131,"de":15402,"dg":238,"Ilg":538,"di":31560,"dh":99,"dk":208,"dm":1790,"dl":210,"do":13968,"dn":150,"ds":320,"dr":6349,"ew":210,"ex":138,"eu":1022,"ev":4073,"ey":228,"ez":1754,"fa":1478,"h ":675,"Ind":876,"fe":2397,"eh":155,"eg":6969,"ef":1143,"ee":377,"el":20835,"ek":14743,"ej":2777,"ei":27949,"ep":4431,"Imp":87,"eo":2521,"en":55954,"em":13103,"et":36257,"es":24051,"er":37980,"ca":1365,"bz":182,"e ":76709,"by":382,"bs":381,"br":2910,"bu":7186,"bt":432,"bn":67,"bo":6948,"bj":1259,"bl":3193,"bi":8863,"bd":129,"be":9419,"da":31040,"f ":470,"cy":129,"cu":428,"ct":550,"cr":288,"co":1164,"cm":472,"ck":632,"cl":149,"ci":18836,"ch":6035,"ce":6724,"cc":125,"Iki":75,"c ":600,"az":2975,"ay":393,"ba":18685,"d ":4075,"at":26947,"as":91731,"ar":60917,"ax":94,"aw":113,"av":20318,"au":60068,"ak":21549,"al":70175,"ai":71518,"aj":9247,"ao":400,"ap":19804,"am":34880,"an":55907,"ac":11205,"ad":17624,"aa":279,"ab":6312,"ag":11672,"ah":654,"ae":3599,"af":1358,"nu":16862,"nt":40253,"ns":5838,"ič":2386,"nr":387,"np":87,"no":25328,"nn":299,"iė":81,"fų":79,"nz":353,"ny":7794,"nv":1496,"oe":521,"of":2043,"oc":3010,"od":8826,"oa":712,"ob":3847,"om":18799,"on":30734,"ok":15352,"ol":18423,"gš":230,"oi":681,"oj":37495,"ją":2263,"og":8954,"oh":445,"ot":12743,"m²":434,"os":91367,"gū":892,"ov":9611,"ou":825,"op":6292,"oo":622,"or":24858,"jė":931,"gų":1741,"ję":663,"r ":33992,"ox":93,"ow":356,"oz":1228,"oy":145,"pd":423,"pe":8966,"Ign":235,"gž":880,"pg":158,"pa":38606,"pc":152,"pl":7261,"pm":79,"pn":207,"po":11055,"ph":742,"pi":24691,"ką":1329,"pj":353,"pk":273,"lo":17284,"ln":7253,"lm":1772,"ll":1349,"ls":6461,"dū":239,"lp":828,"lv":2437,"lu":5702,"lt":6648,"dų":1603,"lz":63,"ly":8935,"gę":183,"gė":2321,"o ":113444,"md":246,"ma":41541,"mb":3140,"mg":95,"dž":9497,"me":27128,"mf":234,"mk":64,"ml":224,"mi":27912,"eš":4905,"mn":423,"mm":415,"mp":5761,"mo":36514,"mt":1706,"ms":5086,"mu":8277,"gį":95,"mz":185,"my":1666,"hė":71,"p ":5826,"na":39063,"nb":286,"nc":4749,"nd":18751,"ne":20163,"nf":1054,"ež":4639,"ng":14841,"nh":168,"ni":75394,"ią":1524,"nj":255,"nk":20248,"nl":177,"nm":383,"jy":130,"dį":460,"ju":6480,"eč":2839,"bū":3463,"jo":44031,"ki":36060,"kh":180,"kg":90,"ke":8017,"kd":1358,"kc":1366,"ka":55987,"m ":17519,"bų":1576,"ky":6899,"ks":8217,"cū":948,"kt":10687,"ku":20625,"eį":147,"kv":1386,"ko":29827,"kr":12212,"kl":14764,"km":7611,"kn":695,"li":63975,"lh":105,"lk":4623,"lj":376,"gą":598,"le":15356,"ld":6869,"lg":3321,"lf":324,"la":33178,"lc":275,"lb":5099,"fė":82,"cų":73,"n ":4899,"hr":575,"hs":179,"ht":431,"hu":755,"hi":2459,"hn":698,"ho":2226,"hl":151,"hm":207,"id":19607,"ic":4825,"ib":3663,"ia":66700,"ih":166,"ig":7460,"if":2042,"ie":61163,"hy":403,"k ":2911,"cė":232,"ir":43336,"is":76128,"it":24630,"iu":21162,"iv":9558,"ix":156,"aš":6163,"ii":607,"dą":519,"ij":49065,"ik":38607,"il":20049,"im":33709,"in":120546,"io":45938,"ip":8649,"je":37765,"až":6015,"ji":8060,"iz":7107,"dė":5783,"dę":233,"l ":5566,"ja":28492,"są":2757,"xi":80,"pš":499,"sč":2453,"pū":264,"rį":1236,"ww":153,"rę":1878,"z ":658,"rė":10366,"ož":891,"šį ":141,"nž":291,"oš":750,"wi":168,"rą":1320,"wn":67,"wo":98,"rč":361,"ws":118,"vy":6021,"nų":7287,"vz":413,"y ":1490,"wa":302,"we":130,"vl":94,"vk":143,"nš":207,"vi":38809,"mž":705,"vu":2039,"pį":89,"vr":219,"vs":237,"vn":98,"vo":18294,"pė":6097,"mų":3539,"uz":1745,"ux":118,"uv":14825,"ve":15404,"va":45949,"pę":314,"x ":613,"mš":101,"ui":3816,"uj":5784,"pą":197,"uk":12269,"ul":12572,"ue":864,"uf":303,"ėšr":96,"ug":10980,"lž":345,"uh":117,"ur":34041,"pč":97,"us":51555,"mū":487,"ut":11996,"um":9287,"un":10381,"uo":35316,"up":8302,"ty":13326,"lų":4078,"tz":73,"nį":1610,"tu":28297,"tt":447,"tw":77,"tv":4512,"ub":4404,"ua":1611,"ud":10289,"uc":1769,"w ":260,"to":36142,"tn":718,"tm":1109,"tl":1570,"ts":3686,"lū":569,"tr":20341,"oč":849,"tp":243,"tg":277,"tf":256,"te":29101,"tk":518,"tj":104,"lš":275,"ti":64800,"th":1088,"v ":492,"nę":1600,"kų":5621,"nė":25365,"tb":1204,"tc":76,"ta":61331,"su":18269,"sv":2479,"kū":2551,"ss":694,"st":45024,"sy":1283,"sz":67,"sl":4978,"sk":13287,"sn":3503,"sm":4814,"sp":7479,"so":8499,"sr":2349,"nč":4435,"sd":318,"sc":661,"sf":460,"se":19656,"sh":403,"sj":177,"ną":1594,"kš":7202,"si":47811,"rz":154,"jų":7476,"mė":4474,"u ":18088,"mę":301,"sa":23030,"sb":164,"mč":71,"rr":385,"jū":2283,"rs":5538,"rt":15475,"lį":874,"ru":13317,"rv":2004,"ry":13171,"rp":4617,"ro":31644,"rn":3965,"rm":7673,"rl":1174,"rk":4790,"mą":3705,"rj":224,"ri":79105,"rh":115,"rg":5620,"iž":716,"rf":267,"re":18683,"rd":4525,"rc":1831,"rb":9032,"ra":68430,"t ":8619,"lę":789,"ių":36065,"lė":8350,"kį":293,"qu":225,"iū":2482,"lč":267,"lą":1161,"iš":22230,"kė":5197,"s ":278368,"kę":593,"px":100,"py":2379,"pt":3572,"pu":6072,"jį":548,"pv":639,"pp":160,"kč":96,"pr":22301,"ps":4103,"IX ":219,"zę":74,"zė":693,"už":4062,"yč":2372,"vū":491,"vų":1508,"uš":1079,"tž":178,"IV ":137,"tš":139,"sų":1592,"vė":5454,"vę":713,"tų":12691,"tū":4346,"vą":321,"rž":1586,"rų":3959,"sū":452,"vč":186,"Hor":71,"zg":207,"zi":7116,"rš":2441,"zb":85,"zd":1810,"ze":985,"tę":1071,"za":3048,"Hom":79,"yz":303,"Hon":129,"tė":5769,"Hol":87,"zy":69,"rū":3551,"zr":101,"uč":735,"zu":1165,"tį":886,"zo":1897,"zn":153,"zk":67,"zm":1647,"zl":136,"pž":94,"yg":3318,"ye":94,"yc":258,"yd":2201,"ya":257,"yb":11044,"sę":282,"sė":3998,"pų":330,"yv":6788,"sį":230,"yt":11083,"ys":9392,"yr":12733,"yp":1504,"yo":203,"yn":5647,"ym":5531,"yl":2089,"yk":7720,"yj":6842,"tą":2285,"yi":98,"Arg":584,"Are":73,"Arc":130,"Ara":258,"Arm":184,"Ark":155,"Ari":111,"šči":2647,"Apo":92,"Atl":385,"Asu":66,"Ast":264,"Art":193,"Avi":81,"Aut":259,"Aus":646,"Auk":724,"Aug":852,"Ats":131,"yž":529,"Aze":82,"zū":96,"Azi":595,"zų":230,"yš":830,"šė ":158,"šės":100,"šėj":66,"Bag":85,"Bah":87,"Bai":88,"Bak":129,"Bal":1866,"Ban":272,"Bab":93,"Bad":64,"Bar":458,"Bat":90,"Bas":130,"Bau":99,"Abi":168,"Ada":67,"Ach":87,"Adm":203,"Adr":71,"Aga":104,"Afr":719,"šą ":73,"Air":332,"Aka":93,"Akm":194,"Ala":187,"Alb":193,"Alg":65,"Ali":208,"Ale":201,"Alt":143,"Aly":220,"Alk":99,"Alp":174,"Ame":1274,"Ama":241,"Ang":426,"Ank":145,"Ana":165,"And":549,"Any":154,"Ant":913,"Api":205,"Apa":86,"Buv":78,"But":90,"Bul":113,"Bur":231,"Bud":102,"Bue":112,"Bui":103,"Bru":71,"² ":443,"Cac":84,"Cad":64,"Cal":67,"Cam":66,"Car":189,"Can":84,"Cap":73,"Bet":72,"Ber":374,"Ben":312,"Bel":409,"Baž":77,"Bil":78,"Bir":299,"Bla":117,"Bre":103,"Bra":609,"Bro":169,"Bri":429,"Bol":312,"Bon":72,"Bor":174,"Bos":142,"Bot":70,"Dei":68,"Del":74,"Dem":131,"Dep":64,"Deg":63,"Dam":137,"Dan":260,"Dar":403,"Dau":478,"Dab":105,"Dai":135,"Dal":128,"Cho":100,"Chr":185,"Che":286,"Chi":117,"Chu":119,"Cit":67,"Cen":563,"Cer":118,"Cha":378,"Cro":65,"DP ":99,"Cor":127,"Com":218,"Col":154,"Con":133,"アアア":149,"FA ":185,"ón":71,"Dze":98,"Egi":189,"é ":79,"Dni":78,"Daž":276,"ą ":16360,"Dia":66,"Did":1104,"Dis":102,"Dir":98,"Din":76,"Die":275,"Dub":146,"Dun":110,"Dvi":80,"Dus":63,"Dva":68,"Dru":132,"Dri":158,"Dra":241,"Dod":83,"ES ":63,"Don":122,"Dom":99,"Nem":374,"Nev":213,"Neu":81,"Net":114,"ęs":3467,"Ner":231,"Nep":196,"ėz":158,"ę ":5692,"ėc":117,"ėd":1595,"ėl":4129,"ėk":704,"ėn":2911,"ėm":2033,"ėg":1127,"ėj":12119,"ėt":2531,"ės":37968,"ėv":406,"ėp":181,"ėr":671,"čų":69,"Nat":155,"Nau":859,"−":522,"Nig":114,"Niu":165,"ūšy":191,"Nik":109,"ūši":1752,"ėč":63,"Eže":263,"New":68,"ėž":954,"ėš":258,"Nar":128,"Nam":132,"Nag":68,"Nac":163,"Nuo":622,"ąl":250,"ąj":1470,"ąm":118,"ąn":83,"ąs":1224,"ąr":696,"ąv":409,"Nyd":143,"Či":814,"Če":428,"Ča":214,"či":21375,"čk":154,"če":803,"ča":249,"č ":409,"ąž":190,"čo":121,"ču":90,"ė ":26547,"ųjų":1526,"OS ":98,"Nr ":561,"Nov":113,"Nor":386,"Not":108,"čė":116,"įž":184,"Ją ":106,"Oke":81,"Och":90,"Obe":83,"Į ":110,"į ":15271,"Įe":85,"Įk":141,"įg":465,"įl":469,"įk":1035,"įm":672,"įd":140,"įe":122,"Oli":102,"Įs":221,"įr":905,"įp":182,"įv":1510,"įs":2207,"įt":836,"Ori":91,"Org":75,"Oro":67,"Ost":83," −":501,"Po ":75,"Plu":194,"š ":7298,"Plo":267,"Pli":66,"Ple":71,"Pla":439,"Pin":159,"Pil":450,"Paš":81,"Pir":463,"Pie":1313,"Pic":67,"šį":142,"Per":807,"Pet":236,"Pen":132,"Pel":183,"šč":2693,"šą":98,"šė":408,"Pat":292,"Pas":767,"Par":1014,"Pav":466,"Pau":206,"Pag":484,"Pab":107,"Pad":139,"Pan":697,"Pam":122,"Pap":991,"Paj":94,"Pal":1658,"Pak":297,"šg":221,"še":5219,"šd":199,"ša":5331,"šb":74,"šo":2052,"šp":366,"šm":981,"šn":613,"šk":10936,"šl":1712,"ši":16792,"šv":1932,"šu":1367,"št":7877,"šs":1233,"šr":983,"šy":1194,"Še":341,"Ša":886,"Šl":99,"Šo":70,"Ši":3391,"Šk":111,"Jėz":95,"Šu":220,"Št":155,"Šv":1543,"Šr":75,"Prū":117,"Kėd":210,"ō ":76,"Pun":96,"Pus":118,"Pue":76,"Pro":479,"Pri":882,"Pre":234,"Jį ":73,"Pra":2269,"Pod":91,"Pol":415,"Pon":120,"Pot":100,"Pos":67,"Pop":119,"Por":237,"žr":232,"žs":417,"žt":693,"žu":2236,"žn":2332,"žo":2063,"žp":171,"žv":1312,"žy":1527,"žb":100,"že":6838,"žd":1624,"ža":3699,"žk":289,"žm":1670,"žl":158,"ži":16869,"Žm":91,"Žy":116,"Žu":122,"Žv":178,"Ža":482,"Ži":399,"Že":955,"RS ":294,"Išs":132,"Išt":197,"ž ":1080,"žų":376,"Iš ":185,"žį":113,"žą":94,"žė":568,"SA ":111,"ūči":238,"Rad":254,"Rai":78,"Raj":66,"Rag":90,"Ram":470,"Ran":143,"ū ":138,"šų":238,"šū":280,"ūg":553,"ūd":1733,"ūb":446,"ūz":1060,"ūs":1429,"ūt":1461,"ūv":180,"ūp":172,"ūr":9049,"ūk":1535,"ūl":283,"ūm":598,"ūn":4467,"ų ":88718,"ūč":245,"ųj":1568,"ūš":2032,"ūž":93,"Ita":399,"Isp":323,"Isl":135,"įpr":139,"įma":63,"įmo":598,"Ira":230,"įsi":807,"įsk":80,"įkū":191,"įst":1175,"įta":351,"įte":278,"įtr":77,"įtv":117,"įra":525,"įre":301,"įro":74,"Izr":81,"įga":117,"įgy":242,"Dėl":85,"įei":119,"įdu":68,"įku":691,"Jav":80,"Jau":108,"Jas":71,"įla":456,"Jap":569,"Jan":213,"Jam":221,"Jak":178,"Jel":102,"Jer":74,"Jis":502,"Jie":135,"Ji ":425,"あ":83,"Jo ":148,"Įst":114,"Įsi":88,"Jos":270,"Jon":566,"ア":227,"Joh":97,"Būd":72,"Įku":124,"Jug":66,"Jup":99,"Juo":530,"Jur":232,"Juk":63,"Jun":554,"Įei":85,"Kad":98,"Kab":68,"Kai":1116,"Kam":412,"Kal":1098,"Kap":211,"Kan":625,"Kau":985,"Kat":242,"Kas":171,"Kar":1509,"Kaz":340,"国 ":82,"Ker":168,"Ket":93,"Ken":88,"Kel":250,"Kir":183,"Kit":124,"Kin":537,"Kip":63,"Kie":93,"Kil":126,"Kli":79,"Kle":64,"Kla":523,"Klu":106,"Kon":597,"Kom":332,"Kol":450,"Kos":140,"Kor":624,"Kop":80,"Kov":100,"LR ":167,"Kre":575,"Kra":414,"Kri":437,"Kro":173,"Kru":166,"Kry":125,"Kub":74,"Kul":193,"Kun":174,"Kup":188,"Kur":371,"Kva":100,"Les":78,"Lep":69,"Leo":93,"Len":1971,"Lei":123,"Lau":223,"Laz":170,"MC ":504,"Lai":279,"Lat":571,"Lao":67,"Lap":196,"Lam":138,"Lan":215,"Lab":226,"Kuž":106,"La ":159,"Lib":176,"Lia":138,"Lie":6085,"Lig":81,"Lim":100,"Lin":276,"Lit":89,"Liu":198,"Liv":74,"Luk":93,"Lua":75,"Los":103,"Lot":96,"Lon":143,"ūgš":200,"ūs ":568,"ūpi":97,"ūra":1708,"ūse":158,"ūry":183,"ūru":361,"ūro":3121,"ūri":1981,"ūks":471,"ūka":130,"ūki":544,"ūkl":137,"ūma":254,"ūna":1137,"ūmi":118,"ūdž":157,"Lyg":63,"ūnu":353,"ūni":1251,"ūne":67,"ūno":452,"ūrė":579,"ūrę":259,"Mek":335,"Men":159,"Mel":164,"Mes":186,"Mer":401,"Met":158,"Med":222,"Mez":64,"ūzi":829,"Džo":137,"ūrų":466,"Dža":76,"Dži":72,"Dže":84,"ūkš":76,"ūsi":141,"ūną":68,"ūst":200,"ūnė":216,"ūta":74,"ūte":79,"Man":463,"Mal":406,"ūti":914,"Mar":1387,"Mas":288,"Mag":384,"Mad":147,"Maj":79,"Mak":226,"Mah":72,"Mai":142,"ūty":109,"Mac":86,"ūmų":111,"ūvi":114,"Mau":95,"Mat":219,"ūnų":861,"ūrą":276,"Mok":227,"Mol":370,"Mon":426,"Mos":65,"Mor":209,"Mot":313,"Moz":127,"ūzų":144,"NR ":79,"Mik":194,"Mie":142,"Mia":99,"Mic":168,"Mit":95,"Mir":79,"Mis":99,"Mil":131,"Min":395,"ūtų":160,"ūsų":232,"Maž":500,"Mur":145,"Mus":128,"Miš":117,"Sąj":308,"XX ":204,"XV ":71,"кий":66,"Wor":95,"Wil":72,"Win":96,"XI ":73,"War":82,"Vyr":158,"Vyt":150,"Viž":91,"Vok":795,"Vol":265,"Viš":70,"Vis":391,"Vit":100,"čkų":69,"Zar":256,"Zel":141,"之":194,"並":122,"三":326,"丁":115,"Yra":183,"三三":72,"Sve":90,"Sva":109,"Sur":111,"Sus":251,"Suv":802,"Sum":113,"Suk":74,"Sup":79,"Suo":198,"Sun":92,"Sud":274,"Suc":101,"Sub":64,"Str":249,"Stu":148,"Sti":184,"Sto":157,"Sta":653,"Ste":219,"Ten":81,"Tei":320,"Tel":387,"Tek":128,"Tam":147,"Tan":110,"Tar":749,"Tau":535,"Tai":1790,"Tak":96,"Tal":105,"Tad":89,"Ski":160,"Skr":105,"Sku":184,"Ska":362,"Sim":140,"Sil":118,"Sir":117,"Sin":192,"Sid":156,"Sie":159,"Sib":270,"Sic":64,"Ser":315,"Sep":68,"Sen":642,"Sel":68,"Sem":92,"Sei":374,"TV ":98,"Kūn":234,"国":86,"Spa":162,"TS ":71,"Spi":75,"Spe":132,"Spo":74,"Sof":72,"Sok":963,"Soc":156,"Sol":99,"Son":84,"Sos":108,"Sky":69,"Slo":158,"Smi":70,"Sma":84," 三":86,"Ryt":687,"Ryg":105,"Jų ":127,"Jūr":171,"Rus":1573,"Rug":83,"Rud":101,"Rum":121,"Sak":119,"Sam":191,"Sal":563,"Sac":85,"Sco":107,"Sav":191,"Sat":80,"Sau":518,"Sar":175,"San":807,"Mėn":80,"Rač":79,"SI ":77,"Res":1390,"Rio":84,"Rin":77,"Rib":131,"Rie":98,"Ras":159,"Rau":279,"Rec":68,"Red":71,"Rei":156,"Reg":116,"Ren":82,"Rok":173,"Rob":64,"Rod":82,"SR ":568,"Ros":182,"Rom":573,"SS ":87,"čų ":69," 之":78,"SO ":120,"Vai":313,"Vad":65,"Vel":220,"Ven":367,"Vei":167,"ски":73,"Vas":102,"Van":212,"Val":695,"Vak":682,"Var":578,"Vaš":70,"Vid":634,"Vie":542,"Vir":184,"Vil":1774,"Vik":201,"Vin":109,"Ver":344,"Ves":109,"Ukr":322,"Ukm":131,"Uni":208,"Uru":89,"Ura":110,"Ute":210,"Upė":66,"VD ":82,"VI ":165,"Ter":267,"Tet":74,"Tes":113,"The":467,"Tib":113,"Tie":67,"Tik":149,"Til":74,"Tim":101,"Tin":67,"Tir":87,"Tiu":72,"Tor":126,"Tok":232,"Tol":111,"Tom":115,"Ton":98,"Tru":94,"Tro":116,"Tri":330,"Tre":156,"Tra":520,"Tur":537,"Tun":69,"šga":146,"ši ":168,"šel":123,"šer":281,"šei":4330,"ša ":145,"še ":72,"šas":283,"šar":241,"šau":451,"šac":68,"šai":175,"šak":893,"šal":2584,"šam":125,"šan":259,"Švč":176,"Šve":932,"Švi":88,"što":898,"štr":99,"šte":875,"šti":1747,"škų":474,"šta":1289,"šun":139,"šuo":95,"šul":170,"šum":70,"šus":224,"šuj":65,"šuk":112,"štu":1243,"šty":912,"švi":810,"šve":671,"šva":235,"šut":236,"šuv":83,"švy":117,"špa":109,"šką":187,"špl":90,"šon":165,"šor":222,"šos":190,"šiš":128,"škė":457,"šre":107,"šra":138,"šri":577,"šiū":137,"šių":982,"šsi":699,"šsp":63,"šsk":346,"šru":91,"šsa":81,"šmė":100,"šku":531,"šky":77,"ško":2173,"šle":715,"šli":309,"šla":532,"šme":157,"šeš":251,"šmi":172,"šo ":946,"šma":81,"šmo":366,"šni":181,"šią":67,"šne":70,"šna":94,"šny":138,"šno":80,"šoj":128,"šok":166,"šom":149,"šia":7811,"šie":268,"šin":2480,"šio":1156,"šil":344,"šim":653,"šik":111,"šiu":646,"šir":121,"šis":1523,"šdė":102,"ška":2905,"ški":3659,"ške":337,"štų":188,"štė":332,"štį":112,"šyt":666,"šys":236,"šym":121,"štą":94,"ęs ":3114,"ęsi":184,"ęst":139,"bje":1237,"baž":702,"bis":206,"bit":262,"biu":413,"bio":445,"bip":90,"bir":575,"bik":90,"bil":1165,"bim":181,"bin":2312,"bij":590,"bo ":831,"blo":199,"ble":254,"bli":2467,"bla":154,"bod":66,"bok":148,"bol":1634,"boj":747,"bež":91,"biš":132,"bon":209,"bom":266,"bor":294,"bot":239,"bos":2270,"be ":431,"bam":151,"ban":1542,"bak":168,"bal":1952,"bai":1573,"baj":127,"bac":144,"bad":71,"baz":180,"bau":383,"bat":206,"bas":1718,"bar":1644,"bda":77,"bi ":151,"bei":2412,"ber":929,"ben":2915,"bel":329,"bek":139,"bev":245,"bes":726,"bet":875,"bia":875,"bib":123,"ėdo":412,"bie":263,"ėdi":261,"ėda":433,"buč":70,"bzd":176,"− ":502,"ca ":297,"buž":82,"car":324,"cas":107,"cat":74,"can":137,"cac":140,"cal":88,"ce ":305,"bių":787,"bri":867,"bro":454,"bra":835,"bre":106,"bry":134,"bu ":188,"bru":157,"bso":103,"bse":75,"bta":77,"bst":94,"bti":224,"btr":68,"buo":284,"bur":719,"bul":328,"buk":109,"bum":669,"bui":94,"bud":276,"buv":3564,"but":190,"bus":430,"brė":285,"byl":146,"bys":99,"abų":128,"aka":10783,"am ":1782,"ake":779,"akc":437,"aki":1290,"aji":120,"ėza":80,"ajo":4851,"aju":423,"aiz":904,"al ":2864,"adė":694,"aja":2169,"aje":126,"aik":6012,"ail":788,"aim":3610,"ain":2341,"aip":4816,"air":2272,"ais":9853,"ait":1788,"aiv":2833,"ėsč":100,"ak ":92,"aig":1833,"aid":2977,"aib":279,"ahi":72,"aho":88,"ėvi":102,"aj ":639,"abė":174,"agv":331,"agy":177,"ėva":79,"aha":210,"agl":74,"agm":87,"agi":657,"ėnų":1107,"agr":3158,"agu":296,"agn":741,"ago":977,"anu":591,"anz":118,"any":235,"ano":3129,"ann":125,"anm":118,"ant":17439,"ans":1524,"aič":1223,"anr":199,"ane":1374,"ang":3590,"ani":4762,"anj":123,"ank":4229,"ap ":76,"ana":4088,"anc":1441,"and":6903,"amu":630,"ėtų":311,"amt":459,"amy":484,"amz":131,"amm":86,"amo":3569,"amp":1185,"ams":2382,"ami":5086,"adž":530,"ame":5511,"amb":1223,"ama":10174,"ao ":130,"adų":80,"agė":263,"aly":3612,"alv":1945,"alu":1766,"alt":2672,"als":5664,"alp":263,"alo":3517,"aln":4883,"alm":300,"all":289,"alk":1267,"alg":429,"ali":17593,"alc":176,"ald":5080,"ale":3230,"Šan":75,"ala":5633,"alb":4521,"Šal":318,"Šak":157,"an ":1340,"Šau":91,"ėtį":118,"akv":76,"aky":230,"aks":329,"akr":1125,"Šar":99,"aku":724,"akt":1972,"ako":1771,"akn":187,"akm":413,"akl":356,"aba":2740,"abe":207,"abi":1011,"abl":158,"abo":330,"abr":414,"abs":143,"abu":396,"abz":181,"ae ":3025,"aca":72,"ad ":1165,"ac ":144,"ab ":182,"afo":102,"afr":63,"aft":132,"afi":672,"ai ":28957,"aga":3563,"age":494,"afy":94,"aen":65,"ael":136,"aei":134,"afa":115,"ado":1953,"adr":251,"adm":1262,"adi":7918,"ade":803,"ady":144,"adu":285,"adv":445,"ack":137,"aci":7737,"ach":900,"ace":1807,"ada":1767,"act":213,"azm":131,"azo":425,"azi":1049,"arš":379,"azl":78,"auč":212,"arū":95,"atė":313,"aze":155,"azg":73,"aza":391,"azd":314,"ėcė":111,"arų":1990,"arž":560,"apš":64,"asč":85,"arė":673,"arę":105,"atą":166,"ėgo":219,"ėgi":261,"apų":68,"asė":868,"ėga":161,"avų":296,"ėkt":249,"Šta":114,"ėn ":149,"Šv ":293,"ėla":197,"ėli":1870,"auž":306,"ba ":7831,"azė":203,"ėly":383,"ėgė":107,"Šud":88,"ėme":99,"ėdž":122,"ėmi":1028,"ėms":611,"atū":905,"ėja":1671,"ėl ":1089,"ėdė":151,"ėji":1633,"ėje":5476,"atš":113,"asų":302,"ėjo":1675,"avė":225,"avę":277,"ėju":616,"atž":107,"ėki":72,"auš":245,"atų":809,"ėkl":135,"ėkm":115,"alč":210,"alė":817,"at ":1471,"ėpa":71,"arg":513,"aiž":139,"are":1358,"ard":2315,"arc":907,"arb":6774,"ara":6684,"arp":3635,"aro":3645,"arn":1263,"ėgų":151,"arm":594,"arl":418,"ark":2565,"amą":414,"ėję":513,"arj":115,"ari":8416,"alį":375,"aru":2631,"arv":357,"Šie":85,"Šia":1607,"arr":83,"ars":1153,"ajū":107,"art":6116,"au ":2801,"asa":3470,"ary":2268,"ajų":380,"akš":168,"asi":8082,"ash":79,"ase":867,"asd":82,"aso":710,"asn":256,"asp":307,"ask":1323,"aną":115,"asm":1404,"ės ":35616,"asl":491,"ėnu":240,"ėno":201,"aos":78,"agū":453,"ajė":352,"ar ":4730,"ėni":505,"agų":187,"apa":1300,"ėne":311,"ape":335,"ėna":175,"apd":357,"aką":119,"api":6467,"apg":138,"apl":1752,"apk":227,"apo":1183,"apr":1671,"aps":2502,"apt":510,"apu":404,"apv":201,"apy":1793,"akė":76,"as ":68022,"Ši ":192,"aiš":684,"alą":244,"ėny":160,"ėto":359,"ava":4842,"apė":321,"amų":755,"auz":79,"ėty":82,"aut":4104,"Ško":96,"avo":3989,"ėta":441,"avi":8394,"amž":667,"ėti":999,"ave":644,"ay ":151,"Šeš":127,"avy":790,"anų":720,"avu":579,"arč":154,"arą":182,"anž":85,"anė":190,"akų":454,"ata":3198,"asu":274,"ast":4236,"ass":235,"anč":3200,"asy":280,"asv":107,"Šil":407,"atm":389,"atn":97,"atk":211,"atl":931,"ėra":344,"Šip":64,"atr":904,"Šio":192,"ato":2724,"Šim":69,"atp":71,"ėlė":390,"ate":2024,"atf":194,"Šis":287,"Šir":132,"ėri":244,"ati":4429,"atg":129,"Šiu":193,"ath":131,"alų":2328,"ėsn":115,"aub":219,"att":75,"ats":3002,"alū":263,"atv":1480,"atu":978,"ėst":385,"aty":1953,"aul":3204,"aum":246,"aun":1743,"auo":93,"aup":243,"ėmė":214,"aur":9854,"aus":15793,"ėjų":416,"aud":4737,"ėsi":184,"aug":7354,"ėse":1427,"auj":2881,"auk":5802,"ος":93,"ος ":93,"Vėl":110,"ς ":168,"ėči":63,"Rūd":99,"α ":85,"Sūd":82,"アア":188,"ий ":71,"jei":143,"jer":295,"jek":1582,"jen":63,"jet":69,"jev":166,"ji ":3840,"aža":639,"ažd":237,"aže":494,"aži":1113,"ažn":2141,"ažo":516,"ažu":326,"ažy":107,"jad":82,"izė":124,"jas":2376,"jav":90,"jau":1901,"jap":205,"jar":157,"jak":120,"jan":2657,"jam":5082,"jag":120,"jai":1573,"je ":35197,"ažį":104,"ažų":112,"jog":127,"jok":177,"joj":10950,"jon":4897,"jom":502,"jot":90,"jos":20733,"jor":274,"ск":151,"jis":383,"jim":2557,"jin":736,"jie":392,"ст":86,"jo ":6159,"itn":63,"itm":290,"itk":77,"ioč":215,"itr":489,"ito":5645,"itv":127,"inį":1158,"itu":2883,"itt":74,"ity":2401,"ilų":166,"iub":80,"iuc":232,"ilž":195,"iud":174,"iuj":1926,"iuk":566,"iui":902,"isk":1115,"iną":194,"ism":716,"isl":291,"iso":747,"isp":344,"iss":63,"ikū":653,"inč":492,"isu":1429,"ist":10402,"isv":554,"isy":283,"ikų":1702,"inė":20322,"inę":1356,"ita":3101,"ite":2150,"ith":115,"iti":4567,"ivo":225,"inų":1093,"ivy":313,"ivu":89,"irą":66,"inž":95,"ius":6964,"iur":510,"ium":511,"iul":202,"iuo":4507,"iun":199,"imų":1088,"iuz":146,"iut":1006,"iuv":85,"iva":5713,"ipė":458,"ix ":136,"ivi":1601,"ive":1142,"ipr":458,"ipo":522,"ipu":252,"ips":676,"ipt":461,"ipi":440,"iką":480,"igž":771,"ipl":309,"ikę":172,"is ":52601,"ikė":859,"ion":5845,"iop":388,"ior":133,"ios":8346,"igū":296,"iot":445,"iog":457,"iją":1411,"ioj":3109,"iok":271,"iol":667,"iom":700,"iję":103,"ipa":679,"ipe":332,"iov":183,"igų":264,"ioz":68,"ir ":24988,"iru":470,"irv":355,"irs":602,"ijū":154,"irt":3182,"iro":972,"irp":210,"irm":1827,"irn":109,"irk":393,"iri":3779,"imą":1476,"ikš":1311,"isi":2798,"ish":114,"ise":370,"isd":71,"isc":198,"isa":1339,"iu ":2871,"imė":266,"ijų":2456,"iry":540,"ire":616,"irg":245,"irb":684,"ira":1224,"ird":228,"it ":169,"ilė":771,"ilę":379,"ašų":113,"iuš":73,"dėt":870,"dės":969,"itų":1031,"dėj":1386,"dėm":219,"dėn":263,"dėl":1132,"dę ":83,"ivė":295,"isų":290,"ivų":75,"dęs":150,"ja ":13854,"itą":217,"ipų":79,"isė":1814,"isę":115,"isą":156,"irę":81,"irė":261,"irž":446,"irų":76,"izu":821,"itį":88,"irū":86,"izo":451,"izn":83,"izm":1490,"izi":1251,"irš":1690,"izg":80,"ize":116,"izd":791,"iza":1796,"itę":494,"itė":412,"dė ":795,"kaš":89,"kik":107,"kij":2691,"kim":1590,"kil":1486,"kia":4293,"kie":2272,"kiv":63,"kin":5088,"kio":2376,"kip":128,"kir":3853,"kis":920,"kit":2704,"kiu":661,"kaž":63,"km ":5939,"ki ":3521,"kdy":223,"kg ":77,"kea":110,"ked":124,"kei":560,"kel":3590,"ken":372,"kep":138,"kes":439,"ker":661,"ket":958,"ke ":844,"kci":1331,"kda":895,"kdo":201,"kra":4663,"kre":1055,"klė":428,"kt ":364,"kių":2205,"kiš":1820,"klą":309,"ksa":796,"kse":134,"kry":1180,"kmė":162,"ku ":438,"kro":983,"kru":318,"kri":3232,"kov":891,"km²":423,"kot":816,"kos":8611,"kor":653,"kop":332,"koo":136,"kon":3138,"kom":3814,"kol":1241,"kok":423,"koj":2216,"koh":148,"kod":1418,"ks ":271,"kmu":184,"kme":718,"kmi":91,"kny":405,"kni":155,"kią":80,"klu":945,"ko ":5671,"kly":141,"kle":472,"kla":7712,"klo":1474,"kli":2387,"bų ":1576,"jyb":83,"jus":1760,"jun":1716,"juo":1236,"jur":161,"juj":263,"jui":107,"jud":642,"būn":290,"būk":89,"būr":626,"būs":338,"būt":996,"eči":2678,"dį ":451,"ju ":392,"būd":1044,"kaz":236,"kav":389,"kat":1246,"kau":876,"kar":10769,"kas":6028,"kap":1244,"kan":2442,"kal":11413,"kam":1843,"kaj":116,"kak":332,"kai":11174,"kag":106,"kad":1450,"kac":439,"kab":221,"ka ":5403," Ga":1407,"bėt":104,"bės":4168,"bėn":81,"bėm":94," Ge":1126,"bėj":670," I ":269,"bėg":144,"bėc":110," Fo":747," Fu":218,"bę ":399," Fr":454," Fi":557," Fl":215," Ha":877," He":844," Gy":327," J ":93," Go":421," Gr":2243," Gu":448," Gv":487," Gi":589," Gl":237," Ig":304," Id":102," Ib":64,"guž":295," K ":135," Hy":110," Hu":227," Ho":536,"ha ":309," Hi":515," Ji":1102," Je":431," L ":82," Ja":1776," Iz":149," Dė":110," Iv":74," Ir":401," Is":623," It":425," Im":226," In":1579," Aš":111," Ik":112," Il":691,"ham":166," M ":181,"han":534,"hai":104," Ka":7194,"haj":70,"hal":255,"hau":98," Ke":839," Ki":1466,"har":550,"has":169,"hat":88," Jo":1429," Ju":1786," Bū":168,"hab":63,"had":70," La":2647," Le":2732," Li":7563," Kl":830," Kn":86," Ko":2662," Kr":1957," Kv":191," Ku":1464," Ky":76," Ma":4719," O ":103," Mi":1782," Dž":420," Me":1896," Dū":73,"he ":653," Lo":721," Ly":249," Lu":488," Ne":1796,"а ":158," P ":142," Na":1859," Ež":273," Ni":719," Mo":1991," My":150," Mu":530,"hel":177,"hei":83,"hev":142," A ":384,"het":95,"hes":72,"her":871,"heo":356,"hen":157,"hem":647,"hi ":89," B ":160," C ":148," Ap":776," Am":1804," An":2616," Ak":583," Al":1977," Ai":520," Aj":72," Ag":281," Af":804," Ac":198," Ad":550," Ab":408," Ba":3796," D ":97," Az":731," Av":213," Au":2682," At":910," As":629," Ar":1939," Be":1541,"hie":74,"hid":370," Bi":835,"hia":94,"hip":216,"hin":342," Bl":291,"him":102,"hil":142," Bo":1202,"hij":135," Br":1443," Bu":1122,"his":79,"hit":343,"hir":118," E ":80," Ca":760," Ce":856," Ci":314," Ch":1252," Cl":153," Cr":197," Co":818," Cu":130," Cy":71," Da":2178," Di":2044," De":898," Dr":663," Do":658," Dn":85," Dy":151," Dz":157," Du":604," Dv":187," Ed":144," G ":65," El":573," Ek":234," Ei":124," Eg":301," Et":188," Es":385,"hlo":65," Er":362," Ep":87," En":317," Em":142," Ex":72," Eu":1612," Ev":98," Fe":541,"ho ":213,"hma":111," Fa":424," H ":80,"gma":128,"go ":1512,"gme":171," Są":373,"glo":300,"gle":181,"gli":959,"gla":443," Wo":146," Wi":267," We":123," Wa":210,"й ":139," Vy":520," Rū":228,"gog":103," Zo":73," Ze":220,"gno":577," Zi":68," Tė":65,"gni":373," Za":514," Yr":183,"gne":245,"gna":449," Yo":68," Sė":67,"giš":189,"gpj":199," Vė":216,"о ":63,"gr ":135," Sū":95,"goj":625,"gom":579,"gol":244,"gon":466,"gos":3067,"gor":332,"got":295,"gov":127,"gu ":264," a ":1580,"gro":326," Už":349,"gry":429,"gru":2484,"gra":4017,"gių":416,"glė":83,"gri":3118,"gre":877," R ":90," Jė":115,"gty":102,"glų":187,"gto":154," Os":251," Or":560," Op":146," Po":1526,"gui":113," Pl":1099," Pi":2753,"gum":1158," Ph":102,"gul":484," Pe":1581,"gua":121,"gub":128," Pa":7618,"gue":64,"gst":140," Ny":218," Nr":561," Nu":899," No":770," Ol":265," Ok":221," On":138," Om":89," Ją":106,"gti":868," Od":117," Oc":104," Of":78," Ob":214,"gta":465," Lė":70," Ra":1919,"gvo":218," Ro":1436,"grą":89," Re":2283," Ri":769," Kė":213," S ":144,"guv":99,"gut":67,"gur":151," Pr":4036," Ps":108,"gus":1460," Jį":73," Pu":558,"gun":99,"guo":261," Iš":781,"gvi":98,"gva":685," Sy":113," Sv":277," Su":2443,"grį":216," St":1586," Kū":349," Ta":3980,"gsė":181," V ":128,"gyb":293,"gyd":154," Th":577," Ti":951," Te":1623," Tr":1262,"gyl":77,"gyn":197," To":1060," Ry":866," Jū":181," Ru":2112," Sa":3099," Jų":127,"е ":76," Mė":156," Sh":178," Si":1574," Sc":292," Se":1876," So":1791," Sp":549," Sr":63," Sk":1023," Sl":298," Sm":286," Sn":82,"grū":76," Uz":68," Va":2931," X ":111,"и ":92," Ve":1358," Vi":4303," Vl":71," Vo":1248," Tu":948,"gyv":4200," Tv":72," Ty":93,"gys":254,"bė ":1092,"gzi":495," Ug":88," Uk":462," Ul":82," Un":258," Uo":118," Up":172," Ur":330," Us":82," Mū":111," Ut":265," ja":1311,"iai":12600,"iak":2489,"iaj":841,"iam":6822," dė":1157,"ial":2617," iz":109,"ian":3835," ji":819,"iap":102,"ias":3810,"iar":592,"iau":21521," je":150,"iat":599,"iav":1428," im":762," in":5586," ik":3172," il":1403,"ic ":202," aš":299,"iab":113,"iac":1098," is":1471,"iad":246," it":186," ir":24988,"iag":1048,"ibl":199," ka":22789,"ibi":638,"ibo":741," m ":8180," kg":76,"ibr":360," ki":5307," ke":3545,"ibu":210," jo":2067,"id ":126,"iba":407," bū":2814,"ibe":354," ju":2553," gy":4128," bė":99," ha":363," he":768," gi":1781," gl":388," gr":5317," go":132,"ia ":6457," gu":260," gv":148," k ":116," id":308," ie":140," hi":591," ho":365," hu":138,"iet":17789,"iev":1199," ni":198," ež":2821,"iel":363,"iem":1768," ne":7202,"ien":11441,"iep":530," na":5031,"ier":804,"ies":9563,"ied":842,"ieg":235," my":64,"iek":3632,"iej":2087," mu":1417," mo":7083," mm":210,"ieb":372," ok":189," ol":297," ją":256," oj":106,"ifo":912," od":155," of":644," ob":1166,"ife":169," ny":106,"ifi":598," nu":12007," no":1368,"ifa":104," le":2689,"icr":108,"icu":77," li":4372,"ico":274,"ick":163," la":7451," kv":492," ku":12047,"ici":1931," kt":309,"ich":922," ky":193,"ice":275," kn":370,"ie ":6151," km":6372," kl":2310,"ica":672," kr":4858," ko":8974," me":9020,"idy":563," dž":138," eš":161,"idu":2683," mi":7229,"idv":63," ml":158," gė":342,"я ":102," o ":1212,"idr":494,"ido":937,"idm":185," ma":4864," lu":92,"idi":2189," ly":1967,"ide":3721,"ida":3570," lo":631," ag":258,"aša":470," ab":508,"iid":108," ac":88,"aše":79," ad":1540," am":912,"idą":63,"ašk":334," an":3700," ap":10764,"aši":756," ai":453,"ašo":756," ak":1627,"ašl":96,"ašm":98,"iim":317," al":1456," av":222," au":6951," ar":9760," at":6438,"ašu":283,"ašt":1920," as":2056," d ":1323,"ašy":781," ba":4469,"il ":133,"idė":1297,"ija":13519," bi":992,"ije":95," be":6829,"iaž":208,"iji":627," bo":424," bl":292,"ijo":29798,"ieč":1593," by":148,"ibū":258," bu":4118,"iju":808," br":918," ca":122,"ibų":249," e ":82,"im ":74,"ika":5325,"ige":301,"iga":1803,"ii ":82,"igl":111,"igm":118,"igh":167,"igi":1406,"igu":322,"igt":307,"igr":206,"igo":701,"ign":206,"dą ":495,"ibė":80,"igy":112,"ik ":1008,"imo":10288," er":623,"imn":310," et":431," es":1712," en":778,"ims":264," em":226," ep":239,"imp":910,"idž":3127," ei":683,"imf":152,"ime":1400," el":1508,"imd":91," ek":915," ef":150,"imi":2582,"ieš":2115," eg":645," fe":604,"ip ":3767,"inc":1582,"ind":4737,"ina":9499," fa":728,"imt":970,"imu":2073," eu":161," ev":173,"imy":291," fu":1594,"inm":71,"ino":4836," fr":209,"ašč":176," fo":1905,"int":7918,"ins":1597,"inf":613," fl":132,"ine":2681,"iež":504,"ing":5394," fi":1973,"ini":42857,"ink":9182," ge":4705," ga":6719,"ioc":68,"iod":332,"inu":851,"inv":260,"iny":2814,"ašė":95,"iko":8237," cm":466,"ikm":102,"ikl":4355," co":131,"iki":8010," ce":2733,"ike":332," ch":821," ci":727,"ila":1055,"in ":677," da":11917,"iky":490," cu":64,"ikt":1187,"iku":935,"ikr":1885,"iks":1325," do":606,"ilp":157,"ilo":1045,"ill":367," dr":1386,"ilk":807,"iln":1654,"ilm":942,"ilg":1557,"ilj":190," de":4787,"ili":7113,"ild":935," di":7861,"ile":510,"ima":10774,"imb":476," g ":911,"idų":320,"igė":179,"io ":24537," dv":1810,"ily":138," du":1631,"ils":105,"ilt":617,"ilu":734," dy":1060,"ilv":228," sū":347," zo":229," rū":2140,"hol":535," tė":174,"hom":130,"hon":117,"ко":78," tę":151,"hos":152,"hot":89,"hov":154,"hop":73,"hor":425," yp":378,"ка":91,"ки":93," yr":9482," sė":250,"hni":331,"hno":260," są":2199," pū":86,"ин":66," ww":64,"ий":86," ož":66,"ра":115,"hua":109,"htt":75," už":2934,"hst":134,"ол":71,"ов":122,"hry":109,"но":71,"hro":216,"ни":79,"hri":103," tū":466,"ht ":128,"на":78,"hra":72," vė":1295," ru":1285," jū":1646," ry":5467," mė":866," jų":977," sa":11017," sf":110," se":4482," sc":162," si":4889," sn":168," sm":866," sl":1116," sk":5183," sr":2054,"hyl":73," sp":3493," so":1538,"ве":64," lė":404," t ":238," ra":8074," re":7211," ri":2152," mą":77," ro":1078," pv":390," pu":2293," jį":257," pr":18161," ps":398," s ":108," px":100," lą":374," iš":11701," os":113,"hum":232," ov":65,"hun":68," op":537," or":3230," jė":239,"ан":71,"ал":63," pe":3678," pa":29839,"ар":72," pl":4167," po":4807," pi":10334," pj":71," vy":3074," y ":87," x ":92," va":20321," ve":4247," pė":140," vo":600,"cėl":111," vu":113," vi":14126,"ер":72,"ен":65," ty":567," tv":701," tu":2991," mū":318," ur":214," uo":741," up":3500," un":1322," ul":71," ug":910," ta":10594," nė":349,"hyt":188," st":5898," kū":1165," sv":1124," su":14551," tr":3585," lū":96," to":1975," th":302," ti":5451," te":9733,"fes":435,"fer":701,"fed":364,"fen":78,"fek":526,"fel":82," Ča":214," Či":814," Če":428,"fga":67,"faz":69,"fas":187,"far":115,"žų ":324,"fan":250,"fak":286,"fal":119,"fai":102,"ezė":113,"fe ":71,"etų":4160,"esų":111,"evė":459,"evų":124,"fa ":109,"esė":92,"erį":83,"etą":266,"erė":268,"erč":118," če":566,"esč":286," či":215,"epš":367,"esą":106,"ezu":126,"erų":398,"erž":348,"etė":1071,"eza":64,"esį":127,"ezo":319,"eze":135,"erš":197,"ezi":795,"eta":5454,"enę":98,"ete":1059,"elš":173,"eti":4554,"etn":281,"esp":1704,"esn":1467,"eso":815,"est":4994,"esu":549,"enč":626,"ess":157,"esy":202,"enė":1439,"ekų":115,"eud":63,"euk":102,"eto":2887,"etr":2354,"ett":92,"enį":206,"etu":10440,"etv":1625,"ety":134,"ew ":79,"eve":542,"eva":902,"evo":715,"evi":699,"eut":158,"eur":366,"eus":130,"epė":63,"emų":168,"erą":156,"evr":154,"ey ":158,"evy":281,"enų":1350,"epe":177,"epc":101,"epi":513,"eph":64,"er ":2219,"epa":1258,"eot":67,"eor":538,"eom":87,"eol":734,"eop":149,"eon":218,"eiš":1009,"ekė":269,"es ":8000,"ekę":92,"ept":436,"eps":96,"epu":165,"epo":412,"epr":642,"erk":587,"erl":418,"eri":10880,"emą":219,"erg":1284,"ere":1184,"erf":77,"erc":545,"erd":659,"era":5900,"erb":981," ėj":280,"elę":124,"elė":2221,"et ":1493,"ekį":64,"esj":92,"eną":643,"esk":317,"esm":259,"ekš":67,"esi":2143,"ese":290,"esa":2125,"ery":234,"emė":1363,"ejų":738,"erv":903,"elį":206,"eru":488,"err":173,"ert":1937,"ers":2707,"ern":1320,"erm":1142,"erp":330,"ero":2197,"eki":1989,"ekl":411,"ekm":65,"eko":1042,"ekr":192,"eks":1896,"ekt":4207,"eku":345,"ekv":315,"eky":288,"en ":710,"elb":215,"ela":746,"eld":365,"elf":88,"ele":3424,"eli":8265,"elj":72,"elg":477,"elm":261,"eln":456,"elk":671,"ell":316,"elo":518,"elu":87,"elv":84,"els":353,"elt":670,"ely":474,"eo ":170,"egė":73,"edų":106,"emb":301,"ema":2008,"edž":1549,"eme":1016,"emd":90,"emo":2200,"emi":2274,"emt":191,"emu":703,"emp":946,"ems":853,"emy":348,"ene":2754,"eng":1816,"enb":111,"ena":6485,"end":4440,"enc":1042,"eno":4885,"enm":89,"enk":5159,"enl":92,"eni":6797,"enu":670,"env":1006,"ens":1444,"ent":11928,"enr":107,"eič":280,"enz":118,"eny":1624,"eog":245,"eod":89,"egl":182,"ego":396,"ege":449,"egi":3283,"egz":550,"ebė":292,"egr":181,"egu":769,"egy":91,"ek ":622,"eic":241,"eip":170,"eis":5132,"eir":124,"eim":4571,"eil":568,"ein":1861,"eik":5224,"eid":1499,"eig":1358,"eja":503,"edė":140,"el ":389,"eiz":76,"eit":977,"eiv":749,"ejo":153,"eji":683,"eje":65,"eke":125,"ekc":170,"eka":2352,"em ":150,"ejy":83,"eju":497," į ":8903,"gl ":220,"giu":292,"git":144,"gis":1794,"gir":399," Į ":86,"gil":204,"gim":1321,"gij":3190,"gik":123,"gip":251,"gin":4262,"gio":2880,"gie":143,"gia":3193,"ght":134,"bą ":394,"gi ":457,"gen":3944,"geo":416,"get":168,"ger":1023,"ges":352,"geb":197,"gei":69,"geg":248,"gem":66,"gel":1714,"gdo":74,"gdy":714,"gda":73,"ge ":442,"gab":134,"gac":108,"gad":87,"gai":1374,"gas":1974,"gar":1729,"gau":1337,"gat":335,"gav":268,"gam":2232,"gal":9014,"gan":3227,"ga ":2878," įv":1493," įt":810," įs":1931," įr":895," įp":146," Įs":221," įd":139," įe":113," įg":452," įk":1033," įl":469," įm":645,"fys":93," Įe":85," Įk":141,"fut":1079," įž":65,"fun":535,"fto":75,"ft ":191,"ača":64,"fra":263,"ačk":85,"ači":1928,"fri":745,"fro":133,"for":3388,"fos":117,"fot":172,"fon":490,"fol":145,"ač ":218,"fla":74,"fli":110,"fo ":188,"fic":473,"fig":118,"fij":466,"fil":952,"fik":605,"fin":1043,"fir":67,"fit":88,"fiz":526,"da ":3356,"de ":955,"dac":195,"dad":96,"dab":1199,"dak":155,"dal":5226,"dai":1928,"dag":146,"dae":1242,"dat":189,"das":3048,"dar":5510,"dan":2672,"dam":1100,"dav":1026,"dau":2555,"cul":112,"cto":80,"cti":127,"cta":124,"cus":68,"cur":66,"cko":72,"co ":242,"con":95,"col":102,"com":76,"cor":163,"cos":201,"cop":83,"ciš":133,"cro":177,"cea":1680,"ch ":208,"cer":417,"ces":658,"cet":70,"cen":3061,"cep":179,"cel":113,"ceg":78,"cha":955,"chu":89,"cia":2358,"ck ":279,"cie":95,"cid":198,"che":1211,"chl":85,"chi":1035,"cho":966,"chm":91,"chn":602,"chs":167,"cht":194,"chr":188,"civ":350,"cij":9068,"cik":433,"cil":163,"cif":247,"cis":123,"cit":220,"cin":3236,"cio":1497,"cip":355,"cm ":459,"ed ":292,"eba":313,"ebe":309,"ebi":367,"ebo":120,"ebr":205,"ebu":212,"eag":73,"eae":1640,"eak":217,"ean":215,"eal":365,"ear":134,"eap":89,"eat":373,"eau":64,"ea ":188,"efi":76,"efo":293,"efa":70,"efe":515,"ei ":3954,"ega":737,"eed":76,"edi":2343,"ede":757,"eda":2475,"edy":257,"edu":236,"edo":437,"edr":226,"eck":65,"ech":882,"eci":846,"ece":95,"eca":89,"ect":147,"eco":118,"dyg":104,"dyk":422,"dym":1573,"dyn":853,"dys":311,"dyt":634,"dyd":692,"dyb":2813,"drė":138,"drą":94,"dvy":133,"dvi":1481,"dve":133,"dvo":211,"duv":159,"dur":2035,"dut":428,"dus":534,"dva":622,"dvė":188,"dzi":233,"dor":1140,"don":1347,"dom":1366,"dol":160,"dok":455,"dow":94,"dov":1045,"dot":521,"dos":2310,"ds ":126,"diš":216,"deš":1558,"dmi":1463,"dni":66,"dob":88,"doe":78,"doj":2119,"dum":210,"duo":2102,"duj":255,"dui":167,"dul":493,"duk":700,"dug":90,"dub":205,"dua":83,"dri":926,"dra":1708,"dre":173,"dry":71,"du ":892,"dro":2362,"dru":787,"dge":113,"dic":606,"did":3151,"dia":454,"der":1524,"des":572,"det":124,"dev":201,"deb":268,"dea":123,"ded":1735,"deg":595,"dei":369,"del":1942,"dek":567,"den":3068,"dem":709,"dep":764,"deo":162,"di ":260,"dme":216,"do ":2940,"div":255,"diu":103,"diz":157,"dim":1824,"din":11534,"dio":390,"dip":85,"dir":773,"dis":1529,"dit":234,"die":4136,"dif":150,"dij":4732,"dik":613,"dil":259,"dka":165,"daž":1194,"ižy":171,"rbė":133,"rgu":182,"mą ":3290,"rga":2638,"iža":147,"ri ":2109,"rgl":72,"iži":186,"rgi":812,"rbą":117,"rge":1017,"rgo":391,"ret":1342,"res":1263,"rev":180,"rez":564,"rfi":80,"rfo":87,"rač":122,"rdu":515,"rds":64,"rdv":219,"reb":105,"rea":608,"ree":109,"ref":432,"rec":183,"red":291,"rei":3237,"lėš":194,"rej":92,"reg":2937,"rem":808,"ren":2189,"rek":801,"rel":806,"rer":127,"reo":63,"rep":489,"rda":868,"rcu":85,"rdo":569,"rdi":1074,"rde":192,"re ":1146,"rby":63,"rbt":207,"rbu":464,"rco":114,"rci":353,"rch":1033,"rce":143,"raz":577,"rd ":418,"rao":69,"rap":372,"rar":206,"ras":10157,"rat":2588,"rau":2880,"rav":918,"rbi":1182,"rbl":168,"rbo":606,"rba":5655,"rbe":227,"raj":5239,"rai":3447,"rah":84,"rag":1079,"ran":8258,"ram":2837,"ral":3029,"rak":1364,"rab":639,"raf":875,"rae":172,"rad":3322,"rac":2843,"rpt":814,"rpu":483,"rpr":64,"rps":98,"rpo":225,"rkė":212,"rs ":981,"rpe":180,"rpa":257,"rką":115,"rpi":679,"rgž":70,"ror":154,"ros":5272,"rot":753,"rom":1205,"ron":1539,"rop":2336,"roz":106,"rgų":68,"rou":123,"rov":2454,"row":67,"rob":326,"roa":194,"rod":1480,"roc":897,"roj":2662,"roi":152,"rol":1077,"rok":757,"rof":604,"roe":102,"rog":1825,"rno":408,"rič":321,"rnu":106,"rny":471,"rp ":1398,"rna":1385,"rež":195,"rne":498,"rią":492,"rni":813,"rmo":1239,"rmu":712,"rdų":72,"ro ":7225,"rgė":150,"rma":2602,"rme":740,"rdž":190,"rmi":1316,"rly":64,"rlo":116,"rli":270,"rld":79,"rle":65,"rla":454,"rn ":72,"rky":100,"rkv":63,"rku":184,"rkt":264,"rks":74,"rko":615,"rki":550,"rkl":319,"rke":407,"rka":1300,"rbų":71,"mąs":197,"reč":569,"mąj":193,"raž":304,"rje":132,"riz":580,"rix":85,"rdė":104,"rip":333,"rio":6643,"rit":7580,"ris":4114,"riv":457,"riu":3503,"rig":767,"rij":7031,"rdą":70,"raš":3717,"rii":272,"ril":196,"rik":6018,"rin":15816,"rim":1853,"ria":7346,"rib":1061,"ric":629,"rid":769,"rie":6574,"rif":330,"rk ":142,"rož":108,"jūč":213,"rsė":70,"jų ":7448,"ryb":1588,"ryd":120,"rui":138,"rug":582,"rud":269,"rur":65,"rup":2436,"ruo":2554,"run":372,"rum":1117,"ruk":710,"ruz":216,"ruv":66,"rus":3390,"rut":405,"rva":500,"rmų":317,"rvi":416,"rve":467,"rvo":162,"rnų":71,"rvu":153,"ry ":248,"rsk":222,"rsl":371,"rkš":158,"rsi":1214,"rso":508,"rsm":221,"jūn":185,"rsa":416,"rse":236,"rkų":131,"rta":4621,"rst":803,"jūr":1765,"rsu":138,"rtm":86,"rtn":140,"rto":2230,"rte":485,"rth":95,"rti":4648,"rub":105,"rtr":75,"rtu":1225,"rty":412,"riš":698,"rt ":258,"rių":3254,"mči":71,"rmą":324,"rre":91,"riž":94,"rra":105,"lį ":872,"ru ":632,"rmė":253,"sac":151,"sad":119,"sag":124,"sai":543,"saj":93,"sak":1089,"sal":3421,"sam":580,"ryš":526,"sap":78,"san":3811,"sau":3166,"sat":201,"sas":1914,"sar":840,"sav":6083,"sa ":609,"ryč":1308,"rvų":140,"mėg":132,"rvė":96,"rsų":124,"mę ":264,"rtų":277,"mėt":142,"mės":1624,"mėl":387,"mėm":110,"mėj":427,"mėn":862,"rtė":217,"mė ":740,"rys":1185,"ryt":5807,"ryo":78,"ryp":869,"ryk":138,"ryl":68,"rym":161,"ryn":188,"ryj":340,"rtą":376,"rtį":75,"ną ":1490,"shi":127,"si ":5878," 가":71,"siv":352,"sjo":73,"nąj":98,"sie":2665,"sid":3080,"sic":542,"sib":166,"sia":6343,"kšt":3974,"sit":1385,"siu":976,"sir":1172,"sis":6798,"sip":235,"sin":3201,"kšn":209,"sio":4893,"kšo":166,"kšl":78,"sil":885,"kšm":294,"sim":839,"sij":3056,"sik":1642,"sii":91,"sif":333,"sig":288,"sda":106,"sdi":133,"se ":12437,"ryž":454,"sce":120,"sci":144,"sch":242,"ser":955,"ses":253,"set":159,"seu":67,"sez":169,"sh ":92,"sfe":280,"sfo":80,"sei":720,"sed":68,"sep":203,"sen":3202,"sem":199,"sel":216,"sek":790,"spu":1602,"skė":68,"spy":159,"spo":957,"spr":582,"spe":1156,"spi":670,"sjė":92,"spa":2100,"sot":100,"sov":81,"sol":244,"som":660,"son":563,"sop":70,"sor":222,"sos":1164,"sod":242,"sof":371,"soj":156,"soc":1068,"su ":4472,"smė":297,"sru":176,"sro":178,"sri":1777,"nči":4255,"siž":207,"sra":172,"sių":1944,"slė":668,"st ":506,"siū":210,"siš":352,"ss ":140,"sli":978,"slo":811,"slu":296,"sky":900,"sla":1643,"sle":271,"ski":4050,"skl":344,"sko":1593,"skr":2283,"sku":545,"skv":165,"ska":2455,"ske":580,"kšč":2245,"sno":220,"sny":134,"snu":80,"sna":277,"sp ":78,"sni":2039,"sią":193,"sne":141,"smo":495,"smu":706,"so ":3418,"sma":829,"smi":538,"sme":1637,"syb":334,"kų ":5583,"syn":63,"syt":71,"sys":136,"syk":221,"stą":248,"stę":193,"syv":319,"stė":1387,"nė ":11072,"kūg":75,"sse":159,"ssa":96,"kūn":731,"sso":72,"ssi":140,"kūs":84,"kūr":1568,"snė":370,"skų":182,"ste":4835,"sta":11594,"sto":6918,"sti":7618,"snį":163,"stu":1797,"str":5446,"sua":240,"sty":3413,"slų":200,"sud":2168,"sue":135,"sub":489,"sui":78,"suf":148,"sug":205,"sul":523,"sum":815,"suj":169,"suk":1852,"sup":534,"sun":407,"suo":1175,"sut":1183,"sus":2952,"sur":378,"suv":210,"spė":63,"smų":124,"sva":1159,"sve":370,"svi":243,"svo":286,"svu":88,"svy":123,"tai":9707,"taj":152,"tak":2532,"tal":2568,"tag":213,"tab":401,"tac":699,"tad":469,"tav":1620,"tau":2680,"tat":2848,"tas":15287,"tar":6407,"tap":484,"tan":2917,"tam":3320,"te ":2806,"tbo":1115,"nę ":1530,"svė":126,"가":170,"stų":690,"nėm":645,"nėn":104,"nėl":246,"nėj":3435,"stū":94,"nės":9359,"nėt":145,"nėr":303,"ta ":7677,"suž":77,"nęs":68,"ovų":204,"jęs":545," št":72," šv":1206," šu":230," ši":9378,"pa ":504," šl":369," šo":352," ša":3536," še":4400," Šv":1543," Šu":220," Št":147," Šr":75," Šo":70," Šl":99," Šk":111,"otų":425," Ši":3390," Še":340,"jės":91," Ša":886,"jėg":559,"ovę":68,"ję ":118,"ovė":1571,"pdo":296,"pci":139,"pe ":192,"par":5103,"pat":3653,"pas":6180,"pav":2954,"pau":1209,"pac":165,"pad":1171,"paa":84,"pab":319,"pag":4995,"pak":1745,"pal":2163,"pai":635,"paj":498,"pap":2360,"pam":953,"pan":2096,"ozė":194,"pha":125,"ką ":1267,"pho":90,"phi":136,"gžd":845,"pač":638,"pec":747,"ped":487,"pen":679,"per":4439,"pet":193,"pes":135,"pei":362,"pel":1215,"pek":276,"pla":1821,"pli":2030,"ple":626,"plo":1805,"ply":260,"plu":196,"pkr":163,"paž":694,"phy":268,"pib":499,"pia":510,"pid":180,"pie":9064,"pig":92,"paš":357,"pij":468,"pik":263,"pil":4079,"pim":702,"pin":2920,"pio":1030,"pir":1825,"pis":533,"pit":515,"piu":812,"poz":347,"pr ":158,"por":1711,"pop":634,"pov":195,"pot":290,"pos":1432,"poj":445,"pog":134,"pom":76,"pon":986,"pok":315,"pol":1919,"pob":138,"poe":104,"poc":74,"pod":139,"po ":1517,"psu":123,"pst":87,"pta":1134,"pse":76,"psi":725,"psn":657,"psk":1854,"ptu":124,"pty":174,"pua":68,"pub":1670,"pte":200,"pti":1385,"pto":309,"plū":91,"pra":5043,"pių":716,"plė":383,"piš":241,"pjū":231,"pru":94,"psa":387,"pu ":180,"jį ":548,"kči":82,"pri":9679,"pre":1608,"pro":5447,"poš":212,"pož":275,"pyg":410,"pur":225,"pus":2091,"put":192,"pun":96,"puo":365,"pup":123,"puk":97,"pul":563,"px ":100,"pva":210,"pvz":390,"kę ":172,"kėj":853,"kėn":99,"kėl":172,"kės":2221,"ptū":85,"kėt":269,"puš":167,"pyn":242,"pyj":119,"pyl":1154,"pyk":93,"pyv":70,"pyr":87,"pyt":97,"kė ":1457,"prū":156,"puč":92,"kęs":421,"lą ":721,"iš ":6273,"ląs":439,"išd":131,"iše":155,"išg":193,"iša":318,"išm":207,"išl":1019,"išo":261,"išn":213,"iši":468,"išk":9640,"išt":673,"išv":411,"išp":207,"išs":1093,"išr":686," Ži":399," Že":954," Ža":482," Žy":115," Žu":120," Žv":178," Žm":91," ži":2342," žm":1523," ža":1939," že":2052," žy":592," žv":1024," žo":907," žu":959,"iū ":112," ųj":70,"kį ":292,"lči":255,"iūt":153,"iūr":499,"iūn":1343,"iūl":184,"que":92,"qui":80," šį":69,"ių ":35485,"lė ":2188," ūk":511,"iųj":519,"lėg":91,"lėj":539,"lėd":122,"lę ":354,"lėv":65,"lėt":585,"lės":3311,"lėn":507,"lėm":235,"lėl":106,"lėk":280,"ra ":13206,"lęs":405,"ngo":2538,"ngi":2530,"eži":1071,"ngl":1130,"ngv":440,"ngu":1035,"ežu":89,"ngr":450,"ežt":146,"ngt":1224,"ngs":123,"ni ":526,"eže":2899,"nge":541,"eža":160,"nga":2804,"ežd":87,"nha":74,"ią ":1321,"neg":409,"nei":1033,"nel":523,"nek":262,"nen":435,"nem":377,"nep":854,"neo":246,"ner":1909,"net":3370,"nes":2353,"nev":652,"neu":225,"ndy":107,"ng ":636,"nea":242,"neb":233,"nec":126,"ned":530,"nef":72,"nfo":543,"nfl":92,"nfr":63,"nez":420,"nfe":266,"nco":109,"nci":2521,"nce":603,"nch":181,"ne ":5137,"nbu":79,"ndu":1568,"ndr":3362,"nds":72,"ndo":1993,"ndi":4736,"nde":2551,"nda":1898,"nak":285,"nal":3006,"nam":4510,"nan":2181,"nap":314,"nar":1177,"nac":1442,"nad":530,"nae":88,"naf":82,"nag":711,"nai":2792,"naj":138,"nc ":104,"nab":100,"nbe":88,"nd ":453,"nav":974,"nau":2982,"nat":1500,"nas":9068,"naz":237,"na ":6125,"muš":82,"myr":132,"myn":393,"myl":81,"가 ":71,"mzd":138,"myk":132,"myb":757,"fų ":79,"nyb":586,"ntą":186,"nyj":775,"nyi":66,"nyg":399,"ny ":199,"nvi":1009,"nux":72,"nve":361,"nva":85,"nuk":354,"nul":255,"num":449,"nun":66,"nug":200,"nui":231,"nus":1958,"nut":401,"nuv":180,"nuo":11505,"nur":161,"nty":1460,"ntv":111,"nto":3213,"ntu":1006,"nts":156,"ntr":4642,"nti":13882,"nth":149,"ntg":70,"nta":6698,"nte":3240,"nsu":225,"nkų":1281,"nsp":335,"nso":235,"nst":1864,"nse":182,"nkš":139,"nsi":456,"nsl":149,"nsk":533,"nsa":277,"nu ":681,"nro":72,"iči":2192,"nri":70,"nra":165,"nių":11248,"nt ":3145,"niū":1065,"niš":1026,"nką":172,"ns ":1187,"nkė":2543,"nod":224,"nog":120,"nok":84,"nol":827,"noi":70,"noj":1649,"nop":168,"nom":2167,"non":256,"not":507,"nos":4995,"nor":1222,"nov":1035,"ngų":481,"noz":151,"nne":81,"než":127,"nni":71,"nme":211,"nma":125,"neš":331,"ndž":626,"ngą":233,"nla":91,"ndų":534,"ngė":262,"no ":11621,"ndū":86,"nke":587,"nkl":1886,"nki":5054,"nkc":507,"nka":2908,"nku":626,"neį":137,"nky":223,"nko":1384,"nks":891,"ncū":939,"nkt":1190,"nkr":206,"iąj":181,"naž":94,"nja":76,"ndė":404,"njo":112,"ndą":97,"nij":5825,"naš":624,"nig":783,"nif":163,"nie":779,"nid":254,"nic":409,"nia":7994,"nk ":388,"niz":2108,"niu":3647,"niv":780,"nis":15940,"nit":387,"nir":72,"nio":7526,"nip":69,"nim":4778,"nin":8141,"nik":1554,"nil":147,"ogs":78,"ogr":2210,"ogu":324,"ogi":3408,"ogl":119,"ogo":286,"ogn":64,"oga":839,"oge":235,"oho":167,"oha":70,"ohe":76,"obė":124,"oj ":68,"ją ":2223,"gšt":167,"odą":88,"oid":309,"ok ":122,"oju":555,"obū":144,"ojo":4241,"oji":3887,"oje":21105,"oja":6655,"odė":378,"ol ":243,"oce":779,"och":261,"oci":1478,"ock":185,"obs":81,"obu":232,"odg":104,"ode":1122,"odk":163,"odi":1127,"odo":1175,"odr":68,"of ":299,"oda":2306,"oel":84,"oet":66,"oeu":79,"ody":417,"odu":589,"og ":261,"ofi":842,"oft":141,"ofo":158,"ofe":379,"ofa":95,"oa ":103,"nyč":782,"oac":66,"oba":242,"od ":72,"oar":69,"oat":135,"obo":229,"obl":199,"obj":1006,"obi":1248,"obe":189,"nyn":1169,"nyk":427,"nyr":226,"nyt":99,"nys":2919,"ntė":672,"nzi":126,"nzo":87,"ntį":195,"nsų":145,"ntū":104,"ntų":1010,"gų ":1699,"osė":119,"orė":417,"ows":92,"orą":78,"orų":130,"orū":115,"ozo":156,"ozi":309,"jė ":190,"otė":267,"oza":345,"otą":235,"olų":162,"oty":482,"otu":369,"ow ":66,"oti":3180,"ote":1275,"ott":72,"otr":264,"oto":2263,"otn":65,"okų":103,"ost":1854,"osu":63,"osv":137,"ota":3370,"onė":1445,"osi":4557,"okš":697,"osk":117,"oną":313,"ose":10057,"osf":255,"osp":155,"oss":88,"gūr":160,"osm":327,"osl":114,"oso":811,"osn":165,"gūn":307,"ovy":172,"onų":1034,"ovi":2936,"onš":70,"ovo":1368,"ovu":118,"ovs":154,"omų":264,"opė":75,"ox ":72,"ova":2312,"ove":473,"oun":122,"oup":69,"ous":97,"our":160,"out":83,"opo":1809,"opi":1192,"opl":208,"ope":871,"oph":333,"opa":456,"os ":71850,"okė":208,"opu":410,"opr":78,"opt":255,"ops":178,"ool":67,"ood":82,"or ":364,"ojė":85,"ogų":154,"oor":180,"ork":297,"orl":173,"orm":3710,"orn":376,"oro":1427,"orp":329,"orc":113,"ord":1011,"ore":636,"orf":147,"org":2280,"ori":8425,"omą":125,"omė":233,"ojų":757,"ou ":101,"osa":489,"gūb":364,"ort":1674,"ors":672,"orv":193,"oru":254,"ory":137,"olą":105,"m² ":432,"ot ":142,"olė":893,"orb":205,"ora":1549,"olę":89,"okį":63,"ola":1063,"old":223,"on ":1119,"oli":7420,"oll":172,"olk":163,"olf":87,"ole":1072,"olg":102,"olt":96,"olm":81,"oln":64,"olo":5241,"oly":304,"odų":160,"ogė":746,"olu":523,"oka":1176,"om ":163,"oki":2742,"oke":340,"okr":516,"oks":1989,"oko":845,"okl":512,"oky":4231,"okt":115,"oku":1484,"ona":5705,"ond":604,"onc":437,"onf":314,"one":3050,"ong":677,"oni":5683,"onk":450,"ono":5947,"ons":941,"ont":1350,"onu":771,"onv":131,"ony":229,"onz":95,"oma":4058,"ome":2921,"omb":322,"omi":4219,"odž":830,"omp":1868,"omo":2822,"omu":462,"oms":893,"omy":305,"op ":190,"la ":3891,"kyč":84,"ksų":107,"kvė":157,"ktų":516,"ktū":882,"le ":987,"lci":77,"lde":301,"lda":470,"ldo":1438,"ldi":380,"ldu":86,"lab":885,"lac":354,"lad":233,"lag":301,"laj":360,"lai":7095,"lal":283,"lak":544,"lan":3678,"lam":672,"lap":1033,"lar":290,"lat":1022,"las":4962,"lau":4662,"lav":1958,"lay":83,"laz":248,"lba":2195,"ld ":140,"lbe":120,"kyš":114,"lbi":260,"lbo":1044,"lbu":643,"kvi":414,"kve":103,"kva":547,"kuv":68,"kut":500,"kus":1457,"kur":11466,"kup":293,"kuo":1084,"kun":573,"kum":831,"kul":3442,"krą":130,"kvo":154,"kta":2002,"kte":286,"cūz":939,"ksp":237,"ksu":217,"kst":1638,"ksi":1031,"kso":492,"ksn":481,"ksm":470,"ksl":1822,"kub":70,"kui":142,"kty":770,"klų":780,"ktr":1113,"ktu":872,"kti":2012,"kto":1582,"kyt":491,"kyr":514,"kys":407,"ktė":87,"krū":445,"kuč":63,"krų":140,"cų ":73,"kyb":405,"kyd":213,"kyk":2742,"kyj":122,"ktą":149,"kym":1532,"kyl":177,"ksč":304,"lpo":78,"lpn":97,"lpi":224,"lkė":206,"ls ":120,"lpt":73,"lok":724,"lon":920,"lom":534,"lop":556,"lor":335,"lod":121,"loc":79,"log":3426,"loj":732,"loi":69,"lpa":143,"los":2610,"lot":1612,"lou":74,"lov":512,"lno":410,"lią":195,"lni":4011,"lež":588,"lne":64,"lob":276,"lny":212,"lnu":597,"lmo":217,"lmi":148,"lme":109,"ldž":460,"lma":561,"lna":1027,"lmu":116,"lti":1386,"lto":827,"ltr":83,"loč":162,"ltu":191,"lty":140,"lub":724,"lkš":220,"lsi":157,"lsk":87,"lso":116,"dūr":138,"lkū":97,"lst":3935,"lsv":208,"lnė":167,"lkų":772,"lta":1286,"lte":434,"lu ":327,"lmė":408,"lsa":135,"liš":786,"liū":227,"lių":4116,"lt ":76,"lbė":158,"gą ":583,"lgu":66,"lgy":105,"lgo":332,"lge":222,"lbą":82,"lgi":1731,"li ":2175,"lga":584,"lač":341,"lfi":69,"lfa":89,"lez":63,"leu":86,"lev":356,"les":733,"let":811,"ler":662,"leo":285,"lep":84,"lem":868,"len":3529,"lek":1990,"lel":445,"lei":2618,"leg":368,"lef":117,"led":360,"lec":77,"ldy":3239,"lls":89,"llu":67,"lo ":4298,"lla":282,"lle":203,"lli":227,"llo":104,"lko":1340,"lku":68,"lks":80,"ln ":170,"lka":889,"lke":67,"lki":640,"lkl":70,"lbų":491,"lje":178,"ll ":250,"lja":125,"lit":2868,"lis":6123,"lip":320,"lio":6518,"lin":10945,"lim":1681,"ldė":95,"liz":1115,"liv":318,"liu":3368,"lic":390,"lid":423,"lia":9617,"lib":160,"lik":3451,"laš":117,"lij":2779,"lig":956,"lie":4974,"lif":303,"ma ":8966,"gęs":112,"mb ":104,"lvų":129,"mac":657,"mai":3495,"maj":238,"mak":310,"mad":111,"mag":648,"mar":995,"mas":16980,"mal":1077,"mam":360,"man":2648,"maz":236,"mav":409,"mau":158,"mat":2440,"mba":403,"mbl":299,"mbi":672,"mbe":160,"mbr":361,"mbo":656,"me ":4745,"mbu":328,"mdo":70,"mdi":69,"med":2275,"meg":289,"mec":166,"met":7146,"mes":916,"mer":2496,"mem":105,"mel":455,"men":7636,"mei":219,"mez":71,"mfo":93,"lmų":71,"lpė":80,"lva":657,"lve":135,"lvi":553,"luk":80,"lui":136,"lup":118,"luo":731,"lun":291,"lum":619,"lut":328,"lus":1933,"lur":73,"luv":66,"lnų":522,"ly ":90,"lvo":651,"lyb":79,"lyd":329,"dų ":1583,"ltą":68,"lyj":2459,"lyk":200,"lyg":1880,"lsč":1443,"gė ":262,"lyv":644,"lyp":129,"lym":88,"lyn":910,"lys":1218,"lyt":728,"gėl":263,"gėj":295,"gėg":66,"gę ":71,"lvė":163,"ltų":271,"gėr":187,"ltū":1732,"gės":1188,"mpi":2031,"mph":67,"mpe":889,"mpr":78,"mpo":545,"mpl":367,"mpu":163,"ms ":4671,"mog":880,"moc":111,"mob":923,"mod":511,"mon":3483,"mok":6158,"moj":1912,"mom":231,"mol":407,"mor":477,"mos":8683,"mot":735,"mpa":1170,"mu ":1142,"gį ":94,"miš":1246,"mių":389,"mt ":92,"mto":342,"mtm":156,"mti":479,"mso":66,"msi":145,"mta":393,"mur":124,"mus":1181,"mut":199,"mui":800,"mul":740,"mum":317,"mun":878,"muo":1470,"muz":1069,"mpė":146,"džo":105,"dža":265,"mga":68,"eš ":414,"mi ":2927,"dži":8825,"dže":173,"meč":426,"mbū":66,"maž":1405,"min":8866,"mio":695,"ešo":276,"mil":606,"mim":392,"ešm":321,"mir":512,"mis":3697,"ešp":103,"ešt":271,"mit":1456,"ešu":171,"miu":166,"mic":65,"mia":1046,"eša":283,"mig":185,"eše":206,"mie":3684,"mid":149,"mik":627,"ešk":262,"mij":1021,"eši":2201,"maš":150,"mo ":11787,"mln":124,"mm ":215,"mna":274,"meš":73,"vėž":564,"tša":98,"įve":191,"įva":943,"įvy":373,"tūr":3760,"tūn":64,"tūk":418,"sūn":301,"sūr":75,"sų ":1585,"vė ":1134,"Ček":141,"Čer":143,"vęs":499,"Čiu":96,"vėr":82,"vės":1539,"Čik":109,"vėd":103,"Čil":228,"vėm":70,"vėn":180,"vėp":105,"Čia":184,"vėj":505,"vėl":1093,"vę ":211,"rža":90,"rže":425,"rži":124,"ržo":186,"ržu":185,"ržy":332,"vą ":302,"ržų":128,"vč ":177,"zra":92,"zmą":73,"uči":685,"ršū":168,"čem":518,"rūd":121,"rūg":209,"tį ":848,"rūt":179,"rūs":316,"rūv":85,"rūk":126,"rūn":147,"rūm":473,"rūp":93,"zmų":92,"zuo":830,"zul":113,"čia":6305,"čiu":3945,"čin":247,"rų ":3880,"čio":4188,"rūš":1748,"rųj":78,"čią":252,"čių":6037,"čiū":111,"zga":86,"rš ":371,"zdu":307,"zdy":84,"zdo":187,"zeu":81,"zen":162,"zel":75,"zer":347,"ze ":133,"zda":224,"zdi":311,"zde":65,"zac":1511,"zai":89,"zam":101,"zan":208,"zal":69,"zar":93,"zau":206,"zav":191,"zas":215,"zos":160,"zot":82,"zon":766,"zol":127,"zo ":283,"zma":593,"zmo":623,"zme":95,"zdž":483,"zna":91,"zmu":127,"rša":115,"zia":212,"zie":245,"zid":291,"zic":125,"zij":2812,"rši":542,"zin":555,"zil":400,"zik":1298,"ršk":199,"zio":150,"zis":547,"ršt":245,"zit":198,"ršu":471,"yvu":368,"ynų":327,"yvy":146,"yvo":316,"yve":3277,"yvi":885,"yva":1082,"ymų":245,"ytu":3236,"yto":736,"yti":2477,"yta":2174,"ynė":548,"yst":1756,"yną":129,"ysk":104,"ysl":216,"ysi":1379,"ykš":318,"yse":638,"sį ":224,"ymė":134,"ymą":285,"yri":1443,"yro":395,"yru":239,"ylė":72,"yra":10061,"yre":153,"ys ":5011,"ykę":197,"ypt":748,"ygų":179,"ypa":451,"yop":72,"yny":165,"ynu":272,"tęs":608,"yvū":473,"yvų":140,"za ":200,"tėl":64,"tėn":94,"tėm":94,"tėj":863,"ytų":2089,"tės":2264,"tėv":185,"tę ":460,"yzd":234,"yrų":212,"ytą":75,"tė ":2107,"ytė":146,"ysč":138,"yrė":91,"ybi":1941,"ybo":1219,"yda":247,"yde":256,"ydi":267,"ydo":238,"ydr":112,"ydy":152,"ya ":66,"sęs":72,"rįž":117,"ybe":375,"yba":1117,"ydį":315,"ybų":501,"yka":208,"ykd":1149,"yki":766,"ykl":3525,"yko":378,"yks":518,"yku":494,"yn ":82,"yla":244,"yli":1437,"ygą":95,"yll":79,"ylo":78,"yma":917,"ydų":119,"ymi":564,"ydž":370,"yme":67,"ymo":2861,"ymu":353,"yna":1411,"yni":762,"yne":693,"yno":1069,"ygi":962,"ygl":225,"ybą":107,"yga":678,"ybė":5361,"tą ":2180,"ygo":549,"ygu":328,"ybę":375,"yin":78,"tąj":82,"yje":6777,"sči":2451,"pūs":102,"rį ":999,"sė ":786,"sėd":208,"sėk":228,"sėj":581,"sės":2025,"sėt":101,"sę ":210,"rįs":115,"pų ":324,"są ":505,"ožy":124,"ože":207,"oža":97,"oži":226,"rėž":276,"sąv":390,"sąr":690,"sąs":356,"sąj":351,"sąm":110,"sąl":240,"sąn":78,"pši":366,"ręs":410,"rėg":75,"rėl":160,"rėj":1557,"rėn":386,"rėm":119,"rėt":168,"rės":6344,"rę ":1445,"rėd":146,"ww ":76,"rąž":93,"rė ":1022,"www":76,"ws ":91,"rči":327,"nžu":77,"rą ":1079,"nži":161,"rąj":82,"ošt":122,"oši":132,"oše":197,"oša":95,"vyl":67,"vyk":2515,"vyn":610,"vyr":1040,"vyd":92,"vyj":96,"vys":564,"vyt":65,"vyz":235,"nųj":77,"war":74,"viš":606,"vro":160,"vių":2220,"vsk":219,"vu ":109,"pį ":89,"vus":1133,"vuo":278,"vum":127,"vul":245,"vz ":411,"nų ":7207,"vyb":651,"vož":79,"via":688,"vio":508,"vir":3137,"vik":248,"vil":1104,"vim":2439,"vin":4831,"vig":137,"nši":88,"vij":1156,"vic":102,"vid":2656,"vie":10516,"viz":527,"viv":2783,"viu":186,"vit":264,"vis":3495,"važ":200,"vka":106,"vo ":7394,"vež":182,"vič":254,"voj":2810,"vol":423,"vok":960,"von":160,"vor":253,"vot":192,"vos":5796,"ąra":686,"vi ":818,"ąjį":197,"vač":96,"mži":691,"ąją":384,"ver":3346,"ves":601,"vet":199,"vej":358,"vei":3674,"veg":178,"ven":4988,"vel":635,"vek":95,"ved":568,"ąmo":118,"ąna":83," − ":501,"ve ":425,"ąly":225,"val":10598,"vak":4952,"van":3055,"vam":251,"vap":91,"var":5998,"vat":733,"vas":2439,"vav":423,"vau":1068,"vaz":104,"vab":435,"vac":68,"vad":6655,"vai":6631,"vaj":535,"ąju":613,"vag":166,"uvų":343,"ąja":230,"va ":1330,"utų":550,"pės":2048,"pėj":200,"pėm":214,"pėn":79,"uvę":282,"pėd":630,"usų":229,"pę ":262,"uvė":461,"urž":199,"mūš":172,"mųj":304,"urų":123,"urš":132,"uzi":1325,"usį":91,"uza":114,"uzd":74,"utė":482,"pė ":2903,"urį":786,"mų ":3232,"usę":91,"usė":442,"usą":115,"uož":251,"urė":7194,"urę":1318,"uoš":293,"umų":278,"upę":254,"ux ":100,"upė":4550,"uvi":2426,"uvk":94,"uvo":8973,"uva":1382,"uve":227,"uvy":103,"unų":111,"uvu":401,"usl":117,"usm":292,"usk":802,"ukš":4009,"usi":16156,"mūg":65,"usd":94,"use":242,"usa":1585,"unė":100,"ukų":215,"usy":348,"usv":157,"usu":325,"ust":2671,"uss":74,"mūs":116,"ukū":174,"mūr":92,"usr":197,"uso":1941,"uti":3065,"ute":1211,"uta":1298,"utb":1100,"ulų":95,"uty":105,"uts":108,"utu":465,"uto":2462,"utr":654,"uoč":243,"us ":25324,"ukė":207,"ut ":98,"ulė":940,"urb":304,"ura":1290,"urd":135,"ure":433,"urg":609,"umą":619,"uri":13437,"pči":95,"urk":677,"urm":174,"urn":819,"uro":2323,"urp":92,"urs":335,"urt":2267,"uru":270,"ulį":98,"urv":125,"ury":263,"ujų":216,"uog":115,"uod":1799,"uob":148,"uop":102,"uon":468,"uol":1850,"uom":2229,"uoj":2916,"ują":85,"uok":472,"uot":3875,"uos":9387,"upa":260,"ugų":171,"uoz":64,"ur ":478,"uką":82,"upi":1336,"upe":880,"upo":164,"upr":184,"upy":138,"upt":113,"upu":131,"ump":675,"umu":499,"umi":565,"umo":1874,"uma":2535,"umb":630,"ume":1015,"udž":589,"uly":692,"ugė":81,"uo ":11031,"ugę":74,"unt":286,"uns":125,"unu":78,"unk":1010,"uni":2717,"uno":1046,"unc":101,"und":514,"una":778,"ung":2769,"une":377,"up ":104,"uks":488,"ukr":338,"uku":1424,"ukt":1044,"uko":768,"ukm":63,"ukl":276,"uki":835,"ukc":193,"uke":516,"um ":371,"uka":1363,"ubų":81,"uju":231,"ulv":76,"ulu":205,"ult":2376,"uls":117,"ulp":163,"ulo":319,"ulm":98,"ulk":1598,"uli":4261,"ulg":118,"ule":258,"ula":686,"un ":91,"uid":65,"uik":63,"uil":83,"uin":83,"uis":152,"uic":69,"ąvo":220,"uje":2229,"uji":238,"ujo":901,"ąve":118,"ąva":67,"uit":183,"uiz":104,"ul ":100,"udė":847,"uja":1817,"ugi":2043,"ąsi":447,"lži":190,"ugd":727,"uge":478,"ugn":281,"ugo":862,"ugp":256,"ugl":79,"ui ":2863,"uga":3449,"ugy":234,"ugv":81,"ugu":1147,"ugs":210,"ugr":96,"uha":63,"pą ":193,"ąst":536,"uda":2525,"ude":508,"udi":1843,"ubo":317,"ubt":123,"ubr":94,"ubu":247,"ue ":115,"uci":1337,"uch":229,"uer":154,"ufo":165,"udu":90,"udr":145,"udo":3114,"ug ":571,"udy":189,"udz":149,"uen":154,"uel":163,"uei":67,"tyč":85,"tuš":104,"ua ":181,"uau":101,"uar":229,"ual":389,"uan":260,"ubi":273,"ubj":203,"ubl":1778,"ube":224,"uba":739,"uac":101,"trų":261,"trū":89,"tyv":1223,"tyg":105,"tyj":2629,"tyk":592,"tyl":66,"tym":1125,"tyn":745,"tyr":732,"tys":1652,"tyt":1130,"tvė":152,"ty ":191,"tvy":70,"tve":795,"tvi":1569,"tva":1876,"tur":3389,"tus":4707,"tut":476,"tuv":8023,"tui":321,"tul":676,"tuk":242,"tun":200,"tum":1081,"tup":188,"tuo":4132,"tub":127,"tua":342,"tud":729,"tuc":1071,"tug":166,"tyb":2995,"lų ":4053,"trė":213,"trą":137,"ts ":284,"tiš":751,"tre":865,"tt ":65,"tra":6670,"tri":3774,"oči":767,"tru":2118,"tro":4397,"nį ":1595,"tu ":2200,"try":1680,"tsa":349,"lūd":70,"tsi":864,"lūn":117,"lūk":105,"tsk":627,"tsp":242,"tst":1087,"lūs":124,"tte":91,"ttp":75,"tme":480,"tma":182,"to ":9437,"tmo":148,"tmi":171,"tni":215,"tne":192,"tp ":76,"tna":162,"tno":94,"tod":622,"toc":126,"toj":3705,"tog":985,"tob":201,"tov":2012,"tos":4057,"tot":663,"toz":74,"tom":2117,"ton":1654,"tok":1091,"tol":2595,"tor":6343,"top":234,"tr ":100,"tpa":67,"tij":3726,"lši":179,"taš":256,"til":880,"tik":5456,"tif":144,"tie":4693,"tig":115,"tir":719,"tit":1932,"tis":9550,"tin":18689,"tim":2115,"tip":1038,"tio":733,"thu":146,"tia":180,"tib":66,"tic":399,"tid":346,"taž":90,"tiz":264,"tiu":112,"tiv":191,"tko":75,"tku":65,"tka":159,"tli":717,"tla":468,"tle":281,"tem":2567,"ten":1501,"teo":504,"tep":206,"tei":4906,"tek":2029,"tel":3046,"teg":305,"tea":212,"teb":306,"tec":578,"ted":149,"tfo":195,"th ":187,"tez":110,"tet":1080,"tes":640,"ter":7958,"ti ":12579,"tga":173,"tač":773,"tho":100,"the":357,"thi":68,"tha":124,"yži":382,"zūr":65,"žė ":79,"zų ":230,"žėj":93,"žės":302,"yšu":129,"yšk":285,"yši":281,"žįs":104,"AR ":460,"AT ":96,"AV ":1248,"zę ":74,"zės":255,"BA ":84,"AB ":129,"가가":99,"Žie":168,"Žmo":87,"Žal":202,"Žai":105,"Žem":792,"ža ":218,"vųj":76,"vų ":1432,"Žva":101,"žli":98,"žka":118,"žin":2776,"žim":518,"žik":242,"žir":69,"žio":3609,"žiu":1205,"žis":284,"ždė":292,"žia":4861,"žie":756,"三 ":108,"žpa":73,"žos":282,"zė ":373,"žny":789,"žoj":209,"žol":428,"žod":694,"žmo":1552,"žią":130,"žni":1016,"žna":456,"žo ":203,"ždž":217,"žde":109,"žda":511,"žas":486,"žba":64,"žai":1499,"žal":557,"žan":496,"žar":129,"ži ":73,"žer":3193,"žes":178,"žet":91,"žei":363,"žel":344,"žem":2279,"žen":275,"ždy":272,"ždu":70,"ždi":76,"už ":1010,"uža":101,"užd":391,"uže":68,"užs":382,"užt":281,"užr":186,"užu":95,"užk":126,"uži":622,"užp":129,"užn":124,"žys":63,"žym":728,"žyg":68,"žyd":166,"žyb":321,"žtv":87,"žud":129,"žuv":1113,"žut":66,"žur":382,"žuo":217,"žve":120,"žva":821,"žvi":225,"žvy":103,"žra":185,"žių":1603,"žiū":506,"žsi":337,"žta":167,"žte":70,"žti":234,"yči":2350,"vūn":458,"užė":257,"tųj":219,"tų ":12460,"ušė":81,"之 ":65,"ušt":63,"ušk":90,"uši":396,"uša":109,"tžv":91},"n_words":[6266541,7160065,6094403],"name":"lt"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mal b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mal new file mode 100644 index 000000000..422334423 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mal @@ -0,0 +1 @@ +{"freq":{"D":213,"E":274,"F":167,"G":214,"A":497,"B":279,"C":430,"L":186,"M":384,"N":219,"O":182,"H":218,"I":415,"K":134,"T":348,"P":401,"S":493,"ിത ":164,"R":240,"f":703,"g":1106,"d":1581,"e":5009,"b":935,"c":1838,"a":5004,"n":3585,"o":3390,"l":2378,"m":1762,"k":455,"h":2313,"i":4303,"w":903,"v":415,"u":1770,"t":4207,"s":2723,"r":3549,"p":1477,"y":840,"x":345,"ില ":173,"ിയ ":1562," m":228," n":149," o":399," h":314," i":345," d":151," e":167," f":185," a":486," b":205," c":370," t":707," w":308," p":446," s":377," r":294," H":179," I":298," N":154," O":131," L":160," M":333," B":247," C":358," A":386," F":135," G":193," D":163," E":193," S":374," R":193," P":342," T":265,"ും ":8335,"ا":186,"ുക ":185,"ീയ ":378,"ാൻ ":875,"ാർ ":676,"ാൾ ":197,"ാൽ ":543,"ാഗമ":334,"ാഗത":387,"ാഗങ":167,"ാക്":1414,"ാകു":356,"ാങ്":227,"ാജാ":164,"ാജ്":625,"ാടി":272,"ാടക":206,"ा":135,"In":142,"ാട്":1178,"ാടു":187,"ിംഗ":155,"ാണു":455,"Th":138,"ാണി":500,"ാണപ":194,"ാതി":141,"ാതന":248,"ാണ്":9070,"ാത്":940,"ുഴ ":240,"ാനം":570,"ാദി":179,"ാനത":448,"ാധാ":281,"ാധി":232,"ാനങ":199,"ാദ്":187,"ാനു":295,"ാനി":583,"ാനാ":214,"ാനപ":155,"ാനമ":615,"ാപന":156,"ാന്":803,"ാപി":311,"ാപ്":231,"ാമം":286,"b ":294,"a ":674,"ാമത":404,"ാമപ":768,"ാമമ":268,"ാമാ":133,"ാമി":294,"ായക":210,"ിൻ ":265,"ാമ്":413,"ാരം":468,"ായത":1564,"ായി":3609,"ായാ":181,"ായ്":163,"ാരമ":247,"ാരന":265,"ാരത":490,"ാരണ":361,"ായു":463,"ാരാ":454,"ാരി":539,"ാലം":169,"ാരു":187,"ിൽ ":7420,"ാര്":247,"ാറു":256,"ാറി":215,"ാളം":134,"ാലക":339,"ാലയ":259,"ാറ്":497,"ാലത":252,"i ":213,"ാവ്":303,"ാവി":316,"ാവു":302,"ാവാ":229,"ാഴ്":134,"ിക്":6093,"he":539,"ha":244,"gh":231,"ികാ":247,"ികമ":181,"ികള":716,"g ":236,"ea":262,"ec":168,"ed":311,"de":246,"ാളി":252,"di":309,"h ":190,"ാലി":392,"ാലാ":156,"el":240,"ാളത":153,"ാലൂ":542,"ാലു":158,"ികം":150,"en":424,"em":159,"et":186,"es":424,"er":794,"ca":205,"e ":1341,"ിച്":3119,"ാഹി":294,"ിചെ":253,"da":131,"ിങ്":403,"ാസ്":1047,"f ":272,"ct":158,"co":290,"ാസി":297,"ci":170,"ch":206,"ce":229,"c ":161,"ാസമ":136,"ാഷ്":369,"ാഷയ":224,"d ":539,"at":600,"as":248,"ar":530,"al":614,"ാശി":190,"am":238,"an":747,"ac":198,"ad":149,"ാസം":149,"ികൾ":430,"nt":385,"ിഞ്":388,"ns":149,"no":135,"of":259,"om":259,"on":664,"ു് ":338,"ol":194,"ou":163,"op":135,"or":514,"r ":518,"pe":169,"ിടക":167,"lo":176,"ll":179,"o ":216,"ma":277,"mb":320,"me":225,"mi":137,"p ":313,"na":310,"nc":163,"nd":424,"ne":310,"ng":305,"ni":239,"്":186908,"ൊ":2828,"ോ":12821,"ൈ":2243,"െ":27110,"േ":13547,"ൂ":8137,"ൃ":1848,"ീ":8295,"ു":58406,"ൗ":469,"m ":405,"ൽ":11771,"li":349,"ർ":12870,"ൾ":4761,"le":352,"ൻ":6054,"ൺ":871,"la":410,"n ":864,"ഈ":1751,"ഉ":3287,"എ":6292,"ഏ":1399,"ht":515,"hu":298,"ം":26623,"hi":201,"ആ":4557,"ഇ":5473,"അ":8089,"id":145,"ച":18270,"ic":457,"ങ":13504,"ia":297,"ഘ":772,"ട":30378,"ഞ":4086,"ig":259,"ജ":7532,"ie":161,"ഓ":760,"ഒ":5000,"ഐ":333,"ഗ":10132,"ഖ":1936,"ക":65976,"ഔ":217,"ന":73400,"പ":39149,"is":392,"ഫ":2123,"it":348,"ബ":5674,"ഭ":5198,"മ":32874,"ിടെ":160,"യ":48687,"ഠ":364,"ഡ":3439,"ണ":22285,"il":179,"ത":67027,"ഥ":4613,"ിട്":804,"in":824,"ദ":11612,"io":368,"ധ":5371,"ഹ":4850,"സ":25595,"ി":86416,"ാ":63951,"റ":22910,"ര":47335,"ള":18695,"ല":30821,"വ":29294,"ഴ":3384,"l ":444,"ഷ":7585,"ശ":8287,"ww":338,"ിധാ":325,"y ":432,"ിദ്":640,"ിതി":938,"ിതാ":203,"ിതമ":146,"ve":190,"x ":258,"ul":150,"ur":239,"us":255,"um":390,"tt":296,"ിത്":1980,"w ":236,"to":263,"tr":153,"tp":241,"te":463,"ti":568,"th":747,"ta":278,"ss":146,"st":355,"se":201,"si":227,"ിപ്":1405,"rt":139,"ry":142,"ിനി":378,"ിനാ":453,"ro":259,"ri":601,"ിനെ":479,"re":445,"ിനു":1055,"ra":513,"t ":716,"ിന്":5173,"s ":1099,"px":216,"ിനോ":212,"ിമാ":267,"ിയന":152,"ിയപ":914,"ിയമ":337,"ിയയ":135,"ിയത":291,"ിയി":1237,"ിയാ":1791,"ിയോ":318,"ിയു":1173,"ിയെ":180,"ിയേ":145,"ിയം":136,"ിഭാ":320,"ിലവ":146,"ിലാ":907,"ിലി":195,"ിലു":1762,"ിലൂ":238,"ിലെ":4614,"ിലേ":330,"ിലൊ":225,"ിലോ":400,"ില്":2038,"ിഴക":306,"ിളി":317,"ീകര":447,"ിറങ":160,"ിരാ":141,"ിരി":844,"ിരു":2143,"ിയൻ":295,"ിറ്":420," ല":2034," ര":2887," റ":942," ശ":1879," ഷ":238," വ":10435," സ":10862," ഹ":1263," ഡ":822," ധ":248," ദ":2030," ത":5869," ഫ":858," പ":15081," ന":8054," യ":1000," മ":9063," ഭ":2376," ബ":2531," ൽ":544,"ശ്ര":558,"ശ്യ":219,"ശ്ശ":386,"ശ്വ":377,"ശ്ച":178,"ശേഷ":320,"ഷത്":575,"ശൂർ":174," എ":6248," ഏ":1397," ഈ":1746," ഉ":3278," ആ":4494," ഇ":5444," അ":8029," ട":631," ജ":4225," ച":4988," ഘ":145," ഗ":2980," ഖ":305," ക":14030," ഔ":215," ഓ":757," ഒ":4983," ഐ":325,"ശേര":218,"സത്":172,"വർഷ":372,"ഷിണ":161,"സഞ്":150,"ഷിക":304,"വർഗ":216,"വർത":599,"ഷിയ":170,"സങ്":186,"സരി":133,"സമ്":174,"സമാ":200,"സമു":201,"സഭയ":152,"ഷ്ണ":218,"സഭാ":174,"ഷ്ട":557,"ഷ്ഠ":143,"ഷ്യ":741,"സന്":155,"ഷേത":398,"ഹത്":297,"സൂച":143,"സിസ":131,"സിയ":151,"സില":142,"സിന":374,"സിപ":159,"സാധ":303,"സാന":195,"സാമ":424,"സിക":356,"സാഹ":254,"സിദ":345,"സസ്":334,"ാം ":756,"സോഫ":142,"സ്യ":395,"സ്റ":846,"സ്ല":281,"സ്ഥ":2863,"സ്പ":221,"സ്ത":2267,"സ്ക":623,"സ്സ":397,"സ്വ":855,"ഹിത":291,"ഹാര":204,"ഹായ":132,"ഹിന":258,"ാന ":514,"ഹ്മ":132,"ിക ":723,"ാള ":284,"സർക":222,"ാല ":148,"ായ ":2610,"െക്":658,"െട്":1283,"െടു":2359,"െങ്":500,"േക്":437,"െള്":180,"േഖല":167,"െറ്":191,"െല്":138," ഈ ":1593,"െത്":201,"െന്":699,"െബ്":146,"െപ്":220,"െറി":225,"െറു":216,"െയ്":1600,"െയു":744,"െയാ":471,"െയി":161,"േശം":258,"േശത":140,"േഷം":140,"േശങ":199,"ൈക്":133,"േശ്":174,"േശി":194,"േശീ":282,"േഷ്":132,"േഹം":278,"േഹത":162,"േഷൻ":136,"േത്":452,"േതാ":159,"േണ്":180,"േന്":408,"േയു":430,"േരള":1271,"േരി":960,"േരു":255,"േറ്":263,"ീവി":408,"ുക്":824,"ുകൊ":132,"ുകി":165,"ുകാ":227,"ുകള":1051,"ുകയ":410,"ീറ്":411,"ീരത":159,"ീതി":299,"ുംബ":279,"ിസ്":1202,"ിശ്":421,"ിശേ":137,"ിവർ":154,"ിഷ്":341,"ിവയ":235,"ീക്":294,"ിഴ്":206,"ിവര":215,"ിവസ":160,"ിവാ":178,"ിവി":329,"ുവി":444,"ുവാ":341,"ുവന":251,"ുവര":355,"ൂക്":727,"ുഷ്":354,"ുറ്":170,"ുളം":204,"ുറി":322,"ുറത":245,"ുരു":345,"ുരാ":293,"ുള്":2528,"ുമ്":328,"ൂർ ":1389,"ുറം":199,"ുമാ":1413,"ുരം":260,"ുമു":219,"ുന്":10068,"ുനി":282,"ുപ്":479,"ുതു":171,"ുതി":335,"ുണ്":1051,"ുത്":1223,"ുതൽ":371,"ുദ്":545,"ുടെ":2766,"ുടേ":141,"ുട്":263,"ുടു":255,"ംഗീ":301,"ംഗ്":542,"ാർക":154,"ുടങ":281,"ാർത":251,"ാർഡ":136,"ുകൾ":669,"ീഷ്":363,"ീസ്":201,"ംഖ്":225,"ംഗല":153," ബ്":675," ഭര":361," മണ":230," ഭൂ":280," മത":278," ഭാ":1188," മദ":178," മന":430," മല":1061," മര":285," മറ":395," മഹ":339," മൂ":522," മു":1582," മീ":223," മി":342," മാ":1333," മോ":137," മേ":380," മെ":288," പൊ":392," പോ":463," പ്":4372," ബന":199," ഫ്":175," ബി":227," ബാ":363," ബു":137," ബോ":172," പക":257," ന്":326," നോ":233," പദ":316," പന":151," പണ":151," പത":547," പഞ":607," പട":612," പഴ":174," പല":234," പറ":573," പര":747," പെ":480," പേ":780," പൂ":332," പു":1278," പാ":1107," പി":660," നൽ":229," നക":244," നഗ":396," ദേ":508," ദ്":241," നദ":211," നട":599," നവ":174," നൂ":265," നീ":290," നെ":227," നേ":376," നാ":1197," നി":2688," തെ":531," ദക":157," ത്":183," ദി":368," തി":720," താ":982," തു":591," തീ":297," തൃ":268," തന":303," തമ":355," തര":169," തല":366," ഡി":290,"ൂറ്":264,"ംബത":191,"ൂരി":182,"ൂമി":187," ടെ":156,"ംബർ":289,"ൂണി":149," സർ":371," ഹൈ":162,"ൂന്":269," ഹാ":165," ഹി":383," സെ":318," സൂ":331," സു":414," സി":733," സാ":1185," സഹ":208," സസ":221," സ്":2807," സോ":248," സൈ":131," വർ":592," സഭ":212," സമ":812," ശേ":181," ശ്":451," ശാ":428," ശി":199," സം":1809," വൈ":304," വേ":548," വെ":601," വ്":771," വസ":228," വി":3041," വീ":201," വാ":826," വൃ":131," വന":287,"ുസ്":374," വല":423," വഴ":131," വള":462," വര":613," വയ":153," വക":168," വട":443,"ംവി":172," ലോ":543,"ൂട്":482," ലെ":167,"ിൽപ":165," ലി":203,"ൂടെ":257," ലാ":299,"ൂടു":168,"ൂടി":333," റോ":225," ലഭ":180,"ംസ്":701," രീ":168," രൂ":379," രാ":1161,"ിർമ":366," യു":294," രണ":452," യൂ":213," രച":157,"ിർത":148," ഉൾ":449,"ൃഷ്":193," എം":133,"ൃശ്":191," എന":4353," എട":138," ആധ":137," ആദ":541," ആന":214," ആയ":406," ആറ":135," ആര":244," ആല":221," ആവ":187," ആസ":220," ഇട":294," ഇത":1342," ഇദ":201," ഇന":1407," ഇല":190," ഇര":190," ഇവ":544," ഇസ":230," അർ":208," ഉദ":192," ഉണ":345," ഉത":324," ഉയ":159," ഉപ":1087," ഉള":175," ഇൻ":148," അം":186," അത":659," അണ":160," ആം":188," അട":472," അക":377," ആണ":724," ഇം":372," അവ":660," അസ":137," അറ":908," അല":394," ആക":232," അഭ":214," അമ":420," അയ":173," അര":179," അപ":189," അഥ":462," അദ":348," അധ":209," അന":672," ജന":950,"ൃതി":272," ചെ":1896," ചേ":382,"ൃത്":357," ചാ":241," ചി":892," ചു":295," ജോ":204," ജി":1596," ജീ":407," ജൂ":195," ജ്":148," ഗാ":220," കർ":226," ഗു":264," ഗ്":1743," ഗോ":177," ഗണ":178," ചര":212," ചല":414," ഓഫ":177," ക്":1197," കെ":231," കൈ":147," കേ":1543," കൊ":822," കോ":957," കാ":1855," കി":865," കീ":159," കു":1227," കൂ":693," കൃ":254," കവ":234," കര":347," കമ":372," കഴ":213," കള":233," കല":418," കന":144," കഥ":180," കട":337," കണ":816," ഏറ":601," എഴ":295," ഏക":259," എല":187," എറ":154," എസ":137," ഒന":341," ഒര":4105," ൽ ":540,"മി ":226,"ബർ ":418,"പ്ര":5359,"പ്യ":278,"പ്റ":162,"പ്പ":6916,"പോൾ":223,"രം ":1921,"ബത്":224,"ബന്":340,"ഫ്ര":256,"ഫ്റ":145,"പരമ":221,"പയോ":768,"പരി":493,"പരാ":131,"പറയ":460,"യം ":1215,"പള്":185,"പാട":326,"പാദ":161,"പാത":301,"പാല":480,"പിച":417,"നൽക":242,"പിക":595,"പിന":279,"പുക":146,"പാർ":143,"പുത":214,"പുര":764,"പുറ":547,"പുഴ":384,"പൂർ":310,"പെര":170,"പെട":3183,"പേര":707,"പൊത":227,"പോല":201,"രെ ":495,"രു ":4025,"ലം ":658,"ഭാഷ":528,"ഭാവ":201,"ര് ":145,"ഭിച":159,"ഭിന":146,"ഭാഗ":860,"ഭാര":363,"മങ്":199,"മന്":204,"മനു":281,"മപഞ":718,"മദ്":277,"മത്":656,"ഭൂമ":198,"മണ്":363,"ളം ":631,"മലപ":135,"മറ്":307,"മലയ":732,"റു ":169,"യർ ":285,"മരണ":133,"റി ":343,"ഭ്യ":155,"മമാ":310,"യൻ ":979,"രണ ":296,"ഭക്":141,"യി ":2287,"റം ":319,"യോ ":322,"യ് ":274,"യെ ":323,"രള ":241,"ബ്ര":460,"മൻ ":173,"ബ്ള":167,"ബ്ല":277,"ഭരണ":352,"രി ":963,"പി ":248,"ദ്ദ":733,"ധമാ":139,"ദ്വ":180,"ദ്യ":1112,"ദ്ര":848,"ദ്ധ":1337,"ദേഹ":453,"ദേശ":1461,"ദേവ":242,"ധീക":138,"ധിയ":166,"ധാര":358,"ധിക":430,"പ് ":643,"ധാന":997,"നടന":157,"നടത":237,"നത്":2604,"നതു":269,"നതി":539,"നതാ":252,"നങ്":656,"നഗര":403,"നക്":345,"ദത്":171,"ദിയ":235,"ദിവ":229,"ദിന":206,"ദായ":132,"ദിക":158,"പങ്":155,"പക്":254,"പകര":152,"മം ":430,"ബി ":170,"ന്ത":3077,"ന്ദ":1121,"ന്ഥ":210,"ന്ന":18547,"ന്ധ":586,"ന്റ":3777,"ന്മ":414,"ന്യ":476,"നോവ":149,"പനി":191,"പന്":169,"പതി":293,"പത്":765,"പട്":440,"പടി":267,"പഞ്":1398,"ബ് ":189,"നയി":167,"നറി":301,"നപ്":274,"നമാ":873,"ധ്യ":502,"നനം":232,"നദി":238,"നന്":309,"നൂർ":159,"നേത":186,"നേട":136,"നെയ":183,"നാൽ":247,"നുമ":332,"നുള":311,"നുസ":192,"നുഷ":303,"നുവ":212,"നിസ":191,"നും":1607,"നുക":143,"നിർ":607,"നിൽ":228,"നൂറ":277,"നിവ":495,"നിയ":759,"നിര":355,"നിറ":179,"നില":691,"നിമ":172,"നിന":1060,"ദർശ":140,"നിച":204,"നിക":437,"ഫ് ":323,"നാല":249,"നാമ":420,"നായ":1102,"നാണ":1039,"നാട":633,"വർ ":251,"ഹം ":356,"വകാ":131,"വക്":151,"വടക":415,"ഴിക":261,"ഷ് ":469,"ളിക":406,"ളായ":311,"ളാണ":384,"വംശ":155,"ളുട":947,"ളിയ":253,"ളില":1194,"ളും":648,"ളിൽ":1372,"ളെയ":186,"ളോക":168,"ള്ള":3418,"വൻ ":161,"ൾപ്":365,"ല്പ":290,"ല്ല":3043,"ല്യ":139,"ളരെ":204,"സം ":495,"ഴക്":419,"ലായ":359,"ലാമ":187,"ലിക":373,"വ് ":420,"ലിന":217,"ലിപ":166,"ലാണ":736,"ലാത":169,"ലാം":153,"ലൂട":241,"ലുള":500,"ലൂക":546,"ലീഷ":334,"ലുക":166,"ലിയ":569,"ലും":1211,"ലേയ":136,"ലേക":222,"ലേജ":143,"ലെയ":139,"ലെങ":175,"ളത്":1319,"ലോമ":256,"ലോക":643,"ലൊന":171,"ൾക്":604,"ൽപ്":210,"ശസ്":398,"ശിയ":152,"സംഘ":223,"സംഖ":216,"സംഗ":292,"സംബ":143,"സംഭ":157,"ശീയ":288,"സംവ":186,"സംസ":658,"ശിക":160,"ശാല":131,"ശാസ":704,"വേദ":193,"വേണ":171,"വെള":233,"വെയ":137,"വൈദ":160,"വേഷ":140,"വൃത":136,"ർവ്":178,"വിൽ":193,"ൽക്":256,"വുമ":350,"ർഷത":185,"ശത്":307,"ശമാ":164,"ഷൻ ":245,"വ്വ":236,"വ്യ":986,"ർമ്":559,"ർപ്":202,"al ":246,"വസാ":210,"വഴി":162,"ർന്":390,"വളര":299,"വലി":422,"ർദ്":196,"and":176,"ർണ്":319,"വരി":311,"വരു":524,"വരെ":305,"ർത്":1697,"an ":167,"വിസ":175,"വിശ":604,"വിഷ":250,"വിവ":377,"വില":388,"വിള":304,"വിയ":254,"വിഭ":320,"ർഡ്":135,"വും":1320,"വാർ":151,"വാക":237,"വാത":177,"വാണ":177,"ർട്":250,"വാദ":195,"വിക":518,"സ് ":1944,"വാസ":359,"വായ":334,"വിത":325,"വിധ":550,"വിദ":293,"വിന":462,"വിച":163,"വിട":354,"വസ്":414,"ശങ്":338,"ർജ്":166,"ർച്":198,"വനന":179,"ൻസ്":171,"വത്":265,"ർഗ്":232,"ർക്":684,"ഴുത":366,"ഴിയ":159,"ൻറെ":142,"വയാ":176,"വയു":170,"സി ":306,"വയം":133,"ati":208,"വന്":355,"ളി ":445,"രയി":142,"റർ ":428,"രമ്":132,"രമു":245,"രമാ":1123,"വം ":264,"രളത":906,"രശസ":300,"രവു":183,"രവാ":158,"റക്":177,"രധാ":578,"യേക":178,"രദേ":627,"രനാ":222,"രന്":347,"രപ്":252,"യോഗ":971,"യ്ത":319,"യ്യ":1468,"യ്ക":431,"രഞ്":146,"യാപ":286,"യാന":412,"യാണ":2227,"യാക":148,"യിട":223,"യാസ":209,"യാള":680,"യിക":256,"യായ":924,"യും":2125,"യില":2744,"യിര":1399,"യുമ":248,"യുത":144,"യുന":1398,"യുട":1638,"രണം":295,"രണത":177,"രണമ":149,"യുള":358,"യിൽ":1778,"യൂട":261,"രണ്":518,"രത്":1578,"രതി":352,"രതീ":156,"രക്":477,"യവസ":141,"ലെ ":4757,"യസ്":188,"രങ്":806,"രജ്":131,"ലോ ":133,"ലി ":304,"യയു":269,"ലാ ":171,"യയി":607,"മ്ര":188,"മ്യ":161,"രൻ ":203,"യമാ":807,"മ്പ":1717,"മ്മ":1128,"രകാ":407,"മേര":234,"മെന":220,"മേഖ":168,"മുൻ":206,"യതി":155,"യത്":2606,"യപ്":1110,"യനാ":300,"യന്":328,"മാണ":3756,"മാത":372,"മാന":490,"മായ":3224,"മാക":397,"മിന":134,"മിയ":208,"മാര":358,"മാറ":260,"മാല":167,"മിക":467,"റ് ":1265,"മാസ":192,"മിച":154,"മൂല":253,"മൂന":234,"മുള":608,"മുസ":161,"മൂഹ":169,"മീറ":381,"രംഭ":134,"രംഗ":221,"മിഴ":237,"മില":152,"മുന":161,"മുണ":204,"മുത":397,"മുദ":221,"മാർ":420,"മുഖ":353,"മുക":147,"യക്":335,"യകാ":146,"യങ്":581,"മഹാ":304,"റെ ":3202,"ലസ്":209,"ലവി":164,"വി ":249,"ലയി":1550,"ലയാ":752,"ലയു":182,"വാ ":463,"ലമാ":175,"ഷം ":301,"ലപ്":395,"റ്റ":5132,"ലഭി":141,"റെയ":243,"റിൽ":141,"ലണ്":140,"ലത്":725,"റാണ":337,"റിന":263,"റിക":201,"ഴ് ":251,"റിച":232,"റും":178,"റിയ":1715,"റില":158,"റുക":338,"ലങ്":374,"ലച്":445,"ലക്":585,"റവു":574,"ലകള":209,"ശം ":392,"ഴി ":137,"റയു":379,"ര്യ":585,"റബി":132,"റപ്":145,"രോഗ":204,"രെയ":158,"റത്":391,"രുവ":555,"രിൽ":376,"രൂപ":574,"രീക":374,"രില":203,"രിയ":788,"രിസ":279,"രീത":277,"രും":137,"രീയ":292,"രുക":338,"രീര":138,"രുട":311,"രുന":2242,"രുത":325,"രുമ":189,"രാധ":160,"രാണ":212,"രാത":212,"രാഗ":175,"രാജ":994,"രിപ":260,"രിന":226,"രിട":191,"രിത":358,"രിച":602,"രാഷ":322,"രാശ":159,"രായ":317,"രാമ":1573,"റഞ്":136,"രാവ":195,"രിക":1867,"രാള":187,"റങ്":254,"രസ്":464,"രവർ":501,"ളെ ":475,"രസി":277,"ാ ":1411,"ി ":10063,"ീ ":761,"ു ":10222,"ഗീത":286,"െ ":14490,"കൾക":240,"േ ":611,"ഗിച":235,"ച് ":831,"ഗിക":587,"ഗാന":207,"ഘടന":192,"ൈ ":191,"ൂ ":136,"ഗത്":599,"മ ":394,"ര ":1278,"യ ":5708,"ion":318,"ഖ്യ":445,"വ ":552,"ഗമാ":450,"സ ":133,"ഷ ":141,"ചു ":503,"ല ":970,"റ ":307,"ഴ ":264,"ള ":2840,"ഗ്ഗ":220,"ഗ്ല":445,"് ":30096,"ഗ്ര":2123,"ോ ":1249,"ങൾ ":1356," In":137,"കല്":194,"കലാ":228,"കറ്":169,"കവി":299,"he ":334,"കഴി":190,"കളെ":330,"കളു":895,"കളി":1388,"കളാ":321,"കിയ":350,"കിഴ":329,"കില":839,"കും":421,"കായ":240,"കാര":1466,"കാവ":233,"കാശ":316,"കാസ":134,"കാറ":154,"കാല":744,"കിട":299,"കുമ":280,"കുള":420,"കുറ":545,"കുവ":161,"കിൽ":695,"കൂട":756,"ം ":21178,"കുക":537,"കീഴ":158,"കുട":502,"കാർ":351,"കാൻ":202,"കുന":3755,"കുപ":182,"കാക":163,"കാണ":507,"കാന":330,"കാട":474,"കഥാ":145,"കന്":204,"കനു":217,"കനാ":221,"കണക":160,"കണ്":651,"കത്":528,"കമാ":395,"കമ്":385,"കയാ":132,"കയി":197,"കയു":359,"കരണ":329,"കരു":191,"കരി":544,"കപ്":708," in":230,"ച ":753,"ഗങ്":342," ht":204," of":235,"ട ":916," an":158,"ണ ":661,"ഗണി":159,"ത ":1303,"igh":217,"ധ ":268,"ing":193,"ങ് ":236,"ന ":6972," co":199,"in ":185,"ദ ":154,"കൊല":162,"കൊള":171,"കൊണ":402,"കൊട":175,"കേര":1281,"കേന":314,"ഈ ":1594," ww":169,"htt":234,"കൃത":542,"ht ":197,"കൃഷ":204," ri":189," px":215,"hum":268,"ക്ട":264,"ക്ത":515,"ക്യ":293,"ക്ഷ":2208,"ക്ര":1063,"ക്ല":147,"ഖ ":135,"ക്സ":418,"ക ":1483,"കോട":568,"കോഴ":224," th":549,"ക്ക":14730,"ജനന":254,"ജനു":148,"ജനി":202,"ജന്":153,"ങൾക":243,"er ":252,"es ":231,"ച്ച":4631,"ent":145,"ght":209,"ജ്യ":739,"ജ്ഞ":320,"ജ്ജ":187,"ജീവ":507,"ജില":1519,"ട് ":2684,"ടു ":337,"ടി ":838,"ടെ ":2958,"ചത്":271,"ജ് ":184,"ങിയ":431,"ചക്":148,"ങളെ":405,"ങളാ":313,"ങളി":1296,"ങളു":891,"ed ":198,"ചേർ":314,"ചെയ":1441,"ചെറ":399,"ചേര":187,"ചെട":173,"ചിട":172,"ചിത":936,"ചായ":1294,"ചാര":301,"ചിന":169,"ചിപ":139,"ചിര":413,"ചിറ":138,"ചില":197,"ചലച":426,"ടം ":259,"ചരി":346,"ങ്ങ":6013,"ങ്ക":1271,"ടാക":287,"ടുക":629,"ടും":382,"ടിൽ":160,"ടുള":178,"ടുവ":240,"ടുമ":147,"ടുപ":172,"ടുന":1925,"ടുണ":196,"ടുത":820,"ടിച":133,"ടിഞ":226,"ടായ":281,"ടിക":477,"ടാമ":153,"ടിസ":180,"ടിര":215,"ടില":180,"ടിന":182,"ടിയ":767,"rig":195,"ടേയ":132,"ടെയ":346,"ട്ര":721,"ട്ട":5142,"ണു ":234,"ഥം ":166,"ണി ":174,"ണ് ":9312,"തി ":1445,"തു ":412,"ദം ":215,"തെ ":1217,"ണം ":720,"ഡി ":135,"px ":213,"ടർ ":247,"ടങ്":577,"ടക്":856,"ഡ് ":679,"ഞാറ":228,"ടന്":213,"ടത്":622,"തം ":428,"ഞ്ഞ":800,"ഞ്ച":1999,"ടയി":180,"തപു":179,"തന്":625,"ോർ":445,"ോൾ":398,"തനാ":181,"്മ":2196,"്യ":11234,"്ര":16053,"്റ":10182,"്ല":4477,"്ള":3597,"ng ":163,"്വ":2298,"്ശ":389,"്ഷ":2226,"്സ":1373,"ോൺ":268,"തമാ":549,"തമി":248,"തരം":239,"ോസ":481,"ോഷ":199,"ോഹ":213,"ോഴ":323,"ോള":566,"ോവ":275,"ോര":171,"ോയ":198,"ോല":414,"ോറ":240,"ോബ":223,"ോഫ":177,"ോമ":554,"്ബ":173,"ണ്ഡ":544,"ണ്ട":3469,"്പ":9300,"്ധ":1930,"്ന":18960,"്ഥ":3459,"്ദ":2047,"്ണ":1196,"്ത":22771,"്ഡ":591,"്ട":9563,"്ഠ":162,"ണ്ണ":973,"്ഞ":1123,"്ജ":323,"്ച":6932,"്ങ":6013,"്ഗ":330,"്ക":17340,"ൊണ":430,"ൊത":283,"ൊന":285,"ൊട":319,"േർ":559,"ോദ":305,"ോണ":319,"ോത":321,"ോപ":434,"ോന":149,"ോജ":148,"ോഡ":324,"ോട":1348,"nd ":168,"ോക":1283,"ൊള":210,"ൊല":199,"തപ്":226,"ോഗ":1263,"ൊര":233,"േന":623,"േവ":391,"േശ":1652,"ൈക":178,"േറ":444,"േല":220,"േയ":868,"േര":2800,"േഹ":481,"േസ":147,"േഷ":809,"ൈദ":208,"ൈന":296,"ൈവ":271,"ൈറ":197,"െൻ":139,"െൽ":155,"െർ":168,"ൈസ":157,"ണിത":465,"െക":672,"െങ":501,"ണിയ":184,"െട":3862,"െത":287,"െന":785,"െപ":232,"െബ":161,"െമ":160,"െയ":3291,"െര":246,"െറ":681,"ണാട":139,"െല":319,"െള":276,"േക":651,"േഖ":487,"ദ് ":330,"ണിക":268,"െസ":158,"േജ":272,"േട":244,"േത":832,"േണ":267,"േദ":234,"ൃത":879,"ുൽ":137,"ുൻ":211,"ുർ":254,"തനം":152,"ൃഷ":287,"ൃശ":256,"തത്":650,"ൂർ":1703,"ണൂർ":281,"ുപ":1108,"ുര":1360,"ുമ":2460,"ുഭ":196,"ുത":2652,"ുണ":1220,"ാൾ":251,"ുന":10596,"ുദ":692,"ൂച":155,"ുഹ":134,"ിൽ":7943,"ിൻ":555,"ൂട":1342,"ിർ":824,"ുള":2978,"ുഴ":501,"ൂക":744,"ുറ":1425,"ുല":285,"ുഷ":436,"ുസ":641,"ുവ":2148,"ുശ":133,"ൂപ":660,"ൂമ":233,"ു്":339,"ൂറ":506,"ൂര":435,"ൂണ":183,"ൂത":256,"ണു്":155,"ൂന":329,"ീർ":319,"ൂല":403,"ൃക":135,"ൂഹ":200,"താര":239,"തായ":301,"തിക":867,"താവ":406,"താല":576,"തിച":316,"താണ":917,"താന":186,"തിയ":1314,"തിര":1091,"തിറ":164,"തില":2687,"തിന":3912,"തിപ":216,"താം":142,"തലസ":164,"തമ്":155,"തോട":190,"ഥമാ":131,"ത്വ":330,"ത്സ":249,"ത്മ":171,"ത്ര":4088,"ത്യ":2047,"ത്ത":16443,"ത്ഥ":385,"of ":224,"നി ":376,"തുട":444,"തുന":334,"തുമ":302,"തുള":199,"തുവ":386,"തും":420,"തീയ":195,"തീര":189,"തുക":619,"തീർ":152,"തൃശ":187,"തിർ":138,"തിൽ":2321,"തെക":351,"തെയ":178,"ർമ":803,"ന് ":1964,"ർശ":261,"ർഷ":608,"ൽക":534,"ർവ":450,"ഥാപ":368,"ർണ":557,"ഥാന":1185,"ർഡ":239,"ർട":256,"ർജ":233,"ർപ":232,"ർന":493,"ർദ":256,"ർത":1751,"ൻറ":218,"ൻസ":353,"ർച":209,"ർക":724,"ർഗ":447,"ൻഡ":203,"ഥിത":865,"ൻപ":166,"ൾപ":377,"ൾക":618,"ൽപ":280,"പം ":271,"നീ ":509,"നു ":3729,"ദക്":161,"ഥവാ":438,"on ":337,"നെ ":631,"ഉള":177,"ഉയ":159,"ഉപ":1088,"ഇൻ":149,"ഇര":190,"ഇല":190,"ഇവ":544,"ഇന":1412,"ഇസ":231,"അർ":208,"ഉണ":345,"ഉത":324,"ഉദ":193,"le ":135,"എട":140,"എന":4361,"ൺ ":614,"എഴ":295,"ഏക":259,"എല":190,"എറ":155,"എസ":156,"ഉൾ":449,"എം":136,"ംഘ":229,"ംഖ":254,"ംഗ":1698,"ംക":276,"ംശ":210,"ംസ":820,"ംവ":207,"ംഭ":344,"ംബ":834,"ഡിയ":165,"ത് ":4999,"അസ":137,"അവ":661,"ആണ":726,"ഇം":373,"അപ":189,"അധ":210,"അന":675,"അഥ":462,"അദ":350,"ആക":235,"അറ":909,"അല":395,"അയ":178,"അര":181,"അഭ":217,"അമ":421,"ആസ":222,"ഇത":1342,"ഇദ":201,"ഇട":298,"ആദ":541,"ആധ":137,"ആന":248,"ആല":222,"ആവ":187,"ആയ":406,"ആര":244,"ആറ":138,"അം":186,"അക":377,"അട":473,"ആം":188,"അത":670,"അണ":160,"ചേ":581,"ചെ":2298,"ചു":1255,"ചി":2735,"ചാ":2146,"ച്":5556,"ചത":464,"ചന":269,"ങാ":172,"ങി":552,"ചല":494,"ങ്":7589,"ചയ":168,"ചര":413,"ങന":154,"ങള":3065,"ചക":269,"കൾ":1615,"ഗീ":392,"ഗി":1014,"കൽ":282,"ഗു":368,"കർ":533,"ഗാ":550,"ഘട":411,"കൻ":533,"ഗസ":163,"ണങ്":272,"ഗോ":498,"ഗ്":3272,"ഞാ":426,"ടണ":268,"ടത":795,"ടപ":165,"ടന":619,"ടമ":180,"ഞ്":2940,"ടല":163,"ടറ":140,"ടയ":443,"ടവ":181,"ടാ":1306,"ടം":274,"ടക":1208,"ടങ":583,"ജൂ":197,"ജീ":561,"ജു":186,"ജാ":371,"ജി":2005,"ജോ":210,"ജ്":1493,"ങൾ":1604,"ജന":1163,"ജല":137,"ണക്":248,"ജയ":163,"ഓഫ":177,"ൾ ":3523,"ഒര":4108,"ഒന":344,"ൽ ":10227,"ർ ":4755,"ൻ ":4719,"ഏറ":601,"ഗമ":519,"ഖ്":518,"ഗര":457,"ഗല":182,"ഗവ":220,"ഗങ":344,"ഗണ":317,"ഗത":782,"കൈ":174,"കേ":2116,"ഖന":135,"കെ":542,"കോ":1765,"കൊ":1243,"ഖര":135,"ക്":21779,"ഖല":214,"കസ":257,"കവ":506,"കി":3548,"ഗം":303,"കീ":288,"കാ":6054,"കൃ":756,"കു":7634,"കൂ":1037,"കപ":759,"കദ":149,"കഥ":303,"കന":747,"കല":863,"കറ":301,"കഴ":243,"കള":3150,"കമ":989,"കര":1697,"കയ":816,"കങ":196,"കക":230,"കണ":938,"കത":663,"കട":577,"കം":672,"നന":662,"നപ":369,"നയ":493,"നമ":1154,"ധ്":613,"നറ":327,"നല":133,"നവ":539,"നസ":256,"നാ":4964,"ദർ":205,"നി":6348,"പം":293,"നീ":1069,"നു":7416,"നൂ":483,"നെ":1274,"നേ":692,"നോ":770,"ന്":30257,"mb ":256,"പക":675,"പങ":155,"പഞ":1399,"പട":805,"പത":1182,"പണ":230,"പന":675,"പദ":488,"പയ":870,"പമ":183,"പറ":902,"പര":1220,"പള":198,"പല":318,"പഴ":198,"പാ":2340,"നൽ":278,"പി":2507,"പീ":178,"പു":2667,"പെ":3528,"പേ":973,"പൂ":626,"ഫല":133,"പ്":13660,"പോ":1036,"പൊ":466,"ണപ്":245,"ഫി":226,"ബന":358,"ഫെ":137,"ബത":225,"ഭക":205,"ഫോ":209,"ഫ്":882,"ബൈ":150,"ബോ":333,"ബി":709,"ബാ":585,"പർ":146,"ബു":258,"മം":543,"മങ":200,"ഭവ":280,"ഭയ":191,"ഭര":449,"ബ്":1417,"മക":266,"ണത്":429,"മന":817,"മധ":161,"മദ":367,"മപ":831,"യം":1280,"ഭി":475,"ഭാ":2218,"മത":1028,"മണ":590,"ഭൂ":412,"യങ":585,"മസ":322,"മഹ":381,"മല":1243,"യക":899,"മമ":375,"ഭ്":194,"മയ":404,"മര":545,"മറ":466,"മോ":397,"മൊ":134,"മ്":3221,"യമ":1442,"യന":858,"മേ":980,"മെ":621,"യപ":1289,"മൈ":144,"യത":3000,"മൂ":870,"മി":2147,"ബർ":483,"മാ":10411,"മു":3097,"മീ":726,"രം":2337,"രഞ":148,"യാ":6131,"രജ":211,"രച":317,"യസ":303,"രങ":807,"യവ":498,"രക":1280,"യറ":218,"യല":155,"യയ":1033,"യര":304,"രയ":465,"രമ":2024,"യ്":2647,"യോ":2076,"രപ":409,"യേ":524,"രന":771,"രധ":593,"യെ":576,"രദ":892,"രത":2444,"രണ":1938,"യൂ":920,"യു":6606,"റം":434,"യി":9140,"ടു":5165,"ടീ":186,"ടി":3790,"ടെ":3674,"ടേ":223,"ട്":8736,"ടോ":357,"ഡല":261,"ഡാ":142,"ടർ":374,"ഡി":791,"ണം":729,"ണങ":272,"ണക":349,"തം":452,"ഡെ":175,"ഡ്":914,"ഡോ":225,"തങ":173,"തക":671,"ണവ":186,"ണി":1469,"ഥം":170,"ണു":765,"ണൂ":306,"ണാ":642,"തട":148,"ണപ":319,"ണത":458,"ണയ":165,"ണമ":522,"തി":15367,"താ":3666,"തൃ":441,"തൂ":222,"തു":3776,"തീ":783,"ദം":233,"തവ":316,"ണ്":14451,"തമ":1061,"തയ":396,"തല":712,"തര":903,"തത":746,"തപ":458,"തന":1444,"ഥാ":1753,"ഥി":968,"ദത":182,"ഥവ":455,"ത്":29067,"ഥമ":194,"ഥയ":152,"ഥല":260,"ദക":185,"തെ":2173,"തേ":368,"തൊ":210,"തോ":646,"ധത":175,"ദു":403,"നം":1457,"ദീ":159,"ദി":1290,"തൽ":420,"ദാ":495,"ദര":150,"ദമ":198,"നത":3826,"നദ":293,"ധീ":204,"ധി":1094,"ധു":167,"ധാ":1533,"നട":732,"നങ":658,"നക":609,"നഗ":483,"ധമ":209,"ദ്":4614,"ധന":255,"ദേ":2169,"ദൈ":141,"ഹി":1080,"ഹാ":862,"ഷൻ":274,"ഹൈ":165,"ഹ്":425,"ഹോ":192,"സി":2539,"സാ":1870,"സഹ":227,"സസ":365,"സേ":205,"സെ":370,"സു":655,"സീ":147,"ഹത":306,"സൂ":414,"സ്":11156,"ഹമ":212,"ഹര":199,"സൈ":220,"സോ":402,"സർ":564,"ണാക":136,"ാബ":224,"ാഭ":193,"ാപ":1119,"ാന":5014,"ാദ":754,"ാധ":756,"ാത":1928,"ാണ":10704,"ിം":358,"ാട":2078,"ിഞ":391,"ിജ":257,"ാഹ":589,"ിച":3441,"ിങ":411,"ാസ":2241,"ാഷ":985,"ിഗ":248,"ാശ":745,"ാവ":1901,"ിക":9608,"ാഴ":297,"ാള":1241,"ാല":2916,"ാറ":1288,"ാര":3963,"ായ":9472,"ാമ":3387,"ാം":1111,"ാച":293,"ാജ":1079,"ാഗ":1285,"ാഖ":155,"ാങ":229,"ാക":2271,"ീപ":245,"ീന":303,"ീയ":989,"ും":8705,"ീത":716,"ീസ":331,"ാൽ":616,"ാർ":1852,"ുട":4050,"ാൻ":1060,"ീല":186,"ീറ":467,"ീര":476,"ീഷ":499,"ുഗ":147,"ീവ":642,"ുഖ":381,"ുക":4108,"ീഴ":170,"ിധ":718,"ിന":8501,"ിപ":1879,"ിഭ":450,"ിമ":977,"ിട":1697,"ിഡ":255,"ിണ":277,"ിത":4094,"ിദ":770,"ിസ":1623,"ിഷ":679,"ിഹ":196,"ീട":157,"ിര":3940,"തങ്":171,"ിയ":9237,"ില":11613,"ിറ":959,"ീക":980,"ിഴ":585,"ിള":544,"ിശ":915,"ിവ":1776,"റെ":3559,"ലന":318,"റേ":484,"റു":1385,"ലണ":143,"ലത":808,"ലമ":351,"റ്":6646,"ലയ":2792,"ലപ":453,"റോ":534,"ലഭ":229,"റവ":704,"ലങ":375,"ററ":173,"ലക":1101,"റാ":1047,"യർ":416,"യൻ":1031,"റീ":135,"ളം":676,"റി":3562,"നം ":1340,"ലച":462,"രെ":725,"രേ":448,"രൂ":693,"റണ":147,"റത":394,"രീ":1446,"ലം":722,"രു":8550,"റയ":625,"റമ":259,"ര്":755,"രോ":818,"റബ":175,"റപ":149,"രശ":457,"രവ":1227,"റക":237,"രള":1305,"രര":176,"രി":6901,"രാ":5614,"മർ":179,"മൻ":182,"റഞ":137,"രഹ":238,"റങ":256,"രസ":985,"ളെ":751,"ളേ":165,"ളോ":309,"ള്":3452,"ഴയ":224,"ഴക":439,"ളവ":247,"ളാ":873,"റർ":523,"വം":540,"ളി":4155,"ളു":2116,"ലൂ":979,"ളത":1504,"ലൈ":193,"ലെ":5253,"ലേ":789,"ല്":3649,"ളമ":142,"ലൊ":242,"ലോ":1419,"ളര":321,"ലവ":344,"ളക":192,"ലസ":248,"രൻ":214,"ലു":2355,"ലീ":583,"ലി":2464,"ലാ":2706,"ഷക":240,"ശയ":135,"ശമ":220,"വ്":1715,"ശര":163,"വോ":132,"വെ":830,"വൈ":359,"വേ":1138,"ശന":174,"വു":2019,"വൃ":226,"ശത":359,"വാ":3225,"വി":6428,"ഷം":305,"വീ":487,"വഹ":163,"വശ":269,"വസ":973,"ശങ":339,"ശക":161,"വഴ":173,"വള":556,"വല":693,"വര":1681,"ണമാ":331,"വയ":976,"വമ":167,"ഴ്":515,"വന":931,"വണ":138,"വത":706,"ശം":401,"ഴു":589,"വട":524,"ഴി":934,"വച":214,"വക":573,"സര":276,"സവ":164,"സന":236,"ഷേ":485,"സഭ":457,"ഷ്":2365,"സമ":1136,"ഷി":1059,"ഹം":374,"സത":207,"സങ":187,"വൻ":194,"സഞ":150,"ഷാ":253,"വർ":1764,"ഷര":160,"ഷയ":312,"ശേ":646,"ഷന":151,"ഷമ":135,"ശ്":1951,"സം":2540,"ശീ":345,"ശു":222,"ശാ":1071,"ശി":810,"ദി ":217,"തൽ ":385,"ഷണ":462,"ശൂ":214,"ഷത":605,"ശസ":408,"ഇസ്":226,"ഇന്":1364,"ഇദ്":200,"ഇവി":189,"ആസ്":173,"ഇത്":627,"ഇതി":553,"ആണ്":627,"ആദ്":407,"ആയി":224,"അവസ":151,"അല്":193,"്സ്":542,"്സി":291,"്ഷ്":138,"്ലെ":193,"്ലേ":201,"്ലോ":274,"്റർ":497,"്ളി":382,"്ളു":150,"്റേ":221,"്റെ":3192,"്ലയ":1398,"്റ്":2584,"്ലി":325,"്ലീ":428,"്ലാ":703,"്ളത":321,"്ലൂ":138,"്രേ":194,"്ററ":147,"്രോ":492,"്റവ":566,"്റു":446,"്യൻ":654,"്റാ":444,"്റി":828,"്രപ":199,"്രന":361,"്യേ":240,"്രധ":583,"്രദ":820,"്രത":1256,"്യൂ":574,"്രര":148,"്രയ":207,"്രമ":1061,"്യോ":256,"്രഹ":203,"്രസ":612,"്രവ":914,"്രശ":364,"്രു":156,"്രി":1522,"്രീ":856,"്രാ":2390,"്ഷര":156,"്ഷേ":452,"്ഷി":552,"്ഷത":297,"്ഷണ":214,"്ശേ":205,"്വര":172,"്വയ":160,"്വീ":179,"്വാ":520,"്ളോ":174,"്വത":242,"ഇംഗ":366,"അഥവ":448,"അതി":433,"അത്":146,"അനു":271,"അന്":287,"അധി":169,"അദ്":338,"അഭി":173,"അറബ":149,"അറി":618,"അമേ":219,"്ങന":152,"്കൽ":212,"്കൻ":384,"്ചേ":162,"്ചി":1394,"്ചാ":1705,"്ചു":944,"്ങ്":141,"്ങാ":169,"്ങി":542,"്ചത":372,"്ങള":3056,"്ങൾ":1597,"അക്":233,"്ച്":847,"്ടത":365,"്ടണ":266,"്ടറ":139,"്ടയ":169,"്ഞാ":395,"്ടം":148,"്കട":170,"്കം":167,"്കൊ":183,"്കോ":591,"്ക്":1983,"്കപ":570,"അടി":235,"്കയ":184,"്കള":257,"്കര":378,"്കറ":207,"്കി":2121,"്കാ":2470,"്കൃ":134,"്കൂ":155,"്കു":5270,"്കേ":378,"്കെ":229,"്നവ":135,"അംഗ":150,"്ധ്":347,"്നറ":289,"്നത":3020,"്ധി":284,"്ധാ":165,"്ന്":1214,"്നെ":265,"്നാ":1196,"്നൂ":143,"്നു":4523,"്നീ":591,"്നി":970,"്പറ":240,"്പര":163,"്പന":256,"്പത":250,"്പ്":921,"്പോ":426,"്പെ":2946,"്പൂ":178,"്പു":822,"്പി":1252,"്പാ":674,"്യങ":413,"്യക":572,"്മാ":586,"്രം":725,"്മി":445,"്മദ":157,"്യം":593,"്യസ":193,"്രങ":393,"്യവ":286,"്രക":715,"്യു":1251,"്റം":197,"്യാ":1524,"്രജ":175,"്യന":356,"്യത":846,"്യര":146,"്യമ":802,"്യയ":869,"്യപ":213,"്ടു":1302,"്ടി":1743,"്ടാ":1065,"്ട്":2062,"്ടോ":261,"്ടെ":178,"്ഡല":230,"്ടർ":257,"്തം":182,"്തക":337,"്ഥം":135,"്ണാ":141,"്ണൂ":295,"്തത":221,"്തപ":248,"്തന":539,"്തമ":327,"്തര":440,"്തവ":158,"്താ":1357,"്തി":9289,"്തീ":242,"്തു":1834,"്തൂ":145,"്തെ":1346,"്തേ":231,"്തോ":380,"്ഥമ":153,"്ത്":4115,"്ഥല":260,"്ഥാ":1534,"്ഥി":931,"്ദി":192,"്ദേ":658,"്ദു":211,"്ധത":135,"്ധമ":162,"്ദ്":530,"ോളി":145,"ോമീ":259,"ോഫ്":143,"ോസ്":247,"ോഴി":212,"ഉൾപ":337,"ww ":169,"www":169,"ൊരു":147,"ോൾ ":349,"ോൺ ":165,"ോഗി":791,"ോഗ്":169,"ൊല്":164,"ോകത":185,"ൊള്":135,"ോക്":696,"ോട്":908,"ോഡ്":151,"ോപ്":223,"ോത്":164,"ോദ്":147,"്ച ":729,"്ട ":817,"്ത ":630,"ഉള്":169,"്ന ":5898,"us ":153,"്ര ":614,"്യ ":889,"ൊട്":150,"േർന":202,"ൊതു":218,"umb":269,"ൊണ്":419,"്ള ":2181,"്ല ":256,"ഉപയ":669,"ൊന്":268,"ൈദ്":158,"ഉണ്":335,"ഉത്":318,"ൈറ്":167,"ttp":234,"tp ":236,"tio":259,"thu":262,"്ക ":209,"ter":154,"the":302,"കം ":627,"എസ്":144,"ഏകദ":134,"എഴു":292,"ഏറ്":547,"എന്":4356,"എല്":166,"കൻ ":521,"�":641,"ഗ് ":228,"കങ്":196,"കൽ ":221,"കൾ ":1360,"ഓഫ്":164,"ക് ":1892,"ഒന്":342,"കര ":204,"കെ ":257,"കേ ":146,"കി ":452,"ഗം ":252,"ഒരു":3867,"കു ":269},"n_words":[1303092,1392078,987774],"name":"ml"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mar b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mar new file mode 100644 index 000000000..19a194292 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mar @@ -0,0 +1 @@ +{"freq":{"णां":79,"णाच":69,"थे ":276,"तका":129,"था ":217,"ोल्":72,"ोलि":66,"ोला":81,"ोर्":136,"ोबर":168,"णता":197,"तंत":167,"ोव्":196,"तो ":552,"णजे":209,"्तर":330,"ं ":115,"्त्":568,"्ते":64,"्थळ":62,"तां":107,"्ता":389,"ः ":139,"्ती":202,"ताक":90,"्ति":145,"्तु":82,"ताच":344,"्दर":73,"तात":957,"तान":226,"्थि":115,"ताम":63,"्था":569,"तार":104,"ताल":160,"तिक":153,"्थे":76,"तीं":64,"्दा":73,"а":72,"्धत":82,"तिह":109,"तीच":131,"तिस":79,"्ट्":957,"्टो":150,"्टे":199,"्टी":161,"्टा":154,"्टि":89,"इ ":181,"तसे":151,"धन ":83,"्तक":79,"दी ":549,"्यं":164,"्मन":141,"्यक":342,"दू ":113,"्मा":304,"्मि":128,"्रं":90,"्यत":102,"्मे":88,"्यप":104,"्यम":126,"्रक":379,"्यव":153,"्रज":340,"्यु":195,"्या":9729,"्धा":165,"तया":65,"्ने":69,"तरे":84,"्ना":140,"तरा":162,"तरर":91,"्पन":111,"दा ":131,"्पर":85,"तले":94,"तला":76,"्पा":80,"ण्य":949,"ا":67,"तमि":228,"्का":190,"्कृ":130,"्कर":75,"दर ":72,"णून":182,"तदा":122,"्ञा":188,"दल ":81,"तत्":79,"णार":809,"णात":73,"्गा":89,"्चि":216,"्चा":100,"णुक":137,"्चन":73,"थ ":288,"द ":645,"ध ":495,"न ":5349,"ड ":671,"थील":100,"ठ ":317,"थाप":202,"ण ":1146,"थान":236,"त ":6358,"थित":69,"धी ":120,"ज ":339,"दक्":266,"ञ ":122,"धा ":98,"ट ":1322,"ं":13502,"ः":232,"ँ":308,"आ":6891,"इ":1323,"अ":4895,"ऊ":224,"ऋ":69,"ई":607,"उ":1473,"घ ":103,"ए":2374,"ओ":357,"ऑ":510,"ऐ":63,"ग":7424,"ख":2772,"क":20151,"औ":108,"छ":206,"च":12137,"घ":1111,"ट":6169,"ञ":320,"झ":981,"ज":8381,"ठ":2153,"ड":3743,"ढ":440,"ण":6906,"त":27784,"थ":2477,"द":9254,"ध":4679,"न":18404,"प":12607,"फ":1499,"ब":5130,"्ग ":233,"भ":4247,"म":15733,"य":22975,"र":35779,"ळ":2991,"ल":18817,"व":16505,"ष":4156,"श":6670,"ह":17826,"स":18689,"ऽ":116,"ि":18218,"ा":66714,"थवा":122,"े":31183,"ॅ":601,"ू":4430,"ृ":896,"ी":21357,"च ":843,"ु":7163,"ौ":422,"्":44808,"ो":8505,"ै":961,"ॉ":916,"०":1926,"१":3312,"्क ":91,"६":758,"७":829,"८":1020,"९":2445,"२":1611,"३":695,"४":690,"५":705,"क ":4288,"ग ":912,"ख ":378,"त्स":89,"त्व":365,"त्प":68,"त्र":2148,"त्य":1716,"त्म":72,"त्त":815,"त्न":66,"ம":77,"த":78,"ா":90,"ி":93,"ர":79,"तून":246,"க":89,"तुर":76,"ॉर्":122,"்":211,"तीत":68,"तीन":98,"तीय":438,"तील":2444,"तेल":85,"ई ":267,"ै ":165,"्न ":140," ख":774," ग":1923," औ":107,"ोजी":152," क":6366," ओ":265," ऑ":506," ट":487," ज":3863," झ":541," च":2075," छ":154," घ":462," इ":1199," आ":6783," अ":4797," ए":2269," ऊ":68," उ":1326," ई":99,"दार":306,"दिग":99,"दान":93,"दाच":70,"दिल":153,"दिव":143,"्फ ":77,"दिर":79,"े ":16291,"दीच":62,"नंत":140,"दुर":84,"दुस":164,"ोठे":238,"्म ":214,"ू ":729,"्य ":1111,"्र ":868,"ि ":987,"नी ":1364,"ोणा":90,"ी ":12189,"ोत्":125,"ोतो":104,"ोते":752,"ोती":123,"ोता":310,"ु ":263,"ा ":17571,"ोधन":72," ८":95," ९":93," ६":115," ७":115," ४":132," ५":115," २":1066," ३":209," ०":70," १":2735,"्व ":312," प":6615," फ":822," न":2997," म":6902," य":3998,"्ष ":149," ब":2263," भ":2543," ठ":228," ड":419,"ह ":265," द":3178," ध":461," त":3644," थ":112,"ोपा":104," ह":7628," स":7738," ल":2032," र":3046," श":2241," व":5406,"ने ":992,"्स ":322,"स ":1697,"ष ":215,"थ्व":73,"श ":822,"व ":2502,"्च ":156,"दरम":106,"ळ ":724,"्ट ":345,"ल ":4586,"्ञ ":122,"दर्":246,"ना ":828,"्ड ":88,"र ":6250,"य ":2749,"्ठ ":232,"म ":1312,"्ण ":136,"ोका":76,"ोकस":391,"भ ":104,"ब ":134,"्थ ":178,"फ ":180,"्त ":411,"्ध ":328,"प ":291,"्द ":119,"टना":76,"डू ":84,"डी ":137,"डा ":115,"ठे ":245,"ठी ":788,"ञान":146,"टोब":135,"ट्य":132,"ट्र":1051,"ट्ट":87,"टेड":67,"टेक":65,"तः ":64,"डे ":134,"टां":121,"टें":125,"टात":71,"टार":107,"टिक":111,"ठ्य":96,"णी ":301,"णि ":782,"णा ":114,"्ह्":230,"्सि":71,"्हण":631,"्हा":235,"्हि":103,"्हे":192,"्स्":66,"ठिक":87,"डणु":118,"्लि":183,"्ली":63,"्ला":198,"्ले":93,"्रद":304,"्रथ":62,"्रत":188,"्रण":89,"्यू":155,"्रप":582,"्ये":1183,"्रम":557,"्यो":94,"्रल":83,"्रव":174,"्रश":146,"्रह":141,"्रस":352,"्रा":1606,"्रु":153,"्रि":802,"्लं":83,"्री":882,"्रे":549,"्रो":151,"्र्":109,"्षण":152,"्शि":77,"्षे":198,"्षि":311,"्षा":344,"्षी":88,"्वत":172,"्वज":70,"्वर":132,"्वी":309,"्वे":282,"्वि":88,"्वा":1006,"ड्य":63,"ता ":928,"ती ":831,"ते ":2330,"णे ":394,"डाच":85,"डात":62,"डिय":72,"डिस":128,"डील":75,"तर ":662,"डून":170,"जे ":259,"जा ":105,"जी ":439,"चीन":184,"चित":727,"चार":281,"चाल":111,"चिन":184,"चिम":207,"जगा":147,"च्य":2911,"च्च":223,"जन्":279,"टक ":89,"जनत":86,"जधा":220,"टन ":79,"जाग":68,"जां":62,"जिल":278,"जास":142,"जार":66,"जान":157,"जात":654,"जाण":139,"जरा":68,"जर्":134,"जवळ":124,"जोड":73,"ज्य":1261,"ज्ञ":320,"जीव":120,"जुन":111,"जुल":121,"जून":124,"टर ":126,"झाल":422,"टी ":174,"टा ":105,"ठा ":104,"ंघ":431,"ंख":180,"ंग":1699,"ंक":394,"ंड":876,"केत":187,"ंट":262,"ंज":187,"ंच":1704,"केच":132,"केट":130,"ँड":81,"ंश":217,"ंस":555,"ंव":461,"् ":692,"ंध":318,"ंद":1200,"ंन":966,"ंथ":109,"ंत":1644,"ंम":356,"केल":701,"ंप":555,"ंभ":92,"ंब":953,"ो ":900,"ँग":72,"आण":837,"आढ":90,"इं":419,"कृत":201,"अस":1528,"अश":181,"आग":71,"अव":109,"आक":127,"अल":143,"अर":282,"अभ":461,"अम":428,"अप":77,"अध":195,"अन":311,"अथ":144,"इत":287,"आश":86,"आह":3959,"आल":245,"आय":156,"आर":178,"आप":132,"आफ":117,"कृष":91,"आध":103,"अं":259,"आं":194,"कें":67,"अत":143,"अण":68,"अक":80,"उर":65,"उप":257,"उल":75,"ऊन":63,"ऊर":66,"इस":98,"उं":94,"खले":96,"उच":118,"उत":389,"उन":70,"उद":171,"कोण":88,"कोल":77,"एक":1893,"एख":65,"एप":100,"क्क":92,"क्ट":201,"क्त":320,"क्य":169,"क्ष":1291,"क्र":523,"क्स":174,"ऑस":91,"ऑफ":67,"ऑक":141,"ऑग":114,"गर":430,"गल":148,"गळ":139,"गव":115,"खे":276,"गप":74,"गम":74,"ख्":538,"गट":66,"खा":505,"खि":83,"गड":87,"खी":84,"गण":286,"गत":154,"खर":91,"क्":2945,"खल":175,"के":1566,"खन":94,"कॅ":149,"को":604,"कॉ":161,"कि":847,"की":630,"गं":74,"का":3922,"कृ":301,"कु":375,"कू":79,"कस":544,"कव":162,"कश":95,"कल":330,"खक":117,"कम":167,"कर":1579,"कप":84,"कथ":172,"कन":175,"कड":224,"खं":163,"कण":68,"कत":150,"कक":66,"कं":129,"ओळ":135,"ची":1602,"चि":1243,"चा":1991,"चे":2243,"चौ":88,"च्":3182,"० ":717,"जग":235,"जक":120,"चन":187,"चर":81,"चल":81,"चव":64,"घा":367,"घे":138,"चं":156,"घट":138,"गा":1549,"गस":133,"घड":69,"गी":328,"गि":172,"गू":80,"गु":294,"गो":373,"ग्":1223,"गे":325,"घर":90,"टन":228,"ञा":188,"टा":652,"टल":177,"टर":206,"खाद":93,"४ ":416,"झा":550,"झि":70,"टच":62,"३ ":377,"टक":258,"जो":179,"जे":499,"जू":189,"जी":702,"जु":275,"जा":1637,"जि":541,"२ ":421,"ज्":1646,"जन":601,"खान":75,"जध":220,"खाल":87,"जस":63,"जव":226,"१ ":522,"जर":265,"जल":91,"जय":81,"जम":98,"डच":80,"ठा":219,"ठि":103,"ठव":67,"५ ":430,"टे":445,"ट्":1360,"टो":293,"टी":396,"टि":297,"डा":413,"डि":310,"डी":307,"डल":139,"डळ":73,"डव":71,"६ ":435,"ठ्":106,"डम":84,"डर":65,"ठी":879,"डत":76,"डण":186,"डन":65,"ठे":307,"तं":195,"तः":94,"ढा":78,"णज":221,"णक":97,"७ ":492,"ढळ":87,"ड्":156,"डो":138,"डॉ":73,"डे":278,"डू":298,"डु":64,"णि":910,"णी":405,"णु":223,"णू":264,"णा":1365,"तक":277,"८ ":406,"णप":91,"णत":272,"९ ":481,"तव":72,"तस":223,"ति":798,"ता":3296,"तू":362,"तु":325,"ती":4269,"दं":76,"तद":128,"तत":106,"तप":146,"तन":88,"णे":550,"तम":332,"ण्":982,"तय":70,"तल":255,"तळ":94,"तर":1232,"थव":138,"था":849,"थी":145,"थि":153,"ते":2652,"तो":665,"त्":5456,"खेळ":198,"थळ":77,"दक":326,"दृ":82,"धत":108,"दू":226,"दु":367,"नं":194,"दी":767,"दि":707,"दा":1004,"थे":411,"दन":81,"दव":72,"दल":156,"दर":524,"थ्":121,"धा":812,"नच":194,"नत":190,"नद":208,"धी":622,"नड":78,"धि":310,"धू":73,"धु":110,"दो":255,"द्":1977,"धन":165,"दे":1492,"नक":199,"नग":152,"धर":260,"धल":79,"नर":109,"नल":207,"नव":362,"धे":84,"नय":86,"नम":96,"ध्":1350,"नी":1612,"पं":155,"नु":263,"गळ्":76,"ने":2153,"नस":171,"ना":2993,"नि":1438,"पक":409,"नो":289,"नै":75,"न्":1414,"पत":355,"पण":229,"पन":409,"पद":339,"पड":106,"पट":647,"पश":225,"पह":161,"पस":114,"पल":219,"पर":957,"बई":129,"पे":273,"पै":233,"पॉ":77,"पू":594,"पृ":102,"पॅ":69,"पा":1577,"पि":254,"बं":239,"पी":379,"पु":752,"बच":72,"फळ":72,"प्":3134,"पो":211,"बन":164,"फे":175,"बद":156,"बत":64,"फु":80,"फि":95,"फा":147,"फो":62,"फ्":393,"बर":861,"बह":109,"बि":244,"बा":902,"बु":115,"मं":347,"बी":172,"बे":403,"बॉ":75,"बो":197,"भर":75,"ब्":696,"मक":100,"गरा":120,"गरी":78,"मग":69,"मज":82,"मच":80,"यं":250,"भि":399,"भा":2637,"मत":229,"भू":282,"मण":132,"भे":177,"मन":439,"मध":1532,"मद":153,"भौ":79,"भो":73,"मल":215,"यक":493,"भ्":94,"मर":604,"मह":1126,"यत":203,"मृ":108,"मू":271,"मॅ":66,"ख्य":500,"मि":1010,"यट":74,"मा":2886,"मु":1239,"रं":435,"मी":463,"मो":679,"यम":237,"म्":1246,"यन":341,"मे":875,"यप":140,"मै":72,"यव":231,"रख":99,"रग":70,"रक":670,"यल":98,"यर":147,"या":14036,"रज":391,"रच":375,"यस":75,"रध":68,"रद":356,"रथ":65,"रत":1594,"यू":189,"रण":1061,"यु":675,"यी":118,"यि":121,"रय":68,"रम":767,"रभ":78,"रब":97,"यो":389,"रफ":64,"रप":674,"ये":1927,"रन":85,"गाच":88,"लय":143,"लब":72,"लन":141,"लढ":74,"गात":319,"लच":92,"लग":102,"लक":174,"र्":5914,"रो":716,"रॉ":92,"रे":1413,"गां":194,"रू":387,"लं":299,"री":2531,"रु":575,"रि":1770,"रा":6808,"रह":201,"रस":797,"रश":254,"रव":382,"रल":306,"रर":139,"ळ्":150,"ळे":264,"ळा":565,"वं":149,"ळी":258,"ळू":62,"ळव":128,"ल्":2173,"लो":767,"चन ":87,"लू":62,"ळण":107,"ळत":82,"लै":137,"ले":3399,"ळन":66,"लु":220,"ली":1530,"लि":1122,"ला":2983,"लव":72,"ळख":135,"ळक":78,"वो":76,"शब":124,"वै":95,"वे":911,"शन":181,"शव":74,"षक":96,"व्":1218,"शर":79,"वश":88,"गस्":118,"वस":571,"वू":99,"वृ":105,"शत":95,"वा":3822,"वि":1941,"वी":773,"वन":263,"शक":187,"वळ":226,"वल":308,"वर":1642,"वय":91,"वज":113,"वच":65,"वक":74,"वण":225,"वत":410,"वड":312,"वट":66,"सन":187,"षे":500,"सप":188,"सभ":348,"ष्":1679,"सम":806,"सर":1179,"सल":632,"सव":108,"सच":99,"षा":600,"षि":375,"षी":127,"सण":108,"सत":526,"सद":113,"सध":64,"शे":245,"श्":798,"शो":167,"षय":121,"सक":135,"शह":705,"सं":1892,"शी":422,"शु":72,"शा":1405,"शि":914,"षण":199,"हे":6136,"हॅ":73,"हु":162,"ही":1380,"हि":1219,"हा":3206,"ह्":871,"हो":1733,"हन":73,"से":980,"सु":643,"सी":265,"हत":249,"सू":619,"हण":691,"सि":714,"सा":2701,"सह":169,"हव":64,"हस":71,"हम":90,"स्":3801,"हय":143,"हर":898,"सै":65,"सो":298,"ात":6409,"ाथ":69,"ाढ":83,"ाण":917,"ाठ":965,"िं":1222,"ाड":364,"ाट":442,"ाब":339,"ाभ":170,"ाप":1160,"ान":3426,"ाद":925,"ाध":343,"गुर":68,"ाव":2259,"िख":96,"िक":2722,"ाळ":594,"ाल":2412,"ार":6697,"ाय":1081,"ाम":1731,"िज":229,"ाह":1051,"िच":184,"ास":2359,"ाष":1328,"ाश":369,"िग":160,"ां":4665,"ाँ":113,"ाऊ":66,"ाइ":80,"ाई":239,"ाउ":96,"ाक":602,"ाच":4155,"ाझ":79,"ाज":2078,"ाग":1046,"ाख":206,"ीण":65,"ीठ":87,"ुं":330,"गिर":64,"ीत":755,"ीप":214,"ीन":664,"ीम":234,"ीय":1104,"ील":3494,"ीर":265,"ुग":140,"ुख":527,"ीव":305,"ुक":528,"गीत":150,"ुज":89,"ीस":155,"ुट":125,"िट":204,"गाव":277,"ीं":192,"िड":79,"गाल":127,"िण":383,"ित":1967,"गाय":92,"िद":477,"िध":193,"िन":1260,"िप":347,"िब":126,"घटन":111,"िभ":130,"िम":634,"िर":694,"िय":1422,"िल":1282,"ीक":319,"िळ":425,"िश":552,"िव":770,"िस":721,"िष":365,"िह":250,"ीच":727,"ीज":85,"ेव":793,"ेश":1384,"ेळ":324,"ैक":225,"ेल":2762,"ेय":96,"ेर":672,"ेम":206,"ेब":175,"ेप":128,"ेन":599,"ैद":75,"ॉं":62,"ेह":98,"ेस":492,"ेष":313,"ॉक":64,"गेल":207,"ैव":63,"ैन":90,"ॉन":105,"ॉट":71,"ॅर":127,"ॅन":107,"ें":768,"ेक":722,"ेख":448,"ेट":491,"ेड":164,"ेत":2226,"ेण":224,"ेद":177,"ेथ":380,"ेग":137,"ेच":757,"ेज":75,"ृथ":73,"ृत":438,"ृष":221,"गोल":138,"ुत":238,"ुण":210,"ुढ":64,"ुड":67,"ूं":81,"ुन":719,"ुध":64,"ुद":440,"ुप":192,"ुर":1052,"ुम":183,"ुळ":257,"ग्ल":179,"ूक":85,"ुल":420,"ुष":125,"ुस":491,"ुव":264,"ग्र":670,"ूच":81,"ग्द":71,"ग्न":84,"ूत":126,"ून":1612,"ूप":102,"ूम":143,"ूर":779,"ूल":112,"ूळ":67,"ूह":94,"चा ":1450,"्व":2745,"्श":274,"्ष":1475,"्स":788,"्ह":1660,"्म":1315,"्य":13761,"्र":9096,"्ल":826,"ची ":1393,"ोर":443,"ोय":88,"ोल":499,"ोब":307,"ोम":148,"ोस":168,"ोष":97,"ोह":121,"ोळ":97,"ोश":68,"ोव":325,"्ण":384,"्त":2563,"्ड":225,"्ट":2277,"्ठ":301,"्झ":104,"्ञ":320,"्फ":142,"्ब":125,"्प":569,"्ध":714,"्न":549,"्थ":1118,"्द":543,"ौर":111,"्ज":211,"्च":600,"्ग":488,"्क":801,"ों":135,"ॉर":159,"ॉल":165,"ोज":285,"ोड":211,"ोट":232,"ोठ":384,"ोद":77,"ोण":200,"ोत":1519,"ोप":280,"ोध":220,"ोन":394,"ोक":697,"ोच":112,"ोग":276,"चे ":2125,"घात":147,"घाच":71,"चंद":96,"घेत":69,"०६":62,"०७":100,"०४":65,"००":610,"०१":76,"०८":75,"०९":89,"१०":143,"१५":108,"१६":128,"१७":139,"१८":321,"११":87,"१२":105,"१३":94,"१४":109,"१९":1554,"२१":65,"२०":603,"८०":89,"८६":64,"९०":106,"९६":205,"९५":154,"९८":288,"९७":177,"९२":135,"९१":161,"९४":175,"९३":129,"८८":69,"८९":125,"९९":420,"३०":86,"२३":65,"२२":68,"२५":80,"२७":76,"२६":63,"२८":64,"५०":65,"६०":76,"जन ":67,"चना":79,"के ":109,"का ":542,"ओळख":133,"की ":396,"खक ":110,"कर ":232,"कन ":100,"काह":112,"किन":92,"काम":326,"कार":1020,"काय":62,"काल":221,"काळ":222,"काश":148,"कास":81,"किम":109,"किल":76,"कीय":113,"कां":335,"काद":84,"कात":158,"काण":89,"किं":328,"काच":171,"कवी":78,"कसं":90,"कशा":76,"कसभ":296,"कला":81,"कल्":115,"गी ":87,"कर्":219,"गा ":89,"करा":112,"करू":89,"करी":67,"三":73,"करत":181,"करण":522,"कथा":145,"कडे":62,"कडू":62,"गर ":134,"खंड":160,"कंप":101,"एप्":100,"एका":149,"एखा":65,"ऑफ ":63,"ऑस्":91,"ऑगस":114,"ऑक्":139,"०९ ":83,"०८ ":72,"०७ ":92,"ऊर्":63,"११ ":69,"१२ ":81,"१३ ":67,"१० ":113,"१६ ":75,"१७ ":70,"१४ ":80,"१५ ":76,"०० ":116,"०४ ":63,"एक ":1511,"आणि":780,"आपल":113,"आफ्":114,"२००":459,"आले":120,"आर्":98,"आहे":3954,"इति":65,"इतर":127,"अथव":122,"अति":63,"१९१":93,"१९८":221,"१९९":347,"१९६":128,"१९७":149,"१९४":143,"१९५":124,"१९२":109,"१९३":101,"अधि":146,"अने":154,"अभि":344,"अभ्":70,"अमे":278,"अमि":68,"अर्":160,"आका":68,"असल":335,"असत":304,"असण":73,"अशा":75,"अशी":64,"असे":343,"असू":247,"असा":90,"इंड":62,"इंग":258,"आढळ":87,"००९":79,"००७":86,"் ":95,"उच्":113,"उद्":130,"३० ":73,"उत्":376,"१९ ":73,"२७ ":71,"ऊन ":62,"२८ ":62,"२५ ":73,"इस्":65,"२० ":116,"ेशा":514,"ेशि":132," ओळ":134," कं":103,"ेष्":213," खं":102," कथ":124," कम":84," कर":956,"ैकी":208," कल":112," कव":97," कि":683," का":1385," कृ":78,"ेवर":160," कु":249," के":933," कॅ":146," को":333," कॉ":122," क्":525,"ेवा":214," एक":1893," एख":65," एप":100," ऑक":140," ऑग":114," ऑफ":67,"ेस्":75," ऑस":91," चौ":88," च्":195," जग":208," ची":128," चि":913," चा":258," चे":120," जर":148," जम":72," १ ":124," जन":432," ज्":461," २ ":80," जि":352," जा":1062," जू":107," जु":247," जी":146," जे":116," जो":163," ३ ":78," झा":447," खे":215," गण":130," गट":64," खा":206," घर":66," गो":192," ग्":328," गे":212," गु":208," गा":404," चं":92," घे":131," घा":63,"ंट ":79," अं":254,"ेथे":251,"ेथी":97," अप":73,"ेते":395," अन":300," अध":194," अथ":143," आक":124,"ेता":130," अल":139,"ेती":391," अर":236," अम":426," अभ":454," अस":1524," अव":109," अश":180," आग":68,"ेत्":247," आढ":90," आण":837," इं":409,"ेणा":90," अक":80," आं":187,"ेण्":83," अण":68," अत":140,"ेतल":69,"६० ":62,"ंत ":465,"ंड ":204,"ेने":94,"ेन्":114,"ेनि":72,"ंग ":304,"ेब्":104,"ेळा":116," इस":89,"ेल्":528,"ेलि":98,"ेली":343," इत":279,"ेला":618," आह":3959,"ेले":852," आश":86," आर":162," आय":154," आल":243,"ंच ":100," आध":97," आप":129," आफ":117," उल":66," उप":255," उद":168," उत":384,"ेरि":321,"ेरी":87," उच":118,"ंघ ":80," वा":841,"ोत ":71," वि":1279," शत":75," वस":293," व्":476," शर":73," वे":251," वै":84," शब":119," सं":1488," शि":338," शा":307," शह":692," शे":119," श्":176," शो":63," शक":86," वर":325," वन":73,"ोन ":196," ला":353," लि":318," ले":317," लो":622," या":2852," रच":72," यु":309," यो":83," ये":604," रश":94," रा":1893," रि":79," रस":83," रे":153," रु":64," रो":269,"ंद ":67,"ोर ":89," हो":1650," ह्":509," हि":526," ही":801," हा":1542," हे":1892,"ोल ":64," सम":640," सप":137," सर":815," सद":67," सध":64," सत":74," स्":1248," हर":99," हय":132," सो":189," सा":1287," सि":219," सह":142," से":175," सी":112," सु":443," सू":90," दर":173," दृ":63," दु":235," दा":117,"ोक ":70," दि":467," दक":264," त्":1085," तो":143," ते":655," तय":65," तम":233," तर":237," तत":72," ता":327," ति":182,"ोग ":64," ती":172," तु":116," तस":163," ७ ":73," ६ ":68," डि":141," टे":67," ट्":135," टो":93," ५ ":63," ठि":88," ४ ":80," टा":72," मो":576," म्":694," मे":240," मै":64," मू":114," मृ":78," मा":1083," मि":294," रं":86," मु":622," मह":1114," मल":145," मर":508," भौ":66," मन":77," मध":589," मत":139," भू":208," भा":1980," ब्":283," बे":267," बो":108," बा":493," बि":111," मं":217," बह":106," फ्":212," बर":139," बद":64," बन":145," फे":128," फा":98," फु":65," फि":73," बच":70," प्":2295," पो":147," पि":143," पा":818," पु":600," बं":158," पे":127," पॉ":75," पृ":96," पू":277," पर":492," पश":206," पह":159," पड":69," पट":81," पद":228," पत":76," न्":105," नो":178," पक":276," नि":731," ना":905," पं":133," ने":304," नव":130," धा":110," नद":157," दे":1033," द्":193," दो":206," धर":205,"ॅरि":66,"ेंट":68,"ेंद":165,"ेंब":371,"८९ ":68," द ":78," इ ":175,"ेल ":174,"८० ":71,"ेर ":66,"ेस ":273,"ेश ":484,"ेव ":85," स ":136,"ेच्":192,"ेचे":150,"ेचा":92,"ेची":66,"ेकड":79,"ेखन":78,"ेक्":200,"ेखक":117,"ेटा":76,"ॉन ":63,"९८ ":66,"९९ ":71,"९६ ":77,"९१ ":71," व ":1440,"ृष्":213,"ृथ्":72,"ृती":81,"ृत्":188,"अंत":115,"ेत ":845,"ेन ":118,"ेट ":229,"ेड ":81,"९९६":63,"ेक ":319,"ेख ":111,"ेच ":240,"आंत":108,"ुष्":79,"ुसर":130,"ुवा":185,"ुळे":148,"ुला":65,"ुलै":113,"ुरा":109,"ुरस":95,"ुरो":111,"ुर्":256,"ुरु":156,"ुरू":78,"ुमा":140,"ुप्":76,"ुनि":101,"ुनी":63,"ुना":87,"ुद्":358,"ुत्":100,"ंच्":531,"ंचा":365,"ंची":306,"ंचे":348,"ंग्":429,"ंगा":332,"ंघट":78,"ंगी":166,"ंघा":242,"ंका":93,"ंख्":149,"ंगल":89,"ंगण":71,"ंडा":180,"ंडळ":71,"ंना":305,"ंनी":632,"ंपै":165,"ंबई":124,"ूर्":429,"ंपा":63,"ंपर":71,"ंपन":86,"ंत्":351,"ंता":140,"ंती":82,"ंतर":401,"ंद्":289,"ंदी":266,"ंदू":116,"ंदा":71,"ंदि":113,"ंदर":105,"ंबर":448,"ंमध":305,"ंस्":364,"ंसा":99,"ुस्":136,"ंवर":89,"ुसा":139,"ंवा":298,"ंशो":74,"ाळी":71,"ाळा":189,"िकन":68,"ाला":601,"ालि":128,"ाली":458,"ालु":126,"ाल्":170,"ाले":279,"ावि":118,"ावी":70,"ावा":374,"ाव्":94,"ावे":148,"ावण":64,"िका":572,"ावर":588,"ावल":82,"िको":101,"िक्":215,"िके":418,"ाषा":187,"ासत":84,"ाषे":285,"ाष्":810,"ाशि":80,"ाशी":94,"िग्":108,"ासक":92,"ाही":306,"ाहि":257,"िचा":69,"ाह्":62,"ुन ":350,"ासि":69,"ासा":570,"ासु":84,"ाहत":75,"ासू":218,"ास्":488,"िजे":63,"ींच":65,"िणे":98,"िता":173,"िती":211,"ित्":984,"िद्":408,"िना":177,"िनि":68,"िनी":230,"िने":334,"िन्":135,"िपी":179,"िभा":112,"ियन":201,"िमे":82,"ियम":83,"िमी":103,"िमा":152,"ियो":66,"िया":833,"िर्":245,"िरी":73,"िरा":70,"िले":194,"िल्":507,"िला":170,"िली":83,"िसर":109,"िष्":172,"िषय":111,"िश्":136,"िशे":76,"िवस":72,"िवा":161,"िवि":81,"ीका":68,"िवड":238,"ीचे":213,"ीची":91,"िहि":83,"िहा":133,"ीचा":113,"ून ":1516,"ीच्":262,"िसे":127,"िस्":228,"ुंब":177,"ीती":162,"ूर ":255,"ीने":102,"ीरा":80,"ीवर":113,"ुक्":227,"ुका":154,"ुख्":276,"ृत ":101,"ीला":83,"ित ":454,"िण ":169,"िन ":167,"िध ":64,"िल ":211,"िळ ":165,"ीक ":118,"ांड":163,"ांच":1386,"ांक":146,"ांग":206,"ांस":157,"ांव":124,"िम ":197,"ांम":292,"ांब":110,"ांप":219,"ांन":910,"ांद":82,"ांध":110,"ांत":540,"िय ":84,"िर ":71,"िश ":190,"िस ":90,"ागा":289,"ीत ":405,"ागर":198,"ाखा":79,"ाक्":63,"ाका":132,"ाकर":80,"िंद":422,"ाडू":108,"िंव":279,"ाठी":839,"िंग":264,"ाटक":140,"ाजा":172,"ाजी":169,"ाज्":867,"ाजध":220,"ाजव":101,"ाचा":713,"ाची":807,"ाचे":1121,"ाच्":1245,"ाजक":91,"ीन ":336,"ाने":765,"ाना":350,"ानि":81,"ानी":337,"ानु":71,"ानल":114,"ानव":85,"ुख ":209,"ाध्":84,"ापन":141,"ान्":247,"ादी":203,"ानं":83,"ानत":66,"ाधि":74,"ाधा":87,"ानच":62,"ानक":91,"ाद्":145,"ाता":198,"ाती":1964,"ातू":202,"ाणे":107,"ाण्":123,"ातल":106,"ाते":315,"ात्":194,"ातो":153,"ील ":3327,"ीय ":1038,"ातं":85,"ीर ":82,"ाणी":153,"ाणा":214,"ारी":709,"ारि":99,"ारा":1018,"ारस":180,"ार्":1216,"ारे":318,"ालय":129,"ामा":334,"ायक":105,"ाम्":126,"ायन":99,"ामी":72,"ारं":64,"ामु":161,"ाया":101,"ारच":84,"ारख":74,"ारक":98,"ारण":233,"ारत":1080,"ाबा":143,"ामध":252,"ामन":110,"ापर":215,"ापू":104,"ापी":79,"ापा":183,"ाप्":78,"ीस ":70,"ाई ":106,"होत":1397,"होण":97,"ह्म":91,"ह्य":743,"ाक ":79,"ाग ":209,"ाद ":178,"ाण ":173,"ात ":2992,"ान ":859,"ाज ":109,"ाच ":165,"ाट ":100,"ाव ":432,"िक ":1026,"ाळ ":124,"ास ":473,"ाम ":369,"ाल ":196,"ार ":1261,"ाय ":102,"सले":457,"सल्":84,"समु":164,"समा":227,"समू":87,"सम्":80,"सरा":98,"सर्":792,"सप्":140,"सभे":108,"ष्य":98,"ष्ण":139,"ष्ठ":291,"सभा":231,"ष्ट":1050,"सध्":62,"षेत":366,"हत्":160,"सेच":158,"सेन":81,"सें":161,"सीम":75,"सुन":150,"हणू":177,"सुर":133,"सुम":66,"हणत":183,"सून":460,"हणज":210,"सां":148,"साह":175,"सिद":219,"साध":112,"सार":316,"साम":328,"साय":147,"सिक":101,"साव":80,"साल":226,"साग":141,"सिं":119,"साठ":416,"सात":110," १२":89," ११":78," १४":90," १३":81," १६":113," १५":99," १८":311," १७":121," १९":1529," २०":568,"हरा":269,"हर्":68,"स्व":512,"हया":139,"स्य":64,"स्ल":87,"स्थ":759,"स्प":226,"स्ट":559,"स्त":1031,"स्क":382,"सेव":68," १०":100,"हेत":649,"हें":134,"हिल":252,"हिन":68,"हित":204,"हास":245,"हाव":84,"हाय":65,"हार":516,"हाम":139,"हान":148,"हिं":378,"हात":102,"हे ":5167,"षां":107,"सणा":80,"सतो":69,"सते":145,"सता":120,"सत्":153,"षाच":186,"षिण":264,"शेष":68,"शोध":130,"हा ":1574,"ही ":1273,"श्व":169,"श्र":226,"श्य":73,"श्च":243,"शहर":683,"से ":365,"सी ":115,"हर ":423,"संत":74,"शिय":317,"संक":81,"संग":244,"शिव":108,"संख":143,"संघ":417,"संब":106,"संप":91,"संस":355,"संश":79,"शात":171,"शाच":270,"शास":375,"शिक":213,"शां":163,"वेळ":85,"वेल":78,"वेश":67,"वेग":99,"वेद":75,"शतक":63,"वृत":90,"सा ":185,"व्ह":547,"व्य":626,"शब्":122,"वर्":390,"षा ":197,"वरा":67,"वरू":76,"वरी":175,"षी ":90,"वले":122,"वसा":93,"वसल":181,"वस्":189,"सन ":83,"वां":120,"वात":562,"वाद":207,"वान":200,"वाच":234,"वाज":104,"विक":171,"वाल":80,"वास":154,"वाप":201,"वार":452,"वाय":134,"वाम":62,"वित":108,"विन":71,"विद":197,"विध":115,"विज":139,"वाह":173,"विच":82,"विष":207,"विश":185,"वीच":70,"विल":73,"विव":106,"विम":91,"विभ":103,"वीप":110,"वडू":94,"वडण":125,"वणा":82,"वण्":85,"वती":67,"वता":101,"वना":93,"शा ":95,"षण ":107,"शी ":306,"वंश":67,"ळात":171,"ळाड":66,"षक ":73,"ळ्य":142,"शन ":88,"वे ":211,"वा ":653,"वी ":367,"ल्प":162,"ल्य":1022,"ल्ल":251,"ल्व":86,"ल्स":80,"ल्ह":320,"ळना":64,"लेश":64,"लोक":579,"वळ ":98,"लेल":1062,"लेख":355,"लिह":91,"लिश":121,"लिय":136,"लील":65,"लुक":126,"वर ":789,"लां":197,"लाग":85,"लाच":70,"लिं":80,"लाप":66,"लाव":113,"लिक":135,"लास":65,"लिन":79,"लिप":197,"वत ":73,"ळखल":119,"ळे ":200,"ळा ":98,"ळी ":148,"रेस":151,"रोज":164,"रोप":113,"र्श":238,"र्व":1106,"र्स":68,"र्ष":184,"र्म":630,"र्य":552,"र्ल":103,"र्थ":343,"र्द":88,"र्ध":121,"र्न":169,"र्फ":104,"र्ट":116,"र्ड":113,"र्ण":231,"र्त":217,"र्ग":412,"र्क":189,"र्ज":148,"र्च":115,"रीक":109,"रिय":267,"रिल":109,"रिस":109,"रीत":101,"लंड":195,"रीय":372,"रील":210,"रुन":72,"रुप":68,"रुव":148,"रून":145,"रूप":76,"रें":77,"रेक":125,"रेट":62,"रेल":183,"रसा":80,"रसि":236,"रस्":202,"ले ":1654,"लै ":119,"रां":490,"रान":176,"राठ":475,"राट":76,"रात":566,"राण":185,"राज":1474,"राच":427,"रिट":93,"रित":141,"राष":801,"रास":112,"राह":156,"राम":258,"राय":119,"रिक":669,"राव":320,"रलि":71,"ला ":1877,"ररा":122,"रम्":122,"रमा":263,"रमु":208,"रसं":149,"रशि":112,"रशा":97,"रवा":143,"रले":92,"ली ":1229,"रपट":518,"येष":193,"येण":75,"येथ":336,"येत":173,"रदे":228,"योग":175,"युक":84,"युर":149,"युन":102,"युद":90,"याच":1413,"याम":178,"यान":560,"याप":224,"यात":1507,"याद":157,"यास":414,"याव":251,"यिक":66,"याल":203,"यार":164,"रता":731,"रति":74,"रती":443,"रते":65,"रत्":99,"लय ":91,"रणा":308,"रणे":72,"रण्":354,"रचन":71,"यवस":94,"रक्":111,"रजा":126,"रजी":94,"यां":1609,"रज्":107,"रच्":105,"लन ":62,"रे ":511,"महा":885,"महत":141,"यक्":261,"रू ":76,"मले":80,"री ":1362,"मृत":96,"मूह":88,"मुळ":150,"मुल":69,"मुद":185,"र् ":478,"मुख":511,"रंप":65,"रंथ":84,"मुं":140,"रंग":175,"मिळ":390,"मित":196,"मिन":63,"मार":537,"माल":161,"मिक":114,"माव":85,"माह":78,"माण":213,"मात":178,"मान":677,"माच":73,"माज":179,"मां":206,"मोठ":381,"में":100,"मेर":300,"मेल":94,"यत्":103,"रका":358,"म्र":173,"म्य":205,"म्ह":682,"म्म":64,"रत ":129,"यू ":94,"रण ":190,"या ":6887,"भिन":289,"भाव":89,"भाष":512,"भार":1098,"भाग":467,"रम ":63,"यंत":200,"ये ":856,"मधी":410,"मध्":993,"भेव":86,"मनी":88,"भूत":65,"भूम":113,"मतद":118,"मरा":500,"रा ":574,"भ्य":77,"मा ":144,"बर्":157,"मी ":268,"यन ":212,"मे ":125,"बहु":71,"बिय":93,"बाज":80,"बाब":72,"बार":87,"बाद":98,"बां":115,"मंत":114,"मंद":83,"मंड":86,"यम ":64,"रक ":67,"बेर":65,"बेट":143,"बोध":67,"ब्र":411,"ब्द":139,"प्र":2788,"प्त":110,"प्ट":127,"भा ":239,"मण ":66,"मन ":141,"बच्":64,"यक ":87,"बद्":68,"बनव":83,"फेब":101,"फ्र":309,"पहि":119,"पश्":206,"पल्":82,"बी ":93,"बा ":68,"पर्":325,"परि":145,"परा":78,"परं":68,"�":133,"पैक":208,"पृथ":73,"पुस":66,"पूर":541,"पुण":116,"पुत":63,"पुर":350,"पीठ":86,"बंग":106,"बंध":84,"पास":320,"पाच":82,"पाण":105,"पान":76,"पात":141,"पाद":66,"पार":155,"पाल":72,"पाय":64,"पां":102,"पक्":286,"न्न":159,"न्य":422,"न्म":293,"न्ह":93,"न्स":215,"नोव":141,"पद्":103,"पदा":135,"पनी":76,"पना":113,"पणे":87,"बर ":537,"पत्":186,"पती":143,"पटा":141,"नले":90,"नवी":100,"पी ":206,"नदी":146,"ध्य":1211,"नुस":148,"नीच":95,"निस":85,"नेत":475,"नेश":67,"नेव":132,"नेक":163,"बई ":90,"निव":276,"निर":218,"निय":224,"नास":64,"नाह":82,"नाव":453,"निक":308,"नाय":79,"नाम":119,"नार":159,"नात":134,"नाट":176,"नाड":71,"नाच":211,"नाग":125,"नां":144,"द्द":122,"द्व":204,"द्र":575,"द्य":488,"द्ध":540,"धर्":201,"पट ":338,"देव":241,"देश":972,"देण":76,"दोन":169,"धात":66,"धार":222,"धिक":210,"धान":301,"धील":412,"पर ":71,"नता":99,"नगर":128,"पण ":79,"नच्":79},"n_words":[573395,652939,442285],"name":"mr"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mkd b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mkd new file mode 100644 index 000000000..a0c736aa6 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/mkd @@ -0,0 +1 @@ +{"freq":{"D":603,"E":600,"F":432,"G":577,"A":1208,"B":839,"C":1276,"L":579,"M":1021,"N":552,"O":461,"H":549,"I":1773,"J":289,"K":455,"U":346,"T":883,"W":350,"V":551,"P":991,"S":1413,"R":594,"X":347,"f":1092,"g":1689,"d":2970,"e":9834,"b":1224,"c":2969,"a":10833,"n":6781,"o":7437,"l":4802,"m":3009,"j":528,"k":1469,"h":2724,"i":8516,"w":745,"v":996,"u":3216,"t":5815,"s":5501,"r":6845,"p":1803,"z":571,"y":1482,"x":320,"ν":292,"ο":532,"ι":356,"α":455,"ς":427,"ρ":335,"τ":303," m":470," o":776,"ш":16654," i":285," k":375," d":474,"ф":11418," e":367,"х":6666,"ц":21764,"ч":22883,"р":143160,"с":124190," a":559,"т":178546," c":357,"у":55891,"ќ":2840,"џ":1064,"љ":298,"ј":55736,"њ":6876,"ѕ":416," t":538," p":361,"ѓ":4991," s":442,"Ј":1691,"Џ":661,"И":3549,"Л":2399,"К":6325,"Н":3704,"М":7265,"П":6311,"О":4503,"Б":5118,"А":6164,"Г":3754,"В":4777,"Е":2673,"Д":3627,"З":1960,"Ж":390," K":424,"Ш":1184," H":467," I":966," N":433," O":314," L":498," M":897," B":722,"Т":4778," C":1036,"У":965,"Р":4369," A":1024,"С":9342,"Ц":1100," F":403,"Ч":767," G":506," D":520,"Ф":2111," E":476,"Х":1951,"л":91274,"к":111435,"и":261784,"п":63533,"о":278169,"н":193670,"м":56196," S":1135,"г":42718,"в":105270," R":489,"б":32290," P":814,"а":349769,"з":39653," W":317,"ж":11105," V":362,"е":224574," U":304,"д":90920," T":673,"ا":324,"Ист":523," А":5482," Б":5022," В":4654," Г":3616," Д":3069," Е":2489," Ж":385," З":1936," И":3361," К":5975," Л":2339," М":6938," Н":3453," О":4096," П":6133," Ј":1624," Џ":661,"I ":636," б":12052," а":9283," г":16454," в":30954," е":23200," д":18766," з":12782," ж":2284," и":33901," л":4546," к":23687," н":51827," м":12882," п":36928," о":29291," Р":3961," С":8974," Т":4639," У":893," Ф":1931," Х":1928," Ц":1068,"II ":332," Ч":758," Ш":1131," ј":6372," ќ":305," т":10678," у":3946," р":10396," с":42490," ц":3019," ч":2568," ф":5078," х":2102," ш":4226,"Ma":323,"II":479,"Кар":402,"a ":2176,"i ":786,"he":719,"ha":360,"g ":312,"ea":411,"ed":390,"de":624,"di":400,"h ":457,"el":544,"Кра":315,"en":923,"et":387,"es":758,"er":1600,"ca":400,"e ":2587,"da":295,"f ":324,"Кон":322,"co":397,"ci":314,"ch":448,"ce":390,"d ":868,"at":846,"as":511,"ar":1185,"al":1004,"am":363,"an":1614,"ac":442,"ae":314,"nt":684,"of":311,"om":450,"on":1271,"ol":392,"os":424,"ou":298,"op":290,"or":933,"r ":882,"lo":357,"ll":449,"o ":1254,"ma":512,"me":447,"na":717,"nd":628,"ne":472,"ng":429,"ni":597,"m ":843,"km":293,"li":761,"le":704,"la":806,"n ":1564,"hi":303,"id":295,"ic":719,"ia":681,"ie":315,"is":934,"it":584,"il":394,"in":1115,"io":670,"l ":690,"y ":690,"ve":297,"ur":355,"us":735,"to":540,"tr":283,"te":849,"ti":907,"th":673,"ta":699,"st":673,"se":302,"si":446,"rt":285,"ro":643,"ri":940,"re":789,"ra":861,"t ":818,"s ":2376," ја":4740," ју":1544," ќе":299," ра":3709," ре":3839," ри":619," ро":1485," пр":14360," св":1979," си":2281," се":16046," сл":2331," см":1011," ск":603," сп":1778," ср":1095," со":9088," ру":564," са":1270," ти":832," тв":438," те":3329," то":1808," тр":1830," ст":3760," су":653," та":1317," ус":533," уп":512," ун":383," ум":454," ту":815," фо":1103," фр":608," фу":590," фе":667," фи":1284," фа":744," уч":625," уш":328," хр":549," хо":304," хи":314," хе":609," цр":836," ци":311," це":1471," чо":400," чл":393," чи":499," че":954,"На ":392,"Мак":2308,"Мар":480," ше":287," шп":318," шт":2822,"Нов":305,"ад ":2199,"ав ":328,"аа ":1364,"ам ":781,"ан ":3695,"ак ":666,"ал ":2115,"Ово":374,"Ова":565,"аву":1675,"авт":686,"ага":381,"агр":309,"аго":607,"ада":949,"ади":1566,"аде":2265,"адр":313,"адо":1542,"адм":285,"адн":1034,"Опш":342,"аед":445,"би ":515,"ај ":1373,"ажу":426,"аат":3002,"або":1052,"ава":2546,"авн":1461,"аво":532,"аве":1404,"ави":1807,"алс":704,"алн":2980,"ало":848,"алб":313,"ала":1561,"алк":385,"али":3092,"але":2411,"амо":926,"ама":619,"ами":1203,"аме":1650,"ано":1527,"ану":570,"анс":4432,"ант":1418,"анц":867,"ана":3750,"анд":1155,"анг":1211,"ани":6541,"ане":747,"анк":497,"азн":452,"азл":623,"ази":3687,"азб":417,"азв":373,"аза":432,"аин":488,"аку":331,"акт":1164,"ако":4144,"акв":313,"аке":3801,"ака":975,"ач ":549,"Пар":311,"ас ":519,"ар ":2828,"ат ":6463,"ба ":1244,"аш ":464,"Пет":286,"САД":331,"Пол":375,"При":340,"Пре":445,"Про":342,"Рим":340,"Се ":508,"Реп":976,"Алб":429,"Аме":307,"Рус":402,"Ско":700,"Срб":287,"Сев":333,"Све":487,"Сел":334,"Таа":318,"Во ":1246,"Бел":406,"Тур":381,"Тој":871,"Вел":340,"Буг":380,"Гра":387,"Грц":367,"Фил":384,"Фра":322,"Евр":489,"лам":296,"лар":497,"лан":1512,"лас":1834,"лат":1878,"лба":979,"ме ":1911,"ма ":2440,"лав":1747,"лаг":370,"лад":919,"кул":1012,"куп":340,"кув":856,"кци":783,"кој":5826,"кре":290,"кра":1871,"кри":723,"кру":671,"кро":310,"лу ":886,"кса":284,"кси":508,"кст":341,"кте":605,"кти":891,"кто":713,"ктр":386,"кту":473,"кла":474,"кло":480,"ло ":2497,"кле":364,"клу":723,"кни":318,"ког":686,"ков":1275,"ком":1394,"кон":2061,"коп":1132,"кор":1338,"кот":2936,"кое":689,"кои":2339,"кол":2256,"кин":368,"кио":3400,"кит":2518,"ле ":2377,"кви":345,"кед":3751,"ли ":5921,"кај":517,"ква":1424,"кат":5730,"кар":1133,"кан":1422,"как":3097,"кал":885,"каж":406,"каз":294,"кац":351,"кад":630,"ла ":4400,"кт ":520,"ку ":1035,"иња":474,"ко ":6033,"ија":20901,"ки ":14686,"од ":14751,"нај":2709,"нац":749,"нау":554,"нач":1308,"нао":2376,"ог ":396,"нан":329,"нам":682,"нал":1991,"нат":7755,"нас":2005,"нар":1995,"нап":588,"нае":357,"над":781,"нак":346,"нда":719,"нго":310,"нгл":1025,"нга":386,"ое ":669,"неш":642,"нек":1134,"нен":441,"ои ":2794,"нер":1150,"нес":1333,"нет":980,"нег":1025,"нез":398,"нди":607,"ндо":434,"нив":1190,"низ":1413,"ник":2233,"ние":1319,"ок ":1161,"неј":441,"оа ":1059,"ов ":1440,"нав":317,"нт ":615,"мпи":518,"мпе":650,"мот":1353,"мск":1350,"мун":373,"муз":537,"мил":526,"мин":1679,"мио":320,"мис":724,"мир":732,"мит":1061,"миј":737,"но ":8706,"мна":468,"мно":1052,"мод":313,"мож":942,"мон":609,"мор":627,"мај":590,"нд ":382,"мбо":288,"маш":335,"мал":1112,"мак":1628,"мат":1625,"мас":309,"мар":614,"нг ":468,"ман":2367,"маа":339,"меѓ":1150,"мес":950,"мет":2904,"мен":3380,"ни ":9820,"мер":1511,"мед":429,"мвр":974,"не ":1045,"на ":51854,"лош":669,"му ":324,"лни":1621,"лно":1301,"лна":1254,"лок":568,"лог":1288,"лож":284,"лос":414,"лот":1377,"лом":349,"лон":478,"лов":1561,"лоб":414,"луч":790,"луц":507,"лув":419,"луѓ":365,"лст":374,"лск":1346,"лту":424,"лта":406,"лиг":412,"лив":613,"лиз":933,"лим":882,"лик":2508,"лез":472,"лев":497,"лег":370,"лед":1625,"лес":486,"лер":345,"ми ":1067,"лен":3033,"лем":2373,"лек":1469,"лет":727,"лку":522,"мо ":748,"лиц":678,"лич":1268,"лис":1550,"лит":1817,"лиф":510,"лин":1340,"лио":355,"лип":313,"лиј":1726,"лка":359,"пат":1339,"пад":1381,"пак":283,"пан":956,"пар":1020,"паѓ":517,"ре ":437,"оѓа":2306,"ра ":3142,"рв ":449,"пин":286,"пис":1343,"пиш":657,"оја":4079,"ојн":740,"ојо":993,"оју":491,"пла":934,"пли":320,"пле":333,"ро ":695,"пло":389,"рз ":285,"ри ":5094,"пер":1862,"пес":307,"пет":425,"ори":3831,"опј":624,"орд":482,"оре":2005,"орг":1108,"орс":410,"оро":1288,"орм":1326,"орн":663,"опш":1157,"опс":733,"ора":1582,"опе":396,"опи":565,"опо":646,"опр":349,"опа":631,"оте":1213,"отк":367,"оти":883,"ото":5629,"отн":448,"отр":639,"ота":373,"осе":641,"оси":467,"оск":407,"осл":1286,"осн":1425,"осо":623,"ост":6452,"ору":832,"орт":556,"осв":433,"омн":415,"оми":891,"оме":1683,"ома":1343,"олу":1982,"олс":527,"олн":609,"по ":1690,"оло":2164,"олк":576,"олж":334,"оле":2647,"оли":2456,"олг":289,"ола":807,"окр":1306,"окт":286,"око":2063,"онс":2772,"онт":604,"онц":377,"они":3271,"оно":1647,"она":1646,"онг":566,"оне":1032,"омо":661,"омп":789,"ошк":618,"очи":455,"оче":494,"очн":1426,"офи":716,"оце":494,"оци":931,"оцн":311,"ова":2348,"обр":811,"обо":536,"обл":1113,"оби":1201,"обе":598,"па ":1261,"оис":379,"оим":505,"ока":1091,"ој ":6820,"озд":514,"ози":514,"оза":639,"озо":309,"озн":2037,"оиз":367,"одн":2574,"оди":4273,"одр":1508,"одо":1251,"оед":304,"оем":310,"оен":405,"пи ":325,"оет":296,"оже":937,"ове":2546,"ови":5165,"обј":366,"ово":2355,"овн":742,"овр":984,"овс":795,"ога":1201,"оги":878,"огл":313,"ого":815,"огр":1093,"огу":753,"ода":1107,"одг":298,"одв":294,"оде":2517,"от ":21175,"нот":2355,"нос":3399,"ос ":575,"ном":868,"ное":302,"ног":889,"нов":2577,"ор ":1906,"он ":2167,"нкц":314,"нка":519,"нки":331,"мја":559,"ниј":3754,"мји":343,"нир":495,"нис":1095,"нит":3914,"ним":450,"нин":793,"ол ":609,"нио":3455,"нич":1161,"ниц":2089,"нци":1726,"нцу":394,"нув":1506,"нта":1389,"нте":740,"нти":1942,"нто":379,"нтр":628,"нск":8777,"нст":1138,"сам":861,"сан":508,"сат":511,"те ":14904,"сво":1166,"све":1266,"себ":334,"сев":971,"сед":864,"сел":2274,"сек":726,"сеп":284,"ти ":4039,"сен":517,"сем":349,"сет":758,"сер":521,"сис":839,"сит":795,"син":510,"сил":492,"сим":340,"ски":15155,"ска":7767,"сиј":608,"сли":753,"сле":1796,"сла":744,"ско":2753,"сме":854,"слу":574,"сло":1010,"то ":13336,"сна":721,"сни":929,"соб":473,"сов":600,"сод":296,"соз":452,"сок":602,"сно":1836,"спе":625,"спа":419,"сот":388,"сос":874,"сон":314,"соч":283,"соц":292,"сре":870,"спо":1324,"спр":420,"роц":373,"рот":1919,"роф":371,"роп":944,"рос":834,"ст ":3322,"рој":2600,"рст":683,"рти":754,"рск":2698,"руа":354,"рув":1033,"руг":1560,"руж":292,"руп":1220,"рус":732,"рум":335,"рци":855,"рхе":302,"рхи":519,"АД ":331,"рши":562,"рчк":744,"та ":23306,"рад":4624,"раз":2373,"раа":405,"раб":909,"рав":1584,"рам":1207,"ран":5737,"рап":368,"раи":514,"рак":1026,"рал":1971,"раф":696,"рач":346,"рац":462,"рас":1293,"рат":2616,"рби":405,"рањ":570,"рај":718,"рва":669,"рди":936,"реб":752,"рев":1305,"рег":1001,"ред":3985,"реа":398,"рет":3047,"рес":955,"реп":457,"си ":856,"рен":1613,"рем":1904,"рел":504,"рек":1638,"рез":448,"реж":432,"ржа":1664,"реч":605,"реш":461,"се ":11859,"рво":342,"рве":449,"рви":554,"рга":1142,"рда":316,"пје":616,"рио":1095,"рип":420,"рим":878,"рин":740,"рик":1477,"рил":774,"рии":353,"рич":442,"рит":2109,"рир":852,"рис":2774,"рка":561,"ркв":703,"риј":3270,"рза":354,"реј":340,"риб":299,"рив":398,"рие":488,"рид":648,"риз":552,"рзи":395,"рни":1032,"рна":1303,"рок":621,"рол":306,"ром":966,"рон":752,"роз":340,"рои":701,"ров":2202,"рог":438,"род":3344,"роб":326,"рно":847,"рми":912,"рма":1504,"со ":5615,"пра":1665,"прв":1141,"при":3441,"пре":5957,"про":4233,"поп":440,"пор":1847,"пос":2237,"пот":1782,"поч":860,"пој":398,"рт ":589,"пое":340,"под":1948,"пог":377,"пов":1628,"пон":487,"пом":1198,"пол":2038,"пок":698,"поз":1786,"пуб":1193,"пст":289,"пск":1161,"пшт":1492,"са ":460,"вар":956,"ват":2229,"вач":868,"вај":507,"вањ":3265,"ваа":2386,"ван":1597,"вал":1237,"га ":1478,"бук":590,"вто":1107,"вск":1077,"вст":329,"врд":656,"вре":1804,"ври":1040,"врз":737,"вро":757,"гу ":683,"вру":340,"врш":792,"вој":2262,"вол":822,"вои":368,"воз":430,"вое":499,"вод":1487,"вот":2101,"вор":1284,"вос":388,"вни":1914,"вна":1234,"вно":1024,"вле":285,"вла":692,"го ":2513,"вкл":312,"виј":388,"вич":290,"бје":284,"виз":445,"виж":381,"вил":734,"вин":1260,"вио":811,"вис":1212,"вит":1405,"вид":1204,"вие":441,"веќ":667,"вес":376,"вет":2185,"вер":2282,"вен":3438,"ги ":1837,"вел":447,"век":1300,"вез":364,"вее":283,"вед":808,"ва ":8865,"бан":796,"бал":536,"ачи":1031,"ачк":640,"ачу":385,"ашк":290,"афс":366,"афи":298,"ача":344,"аче":347,"аци":3529,"апс":423,"апр":517,"аоѓ":2290,"апа":1524,"апо":665,"апи":499,"арх":678,"арс":1354,"арт":1039,"ару":298,"аса":450,"аре":1123,"ард":653,"ара":1867,"арн":612,"аро":1814,"ари":3185,"арк":629,"аст":2995,"ата":20566,"аси":680,"асе":1117,"асл":312,"аск":436,"асп":410,"асо":310,"асн":388,"ату":514,"ате":2125,"ати":3730,"атк":340,"атн":495,"атп":334,"ато":1865,"атс":493,"атр":330,"бол":467,"бод":337,"бор":1569,"бот":1139,"аќа":380,"бро":2687,"бри":330,"бре":488,"бра":1074,"ајќ":358,"бич":355,"аја":393,"ајг":681,"ајд":338,"биј":384,"ајм":316,"ајн":658,"ајп":372,"ајс":402,"ајч":379,"ања":532,"бла":981,"бли":2035,"ање":3967,"во ":22199,"беш":291,"ви ":3384,"бен":594,"бер":412,"без":326,"бед":404,"бел":545,"бир":443,"бит":461,"бил":3972,"бид":516,"ве ":532,"бат":375,"бар":494,"аѓа":856,"дба":505,"дан":444,"дар":782,"дат":1402,"дви":611,"два":530,"две":568,"ед ":1436,"дал":491,"дад":551,"дав":666,"ев ":387,"дек":1195,"дем":341,"дел":3411,"ден":5845,"дер":607,"деј":478,"дес":441,"дво":453,"ез ":342,"дст":314,"дск":660,"дро":328,"дру":1086,"држ":2045,"дре":612,"дра":666,"ет ":2199,"дув":889,"ец ":658,"ен ":10275,"диш":466,"диц":456,"ем ":1181,"диј":826,"дин":5382,"ел ":3388,"дис":491,"дит":597,"ек ":1095,"доб":755,"дов":988,"дод":356,"ес ":859,"дос":369,"дол":887,"док":331,"дон":4125,"дом":347,"доц":331,"дот":1786,"дна":2163,"дни":2521,"дне":428,"ер ":2117,"дно":2480,"дми":387,"al ":294,"да ":4123,"гал":357,"гаш":492,"гат":448,"ган":1283,"гар":1072,"де ":1153,"and":335,"an ":327,"вув":2038,"гол":2184,"гот":553,"гор":505,"гов":1806,"год":3338,"гру":1162,"грч":711,"гра":5732,"гри":662,"гре":320,"гус":349,"ген":767,"гер":583,"ди ":1894,"гео":440,"гит":546,"гио":772,"гиј":928,"ati":284,"гле":564,"гла":1406,"до ":1648,"гли":1163,"жан":284,"жат":386,"жав":1162,"за ":5828,"жит":423,"еја":386,"ејз":450,"ејс":859,"жив":1211,"жењ":316,"еѓу":1271,"жел":288,"зи ":329,"жен":928,"жно":527,"жни":489,"еќе":715,"жна":492,"ење":1370,"ς ":427,"жув":901,"еј ":342,"ежи":423,"еду":826,"жи ":501,"еза":382,"езн":323,"езд":396,"езе":477,"ези":298,"ева":629,"еви":727,"еве":1630,"еба":481,"ебе":337,"его":1463,"еда":979,"еде":2597,"еди":2433,"едо":4194,"едн":3441,"ево":1021,"же ":578,"евр":732,"ега":454,"еги":839,"ент":3074,"ену":344,"енс":1151,"енц":490,"енк":321,"ени":4714,"емј":955,"ено":2370,"ена":3300,"ене":1764,"енд":500,"еол":430,"еор":360,"еог":380,"епт":359,"епу":1119,"епо":307,"ерс":707,"ерм":1219,"ерн":1475,"еро":1509,"ери":4408,"ерз":406,"ерк":320,"ере":664,"ера":2000,"еке":284,"еки":306,"екл":312,"еко":2603,"ект":1806,"екс":1174,"еку":1063,"ека":1814,"елн":396,"ели":2173,"елу":301,"елс":372,"ело":2613,"еле":3177,"ела":1614,"елб":498,"емо":621,"еми":2065,"еме":2170,"ема":1276,"емв":738,"еци":352,"ечк":442,"ечн":297,"ече":723,"ешт":455,"ешн":741,"ешк":443,"еше":584,"есе":1065,"еси":417,"еск":430,"есн":1000,"есо":341,"есу":502,"ест":3547,"ета":1622,"ети":1694,"ете":797,"етк":321,"етр":679,"ето":5033,"етн":1147,"етс":2563,"етх":473,"иве":1425,"иви":638,"ива":1008,"К ":292,"иен":500,"иер":283,"иет":479,"иже":402,"идо":449,"игр":971,"ида":352,"иди":356,"иде":991,"иво":1058,"ивн":1457,"ига":533,"иги":461,"ико":1235,"ики":550,"ика":4788,"иит":454,"изр":316,"изм":698,"изи":1398,"изд":435,"изг":666,"иза":1563,"изв":1007,"изб":296,"иј ":327,"ион":2538,"иот":8785,"инц":810,"иод":616,"Д ":485,"ине":862,"ини":3140,"ино":890,"инс":2166,"инт":558,"ину":385,"ина":9820,"инд":577,"инг":507,"ими":494,"име":2091,"имс":590,"имо":452,"имп":928,"има":2023,"или":5248,"иле":1067,"илм":478,"ило":1256,"ику":390,"ила":1963,"иси":462,"исе":361,"иса":487,"ист":8007,"исо":810,"исн":402,"исл":520,"иск":3494,"ити":1229,"ите":15877,"ита":1364,"иту":775,"ито":1415,"ипа":375,"ипи":348,"ира":3770,"ире":311,"ири":916,"иро":1138,"ица":1798,"ици":3395,"ифи":395,"ифо":430,"ичи":380,"ичк":3274,"ичн":2026,"ича":867,"иче":543,"ишу":288,"ишт":844,"иша":368,"ка ":12158,"ив ":663,"зав":514,"зае":409,"збу":314,"збо":1117,"ид ":907,"зви":372,"зве":330,"зац":679,"зат":324,"зар":363,"зап":1380,"зан":720,"зам":529,"зби":290,"згр":557,"зда":948,"зво":628,"ие ":1909,"зер":453,"ии ":1591,"зен":322,"зем":1002,"из ":417,"зик":2343,"зир":670,"ил ":3300,"зин":797,"ик ":3740,"ин ":1454,"им ":736,"зиј":706,"зиц":855,"зич":514,"зит":574,"змо":513,"зли":625,"зна":3413,"зни":663,"ир ":506,"ис ":533,"зон":283,"ит ":464,"зра":561,"зув":311,"хе":1090,"хи":1138,"хо":1598,"хр":886,"ха":892,"ци":13250,"цн":316,"цр":866,"цу":450,"ца":2399,"це":3069,"чл":414,"чн":4154,"чо":686,"чи":3265,"чк":5243,"чу":1362,"че":4695,"ча":1926,"шп":336,"шн":1414,"шк":1724,"ши":1346,"шт":6867,"шу":599,"ше":1638,"ша":1244,"ск":26715,"см":1616,"сл":4921,"со":11740,"сн":3623,"ср":1256,"сп":3213,"св":2617,"се":20196,"си":5941,"рш":1040,"са":3377,"рс":3892,"рт":2549,"ру":6871,"рх":1018,"рц":1077,"рч":928,"тн":2841,"тл":534,"тк":1435,"тс":3837,"тр":9143,"тп":601,"то":28365,"те":29796,"тв":4680,"ти":19086,"та":36712,"су":2000,"ст":32059,"сц":293,"ур":4376,"уп":2469,"ут":1165,"ус":3800,"ум":2729,"ул":3220,"ун":2432,"уз":1241,"ук":2337,"уд":1768,"уг":3250,"уж":1378,"уе":298,"уа":1187,"уб":2169,"ув":11713,"тт":407,"ту":4071,"тх":499,"фу":697,"фс":456,"фр":997,"фо":2242,"фи":3122,"фе":1624,"уѓ":407,"фа":1468,"уч":2178,"уш":1171,"уц":759,"џа":360,"is ":354,"ion":475,"јќ":588,"ње":5394,"ња":1280,"ќе":1037,"ќи":734,"ќа":686,"јк":379,"ји":475,"јп":396,"јо":1613,"јн":1588,"јм":402,"ју":2500,"јс":1508,"јч":415,"ја":31927,"јв":456,"јг":710,"јд":458,"је":1464,"јз":570,"ѓа":3178,"ѕв":310,"ѓу":1282,"ѓе":418,"Ју":674,"Ја":560," Ma":317,"he ":401,"а ":151197,"Ис":747,"Им":497,"Ин":571,"к ":7206,"Из":327,"Ле":628,"Ли":491,"Ла":558,"Ку":463,"Кл":294,"м ":4019,"Ко":1594,"Кр":735,"Ки":516,"Ка":1846,"л ":10222,"На":1551,"Не":719,"Ни":442,"Мо":930,"о ":68362,"Ма":3832,"Ми":784,"Ме":823,"Ло":317,"н ":18349,"Лу":312,"Па":998,"Пе":965,"Пи":295,"По":1730,"с ":3798,"Оп":470,"р ":8070,"Ос":606,"Ов":1078,"п ":907,"Но":521,"в ":3431,"Ам":433,"Ан":848,"Ал":1075,"Ав":472,"Ба":928,"Ар":692,"б ":542,"АД":338,"д ":20357,"Во":1671,"Ве":686,"Ви":848,"Га":384,"г ":2028,"Бо":738,"Бр":705,"Бе":879,"Би":685,"Ва":687,"Бу":778,"Ди":461,"Де":856,"Др":341,"До":567,"Ег":326,"Ев":564,"Ге":525,"Гр":1204,"Гл":343,"Го":804,"е ":62888,"Да":437,"и ":77640,"За":893,"Зе":393,"з ":1486,"Ер":317,"ia ":314," km":286," o ":369,"Ст":846,"Та":770,"Ти":438,"Те":690,"То":1430,"ф ":405,"Тр":452,"Ту":524,"х ":407,"Пр":1600,"СА":368,"Ра":521,"Ре":1553,"Ри":680,"Ро":593,"т ":35867,"Ру":528,"Са":911,"Св":650,"Си":589,"Се":1780,"Сл":373,"Ск":807,"Ср":474,"Сп":404,"у ":4465,"Со":1077,"Це":313,"ш ":868,"Цр":465,"Че":319,"ц ":857,"Фр":445,"Фи":522,"Ха":496,"Хр":339,"ч ":920,"Хо":298,"Хе":392,"мб":886,"ма":12609,"мв":986,"ме":13316,"лј":325,"ми":7979,"лм":650,"лн":4295,"ло":11112,"лс":1887,"лт":1426,"лу":4631,"лб":1321,"ла":14718,"лж":375,"ле":15180,"лд":283,"лг":660,"лк":1166,"ли":21964,"кн":889,"кл":2271,"кр":4199,"кс":1892,"ко":29166,"кт":3820,"ку":4201,"кц":796,"ка":27714,"ки":22033,"кв":1916,"ке":4892,"иј":21371,"ињ":534,"иш":2058,"ио":12982,"ип":1917,"им":7924,"ин":21871,"ик":11472,"ил":14255,"ии":2086,"иц":5454,"ич":7399,"иф":1198,"их":496,"ит":22205,"иу":361,"ир":7402,"ис":15994,"ри":23710,"пј":828,"рк":2169,"рл":526,"рм":2952,"рн":3559,"ро":18691,"рп":592,"ра":32025,"рб":1278,"рв":2697,"рг":2004,"рд":2000,"ре":21468,"рж":2185,"рз":1370,"пш":1508,"пр":16649,"пт":674,"пс":1836,"пу":1996,"ој":14117,"пи":3835,"пн":348,"по":20419,"пл":2009,"па":7611,"пе":4276,"оѓ":2317,"ош":1554,"оч":2768,"оц":1836,"ос":13243,"ор":16926,"оп":6149,"оо":627,"ох":400,"оф":1458,"оу":339,"от":31750,"ок":6835,"ол":13527,"ом":7054,"он":15080,"ож":1857,"оз":4638,"ои":4773,"ов":16820,"ог":5746,"од":29777,"ое":2635,"оа":1652,"об":5296,"нц":2585,"нч":293,"нт":6041,"нс":10729,"нф":376,"ну":2258,"но":20747,"нл":307,"мј":1034,"нк":1682,"нз":408,"ни":34239,"не":10732,"нг":2911,"нд":3033,"нб":290,"на":77634,"му":1844,"мс":1507,"мр":516,"мп":2215,"мо":6592,"мн":1816,"ге":2417,"ги":5000,"гн":490,"го":11946,"гл":3601,"гр":9052,"гу":1829,"дг":373,"дв":2181,"дб":788,"да":9183,"вг":415,"ве":13770,"ви":13074,"бј":460,"вк":750,"вл":1274,"вн":4219,"во":32617,"вр":6858,"вс":1589,"ву":2258,"вт":1215,"га":5709,"би":7825,"бе":3314,"аѓ":883,"бр":4813,"бн":514,"аќ":462,"бо":4771,"бл":3356,"ањ":4559,"ај":7017,"бу":1986,"ва":22923,"ад":10986,"ае":1609,"аж":1096,"аз":7096,"аа":4444,"аб":2331,"ав":11512,"аг":2167,"ам":6375,"ан":27243,"ао":2597,"ап":4252,"аи":936,"ак":12466,"ал":15259,"ах":737,"аф":1127,"ач":3591,"ац":3769,"ас":7790,"ар":17103,"ау":1031,"ат":37636,"ба":4355,"аш":1946,"зр":646,"зу":791,"зи":7831,"зо":1382,"зн":4381,"зм":998,"зл":1008,"ив":6555,"иг":2802,"иа":334,"иб":811,"иж":639,"из":7830,"ид":3802,"ие":3605,"ј ":8902,"жу":939,"еј":2932,"жи":2889,"ењ":1526,"жн":1527,"еќ":923,"за":12607,"зб":1994,"зв":1627,"зг":962,"зд":1570,"зе":2250,"еф":889,"ет":17396,"ес":8709,"ер":16613,"еп":2846,"ео":1987,"ен":28920,"ем":9666,"ел":15327,"ек":11126,"еи":513,"ез":2727,"еж":1162,"ее":663,"еѓ":1275,"же":2514,"жа":2420,"еч":1979,"еш":2657,"ех":563,"ец":1329,"дс":1024,"др":5219,"ду":2009,"дн":7627,"дм":697,"до":12951,"ди":12328,"дл":415,"де":15216,"еб":1885,"ев":5864,"ег":3639,"ед":16863,"еа":1309," th":283,"er ":422,"es ":384,"ѓу ":904,"ѓа ":2452,"уци":681,"учу":537,"учн":321,"учи":444,"уче":651,"ушт":599,"уѓе":382,"фев":335,"фер":358,"фиј":319,"фин":438,"фил":788,"фик":307,"фиц":459,"фун":322,"фра":515,"фот":446,"фор":1281,"фск":446,"ца ":1645,"ци ":2599,"хео":283,"хем":340,"хри":386,"ход":569,"хит":310,"сто":6090,"стр":4031,"ств":3177,"сте":2303,"сти":4708,"ста":7801,"сув":590,"сту":413,"тав":2466,"таа":321,"так":837,"тал":1456,"тан":2640,"тат":1512,"тап":396,"уг ":454,"тар":2183,"тац":321,"тву":302,"твр":556,"тво":2438,"тве":696,"тва":548,"тем":1441,"тел":2805,"тео":301,"тен":1940,"тер":3359,"тет":1279,"тес":476,"тек":1487,"тив":1778,"тка":575,"тиј":1079,"ум ":532,"тич":2394,"тин":2798,"тик":921,"тил":553,"тир":892,"тис":499,"тио":463,"тип":307,"тит":1897,"тко":341,"тки":324,"тно":744,"ток":893,"тол":870,"тои":602,"тов":635,"тоа":832,"тни":1408,"тна":541,"тпр":359,"тре":1295,"тра":3106,"три":1787,"тор":3285,"тот":2026,"том":830,"тон":944,"ус ":503,"топ":356,"тоц":289,"точ":1182,"тој":1245,"тст":1499,"тро":1844,"тру":758,"тсе":374,"тск":1871,"тхо":477,"туд":444,"тув":539,"тур":2009,"ува":11421,"уго":905,"уги":667,"уга":1084,"уда":547,"уар":643,"убл":1212,"узи":649,"ужн":805,"уди":328,"удб":322,"уме":785,"уми":352,"улт":955,"ули":697,"ула":701,"ука":732,"укв":382,"упо":434,"ура":1158,"ури":529,"уре":411,"упа":1105,"унк":323,"уна":414,"уни":908,"уст":803,"уте":298,"урц":319,"урс":618,"урн":333,"уск":1016,"уси":423,"шки":805,"шко":400,"шни":549,"шно":321,"шна":496,"шка":496,"шир":378,"шин":495,"шен":456,"шан":341,"што":3204,"шув":475,"ште":1404,"шти":1481,"шта":515,"on ":498,"че ":342,"цен":1177,"чи ":884,"цел":738,"циј":5710,"ции":969,"цио":1351,"цир":340,"цит":991,"цар":343,"цат":333,"цус":389,"црк":515,"чењ":285,"чев":319,"чен":1330,"чес":1120,"чет":714,"чле":406,"чко":656,"чки":2688,"чка":1890,"чин":910,"чит":363,"ше ":558,"чар":740,"чна":1312,"чов":406,"чни":1436,"чно":1236,"чув":1137,"ќи ":636,"us ":554,"tio":345,"ter":323,"the":294,"ѕве":297,"ѓаа":300," ар":1051," ас":329," ат":297," ба":813," ав":1128," ад":312," аз":335," ал":614," ак":630," ан":1462," ам":537," ап":418," бу":674," ва":516," би":4668," бе":1085," бр":3187," бо":1018," бл":584," вт":300," ви":1958," ве":1999," во":21906," вр":2219," вл":994," вк":456," дв":1419," да":2966," го":6416," гл":1761," гр":5370," ге":1159," ги":1230," ев":363," ед":3169," до":4472," др":2545," де":5656," ди":1319," же":492," ел":592," ек":551," зе":866," за":9018," зб":1071," жи":1512," зн":1014," иг":813," из":2798," ил":3716," ин":1410," им":3303," ит":411," ис":2928," ка":5502," ки":580," кр":1663," ко":13222," кн":382," кл":860," ку":901," ла":991," ли":1394," ле":768," лу":423," ло":957," ме":2789," ми":1057," ма":4441," мо":2407," мн":729," му":1023," ни":1307," не":4874," на":43543," но":1774," ол":358," ок":1879," оз":315," ов":1233," од":15767," об":2355," оф":386,"њет":1203," от":647," ор":1315," ос":2370," оп":2029," по":15733," пл":1137," пи":929," пе":1794," па":2332," Ре":1553," Ра":517," Ро":593," Ри":680," Пр":1592,"ќа ":348," СА":357," Пе":961," Па":996," По":1728," Пи":295," Ос":605," Оп":468," Те":689," Ти":438," То":1430," Тр":451," Ст":843," Та":770," Св":648," Си":588," Се":1778," Сл":373," Ск":806," Сп":403," Ср":473," Со":1077," Ру":528," Са":911," Фр":445," Фи":520,"ќе ":750," Ту":523," Цр":465," Це":313," Хр":338," Хо":298," Хе":392," Ха":496," Че":319," Ба":927," Ар":690," Ан":848," Ам":433," Ал":1073," Ав":472," Ва":686," Бу":778," Бо":736," Бр":703," Бе":877," Би":680," а ":1703,"јќи":588," Ег":326," Ев":563," Ди":459," Де":856," Др":341," До":561," Ер":317," Га":384," Ве":685," Ви":845," Во":1669," Да":437," Ге":523," Гл":341," Го":800," е ":17047," Гр":1204," Ис":742," Ин":570," Им":496," Ки":514," Ка":1843," и ":17952,"ње ":4162," За":893," Зе":393," Из":327," Мо":928," На":1547," Не":717," Ни":438," Но":521," Ов":1078," Кл":294," Ко":1590," Кр":732," Ку":462," Ла":557," Ле":628," Ли":490," Ло":316," Лу":312," Ма":3825," Ме":823," Ми":780," Ја":559," Ју":674,"јна":646,"јни":502,"јзи":419,"јек":289,"јго":612,"јал":1511,"јан":1997,"јат":4096,"јав":629,"јаз":2727,"јад":290,"ња ":993,"јче":337,"југ":496,"јуж":519,"јск":745,"јст":589,"јот":1205,"је ":862,"ја ":19199},"n_words":[2810075,3234074,2357835],"name":"mk"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nep b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nep new file mode 100644 index 000000000..22477481b --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nep @@ -0,0 +1 @@ +{"freq":{"ेश्":122,"ेष्":121,"दन ":955," कम":272," कर":171," कल":142," कि":313,"ेशक":101," का":2467," कृ":130," कु":353," के":400," को":746," क्":668,"ेवा":114,"ेवी":117," एक":2232," एम":84," एस":66," एव":82,"ेही":103," चौ":73," चु":87," ची":65," चि":272," चा":174," छन":436,"थी ":98," जर":83,"तको":395," छो":111," जस":287," १ ":94,"तका":126," छा":110," जन":834," ज्":137," २ ":106," जि":1031," जा":297," जु":184," जी":93," जे":102,"था ":777," छ।":1176," जो":201," ३ ":81," झा":69," गर":1726," खो":93," खे":113," गण":154," गत":96," खा":152," घर":283," गौ":72," गो":262," ग्":152,"ैति":183," गु":176," गा":503," । ":1729,"दछ ":91," चल":134,"णमा":89," चर":93," चन":91,"ोल्":69," अं":111,"ोलि":69,"ोला":99,"ोलन":95," अप":72," अन":738," अध":277," अथ":96," आक":83,"ेता":128," अल":77," अर":427," अम":148," अभ":65,"ोर्":161," अस":323," अव":627,"ेत्":416," अक":100," अग":100," अत":71," अञ":333,"ेपा":2443,"ेन्":518,"ोबा":73,"थल ":101,"ेना":77,"ंग ":129,"ेमा":93," एउ":305,"त् ":79,"थम ":65," इल":78," इन":145,"ेली":90,"ेला":163,"तो ":127," आर":92," आय":68," आन":91," आद":140," आध":94," आफ":173," उह":329,"ेर्":71," उप":369," उन":300," उद":118," उत":328,"ेरि":117," उच":89,"ेरै":136,"ंघ ":125," वा":585," वी":67," वि":1830," वु":93,"्तर":540," व्":234," शर":146,"ं ":520,"ैशा":79," वै":119," शब":115," शु":75,"्तो":97," सं":1338,"्त्":507," शि":206," शा":289,"्तै":88," शह":107,"्थल":136,"्ता":424," सक":211,"्ती":153," श्":338,"ताक":144,"्ति":514,"्तु":122,"्थ्":92,"तान":131,"्दछ":254,"्थि":236,"ताम":82,"्था":656,"तार":119,"ताल":259,"तिक":679,"्थी":106,"ताह":141,"्दो":111,"्द्":640," वट":348,"तिन":112,"तिम":220,"ँ ":497,"तिब":72,"्दा":387,"तिल":64," वर":390,"्दी":92,"्दि":109,"तिर":95,"्दू":82,"तीक":85,"तिह":119," वन":80,"्दै":77,"्दे":123,"्ट्":320," लग":144,"्टी":291,"्टा":74," लल":75,"्डल":215," लु":106," ला":569," लि":251," ले":262,"इ ":252," लो":97,"्डक":81,"्णक":65," या":166," यस":2003," यह":103," यि":70,"धन ":65," यु":243," यो":2991,"्तक":221," रा":1721," रह":505," रे":111," रू":232,"दै ":146," रु":253," रो":152,"्बन":84,"दी ":721,"्बि":65,"्मक":109,"्मन":119,"्यक":669,"्मा":313,"्मि":89,"्मी":132,"्यत":93,"्मे":80,"्यम":169,"्रक":2903,"्यव":169,"्यस":223,"्यह":70,"्रज":90,"्यु":227,"्या":1225," हो":3798,"्धा":79,"्धि":77,"्धु":64,"तया":66," हि":324," हा":314," हु":1822," हे":105,"्ने":717,"्नु":381,"तरी":81,"्ना":84,"तरा":100,"्नो":104," सम":2258," सभ":305," सब":222,"्पन":76," सन":367,"्पत":195," सर":306,"दा ":445," सद":429," सत":75,"तर्":239," स्":1058," हर":182,"्फब":94," सो":117,"्पा":1027," सा":1310," सि":468," सह":215," से":264,"्प्":73," सु":497," सू":97,"दि ":71," दल":430," दर":95," दु":249," दा":223,"ोक ":69," दि":387," दक":141," त्":468," ते":64," था":199," थि":1391," तर":320," तथ":624," ता":221,"्क्":76," ति":156,"ोग ":226,"तमा":143,"्को":75," ती":93,"्का":162,"्कृ":122,"्की":66,"ण्ड":575,"ैनि":66," ठु":72," ठू":98," डा":80,"ँको":90," टे":70,"ैभन":80,"तपु":159," ५ ":87," ठा":328,"तन्":137," ४ ":90,"७१ ":81," मो":133," मे":182,"्जा":70," मा":2199," मि":226," मी":71," मु":393,"्जी":68,"्छ।":1182," मह":623," भो":79," मन":295," भे":81," मध":395,"ैमा":131," भु":80," मण":175," भू":134," भि":128," भा":1679," मज":70," भर":94," ब्":200," भद":64," बे":149," भन":724," बै":74," बो":103,"्ञा":169," बा":593," बि":392," मं":65," बी":67," बु":143," भग":64," बह":81," बस":196,"्टर":85," फ्":93," भए":2250," बर":162,"दल ":217," बन":332," फा":77," बज":106,"तथा":612," बढ":88," प्":5303," पो":110," फल":67," पि":113," पा":1007," पु":600," पे":81," पृ":77," पू":312,"ौं ":109," पर":802," पश":191," पह":651," पछ":122," पन":637," पद":103,"णाल":87," पत":3652,"ौँ ":65," न्":72," नै":168," नि":657," ना":582," पं":74,"्चल":413," ने":2763," धे":138,"्छन":169," नय":92," नर":78,"्चि":231," नव":75,"्चा":256," धा":133,"्। ":184," नद":186," दै":64," दे":732," धन":78," द्":298," दो":108," धर":161," नग":197,"थ ":223,"दछ।":89,"द ":562,"ध ":304,"दछन":85,"न ":5506,"ड ":307," छ ":575,"ठ ":146,"थाल":88,"थिए":221,"थाप":321,"ण ":876,"थान":166,"थिय":1145,"त ":3231,"थित":211,"धी ":65,"ज ":416,"दक्":143,"ट ":1241,"धि ":82,"ं":3288,"ः":73,"ँ":2200,"आ":1341,"इ":1404,"अ":4126,"ऋ":113,"ई":1594,"उ":3478,"घ ":163,"ए":6874,"ओ":539,"ऐ":69,"ग":8111,"ख":2732,"क":41084,"औ":111,"छ":5495,"च":3790,"ङ":845,"घ":968,"ट":4637,"ञ":822,"झ":319,"ज":7684,"ठ":1551,"ङ ":292,"ड":2764,"ढ":364,"ण":2637,"त":20032,"थ":4532,"द":12121,"ध":3905,"न":29922,"प":22723,"फ":1251,"्ग ":136,"ब":5465,"भ":7912,"म":22298,"य":17139,"र":42105,"ल":18318,"व":12132,"ष":4104,"श":6654,"ह":13763,"स":20352,"ि":29268,"ा":66742,"े":14995,"थवा":92,"ू":2666,"ृ":815,"ी":11554,"च ":186,"ु":12537,"ौ":1228,"्":49626,"ो":28329,"ै":2713,"।":9235,"०":2064,"१":1785,"्क ":72,"छ ":1403,"६":623,"७":619,"८":678,"९":972,"२":2170,"३":565,"४":638,"५":791,"क ":5557,"ेल ":167,"ग ":763,"ख ":276,"ेर ":327,"त्स":67,"त्व":197,"त्प":68,"त्र":5347,"त्य":758,"त्त":449,"ए ":239,"तीय":69,"द् ":189,"ेस ":70,"उ ":287,"ई ":1278,"ेश ":318,"ै ":1366,"्न ":467,"नै ":335," ख":612," ग":3519," औ":90," क":6153," ओ":97," ऐ":65," ट":271," ज":3597," झ":164," च":1230," छ":2605," घ":502," इ":461," आ":1284," अ":3988," ए":2988," ऋ":77," उ":1784," ई":92,"दार":162,"नो ":211,"दान":85,"दीक":207,"दिर":84,"े ":3604,"दिन":243,"न् ":626,"दुई":79,"ौँम":309,"दुर":326,"ेकप":97,"्म ":374,"ू ":585,"ेका":344,"ेको":828,"्य ":1998,"ेखि":464,"्र ":942,"ेखा":65,"ि ":3525,"नी ":612,"ेटि":110,"ी ":7016,"नु ":137,"ोत्":73,"ु ":1173,"ा ":19102,"ँउ ":227," ८":76," ९":73," ६":100," ७":169," ४":169," ५":165," २":1308," ३":186," ०":277," १":1083," ।":2222,"्व ":234,"ेजी":71,"दस्":318," प":14289," फ":558," न":5247," म":5367," य":5733,"्ष ":268," ब":2996," भ":5836," ढ":70," ठ":526," ड":306,"ह ":271," द":2964," ध":656," त":2303," थ":1702," ह":6806," स":10170," ल":1764," र":4971," श":1531," व":3977,"ने ":1547,"्स ":116,"स ":1459,"ष ":373,"थ्य":109,"श ":446,"्छ ":694,"व ":550,"्च ":74,"दरम":107,"्ट ":232,"ल ":2508,"दलह":69,"नि ":671,"दर्":91,"दलक":97,"ना ":698,"ँग ":83,"र ":6666,"्ड ":120,"य ":3205,"्ठ ":89,"म ":1712,"्ण ":171,"ोखर":85," र ":1581,"ब ":130,"्थ ":94,"फ ":86,"्त ":382,"्ध ":250,"प ":228,"ो। ":2741,"्द ":129,"ृष्":136,"डल ":72,"डी ":201,"डा ":124,"ञ्ज":95,"ञ्च":499,"ृति":122,"ृत्":80,"ञान":153,"ेत ":110,"ठमा":517,"ट्र":339,"ट्ट":87,"ढी ":85,"ेक ":82,"अक्":91,"टिन":116,"अञ्":333,"टीक":104,"ुवा":235,"ूको":117,"ुला":154,"ुलो":69,"ुल्":89,"ुले":184,"ुरा":226,"ुरो":69,"ुर्":237,"ुरी":67,"ुरु":159,"ुरम":86,"ुम्":151,"ुरक":79,"ुमा":298,"णी ":110,"ँदै":80,"ुभय":124,"णा ":67,"डलक":101,"ुभए":420,"ुप्":75,"ुपा":81,"ुपम":101,"ुन्":1483,"ुनै":129,"ुने":151,"ुनु":515,"ुनि":176,"ुना":77,"ुद्":231,"्सा":87,"्से":64,"्ष्":65,"ँमा":361,"्स्":64,"ठाउ":291,"ठूल":104,"्ला":1132,"्लो":92,"्ले":68,"ंचा":97,"्रद":218,"्रथ":82,"्रत":719,"्रण":90,"्रप":72,"्रन":77,"्ये":172,"्रध":142,"्रम":518,"्यो":226,"ंग्":118,"्रय":179,"्रव":165,"्रश":109,"्रह":151,"्रस":389,"्रा":928,"ंगा":83,"्रि":4096,"्री":584,"ठुल":72,"्रै":117,"्रे":422,"्रो":266,"्षक":74,"ीहर":197,"्षर":74,"ंगठ":68,"्षे":409,"्षि":335,"्षा":151,"्षी":92,"्वक":82,"ुग्":67,"्वत":106,"्वर":184,"्वव":84,"्वम":76,"्वय":164,"्वी":175,"्वा":1398,"डौँ":365,"डौं":74,"ूला":68,"ूलो":82,"ति ":1256,"ता ":557,"णको":70,"तु ":113,"ूमि":65,"ूमा":80,"ती ":337,"ूर्":396,"ूपम":142,"तै ":115,"ते ":88,"ूद्":136,"ंमा":238,"ंस्":240,"तर ":294,"ुस्":101,"ुसा":127,"ुहु":425,"ंवि":168,"ाला":279,"ालि":277,"ाली":1573,"ाल्":175,"ाले":372,"छ। ":2152,"ावि":101,"ाशन":833,"िकृ":90,"िका":4480,"ाशक":884,"िको":207,"िक्":271,"ाषा":1077,"ासन":94,"ासद":191,"ाष्":296,"ाशि":795,"ासक":88,"ाही":67,"ाहि":278,"ाहा":83,"ुन ":257,"ासि":356,"ासी":103,"ाहर":380,"ास्":236,"जा ":203,"चलक":256,"िज्":95,"चर्":65,"िजय":135,"जी ":92,"ुर ":568,"ङ्ग":239,"ितप":65,"छन्":559,"िता":146,"िति":411,"ित्":493,"िद्":368,"िधि":130,"िधा":249,"िना":260,"िनि":160,"िनी":149,"िने":242,"िनु":78,"िन्":1022,"चीन":87,"िभि":96,"िभा":91,"ियन":73,"िम्":132,"ियम":114,"िमा":914,"ियो":1315,"िया":360,"िर्":332,"िरा":176,"िले":173,"िल्":1069,"िलो":573,"चित":254,"िला":204,"चाय":66,"चार":351,"चाल":100,"चिव":79,"चिन":100,"चिम":183,"िष्":174,"िश्":356,"िशे":71,"िवा":232,"ीका":189,"ीको":490,"िहा":169,"िस्":142,"ूल ":110,"ीति":294,"च्च":109,"जमा":145,"ीद्":108,"छोर":78,"जन्":230,"जनक":98,"जनत":72,"जधा":122,"जनव":107,"जनै":185,"जनी":264,"जना":168,"जदु":67,"ीमा":357,"ीया":65,"ुक्":205,"ुको":176,"ुका":171,"ुख्":130,"ृत ":152,"ीले":86,"ीला":83,"जस्":157,"जसल":64,"ित ":1545,"िण ":71,"जिल":993,"जिक":146,"जार":186,"जान":79,"जात":246,"जर्":77,"जयी":89,"ाँउ":242,"ाँच":67,"ाँक":137,"िन ":363,"जवा":81,"ाइन":178,"िल ":92,"जोड":89,"ाउँ":218,"ाउं":237,"ाउन":366,"ीक ":78,"ज्य":351,"ाँस":67,"ांग":75,"ज्ञ":223,"ाँल":66,"िम ":169,"िय ":243,"िर ":148,"जील":69,"जीव":121,"ाएक":100,"जुन":124,"टर ":108,"िव ":68,"िस ":86,"ाग्":194,"ागु":64,"ागि":189,"ीत ":128,"ागर":78,"ागम":84,"ाको":3606,"ाक्":157,"ाका":303,"ाओव":397,"ाडी":141,"िंह":72,"ाठम":478,"ाटन":82,"टी ":233,"टा ":741,"ाजा":131,"ाजि":146,"ाज्":244,"ाजन":456,"ाजध":126,"ाजव":83,"ीन ":153,"ाचन":103,"ाङ्":108,"ुई ":73,"ाने":97,"ाना":169,"ानि":283,"ानी":322,"ानु":103,"ानव":65,"ुख ":149,"ानस":161,"ानम":146,"ाध्":103,"ापन":228,"ान्":702,"ानो":110,"ादे":93,"ादी":738,"ादु":180,"ादन":914,"ानक":94,"ाद्":158,"ाति":178,"ाता":140,"ाती":68,"ाण्":134,"ात्":408,"ादक":75,"ीय ":427,"ाडौ":440,"ारी":407,"ारि":163,"ारा":1342,"ार्":2184,"ारे":69,"ालक":765,"ालम":256,"ालय":324,"ालद":78,"ामा":889,"ायक":72,"ाम्":197,"ायण":151,"ायत":156,"ाया":71,"ारक":244,"ारम":182,"ारण":184,"ारत":376,"ाबा":106,"िएक":373,"ामक":80,"ामय":74,"ामम":66,"ापा":186,"ाप्":232,"ुङ ":64,"ंघ":232,"ँस":83,"ौ ":65,"ंख":88,"ंग":634,"ंक":193,"ँल":78,"ंच":134,"केन":240,"ँद":154,"ँड":80,"ँम":363,"ंस":389,"ंह":86,"ंव":201,"् ":1181,"ंत":94,"ंम":241,"केह":83,"ँक":178,"ो ":20357,"ँग":166,"ँच":76,"ँउ":243,"कृत":264,"अस":341,"अव":627,"आक":84,"अल":82,"अर":461,"अभ":65,"आए":70,"अम":151,"घर ":251,"अप":74,"अध":281,"अन":771,"अथ":96,"इत":80,"ाइ ":156,"इए":81,"आय":68,"आर":95,"आफ":174,"कृष":151,"आद":141,"आध":94,"आन":112,"ाई ":1080,"अं":111,"अञ":333,"अत":71,"अक":101,"अग":107,"उम":66,"उप":377,"उह":331,"ऋत":72,"इन":366,"इर":70,"इल":137,"इस":102,"उँ":251,"उं":238,"उक":79,"उच":90,"उट":311,"उत":340,"हो।":2612,"उन":717,"उद":141,"कोट":86,"एउ":305,"एक":5494,"एम":113,"एप":66,"क्क":84,"क्त":425,"क्य":129,"क्न":67,"क्ष":1267,"क्र":426,"क्स":110,"ाँ ":310,"ए।":67,"एव":82,"एर":147,"एस":80,"गर":2258,"गल":135,"गव":76,"खे":215,"गन":66,"खो":112,"गम":263,"ख्":345,"खा":431,"गठ":95,"खि":580,"खी":82,"खु":123,"ाग ":123,"गढ":68,"गण":181,"गत":326,"गको":91,"खर":150,"क्":2722,"खम":75,"गक":127,"कै":214,"के":654,"को":14452,"कि":691,"की":474,"का":12832,"कृ":425,"कु":618,"कू":91,"कस":66,"कव":78,"कह":90,"कल":273,"कम":415,"कर":463,"कप":247,"कन":76,"कत":154,"ाङ ":105,"कक":112,"ओव":398,"चु":124,"ची":172,"चि":731,"चा":795,"छन":717,"चौ":90,"च्":216,"चो":89,"० ":345,"जक":89,"चन":324,"ङ्":397,"चर":129,"चल":599,"घा":108,"गण्":66,"ङम":69,"गते":76,"। ":7045,"गा":955,"गी":218,"गि":310,"गु":302,"गो":351,"गौ":84,"ग्":809,"गे":161,"गै":75,"घर":335,"टन":160,"ञ्":596,"ञा":169,"टा":992,"टर":235,"४ ":302,"झा":105,"३ ":263,"टक":135,"जो":225,"जे":208,"छ।":2479,"जी":387,"जु":351,"जा":939,"जि":1330,"२ ":297,"ज्":670,"जन":1499,"खान":74,"जद":90,"जध":126,"छि":255,"छा":205,"जस":334,"जव":93,"१ ":351,"जर":120,"जल":76,"गठन":79,"छो":118,"जय":160,"जम":205,"ठा":393,"डक":133,"ाथ ":102,"५ ":351,"ठन":83,"टे":203,"ठम":522,"ट्":498,"टो":148,"टी":408,"टि":258,"डा":364,"डि":270,"डी":265,"डल":256,"६ ":313,"ाद ":282,"ठु":73,"ठू":104,"ढी":114,"ढा":72,"ाण ":70,"णक":119,"७ ":328,"ड्":123,"डौ":474,"डो":86,"डे":171,"णि":132,"णी":170,"णा":196,"ात ":197,"तक":594,"८ ":352,"णम":93,"तव":80,"९ ":264,"तह":110,"ति":2878,"ता":1722,"तु":292,"ती":680,"तथ":624,"तप":208,"तन":233,"तम":226,"ण्":631,"तय":73,"तल":91,"तर":935,"थव":101,"दछ":271,"था":1584,"थी":140,"थि":1694,"ते":197,"तै":125,"तो":181,"थम":91,"त्":7154,"थल":165,"खेल":103,"दक":289,"दस":347,"दू":145,"दु":584,"दी":1175,"दि":689,"दा":996,"दन":1011,"दव":74,"दल":480,"दर":324,"दम":71,"थ्":174,"नज":74,"धा":907,"नत":94,"नद":266,"धी":98,"धि":828,"ान ":852,"धु":156,"दो":255,"दौ":70,"द्":2831,"दे":1366,"धन":183,"दै":256,"नक":650,"नग":337,"धर":218,"नर":137,"नल":223,"नव":289,"ाज ":178,"धे":169,"नन":100,"नप":96,"नब":64,"नय":150,"नम":477,"ध्":787,"पं":75,"नी":1179,"नु":1548,"ने":4740,"नस":329,"नह":97,"ना":2286,"नि":2559,"पक":159,"नो":316,"नै":540,"न्":7416,"पत":4116,"पन":1101,"पद":120,"न।":118,"पछ":277,"पट":80,"पश":213,"पह":665,"पस":130,"पल":132,"पम":272,"पर":1026,"पे":166,"पू":427,"पृ":79,"पा":5213,"पि":272,"पी":141,"पु":1182,"फल":131,"फर":70,"प्":6004,"फब":94,"पो":196,"बन":449,"फे":70,"बत":86,"फु":76,"बढ":88,"फू":67,"फा":131,"बज":120,"फ्":316,"भए":2692,"बर":285,"बल":88,"भक":78,"भग":82,"बस":232,"बह":195,"बि":521,"बा":1458,"बु":218,"मं":75,"बी":142,"भद":79,"भन":878,"बे":211,"गरम":92,"बै":272,"बो":141,"गरप":94,"भय":191,"भर":147,"गरे":321,"ब्":486,"मक":339,"गरी":134,"गरि":502,"मग":77,"मज":101,"भि":375,"भा":2323,"मत":163,"मण":318,"भू":158,"भु":153,"गर्":821,"मन":572,"भे":108,"मध":481,"मद":72,"भो":89,"मप":65,"मल":187,"यक":819,"मम":151,"भ्":133,"मय":212,"मर":128,"मस":126,"मह":673,"मृ":68,"यत":299,"मू":114,"यण":158,"ख्य":245,"यद":91,"मि":1113,"मा":10729,"ाट ":785,"मु":840,"मी":348,"रं":73,"मो":273,"यम":527,"म्":2421,"मे":530,"यन":231,"यप":89,"मै":88,"यव":183,"रख":100,"रग":116,"रक":3696,"यल":80,"यर":101,"या":2168,"रज":106,"यह":189,"रच":84,"गमा":170,"यस":2268,"रध":173,"रद":310,"रथ":102,"रत":1236,"रण":521,"यु":657,"यी":175,"यि":191,"रय":191,"रम":1296,"रभ":77,"रब":131,"यो":5061,"रप":226,"रन":174,"ये":226,"लम":462,"लय":351,"लब":81,"लद":123,"लन":243,"गाउ":130,"लच":65,"लग":235,"लक":1487,"र्":6868,"रो":703,"रै":297,"रे":1245,"गाँ":224,"रू":1254,"री":1735,"रु":1451,"रि":5597,"रा":5311,"रह":868,"रस":574,"रश":114,"रव":321,"रल":193,"वं":88,"िक ":1742,"ल्":1854,"लो":1078,"चन ":69,"ले":2083,"लु":247,"ली":1940,"लि":1013,"ला":3708,"लल":168,"लह":138,"लस":69,"शब":122,"वै":233,"शन":968,"वे":271,"षक":102,"शम":116,"व्":325,"शर":176,"वह":113,"वव":90,"वस":368,"वु":106,"वा":3817,"वि":2520,"वी":434,"वप":72,"वन":350,"वध":419,"शक":1037,"वल":144,"वर":826,"वय":169,"वम":117,"वक":170,"वत":227,"वट":383,"ाह ":84,"सन":601,"षे":417,"सप":72,"सभ":377,"सब":248,"ष्":905,"सम":2673,"सर":429,"सल":312,"सव":65,"हक":127,"सच":90,"षा":1291,"षि":415,"षी":120,"िङ ":81,"ास ":619,"सत":83,"सद":673,"शे":152,"श्":1168,"षर":77,"सग":64,"सक":2028,"शह":143,"सं":1482,"शी":150,"शु":136,"शा":630,"शि":1111,"सँ":111,"षण":89,"हे":701,"हु":2366,"ही":279,"हि":1570,"हा":1720,"िए ":165,"ाम ":560,"ह्":87,"हो":3850,"से":478,"हन":162,"सु":586,"सी":345,"हत":108,"सू":105,"सि":1173,"चल ":150,"सा":2163,"सह":275,"हज":68,"हल":85,"स्":3576,"हर":1967,"सै":149,"सो":307,"ात":1181,"ाथ":320,"ाण":404,"ाठ":517,"िं":132,"ाड":760,"ाल ":1016,"ाट":1019,"ाब":231,"ाभ":93,"ाप":949,"ान":3357,"ाद":2589,"ाध":265,"गुर":71,"िख":71,"ाव":435,"िक":7298,"ाल":5422,"ार":6852,"ाय":812,"ाम":2329,"िए":681,"िज":372,"ाह":1078,"िच":143,"िङ":184,"ास":1934,"ाष":1391,"ाश":2631,"िग":115,"ां":267,"ाँ":1104,"ाइ":698,"ाई":1298,"ाउ":964,"ाओ":403,"ाक":4316,"ाए":185,"गुन":74,"ाच":265,"ाज":1659,"ाग":1013,"ाख":288,"ाङ":244,"ाघ":70,"ार ":1305,"ुँ":124,"ीद":163,"गिर":76,"ुई":88,"ीत":508,"ीप":148,"ीन":313,"ीम":461,"ीय":520,"ीब":79,"ील":304,"ीर":227,"ुग":188,"ुख":347,"ीव":147,"गीत":100,"ुक":691,"ीह":209,"ीस":78,"ुङ":145,"ुट":214,"िट":172,"ाय ":70,"िण":163,"ित":2827,"िद":484,"गाय":88,"िध":410,"िन":2481,"िप":245,"िब":181,"िभ":260,"िम":1517,"िर":1038,"िय":2231,"िल":2254,"ीक":872,"िश":533,"िव":468,"िस":542,"िष":301,"िह":253,"ेव":427,"ेश":820,"ेल":681,"सला":171,"ेर":844,"ेम":230,"ेब":84,"ेप":2592,"सले":93,"ेन":806,"ैत":257,"ैज":79,"ेह":196,"ेस":274,"ेष":206,"ैश":81,"ैर":64,"ैल":110,"ैभ":84,"ैम":134,"ैन":181,"ेक":1516,"ेख":723,"ेट":234,"ेड":98,"ेत":801,"ेद":151,"ेग":72,"ेज":215,"समु":85,"समि":387,"समा":459,"ृथ":65,"ृत":389,"ृष":194,"गोर":127,"सरक":167,"गोल":71,"समे":69,"सम्":1386,"ुत":130,"ुण":70,"ुन":2984,"ुद":383,"ुब":76,"ुप":397,"ुर":1722,"ुम":556,"ुभ":589,"ूक":155,"ग्ल":85,"ुल":730,"ुष":88,"ुस":363,"ुव":409,"ग्र":367,"ुश":84,"ुह":538,"सर्":105,"ग्न":160,"ूद":147,"ून":67,"ूप":214,"ूम":171,"ूर":453,"ूल":388,"ूह":74,"सबै":187,"्व":2939,"्श":82,"्ष":1678,"्स":579,"्ह":81,"्भ":100,"्म":1441,"्य":5693,"्र":13669,"्ल":1547,"्।":480,"समय":115,"ष्म":69,"ष्ण":122,"ष्ठ":171,"ष्ट":483,"सभा":365,"सद्":160,"ौत":91,"ोर":513,"ोल":515,"सदस":314,"ोब":119,"ोम":148,"ोस":122,"ोह":153,"सदर":107,"ोश":104,"ोव":69,"्ण":427,"्त":3287,"्ड":711,"्ट":1245,"्ठ":192,"्ञ":223,"्फ":210,"्ब":412,"्प":1700,"्ध":702,"्न":1912,"षेत":396,"्थ":1433,"ो।":3741,"्द":2288,"ौल":71,"ौर":128,"्ज":453,"्छ":2152,"्च":1134,"्ग":579,"्ख":113,"्क":866,"सन्":376,"ोज":238,"ौं":159,"ोड":185,"ोट":228,"ौँ":401,"ोद":66,"ोत":169,"ोप":186,"ोध":78,"ोन":98,"ोख":109,"ोक":287,"ोग":453,"हत्":91,"सेन":118,"छन ":99,"सुन":123,"सिर":66,"सिम":95,"सिन":119,"सुर":172,"साह":147,"सिद":138,"सान":163,"साद":218,"साप":131,"सार":311,"साम":357,"सिक":403,"साल":247,"सिं":91,"साथ":94,"सहर":108," १८":152," १९":516," २०":1012,"०६":103,"०४":114,"०५":217,"०२":500,"०३":93,"००":262,"०१":255,"१०":116,"१५":81,"१७":82,"१८":226,"१२":66,"१४":88,"१९":555,"२०":1126," ७१":72,"हरू":762,"हरु":794,"हरि":77,"ङमा":65,"७१":90,"स्व":373,"९०":64,"छि ":189,"९६":77,"९५":70,"९८":66,"९१":112,"स्र":74,"स्य":402,"स्न":77,"स्थ":1019,"स्प":226,"स्ट":105,"स्त":727,"९९":85,"स्क":351,"२३":69,"२२":66,"२५":83,"२७":122,"२६":80,"२९":70,"२८":115,"सोज":81,"सेव":93," १०":76," ०५":134,"हेक":471,"हेन":82,"जन ":98,"हुन":2172,"हुँ":68,"हिम":124,"हिल":691,"हिन":285,"हित":161,"हास":142,"हिक":125,"हाल":183,"हार":140,"हान":72,"हाद":225,"हाड":113,"हाँ":430,"चना":64,"चन्":135,"सचि":83,"सकि":79,"सका":115,"सको":1596,"सक्":148,"कै ":184,"का ":4257,"कि ":84,"षाक":932,"की ":394,"षिण":127,"हो ":1122,"षिक":187,"ओवा":396,"शेष":71,"हा ":81,"ही ":218,"श्व":419,"श्र":376,"श्य":86,"श्च":215,"शहर":129,"सी ":177,"हर ":124,"संग":215,"संख":67,"संघ":224,"संव":197,"संस":296,"शाख":89,"शित":796,"शाह":92,"शास":187,"सँग":107,"शिक":120,"सो ":69,"शार":66,"वैश":69,"वेश":81,"वुल":80,"शर्":111,"सा ":76,"व्य":273,"शब्":114,"वर्":460,"षा ":211,"किन":120,"काम":260,"कार":2072,"काल":377,"किक":104,"काश":2575,"कास":405,"किस":96,"कुन":166,"कुर":99,"कुम":159,"ववि":79,"शको":75,"कान":97,"काठ":489,"काक":1844,"वस्":272,"वहा":72,"सन ":103,"गि ":141,"वाद":803,"वान":150,"वाच":132,"विक":476,"वाल":112,"वास":237,"कला":91,"वार":1366,"वाम":64,"वित":78,"विन":80,"विद":224,"विध":297,"विज":192,"वाह":64,"गी ":84,"विष":89,"विश":380,"विस":90,"विम":83,"विर":102,"विभ":130,"वीर":70,"कम्":158,"कमा":129,"कर्":161,"गा ":93,"करण":105,"कपु":78,"कपा":103,"वधि":404,"कता":70,"वमा":91,"गर ":180,"वयम":124,"सं ":192,"शी ":67,"गत ":162,"खि ":378,"वटा":364,"खी ":68,"खा ":132,"को ":13998,"शन ":893,"वि ":102,"एमा":79,"वा ":501,"वी ":188,"ल्न":81,"ल्प":107,"ल्य":159,"ल्ल":1131,"एवं":67,"एकी":88,"एका":367,"एकि":98,"एको":2830,"लोक":92,"लेख":158,"शक ":887,"लेक":101,"लेट":101,"लिम":70,"लुम":71,"वर ":134,"लाई":880,"लाइ":94,"लाग":378,"लाक":490,"लाम":331,"लाल":114,"लिक":155,"लाह":236,"लिङ":98,"लित":141,"लिन":92,"वन ":146,"लहर":130,"एउट":304,"ललि":72,"लमा":361,"लद्":81,"लका":156,"वं ":67,"लगा":129,"लको":1159,"लक्":65,"रैम":78,"रेस":80,"रेष":101,"रोप":82,"रोग":68,"र्श":68,"र्व":558,"र्स":92,"र्ष":409,"र्म":544,"र्य":1351,"र्थ":286,"र्द":429,"र्न":750,"र्फ":154,"र्ट":316,"र्ण":301,"र्त":237,"र्ग":285,"र्ख":68,"र्क":192,"र्ज":198,"र्छ":112,"र्च":149,"रीक":121,"रिव":148,"रिय":408,"रीम":87,"रीय":210,"रुक":171,"रुम":97,"रुप":191,"रुल":94,"रूक":141,"रूद":136,"रूप":207,"रूम":82,"रूल":87,"रेक":307,"रेज":78,"रेल":67,"रेर":97,"रेन":80,"रसा":265,"रसि":109,"रहे":467,"रहर":171,"रस्":71,"ले ":1440,"राई":127,"रान":448,"राप":77,"रात":83,"राण":115,"राख":96,"राज":1244,"राक":104,"रिन":282,"रित":70,"राष":293,"राह":72,"राम":287,"रिए":176,"राय":214,"राल":136,"रिक":3842,"लो ":852,"रला":76,"लि ":69,"ला ":807,"रयो":160,"रम्":75,"रमा":715,"रमु":241,"रवा":142,"रले":64,"ली ":1594,"रधा":161,"येक":79,"रदे":155,"रमण":71,"यो।":1126,"रबा":70,"योग":340,"रपा":108,"युक":77,"युर":75,"युन":112,"युद":113,"याङ":69,"याक":103,"याम":150,"यान":128,"याप":111,"यात":120,"याद":68,"यास":84,"यिक":111,"याल":253,"यार":124,"याय":70,"यिन":65,"रति":595,"रत्":114,"रथम":70,"लय ":258,"युव":76,"रतक":192,"रणा":86,"यसक":1478,"यसै":79,"यसल":145,"रगत":68,"यवस":100,"रक्":100,"रको":493,"रजा":74,"याँ":127,"यहा":98,"यस्":93,"लन ":125,"रे ":127,"महे":70,"महा":221,"महि":223,"महत":77,"यको":226,"यक्":275,"रू ":452,"रु ":592,"यका":195,"मले":67,"री ":1056,"मुद":90,"मुख":298,"मुक":206,"मिल":98,"मित":526,"मिन":83,"मार":349,"माल":263,"मिक":100,"रो ":251,"मास":338,"मिट":74,"माण":135,"माड":449,"माध":70,"माथ":111,"मात":198,"मान":717,"माओ":399,"माक":73,"माज":262,"रै ":187,"मोर":76,"यन्":64,"यद्":67,"मेत":64,"मेर":107,"मेल":71,"रका":2994,"यमि":88,"ऋतु":72,"म्र":98,"म्य":162,"यमा":180,"म्प":1201,"म्ब":311,"म्म":335,"रत ":106,"मको":161,"रण ":320,"या ":441,"उहा":325,"यी ":158,"भिन":116,"भित":82,"भाव":75,"यो ":3433,"भास":199,"भाष":1089,"भार":394,"भाग":184,"उपत":120,"रम ":92,"मजद":66,"ये ":122,"मध्":444,"मना":80,"मन्":256,"भूम":78,"मण्":216,"मती":69,"मयि":71,"रा ":1447,"०० ":67,"रि ":116,"ममा":144,"मा ":6826,"बर्":135,"यत ":118,"भक्":69,"मी ":185,"यन ":118,"बस्":105,"बहा":133,"बाल":77,"बाह":65,"बास":89,"बिन":70,"बाट":745,"बाग":79,"बार":117,"बिह":66,"यम ":171,"बेल":114,"यस ":334,"भनि":212,"भने":219,"भन्":420,"बैभ":80,"भयो":166,"ब्र":111,"ब्य":100,"ब्द":140,"एर ":132,"प्य":67,"प्र":5545,"प्त":252,"भा ":133,"मन ":82,"बजा":98,"मय ":66,"यक ":69,"बने":91,"बना":154,"बन्":175,"एक ":2017,"भएक":2580,"फ्न":128,"फ्र":99,"आदि":87,"पहि":540,"पहा":109,"पश्":183,"आन्":94,"पर्":460,"आफ्":129,"इएक":72,"२०२":474,"परि":275,"२०१":229,"परा":119,"२००":176,"पमा":255,"�":311,"फबा":94,"पोख":90,"उन ":91,"पृथ":65,"पुस":117,"पूर":347,"पुग":79,"पुर":744,"पित":80,"पाक":119,"पान":108,"पात":131,"पाद":966,"पार":420,"पाल":2675,"पाइ":114,"बै ":101,"अथव":91,"१९१":90,"१९९":68,"१९६":68,"अधि":111,"अनि":120,"अनु":226,"अध्":166,"अन्":365,"न्च":76,"न्छ":1928,"न्त":1150,"न्ट":89,"न्ध":228,"न्न":383,"न्थ":109,"न्द":1479,"न्य":282,"न्म":233,"न्स":147,"न्।":473,"नैत":179,"अमे":66,"अरू":140,"अर्":230,"अवस":167,"अवध":415,"पनी":71,"पना":230,"पनि":614,"पन्":133,"असो":81,"अस्":166,"पत्":3819,"पति":105,"पता":130,"पछि":199,"पा ":229,"नले":102,"नया":92,"नवा":108,"नन्":74,"०२७":93,"०२८":90,"नदी":180,"धेर":139,"नमा":333,"ध्य":728,"नुह":426,"उटा":296,"नुप":72,"नुभ":561,"नुस":135,"निस":101,"निष":82,"नीत":296,"नेप":2459,"नेत":159,"नेक":221,"फल ":80,"उनी":101,"उनु":99,"उने":183,"उनल":77,"उद्":70,"उनक":91,"नस्":108,"निर":312,"निय":235,"निम":64,"निन":391,"उत्":329,"निध":76,"नाल":106,"निक":384,"नाम":395,"नार":232,"नाथ":91,"नाक":103,"नाउ":100,"नाइ":96,"द्द":65,"द्व":1093,"द्र":692,"द्य":285,"द्ध":407,"धर्":124,"नकप":71,"इने":87,"इन्":241,"नका":130,"नको":327,"इला":81,"देख":530,"देव":249,"देश":451,"दैन":81,"१८ ":75,"दोल":117,"२७ ":96,"धित":72,"धिम":418,"धार":244,"धिक":138,"धान":515,"२८ ":93,"नता":76,"नगर":305,"न। ":91,"उंम":222},"n_words":[614665,704688,490631],"name":"ne"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nld b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nld new file mode 100644 index 000000000..c74f0d267 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nld @@ -0,0 +1 @@ +{"freq":{"D":295391,"E":101171,"F":127232,"G":105530,"A":221658,"B":178586,"C":193400,"L":124657,"M":162943,"N":137196,"O":83395,"H":199830,"I":105198,"J":61744,"K":84088,"U":22509,"T":111990,"W":76478,"V":96433,"P":145276,"S":218863,"R":114676,"Y":11382,"Z":56681,"f":358313,"g":1325585,"d":2549536,"e":9521882,"b":675678,"c":885504,"a":4428747,"n":5174765,"o":3044475,"l":2174413,"m":1301830,"j":487381,"k":957853,"h":1157193,"i":4146613,"w":618312,"v":1136367,"u":1226136,"t":3691802,"s":3058116,"r":3420928,"q":14380,"p":897097,"z":331215,"y":211813,"x":48411,"²":22665,"ï":7308,"í":7570,"ë":58538,"é":54151,"è":10784,"ä":6605,"á":12476,"ü":12035,"ö":12215,"ô":9257,"ó":9442," l":108039," m":271385," n":113728," o":359305," h":429647," i":863484," j":55299," k":151715," d":1022256," e":865604," f":60480," g":362770,"р":6363," a":271750," b":268848," c":85027," z":129440," u":151127," t":287237," w":287907," v":736662," p":253369," s":272741," r":136806," J":58839," K":80686," H":197094," I":88140," N":131673," O":75874," L":120300," M":156963," B":171895," C":177462," A":209281," F":122253," G":98641," D":289943," E":96010," Z":55679," Y":11046,"и":8389,"о":8805,"н":6323," S":205129," R":108525," P":136936,"а":10448," W":74232," V":87489," U":20421,"е":6745," T":105528," é":7785,"A ":9463,"Da":14497,"Cu":5824,"Cl":7287,"Co":57452,"Cr":6279,"Ce":10546,"Ch":35435,"Ci":5986,"Du":33850,"Do":13572,"Dr":5649,"De":198026,"Di":16644,"Fe":6923,"Fa":6211,"Eu":11420,"Er":8327,"En":17423,"El":7917,"Ee":19326,"Ge":21620,"Ga":13267,"I ":14576,"Fr":73223,"Fo":9924,"Fi":11740,"C ":12680,"Au":12206,"Ar":23539,"Ba":28977,"Am":55987,"An":22709,"Al":28901,"Bu":10850,"Br":34564,"Ca":38690,"Bi":11873,"Be":44722,"Bo":26862,"Bl":5807,"Kr":9527,"Ko":15418,"Le":21847,"Li":19176,"La":31976,"Lu":12150,"Lo":28450,"Me":24563,"Mi":26609,"Ma":59234,"Mu":7133,"Mo":28002,"Ni":14152,"Ne":59633,"Na":17889,"No":27858,"Ol":9544,"Gi":5965,"Gr":28322,"Go":11925,"Gu":7667,"Ha":30031,"He":95269,"II":10036,"Hi":30742,"Ho":27037,"Hu":6810,"In":31628,"Is":5913,"It":15844,"Ja":19607,"Je":8912,"Jo":19365,"Ju":6270,"Ka":21546,"Ki":7967,"Ke":10121,"Un":6926,"Tu":6976,"Tr":10760,"Ts":9146,"To":14361,"Th":19966,"Ti":10118,"Te":13194,"Ta":10688,"V ":6513,"St":35202,"Su":9985,"Wo":6733,"Wi":21345,"Wa":15248,"We":22896,"Vo":12732,"Vi":16383,"Vl":8595,"Va":15790,"Ve":22438,"Pr":15997,"S ":6945,"Pe":17479,"Pa":35566,"Po":30054,"Pi":14013,"Oo":13070,"Op":6344,"Or":9483,"Se":15433,"Sc":16133,"Si":16384,"Sh":6081,"Sl":6946,"Sp":19561,"So":16434,"Ru":16114,"Sa":42083,"Re":17106,"Ri":17272,"Rh":6524,"Ro":32707,"Ra":12538,"b ":17772,"a ":223995,"Yo":6270,"Ze":12835,"Zi":6830,"Zu":10609,"Zw":13009,"i ":117137,"gd":23906,"ge":622849,"ga":53344,"fl":6356,"fg":6573,"ff":17069,"fi":41042,"fs":14314,"fr":11929,"fu":6506,"ft":32454,"fo":24009,"j ":85100,"he":517783,"ha":140501,"gn":22691,"gl":11647,"gi":125274,"gh":17920,"gg":9680,"gu":24589,"gt":35908,"gs":36659,"gr":72480,"go":35093,"dt":42741,"du":30903,"dw":10868,"g ":209248,"ea":48028,"eb":81350,"ec":86712,"ed":198243,"de":1265409,"dd":20989,"dg":6934,"di":281697,"dh":8510,"dk":6604,"do":126396,"ds":99321,"dr":53877,"ew":31588,"ex":17157,"eu":69138,"ev":102331,"ey":15758,"ez":66338,"fa":30179,"h ":79224,"fd":18426,"fe":38002,"eh":28491,"eg":168269,"ef":50847,"ee":952339,"el":605553,"ek":125240,"ei":156611,"ep":103855,"eo":27881,"en":2016971,"em":320296,"et":590121,"es":318427,"er":1223846,"ca":46321,"e ":2100607,"bs":5841,"br":58403,"bu":44669,"bo":58794,"bl":25851,"bi":87840,"bb":9494,"be":276525,"da":122637,"f ":90198,"cu":23421,"ct":84409,"cr":11311,"co":70369,"ck":28358,"cl":14976,"ci":82756,"ch":396490,"ce":87968,"c ":16305,"az":12546,"ay":18941,"ba":76157,"d ":427738,"at":401880,"as":187038,"ar":458993,"aw":6737,"av":29958,"au":65384,"ak":138064,"al":362702,"ai":53889,"aj":7035,"ap":71362,"am":172784,"an":1131186,"ac":99694,"ad":102907,"aa":662152,"ab":30531,"ag":85506,"ah":10878,"ae":23635,"af":47867,"nu":31030,"nt":435391,"ns":284103,"nr":14733,"no":95599,"nn":67675,"nz":11234,"ny":9083,"nw":88548,"nv":13925,"oe":163750,"of":83411,"oc":46361,"od":56125,"oa":14423,"ob":29747,"om":159575,"on":522696,"ok":52068,"ol":157894,"oi":33928,"og":70046,"oh":14048,"ot":108603,"m²":22643,"os":81239,"ov":88551,"ou":131520,"op":166634,"oo":370075,"or":483257,"r ":577062,"ow":27555,"oz":6517,"oy":5912,"pe":152921,"pg":12730,"pa":116725,"pl":132966,"po":60048,"ph":12783,"pi":48220,"lo":99408,"lm":24809,"ll":128927,"ls":119057,"lp":13038,"lv":15042,"lu":37402,"lt":126691,"ly":17100,"o ":155926,"md":19425,"ma":206926,"mb":60844,"me":492457,"mi":91034,"mm":32963,"mp":51654,"ië":52728,"mo":56705,"mt":19679,"ms":35581,"mu":25483,"my":6479,"p ":141470,"na":201890,"nb":21559,"nc":69092,"nd":473575,"ne":270200,"nf":9979,"ng":259192,"nh":15116,"ni":168878,"nk":43137,"nl":16899,"nm":6930,"jv":11516,"ju":22953,"js":16655,"jn":70736,"jo":13034,"jk":115620,"ki":53710,"kh":5862,"ke":182363,"ka":118671,"m ":155936,"kw":7713,"ks":46927,"kt":131352,"ku":22530,"ko":60158,"kr":23259,"kk":20620,"kl":29172,"km":27830,"kn":6593,"li":338485,"lh":5934,"lk":34257,"le":302236,"ld":95337,"lg":36498,"lf":20122,"la":398196,"lc":8500,"lb":22338,"n ":2543334,"hr":30422,"ht":107458,"hu":34327,"hi":99792,"hn":9649,"ho":105347,"id":125660,"ic":175476,"ib":14735,"ia":95834,"ig":142126,"if":16130,"ie":477304,"k ":193827,"ir":54494,"is":722822,"it":333187,"iu":13498,"iv":35131,"iw":8456,"ix":5720,"ij":364327,"ik":93516,"il":169468,"im":40230,"in":879621,"io":144997,"ip":26974,"je":41083,"jd":31240,"jf":10910,"iz":17029,"l ":299819,"ja":41826,"xi":7194,"z ":13752,"wi":58960,"wn":7387,"wo":161887,"ws":8197,"y ":100628,"wa":155603,"wd":6545,"we":181101,"vl":34784,"ré":7748,"vi":112804,"vr":17131,"vo":180923,"uz":15014,"ux":8237,"uw":44437,"uv":7894,"uu":52115,"ve":243007,"va":525240,"x ":20927,"ui":271759,"uk":10265,"ul":55545,"ue":25713,"ug":30034,"ur":165500,"us":143221,"ut":46184,"um":51805,"un":100952,"up":10064,"ty":46646,"tz":8930,"tu":100531,"tt":45242,"tw":33429,"tv":9249,"ub":30475,"ua":33926,"ud":45500,"uc":29841,"w ":28312,"to":174226,"tm":7826,"tl":14300,"ts":211260,"tr":144811,"tg":20068,"te":770637,"tk":6386,"tj":6074,"ti":257739,"th":76245,"v ":8380,"tb":23716,"ta":261366,"su":28639,"sv":9064,"ss":138251,"st":562933,"sy":14252,"sz":5928,"sw":6865,"sl":43368,"sk":33909,"sn":9526,"sm":15035,"sp":74738,"so":59040,"sr":6378,"sd":20593,"sc":205927,"se":425364,"sh":26990,"sg":6293,"sj":16338,"si":98258,"rz":20638,"u ":30645,"sa":44187,"sb":15979,"rr":71892,"rs":228779,"rt":187734,"ru":73560,"rv":44462,"rw":18490,"ry":14720,"rp":27084,"ro":286166,"rn":60686,"né":6017,"rm":70366,"rl":117376,"rk":74650,"ri":419079,"rh":16037,"rg":84498,"rf":11818,"re":392586,"rd":257870,"rc":25722,"rb":33548,"ra":285112,"t ":1445388,"qu":12987,"s ":1176543,"pt":24055,"pu":20157,"pp":39364,"pr":99751,"ps":14478,"zi":116688,"ze":78298,"za":31109,"zu":15798,"zo":49094,"ye":6127,"yc":6275,"ya":8170,"ys":18578,"yr":9415,"yp":6946,"yn":9021,"ym":12848,"yl":8352,"² ":22661,"éé":7636,"én":13925,"ë ":43502,"é ":8856,"一":6916," Ga":13216," Ge":21536," Fo":9883," Fr":73181," Fi":11695," Ha":29997," He":95105," Go":11879," Gr":28204," Gu":7630," Gi":5928," Hu":6795," Ho":26988," II":6497," Hi":30725," Je":8879," Ja":19556," Is":5895," It":15839," In":31514," Ka":21414," Ke":10042," Ki":7899," Jo":19317," Ju":6264," La":31862," Le":21646," Li":18941," Ko":15401," Kr":9517," Ma":59034," Mi":26529," Me":24479," Lo":28411," Lu":12123," Ne":59527," Na":17815," Ni":14127," Mo":27929," Mu":7091," Am":55975," An":22679," Al":28811," Ba":28861," Au":12111," Ar":23451," Be":44588," Bi":11811," Bl":5783," Bo":26752," Br":34502," Bu":10803," Ca":38284," Ce":10523," Ci":5893," Ch":35359," Cl":7183," Cr":6209," Co":57213," Cu":5704," Da":14480," Di":16596," De":197691," Do":13329," Du":33818," El":7895," Ee":19260," Er":8309," En":17358," Eu":11409," Fe":6899," Fa":6133," Wo":6660," Wi":21285," We":22829," Wa":15180," Zu":10598," Zw":13007," Ze":12821," Zi":6778," Yo":6266," Or":9466," Oo":13036," Op":6330," Po":29977," Pi":14002," Pe":16009," Pa":35403," No":27810," Ol":9537," Ra":12376," Ro":32636," Re":17067," Ri":17238," Rh":6521," Pr":15952," Su":9973," St":34839," Ta":10649," Th":19903," Ti":10088," Te":13125," Tr":10698," Ts":9134," To":14233," Ru":16099," Sa":42032," Sh":6028," Si":16291," Sc":16056," Se":15382," So":16378," Sp":19500," Sl":6935," Va":15750," Ve":22303," Vi":16318," Vl":8585," Vo":12506," Tu":6926," Un":6865," ja":26885," in":468125," is":385652," ka":34673," ki":8773," ke":15418," ju":21208," ha":22481," he":342958," gr":38760," go":7687," hi":19625," ho":31679," hu":11200," ni":13445," ne":8341," na":55514," mu":11657," mo":19517," ok":9997," om":21439," on":84624," of":50488," nu":5724," no":28282," le":24338," li":33990," la":36262," ku":10447," km":25898," kl":14578," kr":8283," ko":24113," me":105531," mi":19475," ma":109683," lo":6645," af":19870," aa":54537," ac":15329," an":19082," ap":11762," al":65830," au":17140," ar":47665," ba":14963," bi":41311," be":166033," bo":19486," bl":6588," bu":9669," br":10013," ca":7354," e ":8358," er":11018," et":7087," en":320059," ei":19716," el":9897," ee":469095," fe":12855," fa":15977," fo":5946," fi":16445," ge":303157," ga":6353," co":32521," ce":11923," ch":6021," ci":15694," da":51374," do":72769," dr":11539," de":740739," di":128156," du":9386," zo":26839," zu":11699," za":9390," ze":21870," zi":55419," ru":5958," sa":9420," se":22896," sc":26028," si":12277," sl":6445," sp":31376," so":18785," ra":8521," re":91305," ri":13940," ro":16553," pr":57908," s ":10712," ou":7125," ov":18421," oo":33765," op":114061," or":11383," pe":20368," pa":24621," pl":113070," po":21982," wa":118659," we":90321," wo":59080," wi":19128," va":481040," ve":76969," vo":131543," vr":12217," vi":22015," vl":9586," tw":15968," tu":14723," ui":144553," ta":9836," sy":6615," st":111138," su":9964," tr":11805," to":58623," th":14839," ti":18789," te":138599," éé":7588,"Eur":9786,"Eng":13833,"Fra":63542,"II ":7320,"Hij":21364,"Het":68660,"Her":7011,"Gri":6704,"Gra":6848,"Gro":9812,"Ind":7590,"In ":14751,"Hon":6999,"Hol":6098,"Bar":6393,"Alp":5725,"Ame":44932,"Ams":6535,"Ant":6487,"Cal":8797,"Car":7946,"Ber":10327,"Bel":16135,"Bra":7962,"Bri":11166,"Bou":5646,"De ":168413,"Dez":5967,"Dee":6161,"Chi":8065,"Cen":7181,"Cha":14656,"Cor":5822,"Com":7136,"Con":6541,"Cou":26493,"Een":16908,"Dui":29012,"Ned":43974,"Nat":6561,"New":6417,"Nor":10502,"Noo":11547,"Oly":6017,"Oos":10737,"Per":5867,"Par":11966,"Poo":9123,"Ita":15181,"Joh":7769,"Lan":8583,"Man":6806,"Mar":24247,"Mon":9837,"Mid":7429,"Wil":9135,"Wer":5760,"Wes":9343,"Vla":7545,"Ze ":6085,"Sta":16762,"Sin":5858,"Spa":11230,"Rus":11905,"Sai":9817,"Sch":12674,"San":8826,"Rij":7380,"Rom":5676,"Ver":12912,"Uni":5818,"The":11210,"Tsj":8380,"bis":7734,"bin":13224,"bij":36202,"bli":10301,"bla":6463,"boe":8360,"bon":5829,"bor":10260,"bou":11481,"bbe":6915,"ban":15026,"bal":21186,"baa":7632,"bas":9398,"bar":8019,"beh":12808,"beg":7886,"bee":12385,"bed":18175,"ber":72483,"ben":9807,"bel":14825,"bek":19147,"bev":17462,"bes":52050,"bet":13589,"bie":17101,"ca ":12312,"car":7029,"cat":5698,"ce ":27218,"bri":6013,"bro":7591,"bra":10008,"bre":7181,"bru":26538,"bur":21107,"bum":8070,"am ":47277,"ake":12657,"al ":74743,"ail":5969,"ain":18706,"air":10562,"ais":6111,"ak ":11574,"agt":10140,"agn":7735,"anu":16559,"ano":8039,"ann":16248,"ant":55265,"ans":143853,"ane":9267,"ang":46635,"ani":27973,"ank":15316,"ap ":25134,"ana":20565,"anc":16651,"and":178626,"amm":8429,"amp":20053,"ams":9681,"ami":28047,"ame":31772,"amb":6788,"ama":9230,"alv":6355,"alt":35976,"als":49851,"all":30537,"ali":53705,"alc":5747,"ald":14462,"ale":38623,"ala":12213,"alb":11148,"an ":555423,"aks":6554,"akt":91851,"abe":6263,"abi":6431,"ae ":14725,"aaf":9902,"aag":19367,"aad":5831,"aak":81870,"aan":153725,"aal":41110,"aam":28835,"aas":6793,"aar":125046,"aat":183677,"ad ":41911,"afs":8757,"age":22392,"adi":11143,"ade":19021,"ag ":18180,"ach":45489,"ace":13447,"ada":5737,"af ":10774,"act":17739,"at ":119635,"are":27820,"ard":36005,"arc":10579,"arb":9145,"ara":15993,"aro":16161,"arn":8226,"arm":7787,"arl":11777,"ark":11271,"ari":63150,"arr":46599,"ars":14646,"art":89778,"au ":9748,"asi":6239,"ase":7343,"ar ":70080,"apa":7428,"app":11428,"apr":10161,"as ":104628,"aut":12900,"avi":8222,"ave":10618,"ay ":8013,"ata":7505,"ast":27312,"ass":19856,"ato":8717,"ate":41676,"ati":71342,"ath":9399,"att":6300,"ats":113866,"atu":9691,"aug":10264,"Zwe":6862,"Zui":9741,"jec":10400,"jk ":66346,"jaa":10547,"jar":7927,"jan":13106,"jd ":7717,"je ":16212,"jde":16692,"jns":7518,"js ":7214,"jn ":50205,"jks":11628,"jke":29064,"itt":7963,"its":47572,"ity":14389,"iss":57247,"ist":78828,"ita":16110,"ite":28930,"itg":14085,"iti":26080,"ium":6105,"ivi":15930,"ive":12826,"is ":431822,"ion":45782,"ir ":7395,"isi":11995,"ish":6473,"ise":13845,"isc":89426,"isa":6882,"ire":19679,"it ":148319,"iwo":7073,"ize":7008,"kin":23405,"ki ":12463,"kee":5719,"kel":22383,"ken":67439,"ker":29057,"ke ":43164,"kt ":89985,"kse":13533,"kri":8432,"km²":22590,"kor":8329,"kon":7670,"kom":21374,"ks ":13043,"kke":14372,"kle":13907,"kla":8538,"jul":9669,"jun":10013,"jve":8311,"jst":5685,"kan":26234,"kam":11248,"kaa":47537,"ka ":11569,"ham":9052,"han":20214,"hap":31501,"hal":11321,"har":17692,"haa":16281,"had":6694,"he ":78504,"hel":11001,"hei":31175,"hee":28005,"het":305470,"her":18043,"hen":9035,"hem":8872,"hie":14941,"hin":11368,"hil":13952,"hij":15137,"his":12860,"gne":9405,"gna":8227,"gon":7132,"gsd":8056,"gro":30942,"gra":24600,"gt ":25727,"gri":8059,"gre":7606,"gst":8398,"gus":11645,"ial":9076,"ian":13694,"iat":6807,"iaa":21077,"id ":39722,"ia ":31791,"iet":21274,"ieu":11845,"iev":7556,"iel":12150,"iem":5824,"ien":50882,"ier":48258,"ies":24371,"ied":23758,"ief":9097,"iek":35699,"ig ":26250,"ict":38543,"icu":11018,"ico":6343,"ici":9264,"ich":59319,"ice":15194,"ie ":201388,"ica":19828,"idi":13237,"ide":28170,"idd":13665,"ida":12788,"il ":19641,"ijd":30969,"ije":8022,"ijf":10866,"ijk":115115,"ijn":70104,"ijs":16040,"ijv":11367,"im ":7764,"ika":50912,"igd":11510,"ige":49060,"igh":9499,"igi":9202,"igt":11964,"ign":9284,"ij ":80452,"ik ":10619,"ime":7803,"inc":33586,"ind":41153,"ina":22287,"inn":14337,"ino":8487,"int":30127,"ins":19772,"ine":33694,"ing":150853,"ini":14846,"ink":10381,"ioe":9616,"inw":77340,"ikk":7357,"ike":6423,"ila":17614,"in ":405294,"ikt":10786,"ilo":7646,"ill":44186,"ilm":12944,"ili":39663,"ild":8065,"ile":5842,"ima":5906,"io ":71745,"hol":9679,"hou":16715,"hoo":29440,"hor":9181,"hoe":5979,"hui":10622,"hts":6548,"hth":9745,"hti":8381,"hte":21726,"hre":7796,"hri":17051,"ht ":49854,"hum":5764,"ffe":6190,"ffi":6818,"feb":9777,"fen":6207,"fam":16628,"fde":6413,"eze":22604,"ezi":32218,"etb":16830,"eta":11379,"ete":33498,"eti":8945,"eth":6048,"esp":11543,"est":111009,"ess":14653,"etr":9667,"ets":6968,"ett":13669,"ew ":6999,"eve":54896,"eva":7494,"evo":21109,"evi":14484,"euw":17939,"eur":21284,"ewe":9375,"ewo":5810,"ey ":9860,"epe":6552,"er ":333095,"epa":50447,"eor":9695,"es ":93024,"ept":12657,"erk":43542,"erl":61155,"eri":98353,"erg":28574,"erh":11977,"ere":86052,"erd":117197,"era":27762,"erb":15858,"et ":468269,"esl":15451,"esi":12100,"esc":18281,"ese":16953,"erz":13202,"erv":34773,"erw":12350,"err":17024,"ert":36463,"ers":189637,"ern":29282,"erm":20928,"erp":10525,"ero":16315,"eks":13762,"ekt":9522,"en ":1373884,"ela":20546,"eld":60315,"elf":9763,"ele":68456,"eli":59882,"elg":17311,"elk":7255,"ell":29565,"elo":7411,"els":48151,"elt":76311,"emb":35339,"ema":13115,"eme":213429,"emd":11991,"emi":9436,"ep ":11271,"ene":28524,"enh":7989,"eng":11580,"enb":15906,"ena":20359,"end":77370,"enc":8130,"eno":20895,"enn":18048,"enk":9463,"enl":7298,"eni":29460,"enw":7353,"ens":81592,"ent":262064,"enr":11987,"ego":6580,"ege":50512,"egi":74199,"eho":15902,"ek ":28609,"eis":7935,"eil":21113,"ein":30892,"eid":39967,"eig":6260,"el ":169543,"eiz":7508,"eit":10871,"eke":48960,"em ":17335,"gis":18136,"gin":20458,"gio":63608,"gie":9618,"gge":6516,"gep":6253,"gen":119618,"geo":6626,"get":5657,"ger":43727,"ges":41787,"gev":26798,"gew":8731,"gez":31827,"gee":9960,"ged":10354,"geb":49406,"geh":10722,"gem":117467,"gel":56245,"gek":5735,"gde":10792,"ge ":59115,"gd ":7871,"gaa":11487,"gan":14683,"ft ":25649,"for":15464,"fic":10500,"fie":5840,"fil":14418,"da ":11415,"de ":684651,"daa":13978,"dag":8773,"dae":7793,"dat":38507,"dan":11068,"dam":12288,"dde":16386,"cti":18928,"cte":10141,"cus":11312,"clu":9316,"co ":6846,"con":15186,"com":22591,"ct ":40340,"cea":6367,"ch ":51967,"ces":6110,"cen":17525,"cem":10124,"cha":49925,"cia":10705,"ck ":10471,"cie":34119,"che":90373,"chi":44310,"cho":18169,"cht":101737,"chr":21384,"cit":10702,"ed ":30096,"eba":5684,"ebe":6342,"ebi":14653,"ebo":12775,"ebr":30709,"eau":7092,"ei ":13562,"eft":21131,"eek":11355,"een":586471,"eel":149087,"eem":7130,"eef":23903,"eed":19633,"ees":22270,"eer":87604,"eeu":10006,"eet":5732,"edi":16531,"ede":93412,"eda":9229,"eg ":11274,"eds":11135,"edo":6698,"edr":18455,"ech":31918,"eci":6720,"ece":11419,"ee ":19989,"ef ":10385,"ect":16877,"eco":6380,"dwe":6219,"dor":15099,"doo":63254,"don":8072,"dom":7397,"ds ":31717,"dië":7942,"doc":6254,"doe":8162,"dst":15322,"dui":6443,"duc":8131,"dri":17764,"dra":19458,"dt ":39781,"dro":6043,"dsc":11185,"dse":26450,"dic":13497,"dia":8442,"der":192741,"des":13390,"dez":10434,"dec":12054,"dee":111320,"del":33701,"den":135340,"dep":43953,"di ":6337,"do ":6228,"din":21044,"dio":7262,"dis":79203,"dit":10793,"die":85548,"dig":22881,"rha":6318,"rga":14305,"ri ":27658,"rgi":6243,"rge":20743,"ret":8087,"res":26172,"rev":8098,"rdt":29462,"rg ":25954,"rea":7679,"ree":20672,"rec":16838,"red":11064,"rei":15261,"reg":76191,"ren":91873,"rek":7399,"rel":18716,"rda":12870,"rdo":6848,"rdi":16416,"rde":80930,"re ":58121,"rch":10326,"rd ":94954,"ras":7988,"rat":17581,"rbi":10377,"rbe":8163,"rag":7326,"ran":87841,"ram":11943,"ral":17891,"raa":43729,"rad":10061,"rac":17496,"rs ":114967,"rpe":6605,"ros":6652,"rot":12676,"rom":9424,"ron":74395,"roo":21289,"rop":13868,"rou":11473,"rov":34172,"rod":10405,"roc":11802,"rol":11209,"roe":27621,"rog":7078,"rno":7457,"rp ":10130,"rna":17955,"rne":14489,"rni":6410,"rmo":6164,"ro ":8067,"rma":25601,"rme":14051,"rlo":10187,"rli":43352,"rle":10232,"rla":47955,"rn ":7785,"rko":8091,"rke":15492,"rm ":8899,"rip":6607,"rio":7162,"rit":17759,"ris":26171,"riv":7770,"rig":10543,"rij":60217,"ril":12296,"rik":53920,"rin":39022,"ria":15453,"ric":60714,"rid":8288,"rie":42534,"rk ":23012,"rwe":7689,"rwi":6024,"rui":23623,"rug":6639,"rum":7291,"rus":7171,"rva":8120,"rve":6455,"rvl":18128,"rvo":6709,"ry ":9896,"rsi":7125,"rso":10142,"rsp":13174,"rsc":16580,"rse":16920,"rta":7455,"rst":29072,"rto":9036,"rte":64198,"rth":8072,"rti":18904,"rua":9937,"rts":6565,"rt ":52830,"rro":41654,"rri":6371,"rre":14498,"sam":7637,"sat":5699,"shi":8681,"sje":10417,"sie":18702,"sit":8909,"sis":17171,"sin":18433,"sig":6448,"sdi":9330,"se ":245903,"sch":188901,"sco":5845,"ser":23257,"sh ":6367,"sei":5692,"see":12427,"sep":12185,"sen":46205,"sem":40984,"sel":17905,"spo":12356,"spr":14426,"spe":34342,"spi":6360,"son":16537,"soo":14382,"st ":68174,"sla":28873,"ski":9665,"ske":6724,"sme":5826,"sse":83731,"ssa":7327,"sso":6523,"ssi":25931,"ste":153650,"sta":134037,"sto":24680,"sti":36773,"stu":49771,"str":76216,"sus":9037,"tai":6439,"tal":42563,"taa":79421,"tad":33209,"tba":18995,"tat":25594,"tar":9576,"tan":24920,"te ":245946,"ta ":14225,"pe ":6304,"par":65094,"paa":13416,"pan":11481,"pge":11800,"pec":7014,"pen":27399,"per":54393,"pes":8975,"pee":13839,"pel":26450,"pla":118636,"ple":6523,"pij":6479,"pio":11106,"pis":8712,"por":10136,"poo":7190,"pon":6968,"pol":16543,"ppe":30477,"pub":6405,"pte":13585,"pri":21984,"pre":14246,"pro":59321,"que":5834,"ra ":17662,"ngr":7754,"ngt":6149,"ngs":24028,"ni ":14308,"nge":85205,"nga":9441,"nha":5738,"nel":9354,"nen":38308,"nem":7134,"ner":92669,"net":10080,"nes":17246,"ng ":100478,"nee":12320,"nci":34445,"nce":13701,"nch":8196,"ne ":58920,"nbu":5898,"ndr":9897,"nds":53318,"ndo":10563,"ndi":65506,"nde":170234,"nda":12836,"nal":19401,"nam":19197,"nan":5995,"nad":6211,"naa":50268,"nbe":7893,"nd ":125333,"nat":22785,"na ":37268,"nwo":81256,"ny ":6026,"num":6116,"nua":11671,"nty":25239,"ntw":10449,"nto":19506,"nts":8743,"ntr":16443,"nti":22690,"nta":19603,"nte":152583,"nsu":9180,"nst":31383,"nse":133099,"nsc":14189,"nri":8599,"nt ":140657,"ns ":66627,"noe":11549,"noo":19104,"nom":9568,"nov":12875,"nne":42144,"nna":5969,"nni":9362,"nië":12014,"nla":8754,"no ":10798,"nke":14949,"nkr":6212,"nig":15471,"nie":28378,"nic":7027,"nia":7786,"nk ":5831,"niv":5902,"nis":35078,"nin":21782,"ogr":8544,"ogi":8951,"oge":15686,"oiw":7018,"ois":5765,"oir":6590,"ok ":26496,"ol ":12318,"och":15236,"ock":8061,"ode":16327,"ods":9122,"of ":51317,"oek":14333,"oel":8698,"oem":15572,"oeg":10025,"oer":17651,"oet":21912,"oen":24849,"oep":14118,"odu":7865,"oed":12901,"og ":18782,"off":7132,"ofd":11478,"oal":5868,"od ":7190,"obe":14031,"own":6969,"oud":23948,"oth":6889,"ote":16152,"ott":8284,"ots":8865,"oto":6753,"ost":29293,"ota":7234,"ose":6693,"ovi":34676,"ouw":19904,"ove":41666,"oun":29232,"ous":5891,"our":16621,"out":8877,"opp":20304,"ope":17398,"opg":12331,"os ":12938,"oon":17563,"ool":15370,"oom":10898,"ook":25159,"ooi":6071,"oof":13207,"oog":15636,"ood":7845,"or ":123656,"oot":15244,"oos":12524,"oor":222103,"oop":6797,"ork":12244,"orl":12130,"orm":37127,"orn":13425,"orp":13450,"ord":94351,"ore":21033,"org":20784,"ori":18821,"ou ":6777,"ort":47654,"ors":16087,"ot ":44568,"m² ":22639,"ora":14333,"ola":5947,"old":6867,"on ":90823,"oli":23091,"oll":13695,"olk":19645,"ole":13281,"olg":11475,"ols":13292,"olo":16700,"om ":28845,"okt":10174,"ona":29547,"ond":144852,"one":97393,"ong":27845,"oni":32623,"onn":9985,"ono":10092,"ons":14560,"ont":39227,"oma":10713,"ome":31512,"omb":6304,"omi":12146,"omm":12297,"omp":15805,"omt":12605,"oms":11302,"op ":79508,"la ":16552,"le ":71663,"lf ":5640,"lde":29685,"laa":121868,"lac":19544,"lad":5854,"lag":14890,"lai":7568,"lak":20347,"lan":133760,"lar":5948,"lat":13164,"las":13782,"ld ":39055,"lbu":9341,"kun":16374,"kwa":5842,"kte":24985,"kst":6852,"kto":10642,"lpe":6305,"ls ":61450,"lon":9738,"lom":7994,"loo":10759,"lor":5860,"loe":7778,"log":16741,"los":5784,"lië":7455,"lub":9599,"lst":25217,"lte":6994,"lse":20318,"lt ":100197,"lge":14115,"lgi":13560,"li ":13675,"lev":15162,"les":15192,"let":7945,"ler":20832,"lem":10140,"len":59840,"lei":20020,"leg":19493,"lee":17156,"led":8570,"lec":6605,"lo ":6322,"lla":18593,"lle":62567,"lli":22272,"llo":6485,"lks":5894,"lki":11362,"lm ":10134,"ll ":9099,"lit":19124,"lis":19817,"lip":6344,"lin":41169,"lic":12334,"lia":22468,"lij":95486,"lig":34482,"lie":40870,"ma ":13279,"maa":102890,"mar":12201,"mal":14307,"man":28303,"mat":12974,"md ":13491,"mbe":34190,"me ":20464,"med":7669,"mee":138208,"met":69732,"mes":6603,"mer":72670,"mel":11918,"men":146532,"mei":13406,"lve":5791,"lym":7416,"mpi":18269,"mpe":6753,"mpo":7375,"ms ":12121,"moe":5824,"mon":14109,"mt ":13658,"mst":14316,"muz":8520,"min":20688,"mil":24349,"mis":8333,"mit":6248,"mig":6106,"mie":5852,"mid":8678,"ië ":43280,"mma":6643,"mme":17999,"zui":10334,"zee":6519,"zet":5935,"zen":14435,"zel":8377,"ze ":24809,"zan":8216,"zoo":6798,"zon":12147,"zoe":7835,"zie":38234,"zic":12949,"zij":41913,"yst":6749,"ys ":5784,"ymp":7552,"wn ":6464,"wod":7070,"wor":46676,"woo":12376,"won":83488,"woi":6978,"wes":10367,"wer":76690,"wet":5976,"wen":7541,"wel":18559,"weg":14286,"wee":29661,"wit":7604,"win":7741,"wij":18720,"wat":9640,"war":13183,"was":80249,"waa":29854,"vro":6819,"vil":13878,"vin":41497,"vie":14100,"vis":16850,"vla":21113,"vli":6207,"voe":25269,"vol":30369,"von":6589,"voo":92340,"vor":15339,"ver":131519,"ven":47801,"vem":9979,"vel":12213,"vee":14817,"ve ":13676,"val":33641,"van":455616,"vat":5892,"vaa":8390,"uzi":9073,"uwe":13657,"uwd":6413,"uur":48711,"usi":5945,"use":7901,"ust":24814,"uss":30621,"ute":13524,"uw ":14870,"uto":6696,"us ":63461,"ut ":6738,"ure":14305,"urg":25394,"uri":10844,"url":29792,"uro":10683,"urt":8342,"ur ":31687,"umb":6654,"unt":32613,"uns":8285,"uni":16955,"und":14286,"um ":25713,"ult":7652,"uli":14819,"ule":6125,"ula":6204,"un ":7353,"uid":29632,"uik":15052,"uis":15533,"uit":185570,"ugu":11498,"ude":20442,"udi":6485,"ue ":5767,"uch":9124,"ub ":8370,"uar":23535,"ubl":7698,"ty ":41728,"tur":6970,"tus":27504,"tuu":41013,"tud":6157,"twi":6118,"twe":21595,"ts ":120548,"tre":20553,"tra":31398,"tri":58554,"tru":9236,"tro":22667,"tse":38669,"tsc":8839,"tst":17796,"tte":25599,"to ":11397,"toe":15554,"tob":10290,"tot":36145,"tow":6284,"ton":34234,"tor":20776,"tij":29417,"tie":72965,"tig":17350,"tit":9886,"tis":23784,"tin":21180,"tio":32273,"thu":8037,"tic":17261,"tle":5983,"tem":61681,"ten":116036,"tei":13819,"tek":11255,"tel":112278,"tee":16372,"teg":10988,"ted":9251,"th ":11037,"teu":8413,"tes":8744,"ter":133625,"tge":17358,"tho":11376,"the":28515,"tha":9247,"én ":8357,"één":7621},"n_words":[56157687,65372177,47614417],"name":"nl"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nor b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nor new file mode 100644 index 000000000..7dc51ea94 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/nor @@ -0,0 +1 @@ +{"freq":{"D":67298,"E":31132,"F":46085,"G":30699,"A":51244,"B":53160,"C":43132,"L":37752,"M":50816,"N":44173,"O":29040,"H":46630,"I":28485,"J":19280,"K":42898,"U":16316,"T":46770,"W":15084,"V":29381,"Q":2727,"P":33476,"S":98250,"R":33889,"Y":5384,"X":3613,"Z":4254,"f":354544,"g":680290,"d":751947,"e":2892960,"b":291896,"c":77603,"a":1296256,"n":1640496,"o":1106000,"l":1037936,"m":608425,"j":148253,"k":716879,"h":226424,"i":1317183,"w":19861,"v":434834,"u":407647,"t":1430364,"s":1268259,"r":1753294,"q":3203,"p":350711,"z":18142,"y":203712,"x":10440,"²":2235,"Å":2838,"Ø":5129,"í":2375,"é":5770,"æ":27321,"å":157055,"ä":7866,"á":3631,"à":2467,"ü":2355,"ø":174400,"ö":5464,"ó":2058," l":79574," m":127350," n":66294," o":215607," h":91447," i":286253," j":14786," k":126841," d":163994," e":389283," f":217023," g":55928,"р":2932," a":164625,"с":2244," b":141242," c":8452," u":55940," t":125598," v":100006," p":120765," s":286186," r":49569," J":19242," K":42735," H":46471," I":28413," N":43960," O":28901," L":37540," M":50591," B":52872," C":42604," A":51010," F":45901," G":30503," D":67077," E":31023,"л":2294," Z":4215,"к":2313," Y":5370," X":3570,"и":3772,"о":4246,"н":2997," S":97781,"в":2674," R":33770," Q":2713,"а":4944," P":33276," W":14969," V":29296,"е":3204," U":16274," T":46489," å":24460," ø":14695," Å":2834," Ø":5122,"A ":7964,"Da":7415,"Co":15888,"Ch":7594,"Do":3375,"Dr":2174,"De":44977,"Di":3865,"Fe":2733,"Fa":3197,"Eu":2611,"Et":2524,"En":8728,"El":2986,"Ge":3683,"Ga":4272,"I ":9052,"Fy":2932,"Fr":8731,"Fo":9701,"Fl":2786,"Fj":2610,"Fi":5958,"C ":3097,"Au":3599,"Ar":6717,"As":3221,"Ba":9331,"Am":2967,"An":7679,"Al":7567,"By":3184,"Bu":3866,"Br":7415,"Ca":9043,"Bi":3113,"Be":11885,"Bo":6452,"Bl":2411,"Ku":2113,"Kr":5137,"Ko":7893,"Le":5322,"Li":8435,"La":9531,"Lu":3278,"Lo":6840,"Me":7383,"Mi":7116,"Ma":15908,"Mu":2812,"Mo":8218,"Ni":3496,"Ne":6662,"Na":6162,"No":20842,"Ol":2369,"Gr":7570,"Go":2542,"Gu":4480,"Ha":15522,"He":10062,"Hi":2665,"Ho":7455,"Hu":4099,"In":7421,"Is":2952,"Ir":2049,"Ja":4954,"L ":8381,"Je":2911,"Jo":5435,"Ju":2288,"Ka":7574,"M ":2289,"Ki":8846,"Ke":2144,"Un":4807,"W ":3224,"Ty":3546,"Tr":8937,"To":6250,"Th":6517,"Ti":3470,"Te":5634,"Ta":4262,"V ":2848,"Sy":2174,"St":18668,"Sv":4781,"Su":4159,"Wi":3769,"Wa":4239,"We":2978,"Vi":7414,"Va":4893,"Ve":9972,"Pr":5274,"S ":4165,"Pe":5166,"Pa":8226,"Po":5247,"Pi":2410,"Os":6058,"Op":2483,"Or":3270,"Se":7511,"Sc":2844,"Si":5113,"Sh":4054,"Sl":2066,"Sk":6894,"Sp":4048,"So":11528,"Ru":4355,"Sa":11798,"Re":6477,"Ri":4763,"Ro":9292,"Ra":4607,"b ":4101,"a ":140249,"Yo":2095,"Sø":4628,"Xi":2231,"bø":2634,"i ":283647,"fy":8788,"gd":9301,"ge":149531,"ga":32513,"fj":12532,"fl":14388,"ff":8428,"bå":3627,"fi":25866,"fr":47803,"fu":8120,"ft":23386,"fo":101580,"j ":2796,"gy":3318,"he":44416,"ha":66151,"gn":19968,"gl":10219,"gj":12645,"gi":33050,"gh":8862,"gg":35921,"gv":2904,"gu":9872,"gt":8325,"gs":33529,"gr":39232,"go":8838,"dt":33464,"du":13333,"dv":5679,"dy":4144,"g ":242136,"ea":17194,"eb":16045,"ec":4860,"ed":108322,"de":299418,"dd":13784,"df":2274,"di":40822,"dh":3225,"dk":3004,"dm":5071,"dl":19375,"do":17360,"dn":4555,"ds":31560,"dr":31419,"ew":4011,"ex":3115,"eu":5509,"ev":23237,"ey":5833,"fa":23302,"h ":12462,"fe":26099,"eh":7528,"eg":49132,"ef":18320,"ee":8701,"el":199057,"ek":50272,"ei":44782,"ep":20746,"eo":9834,"en":582197,"em":46141,"et":320684,"es":146652,"er":695279,"ca":10711,"e ":500246,"by":34947,"br":29081,"bu":14609,"bo":17004,"bl":54931,"bi":19197,"bb":5548,"be":63706,"db":3584,"da":47371,"f ":9303,"cu":2103,"ct":3488,"co":8095,"ck":10053,"ci":6056,"ch":18251,"ce":8996,"c ":3649,"az":2995,"ay":5287,"ba":35656,"d ":150657,"at":91048,"as":69325,"ar":172213,"av":121888,"au":14940,"ak":30193,"al":135078,"ai":12693,"aj":2677,"ao":2477,"ap":29140,"am":63029,"an":267240,"ac":9777,"ad":37337,"aa":2792,"ab":12532,"ag":40280,"ah":4661,"ae":7154,"af":16520,"nu":7442,"nt":92694,"ns":124075,"nr":3026,"no":52873,"nn":98330,"jø":13856,"ny":13664,"nv":3459,"oe":7618,"of":17045,"oc":8436,"od":26153,"oa":3647,"ob":11128,"om":188777,"on":123342,"ok":27219,"ol":75500,"oi":3014,"og":163889,"oh":4581,"ot":32564,"m²":2226,"os":28900,"ov":41178,"ou":20519,"op":34634,"oo":5024,"or":234371,"r ":604948,"ow":4407,"oy":2125,"pe":55903,"pa":27179,"pl":13813,"pn":2118,"po":25761,"ph":3721,"lä":2860,"pi":29184,"lå":4732,"læ":3598,"lo":47607,"lm":11687,"ll":125327,"ls":54920,"lp":4961,"lv":17299,"lu":16394,"lt":42371,"ly":13905,"hø":10888,"o ":38269,"ma":52812,"mb":14541,"me":153343,"mf":5780,"mk":2245,"ml":5863,"mi":35740,"mn":2923,"mm":59754,"mp":15073,"mo":24316,"mr":8156,"mt":8238,"ms":13233,"mu":35413,"my":4118,"p ":18651,"na":63523,"nb":10179,"nc":6842,"nd":155382,"ne":210727,"nf":8666,"ng":145804,"nh":6700,"ni":70736,"nj":3359,"nk":18937,"nl":14559,"nm":3689,"ju":8303,"jo":49289,"kj":21128,"gå":9251,"ki":30043,"kh":3599,"ke":149522,"ka":75120,"m ":148254,"fø":39544,"ky":6546,"ks":31928,"kt":45246,"ku":18940,"kv":7398,"ko":71373,"kr":37123,"kk":42089,"kl":19159,"km":10210,"kn":9496,"li":148110,"lh":5181,"lk":27090,"lj":4011,"le":206454,"ld":27006,"lg":10977,"lf":6606,"la":117768,"lb":9872,"n ":508629,"hr":3491,"hv":8983,"ht":2318,"hu":13547,"hj":3760,"hi":16514,"hn":2241,"ho":28328,"id":53829,"ic":16512,"ib":6764,"ia":42013,"ig":91825,"if":12391,"ie":49167,"hy":2076,"k ":129587,"dø":14496,"ir":32357,"is":145060,"it":66902,"iu":3847,"iv":28029,"ii":2629,"ij":2484,"ik":79231,"il":114997,"im":14324,"in":224355,"io":25793,"ip":8856,"je":54644,"ji":3380,"l ":114552,"ja":10997,"xi":3017,"tå":6348,"z ":3331,"sø":16304,"så":13214,"wi":2306,"y ":43971,"rø":14616,"wa":4985,"we":2854,"vh":2078,"rå":14698,"vi":56505,"vt":2733,"vs":5579,"vn":14394,"vo":12525,"ve":142305,"vd":3441,"va":71132,"x ":3406,"ui":4966,"uk":21664,"ul":26959,"ue":11327,"uf":3039,"ug":10093,"ur":41090,"us":50014,"ut":47498,"um":19336,"un":102304,"up":9818,"ty":27626,"tu":28284,"tt":93499,"tv":14967,"ub":13117,"ua":11212,"ud":11995,"uc":2853,"w ":4541,"to":63371,"tn":11784,"tm":2957,"tl":16216,"ts":42441,"tr":65044,"tg":7470,"tf":6385,"te":283104,"td":2594,"tk":2587,"tj":4066,"ti":143857,"på":54079,"th":14355,"v ":99425,"tb":9067,"ta":95087,"su":13370,"sv":19448,"ss":49933,"st":245546,"sy":11979,"sl":28878,"sk":191864,"sn":6441,"sm":11084,"sp":37365,"so":108796,"sr":4235,"sd":5831,"sc":5435,"sf":8108,"se":148118,"sh":13228,"sg":2307,"sj":47719,"si":74309,"nø":2380,"u ":10252,"sa":44310,"sb":10119,"rr":19009,"rs":78883,"rt":82606,"ru":50990,"rv":11610,"ry":11156,"rp":5076,"ro":69758,"rn":31836,"rm":21775,"rl":20062,"rk":47716,"næ":4051,"ri":132605,"nå":4464,"rh":6919,"rg":35522,"rf":12509,"re":256059,"rd":66008,"rc":4262,"rb":18116,"ra":128776,"t ":465642,"mø":2258,"qu":2140,"må":7691,"lø":8427,"s ":146195,"pt":7260,"pu":11071,"pp":34390,"pr":51296,"ps":7773,"vå":3732,"za":2150,"væ":7493,"yg":16794,"ye":16616,"yd":10423,"ya":7947,"tø":14974,"yt":13580,"ys":21183,"yr":13910,"yp":7213,"yn":9715,"ym":5956,"yl":14093,"yk":8767,"yi":4209,"² ":2226,"å ":86331,"Øs":2809,"ær":24440,"åp":3244,"ån":3530,"åt":7047,"ås":2737,"år":24111,"åe":2573,"ål":6435,"åk":4798,"åd":11397,"än":3083,"øy":21642,"ør":54354,"øs":14419,"øp":5028,"øv":7903,"øt":3062,"øk":5634,"øn":8821,"øl":4965,"øm":4740,"øe":2478,"ød":34288,"ø ":2765,"之":2379,"专":2738,"三":3026," Ga":4247," Ge":3655," Fy":2931," I ":6572," Fo":9668," Fr":8721," Fi":5928," Fl":2776," Fj":2609," Ha":15503," He":10039," Go":2524," Gr":7534," Gu":4458," Hu":4096," Ho":7447," Hi":2663," Je":2895," Ja":4943," Is":2884," In":7378," Ka":7550," Ke":2113," Ki":8813," Jo":5426," Ju":2284," La":9489," Le":5267," Li":8383," Ko":7880," Kr":5128," Ku":2108," Ma":15819," Mi":7093," Me":7355," Lo":6813," Lu":3268," Ne":6630," Na":6059," Ni":3491," Mo":8183," Mu":2787," Am":2962," An":7665," Al":7546," Ba":9272," Au":3596," As":2828," Ar":6669," Be":11852," Bi":3097," Bl":2409," Bo":6415," Br":7392," Bu":3840," By":3181," Ca":8810," Ch":7563," Co":15800," Da":7402," Di":3846," De":44915," Dr":2166," Do":3289," El":2979," Et":2521," En":8708," Eu":2608," Fe":2724," Fa":3178," Xi":2228," Sø":4627," Wi":3744," We":2962," Wa":4211," Yo":2085," Os":5937," Or":3262," Op":2481," Po":5205," Pi":2406," Pe":5104," Pa":8187," No":20722," Ol":2367," Ra":4586," Ro":9267," Re":6462," Ri":4754," Pr":5244," Sy":2169," Sv":4778," Su":4150," St":18500," Ta":4246," Th":6493," Ti":3455," Te":5588," Tr":8905," To":6181," Ru":4349," Sa":11773," Sh":4026," Si":5095," Sc":2823," Se":7484," So":11504," Sp":4034," Sk":6885," Sl":2061," Va":4882," Ve":9942," Vi":7397," Ty":3541," Un":4794," ja":4722," in":34065," ik":4460," is":2212," ka":20700," fø":33238," kj":12239," gå":5771," ki":10103," jo":2540," ju":4702," ha":40329," he":11962," gi":4943," gj":7272," gr":19932," gu":2109," dø":7855," hi":3888," hj":2877," ho":10427," hu":4249," hv":8245," ne":7120," na":12532," my":2654," mu":6899," mo":13920," ok":2382," ol":3868," om":17822," og":141787," of":9223," ob":2162," ny":3021," no":33974," le":11218," li":27765," la":25410," kv":4363," ku":8567," km":9490," kl":4277," kr":10076," ko":42531," me":70036," mi":10095," hø":6629," ma":17890," lu":2098," lo":3520," ad":3981," am":9313," an":19228," ap":2222," ak":3076," al":9858," av":89135," au":3693," ar":13091," at":7530," ba":13278," bi":6342," be":29509," bo":6968," bl":40680," by":21015," bu":2338," br":16487," ca":3932," er":153435," et":63825," en":123670," ei":4836," el":30282," ek":4165," eg":3293," fe":8817," fa":9591," fu":3699," fr":43218," fo":78205," fl":9728," fj":6013," bå":2550," fi":13808," ge":3067," ga":9278," i ":237285," fy":7547," da":14064," do":2621," dr":4255," de":122624," di":7830," dy":2072," væ":4635," sø":12596," ru":9067," sa":19419," se":29156," sj":3216," si":17713," sl":7113," sk":21745," sp":19430," so":87507," ra":3039," re":25505," ri":2962," nå":3726," næ":2896," ro":6266," pu":2169," pr":27989," lø":2099," må":3587," ov":11878," op":17267," or":7497," pe":8091," pa":7750," pl":5274," po":9080," pi":4926," lä":2565," så":2458," va":41741," ve":33600," vo":3210," vi":14710," ty":6900," tu":3382," ut":27318," un":21502," ta":8589," sy":5687," st":43167," sv":7377," su":2425," tr":14296," to":9228," th":2455," på":53815," ti":62638," te":14306," Øs":2807," å ":15026," år":6691," øs":6280," øy":4235,"Fin":2794,"Eur":2192,"En ":4024,"Eng":3095,"Fyl":2572,"Fra":3815,"Fre":2185,"Fol":3808,"For":3758,"Hel":2604,"Han":5694,"Har":2577,"Ind":2121,"Øst":2801,"Bar":2295,"And":2152,"Car":2172,"Ber":4934,"De ":3390,"Det":18734,"Den":19203,"Dan":2408,"Cha":2366,"Cou":8345,"OL ":7076,"New":2594,"Nor":18501,"Osl":4630,"Par":3554,"Pro":2168,"SA ":4753,"Joh":2414,"Kar":2117,"Kin":6314,"Kon":2546,"Kom":2130,"Kri":2217,"Lan":3221,"MW ":2903,"Lon":2680,"Man":2484,"Mar":5164,"Sør":3934,"Sve":3734,"Str":2300,"Sto":5079,"Sta":5059,"Ste":2680,"Sko":2364,"Som":4932,"Rus":2959,"San":3826,"än ":2530,"Rom":2726,"åde":9646,"ål ":2493,"Vei":2618,"åle":2191,"Vin":2983,"åre":3629,"ård":2572,"år ":14295,"Ves":3148,"ått":3275,"Uni":3264,"Tys":2479,"ær ":4620,"ært":3809,"ære":8422,"The":4012,"Tro":3352,"bis":3511,"bil":4902,"bin":5018,"blo":2551,"ble":31774,"bli":12888,"bla":6396,"bok":3234,"bor":4144,"bbe":3093,"ban":9995,"bak":3210,"bal":7414,"bas":4309,"bar":6636,"bei":5432,"beg":3804,"ber":17512,"ben":4646,"bel":3914,"bev":2185,"bes":8730,"bet":9507,"ca ":4720,"ce ":3774,"bri":5623,"bra":2313,"bre":4128,"bru":13492,"bur":2443,"bun":2536,"bum":3444,"by ":8318,"byd":2738,"bye":5451,"byg":13374,"byp":2127,"am ":5629,"ake":6088,"al ":22413,"ain":3128,"ak ":2688,"agt":4288,"anu":3347,"ano":2720,"ann":21260,"ant":16537,"ans":34997,"ane":10156,"ang":34028,"ani":10694,"ank":5395,"anl":5003,"ap ":5392,"ana":7215,"anc":2796,"and":71633,"amt":3120,"amm":13306,"aml":4533,"amp":3404,"ami":6970,"ame":12312,"amb":2328,"ama":4584,"alv":2901,"alt":13338,"als":4480,"all":28689,"alg":3345,"ali":12960,"ald":4724,"ale":19089,"ala":6862,"alb":4116,"an ":35027,"aks":3242,"akt":7856,"akk":3187,"abl":2978,"ae ":2689,"ad ":7446,"aft":9172,"afi":2584,"ai ":3427,"aga":2271,"age":11424,"adm":2981,"adi":6411,"add":5083,"ade":7303,"ag ":10292,"ach":2606,"ada":2399,"at ":12379,"are":11421,"ard":7601,"arb":5329,"ara":7138,"arn":4304,"arm":4027,"arl":3706,"ark":12605,"ari":9703,"arr":4082,"ars":6026,"art":19222,"asi":5334,"ase":4616,"ask":2682,"asj":20288,"ar ":65150,"apa":4754,"ape":8916,"app":2255,"as ":8910,"ava":2465,"aut":2096,"avn":11841,"avi":3695,"ave":7468,"ay ":2288,"av ":85297,"ata":4831,"ast":9209,"ass":12223,"ato":4866,"ate":21584,"ati":14442,"att":15952,"ats":2979,"atu":5294,"aug":3319,"jer":9769,"jek":2468,"jel":9659,"jem":3205,"jen":18638,"jan":3394,"je ":3919,"jon":34428,"jor":11663,"itu":2594,"itt":16474,"its":2537,"ity":2756,"isk":51560,"isj":4819,"ism":2335,"iss":5696,"ist":35845,"iv ":3591,"ita":7242,"ite":15976,"iti":9684,"iva":2856,"ivi":3570,"ive":13599,"ipp":2048,"is ":12915,"ion":14718,"ir ":6919,"irk":9296,"isi":4522,"ish":2413,"ise":12425,"isa":4298,"ire":7035,"it ":2143,"kil":3815,"kk ":10113,"kin":8354,"kip":2377,"kir":5305,"går":7228,"kis":2484,"kje":16281,"km ":7242,"kel":6677,"ken":15267,"kes":10195,"ker":29257,"ket":9398,"ke ":65844,"kra":11143,"kre":8431,"kt ":12793,"kse":4519,"kro":2450,"kri":13226,"kot":2092,"km²":2186,"kor":5874,"kon":13827,"kom":31756,"kol":9129,"ks ":3032,"kny":2137,"kjø":3238,"kni":5015,"kke":25288,"klu":3574,"kle":4386,"kla":6195,"kli":3140,"jul":2456,"kat":3942,"kar":4133,"kas":2638,"kap":17702,"kan":20091,"kal":14105,"kam":2092,"ka ":6242,"før":14702,"fød":22348,"føl":2302,"ha ":2473,"ham":3082,"han":12460,"hal":3654,"hav":6160,"har":25645,"had":4958,"he ":6327,"hel":5939,"hei":3009,"het":10209,"her":5545,"hen":7004,"hin":2784,"his":4361,"hje":2935,"gle":2190,"gn ":3125,"gla":3596,"gjø":2529,"gni":2494,"gne":11554,"gs ":3264,"gru":12215,"gra":9273,"gt ":5657,"gre":14854,"gst":4516,"gså":9706,"gus":2418,"ial":4669,"ian":8957,"øke":2125,"ølg":2438,"id ":6821,"ibe":2226,"ia ":20599,"iet":4979,"iel":5273,"ien":17663,"ier":7794,"ies":2351,"ig ":24484,"ift":6890,"ør ":13261,"øpe":2597,"ømm":2930,"ich":3831,"ie ":7138,"ica":2979,"ids":3533,"idr":3478,"ønn":3150,"idl":8890,"ide":18687,"idd":2770,"ida":3822,"ønd":2352,"øst":12196,"il ":45404,"im ":2951,"ika":14540,"ige":27059,"iga":2145,"igh":5558,"igi":2075,"igg":17522,"igs":3095,"ign":3006,"øre":10636,"ørs":12878,"ørt":2899,"ik ":6168,"ime":2903,"ind":10332,"ina":14021,"inn":35697,"ino":2582,"int":10160,"ins":19112,"ine":16471,"ing":71844,"ini":7560,"ink":2146,"iod":2244,"iny":3773,"ikl":3957,"ikk":22590,"ike":13916,"in ":20575,"ikt":9421,"iks":3390,"ilo":2911,"ill":23109,"ilk":2217,"øve":6392,"ilm":4862,"ilh":3403,"ili":8732,"ild":3649,"ile":4123,"io ":2961,"ils":3090,"ilt":4137,"ørø":2134,"øy ":5016,"hol":9462,"hov":6717,"øye":5083,"øya":3991,"hvo":3807,"hun":2960,"hus":4616,"hve":2835,"døs":2243,"død":8337,"ffe":3959,"ffi":2131,"fes":3648,"fer":4921,"fem":2188,"fen":2692,"fek":3989,"fel":4217,"fat":5769,"far":3333,"fam":3942,"fal":2369,"eta":7185,"ete":19743,"eti":2646,"etn":3543,"esp":3357,"eso":2351,"est":46619,"ødt":21901,"ess":8652,"esv":2859,"etr":2759,"ets":9941,"ett":37893,"ety":3237,"ew ":2555,"eve":11454,"eva":2230,"evi":2446,"ey ":3642,"er ":431766,"epa":2788,"eor":2578,"eol":2061,"ød ":7105,"es ":40484,"ept":2696,"epu":5041,"epr":2644,"erk":15694,"erl":6414,"eri":32585,"erg":11340,"erh":2771,"ere":60500,"erf":5751,"erd":9568,"era":10673,"erb":3057,"et ":226950,"esk":8307,"esi":10382,"øde":3134,"ese":10631,"erv":4618,"eru":2639,"err":6355,"ert":31938,"ers":27995,"ern":17742,"erm":4003,"ero":2745,"ekk":7221,"ekn":2204,"ekr":3313,"eks":10659,"ekt":15683,"en ":368973,"ela":6680,"eld":5215,"ele":18548,"eli":14582,"elg":2392,"ell":56973,"elo":2842,"elv":10426,"els":37467,"elt":17365,"emb":7048,"ema":3872,"eme":6179,"emm":4042,"emo":2614,"emi":3720,"emp":3266,"ems":2210,"enf":4002,"ene":43923,"enh":3807,"eng":13869,"ena":2893,"end":24201,"enn":18704,"enk":3130,"eni":5336,"ens":38448,"ent":42518,"egn":9280,"ege":7883,"egg":4893,"egi":7310,"eha":2568,"egr":3736,"eis":4556,"eim":2591,"ein":6378,"eie":6921,"eid":6829,"el ":17607,"eke":3082,"em ":6695,"gje":8413,"git":6162,"gis":5345,"gin":2581,"gio":4769,"ghe":4290,"gge":29980,"gi ":3980,"gen":31946,"get":10089,"ger":52848,"ges":4527,"gg ":2739,"gel":10922,"gde":3615,"ge ":33172,"gas":3030,"gar":3339,"gat":3035,"gam":2397,"gal":2375,"gan":11800,"ga ":3023,"fyl":7035,"fte":8757,"fun":3666,"ftv":7006,"ft ":3864,"fra":35021,"fre":5013,"fri":6048,"for":85448,"fot":5733,"fol":6844,"fle":5300,"fly":4535,"fil":5351,"fik":2963,"fin":6087,"fir":2657,"fis":4937,"fje":5241,"fjo":6945,"da ":8120,"de ":60427,"dal":11372,"dag":6176,"dat":3189,"dar":2553,"dan":8876,"dde":9644,"co ":2205,"ch ":3122,"cha":2322,"ck ":3691,"che":4052,"chi":2081,"cke":2693,"ed ":55809,"eba":2196,"ebe":2240,"ebr":3393,"eal":3627,"eat":2589,"efi":2051,"efo":4434,"efe":4659,"ei ":7806,"een":2210,"edl":3176,"edi":4356,"ede":17856,"eda":3620,"eg ":6746,"eds":6107,"edr":4047,"dve":3394,"dus":5910,"don":4573,"dom":4754,"ds ":5042,"dmi":3335,"dni":2776,"dst":4471,"dte":2377,"duk":4468,"dri":5473,"dra":3627,"dt ":28714,"dre":18932,"dsk":5623,"dia":3579,"der":53613,"des":6374,"det":47571,"del":41297,"dek":2450,"den":73325,"dem":4267,"di ":2586,"dle":5037,"dla":2367,"dli":11521,"din":4634,"dio":3152,"dis":11321,"die":2789,"dig":4896,"rga":6400,"ri ":3980,"rgi":2280,"rge":14583,"ret":27902,"res":20361,"rev":6468,"rfa":4418,"rds":3327,"rdv":2179,"rg ":6581,"rea":5698,"ree":2115,"ref":5778,"red":9285,"rei":3228,"reg":12569,"rem":5839,"ren":35981,"rek":8172,"rel":4778,"rer":20318,"rep":8966,"rda":5684,"rdl":3552,"rdi":4958,"rde":19629,"re ":73979,"rbu":2376,"rd ":17240,"ras":7043,"rat":9184,"rav":3015,"rbi":3863,"rbe":5664,"rag":2711,"ran":19588,"ram":7456,"ral":8750,"rak":4191,"raf":12560,"rad":5981,"rs ":8675,"ros":5462,"rom":6997,"ron":6959,"rop":5525,"rov":9073,"rod":9193,"rol":4308,"rof":2729,"rog":4064,"rna":5941,"rne":13070,"ro ":3052,"rma":5722,"rme":6882,"rli":7449,"rle":2859,"rla":5982,"rn ":5061,"rks":2379,"rko":2612,"rki":3108,"rke":16934,"rka":2079,"rm ":3363,"nær":3936,"rio":3486,"rit":8311,"ris":17487,"riv":5194,"rig":8523,"ril":2995,"rik":24390,"rin":21593,"rim":2649,"ria":5352,"ric":2697,"rid":3352,"rie":12327,"rif":3440,"rdø":2401,"rk ":15343,"rup":6154,"run":12301,"rum":4066,"ruk":11189,"rus":6418,"rva":2898,"rvi":2442,"rve":4784,"ry ":3420,"rsk":24627,"rsi":6764,"rso":5206,"rse":3955,"rta":2228,"rst":17535,"rte":20285,"rti":8810,"rua":2277,"rts":5729,"rt ":35053,"rri":3179,"rre":7643,"rra":4011,"sak":3680,"sal":2138,"sam":15315,"sbe":2623,"san":6993,"sat":4359,"sas":3809,"sa ":2445,"ryk":2399,"sha":2088,"shi":3201,"sje":5058,"sjo":34525,"sie":4330,"sid":8350,"sia":4578,"sk ":75137,"sit":9775,"sis":16636,"sin":9850,"sik":9289,"sda":2876,"sby":2166,"se ":19672,"sch":2395,"ser":35054,"ses":4849,"set":9508,"sfo":2877,"seg":6362,"sep":3173,"sen":41736,"sem":4309,"sel":10690,"sek":3507,"spo":8496,"spr":5617,"spe":5862,"spi":12660,"spa":2392,"sol":2063,"som":85971,"son":9679,"sor":2986,"sjø":3410,"st ":39863,"ss ":6097,"sli":3561,"slo":6037,"slu":2332,"sky":2874,"sla":9825,"sle":4538,"ski":8246,"skj":4074,"skl":2812,"sko":10936,"skr":10481,"sku":3651,"ska":22269,"ske":46720,"sma":2688,"sme":3758,"stå":5531,"stø":6651,"syn":2627,"sys":2439,"syk":3044,"sse":15330,"ssa":2824,"sso":3173,"ssl":2943,"ssk":3059,"ssi":8369,"sst":2689,"ste":66334,"stf":2230,"sta":38189,"stn":2344,"sto":16688,"sti":20167,"stl":6400,"stu":3784,"str":25344,"sty":4151,"sun":2773,"sut":4111,"sva":4458,"sve":9604,"svi":2603,"tak":2812,"tal":21730,"tab":3588,"tad":7590,"tba":6294,"tav":2813,"tat":16792,"tas":5433,"tar":7233,"tan":11218,"tam":2411,"te ":58351,"ta ":8154,"pa ":2052,"pe ":5528,"par":10024,"pas":4090,"pan":5764,"län":2721,"pen":10042,"per":17920,"pet":8954,"pes":3294,"pel":3770,"pla":9218,"lær":3470,"pil":11406,"pin":7171,"pis":4864,"por":10569,"pol":7076,"ppr":5964,"ppl":2678,"ppe":9671,"pp ":3799,"pub":5466,"pte":2999,"pri":10360,"pre":12096,"pro":23686,"prå":2961,"løp":3837,"mål":4336,"ra ":37023,"ngi":2137,"ngl":4160,"ngr":2861,"ngt":2215,"ngs":15959,"ni ":4401,"nge":45140,"nga":2868,"ngd":4050,"nhe":2871,"nel":12450,"nen":27435,"ner":33385,"net":21165,"nes":25627,"ng ":54251,"ned":4860,"nfo":4282,"nce":2258,"ne ":72733,"nby":5798,"ndt":4870,"ndr":12413,"nds":12659,"ndo":5458,"ndl":2779,"ndi":6968,"nde":56337,"nda":5748,"nal":12130,"nan":2828,"nar":2470,"nad":2448,"nd ":38901,"nav":9346,"nat":5154,"nas":7061,"na ":15576,"nyi":3711,"nua":2135,"nty":8509,"nto":3515,"ntr":8273,"nti":5299,"ntl":2516,"nta":6663,"nte":28676,"nsp":2257,"nst":14726,"nss":3014,"nse":21534,"nsj":2053,"nsi":3034,"nsl":2182,"nsk":39260,"nsa":2994,"nt ":24653,"ns ":20153,"noe":3540,"nom":6845,"nor":29131,"nov":2911,"nne":42931,"nna":2105,"nnb":5914,"nnl":4919,"nno":3889,"nni":5129,"nnk":2501,"nns":7691,"nma":2510,"nli":4969,"nn ":14981,"nla":6112,"nle":2679,"no ":2847,"nke":3676,"nkr":4191,"nia":6220,"niv":5311,"nis":15475,"nit":2397,"nin":25664,"nik":2124,"ogs":10014,"ogr":5237,"ogi":5246,"ogn":3334,"oge":2102,"ok ":7509,"ol ":2411,"ock":4853,"ode":7882,"of ":4012,"oen":3787,"odu":8565,"og ":134463,"oft":3759,"off":4398,"ofe":2299,"od ":2196,"obl":2263,"obe":3133,"nyt":4280,"jøe":2169,"jør":5841,"ote":3613,"ott":4146,"ots":2202,"oto":3139,"ost":4414,"otb":5531,"osi":2968,"ose":3901,"oss":3129,"ovi":8837,"ove":25154,"oun":9480,"our":3311,"opp":20548,"ope":3654,"opa":2135,"os ":5236,"or ":56677,"ork":4146,"orl":2445,"orm":10647,"orn":3102,"orr":3175,"ord":42679,"ore":13522,"orf":4509,"org":16810,"ori":9530,"ort":20720,"ors":26414,"m² ":2219,"ot ":7999,"orb":6069,"ora":3709,"ola":2381,"old":10833,"on ":35130,"oli":8827,"oll":6799,"olk":9387,"ole":9725,"ols":3475,"olm":2556,"olo":8072,"oly":3133,"oka":3954,"om ":107366,"okk":3118,"oks":3517,"okt":2231,"ona":9739,"ond":6224,"one":22668,"ong":10465,"oni":5288,"ono":3591,"ons":14426,"ont":6196,"oma":5119,"ome":6397,"omb":2444,"omi":3410,"omf":2921,"omm":37033,"omp":3178,"omr":6915,"oms":5919,"la ":5793,"le ":57070,"lde":10166,"lds":2282,"lad":2570,"lag":17793,"lan":58009,"lar":3088,"lat":7640,"las":9906,"lav":2641,"lba":2444,"ld ":6657,"lbu":3945,"kvi":3664,"kva":2672,"kur":2362,"kun":5248,"kul":5655,"kte":10988,"kst":5101,"ksj":6623,"ksi":2580,"ktu":4360,"kti":6575,"kto":3659,"kys":2223,"ls ":2559,"lok":3826,"lon":2509,"lom":14627,"log":6983,"los":2313,"lov":2717,"lme":3805,"lto":5869,"ltu":2394,"lub":3807,"lsk":13894,"lst":8591,"lv ":4083,"lta":2646,"lte":5587,"lse":19815,"lt ":21046,"lge":4495,"li ":4167,"lev":4182,"les":12321,"let":13065,"ler":55284,"lem":5548,"len":25387,"lek":9666,"lei":2319,"leg":6026,"led":5805,"lls":3758,"lo ":5941,"lhø":2797,"lla":5878,"lle":65120,"lli":10408,"llk":3343,"llo":12212,"lke":16528,"lkn":2938,"lm ":3452,"lje":2230,"ll ":17353,"lit":14639,"lis":9353,"lir":3649,"lin":18549,"liv":2248,"lia":5498,"lik":12256,"lig":60844,"lie":7273,"ma ":3762,"mai":2118,"mar":11919,"mas":4336,"mal":3128,"man":16587,"mat":5209,"mbe":7011,"me ":8290,"med":37095,"met":13813,"mes":7734,"mer":33081,"mel":15249,"men":33002,"mfa":2204,"lva":3696,"lve":4358,"lut":2852,"ly ":2856,"lym":3245,"lys":2102,"høy":5492,"hør":3562,"mpi":3576,"mpe":4413,"ms ":2196,"mod":2416,"mon":3257,"mor":2125,"mot":10268,"mt ":3487,"mst":3459,"mrå":7270,"mus":6700,"mun":25496,"min":11788,"mil":8071,"mis":4562,"mid":4108,"mle":3222,"mmu":24025,"mme":31877,"vær":6865,"ytt":5943,"yte":2764,"yst":6626,"ysk":7598,"yrk":2373,"yre":3443,"ypr":2466,"yr ":3697,"ype":2571,"ye ":2367,"yde":4954,"yer":2533,"yen":9116,"ya ":4898,"ykk":3634,"ylk":9083,"ymp":3267,"ygg":10777,"ygd":2788,"yin":3851,"tør":7504,"tøv":4228,"tår":3969,"sør":11014,"så ":11194,"røs":2166,"røn":4125,"røy":2397,"vir":2566,"råk":3246,"vik":8483,"vil":4773,"vin":16505,"vid":3526,"råd":8908,"vit":4787,"vis":10758,"vn ":5466,"vne":6818,"vol":2228,"vok":2535,"vor":4361,"ver":56905,"ves":12440,"vet":7953,"vei":7599,"veg":2114,"ven":15144,"vem":2207,"vel":5384,"ved":23018,"ve ":6401,"val":6677,"van":11534,"var":40025,"vat":3521,"va ":5156,"utø":4075,"usi":6124,"use":8793,"ust":8108,"uss":8811,"utg":6539,"ute":5272,"utt":5236,"uts":3096,"utv":4169,"us ":10711,"ut ":5919,"ure":6307,"urg":2892,"uri":2750,"urn":3039,"uro":3768,"urr":2556,"ur ":5709,"upp":6292,"ume":4177,"unt":9250,"uns":3775,"unk":3135,"uni":6920,"unn":14136,"und":31193,"ung":4670,"une":22585,"uks":4735,"ukt":5470,"uke":5765,"um ":8855,"ult":4324,"ull":5554,"uli":4543,"ule":2555,"un ":3708,"ugl":2152,"ugu":2387,"ude":2985,"udi":2221,"ue ":2256,"ues":2288,"uar":4525,"uan":2334,"ubl":5816,"ubb":3409,"ud ":2293,"typ":2478,"tyr":5657,"tys":4599,"ty ":11596,"tve":8575,"tvi":4656,"tur":14995,"tus":2293,"tun":2106,"tud":2813,"ts ":7521,"tre":18842,"tt ":26597,"tra":17913,"tri":10126,"tru":4763,"tro":7380,"try":2883,"tse":4787,"tsk":2860,"tsu":3903,"tst":7808,"tta":2344,"tte":44536,"tti":2906,"tts":8940,"to ":8546,"tni":6514,"tne":2955,"tob":2085,"ton":7030,"tok":6614,"tol":4307,"tor":21379,"til":54443,"tik":6372,"tif":3581,"tie":3348,"tig":5426,"tit":4010,"tis":16494,"tin":10509,"tio":5365,"tia":3220,"tid":14688,"tiv":7883,"tje":3021,"tli":7658,"tla":4715,"tle":2120,"tem":9786,"ten":44932,"tei":3878,"tek":5962,"tel":9339,"teg":7791,"ted":11925,"tfo":3043,"th ":3609,"tet":33199,"tes":6700,"ter":82933,"tgi":4175,"på ":52716,"ti ":4056,"the":4578},"n_words":[20399254,23799460,17069273],"name":"no"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/pan b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/pan new file mode 100644 index 000000000..1140be0bf --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/pan @@ -0,0 +1 @@ +{"freq":{"ਾਜ਼":17,"ਾਜਧ":12,"ਾਜਾ":13,"ੀਲ ":18,"D":18,"E":20,"F":29,"G":23,"A":52,"B":35,"C":59,"L":38,"M":47,"N":37,"O":37,"H":31,"I":60,"U":14,"T":45,"W":18,"P":47,"S":55,"R":24,"f":103,"g":125,"d":221,"e":655,"b":81,"c":194,"ੀਰ ":33,"a":561,"n":492,"o":398,"l":256,"m":260,"j":16,"k":37,"h":252,"i":537,"w":71,"v":42,"u":236,"t":467,"s":328,"r":400,"p":124,"z":13,"y":106,"x":19,"ਿਆ।":22,"ਾਤਰ":17,"ਾਤਾ":27,"ਾਤੀ":12,"ਿਆਣ":31,"ਿਆਦ":20,"ਿਆਨ":47,"ਿਆਲ":13,"ਿਆਰ":28,"ਿਆਵ":14,"ਿਆਸ":12,"ਾਣਕ":12,"ਾਣੂ":104,"ਿਆਂ":76,"ਾਣੀ":40,"ਾਣਿ":27,"ਾਣਾ":22,"ਾਨੇ":13,"ਾਨਾ":31,"ਿਊਟ":14,"ਾਨੀ":48,"੩੧ ":18," । ":128,"੩੦ ":23,"ਾਦੀ":22,"ਾਦਾ":19,"ਾਨਕ":26,"ੁਝ ":21,"।ਇਸ":14,"ium":27,"is ":22,"ion":36,"ੀਤ ":15,"਼੍ਰ":22,"੦੦੮":24,"ੀਪ ":375,"ੀਨ ":57,"ੀਮ ":51,"ਟੀ ":57,"ਜੋਂ":19,"ਾਗਰ":20,"ਾਕੀ":370,"ਾਕਿ":34,"ਟਾ ":22,"੨੩ ":13," m":24," o":57," h":17," i":57," d":21," e":15," f":30," a":133," b":21," c":34," t":120," w":40," p":41," s":54,"੨੨ ":14," r":16,"੨੧ ":14,"੨੫ ":14,"਼ਸੀ":29," H":25," I":54," N":32," O":31," L":21," M":43,"੨੪ ":13," B":32," C":54," A":46," F":17," G":21," D":15," E":17,"ਿਰ ":73," S":47," R":22,"਼ਹਿ":50," P":44," W":15," T":36,"ਜੀਵ":20,"੨੭ ":13,"੨੬ ":13,"ਿਲ ":25,"ਜੁਲ":54,"ਜਿੰ":30,"੨੯ ":16,"ਜੂਨ":35,"਼ਾਂ":36,"਼ਾਹ":32,"੨੮ ":15,"਼ਿਆ":14,"ੀਕ ":34,"ਜ਼ਮ":12,"਼ਿਲ":75,"ਜ਼ਾ":33,"ਜ਼ਿ":88,"ਾਂਦ":190,"ਜਾਂ":231,"ਜ਼ੀ":72,"ਾਂਤ":20,"ਾਂਸ":16,"ਜਾਬ":125,"਼ੁਰ":27,"ਜਾਤ":13,"ਜਾਣ":55,"ਜਾਦ":21,"ਜਿਮ":22,"ਜਿਲ":12,"ਜੀਅ":19,"ਿਸ ":72,"ਾਅਦ":30,"ਜਿਸ":70,"ਜਿਹ":19,"ਾਇਆ":59,"ਾਇਣ":62,"੨੦ ":14,"ਾਇਲ":17,"ਟਰ ":67,"ਾਈਟ":14,"ਾਈਡ":27,"ਾਉਂ":14,"ਾਈਨ":29,"ਾਉਣ":23,"਼ਬਦ":26,"ੀਂ ":52,"ਿਤ ":82,"ਟਨ ":17,"ਚੰਦ":21,"੧੮ ":12,"ਛੋਟ":13,"੧੯ ":14,"ੀਆ ":53,"ਿਨ ":1101,"਼ਰਵ":39,"ਜਨਮ":32,"ਜਨਵ":39,"ਜਨਸ":13,"ਜਦੋ":15,"ਜਧਾ":12,"ਿਬ ":69,"ੀਤਾ":41,"Co":14,"ੀਤੀ":42,"ੁਆਰ":46," In":28," Ma":13,"he ":69,"ਾੜੀ":12,"ੀਟਰ":38,"Ma":13,"Ol":12," Co":14,"In":29,"L ":13,"।":1840,"ੀਕਲ":22,"ੂਪ ":25,"ੀਕਨ":13,"ਿਲੀ":21,"ਿਲਾ":83,"Th":15,"ਿਲ੍":13,"ਿਲੋ":46,"ਿਲੇ":38,"ੂਨ ":35,"ਿਲਦ":12,"ਵ":3164,"ਲ":4004,"ਰ":5772,"ਿ":5178,"ਾ":10004,"਼":1111,"ਹ":4455,"ਸ":5034,"ਦ":5926,"ਧ":297,"ਤ":3377,"ਥ":271,"ਢ":42,"ਣ":777,"ਠ":69,"ਡ":853,"ਮ":2207,"ਯ":188,"ਬ":2031,"ਭ":430,"ਪ":1926,"ਫ":303,"ਨ":4410,"ਕ":3798,"ਗ":2047,"ਖ":660,"ਐ":62,"ਓ":66,"ਝ":61,"ਜ":2041,"ਟ":625,"ਘ":134,"ਛ":70,"ਚ":1522,"ਅ":1321,"ਆ":1270,"ਇ":2053,"ਂ":2880,"ਏ":233,"ਈ":490,"ਉ":422,"ਊ":48,"ੱ":1924,"ੰ":2555," a ":18,"੦":200,"੧":273,"੪":62,"ਿਮਨ":20,"੫":77,"੨":239,"੩":93,"੮":92,"੯":96,"੬":69,"੭":58,"੨੦੦":38,"ੜ":191,"ੀ":4636,"ੁ":1825,"ੂ":1115,"ੇ":3761,"ੈ":2081,"ੋ":1676,"ੌ":206,"੍":1046,"ੂਲ ":22,"ੀਜਿ":21," Ol":12,"ੂਰ ":25,"b ":18,"ਿਹਾ":91,"a ":87,"ਿਸੇ":29,"ਿਸ਼":57,"ਿਸਾ":23," Th":15,"ਿਸਤ":34,"ਚੌਂ":12,"ਚੋਂ":38,"ਿਵੇ":63,"ਿਵਾ":13,"ੀਕਾ":45,"i ":27,"ਿਟੀ":38,"ge":13," in":40,"ic ":12,"fi":14," is":12,"fo":16,"ਚਾਈ":23,"he":95,"ha":27,"gh":19,"go":13,"g ":34,"ea":30,"ਚਾਰ":34,"ec":17,"ਚਾਲ":16,"ed":45,"de":37,"di":36,"ia ":20,"ev":13,"h ":33,"Ind":16,"ee":14,"el":41,"ei":12,"en":68,"em":14,"et":19,"ੀਆਂ":178,"es":53,"er":114,"ੀਅਤ":34,"ca":15,"e ":169,"ਚੀਨ":33,"be":16,"da":20,"f ":44," of":43,"ct":18,"cs":14,"co":29,"ck":12,"ch":22,"ce":32,"c ":16,"ics":14,"d ":98,"at":58,"as":29,"ar":52,"al":54,"ai":16,"am":68,"an":97,"ac":18,"ad":16,"ab":12,"ਿਨਾ":26,"nt":47,"ns":26," am":51," an":24,"ਿਨੇ":13,"ੈ। ":755,"of":44,"om":42,"on":91,"ol":28," ਅ":1094,"os":19," ਇ":1749," ਆ":274,"ou":18,"or":54," ਏ":119,"r ":72," ਉ":313,"ow":13," ਈ":30," ਕ":1460,"pe":18," ਖ":182," ਗ":918,"ਿਨ੍":12," ਐ":59," ਓ":47," ਜ":1208," ਝ":16," ਟ":112,"po":12," ਘ":42,"pi":19," ਚ":259," ਛ":39,"lo":16,"ਜੋ ":82,"ll":20,"igh":12,"ly":15,"o ":26,"ma":17,"mb":17,"me":42,"mi":19,"mp":27,"mu":48,"na":37,"nc":21,"nd":68,"ne":28,"ng":50,"ni":32,"ਿਤਾ":77,"ਿਤੀ":12," ।":190,"ੀਅਮ":40,"m ":58,"ੀਅਨ":27,"ਿਥਿ":27,"ine":16,"ing":33,"li":35,"le":33,"ld":21,"la":31,"n ":137," co":22,"ht":18,"hu":17,"hi":29,"ho":16,"id":13,"ic":60,"ia":36,"ig":20,"in ":38,"ie":22,"k ":17,"ir":14,"is":39,"it":46,"iu":27,"il":21,"in":129,"io":41,"l ":48,"ਾਰਕ":16,"ਾਰਚ":41,"ਾਰਤ":101,"ਾਰਨ":27,"wo":13,"ਾਮਿ":15,"y ":61,"wa":12,"ve":29,"ਾਰੀ":54,"ur":21,"us":14,"ਾਰਾ":51,"ut":16,"um":56,"un":15,"ty":14,"ਾਰੇ":39,"ua":16,"to":25,"ts":12,"tr":30,"te":65,"ti":67,"ਾਬਕ":377,"th":116,"ta":28,"st":52,"se":26,"sh":12,"si":30," ੨":195," ੩":56," ੪":26," ੫":29,"u ":55,"ਚਰਲ":20," ੬":17," ੭":14," ੮":15," ੯":19,"rs":22,"rt":24,"ry":21," ੧":210,"ro":42,"ri":64,"ਚਲਾ":12,"re":47,"rd":17,"ੁਤ ":26,"ra":24,"t ":72," ਹ":2872," ਸ":2699," ਵ":2408,"ਾਬਲ":23,"ht ":12," ਰ":498," ਲ":715," ਬ":868," ਭ":339,"s ":155,"ੁਣ ":18," ਮ":1134," ਯ":133," ਨ":1023," ਪ":1056," ਫ":184," ਤ":951," ਥ":21,"ਜੇ ":27," ਦ":4245," ਧ":86," ਡ":55,"ਾਬੀ":48," ਢ":16,"pr":12,"ਾਬਾ":23,"ਿਗਿ":35,"ੁਰ ":13," s ":16,"ਾਹੀ":40,"ਾਹਿ":88,"ਿਚਾ":17,"hum":14,"ਾਸਿ":34,"ਾਸ਼":82,"ਾਸੇ":16,"ਜਾ ":63,"ਚਨਾ":19,"ਾਲੇ":56,"ਾਲਾ":46,"ਾਲੀ":54,"ਜ਼ ":52,"ਜੀ ":155,"ਿਖੇ":23,"ਾਵਾ":47,"ਿਖਾ":19,"ਾਵਲ":13,"ਿਕਾ":29," th":90,"ym":13,"ਿਕਸ":14,"ਹਾਂ":94,"ਹੀਰ":14,"ਹੀਨ":13,"ਹੁਣ":12,"ਹੁਤ":24,"ਹਿਰ":60,"ਹਿਲ":50,"ਹਿਨ":24,"ਹਿਬ":75,"ਹਿਸ":19,"ਹਾਲ":13,"ਹਾਰ":25,"ਹਾਨ":18,"ਹਿਤ":27,"ਹੀਂ":44,"ਹਾਸ":57,"ਹਾਈ":26,"ਜਨ ":22,"਼ਨ ":23,"ਹਰਿ":36,"ਹਨਾ":25,"er ":48,"es ":28,"ਸ੍ਰ":19,"ers":16,"en ":20,"ਸਿੱ":77,"ਸਿੰ":78,"ਸੂਰ":32,"ਸੂਬ":12,"ਸਿਧ":13,"ਸਿਰ":19,"ਹਨ।":438,"ent":21,"ght":14,"ਸੀ।":71,"ਸ਼ਨ":37,"ਸ਼ਤ":17,"ਸ਼ਰ":12,"ਸ਼ਬ":26,"ਸ਼ਹ":65,"ਸ਼ੁ":34,"ਸ਼ੀ":30,"ਸਾਂ":13,"ਸ਼ਿ":19,"ਸ਼ਾ":149,"ਸ਼ਖ":29,"ਸ਼ਟ":21,"ਸਾਨ":18,"ਸਾਰ":46,"ਸਿਕ":33,"ਸਿਖ":14,"ਸਾਲ":1144,"ਸਾਹ":90,"ਸਿਟ":36,"ਸੀਅ":29,"ਸਾਇ":73,"ਸ਼ੇ":16,"ਸ਼੍":23,"ਸਿਆ":13,"ਸਰਕ":13,"ਸਮੇ":23,"ਸਮਾ":24,"ਗੜ੍":19,"ਸਰੀ":12,"ਸਲਾ":21,"ਸਤੰ":39,"ਸਦੇ":13,"ਸਦਾ":17,"ਸਦੀ":15,"ਸਨੂ":15,"ਗੁਰ":167,"ਗੋਬ":26,"for":13,"ਸਟਾ":14,"ਗ੍ਰ":502,"ਸਨ।":37,"ਚਾ ":12,"ਸਤਾ":54,"ਸਥਾ":37,"ਸਥਿ":13,"ਗਰੇ":16,"ਗਰਾ":30,"ਗਰੀ":415,"ਿਚ ":162,"ਾਹ ":17,"ਾਸ ":54,"਼ਟਰ":18,"ਿਕ ":134,"ਕੰਪ":19,"ਾਲ ":1369,"੧੬ ":14,"cti":12,"ਗਸਤ":63,"੧੭ ":15,"ਾਰ ":238,"੧੪ ":14,"੧੫ ":13,"੧੧ ":12,"ਾਮ ":62,"ਗਿਆ":104,"੧੨ ":16,"ਗਾਂ":14,"੧੩ ":12,"਼ਖ਼":29,"ਾਬ ":99,"੧੦ ":14,"ਹੱਦ":12,"ਖਾਂ":21,"ਖ਼ਸ":29,"ਖਿਆ":40,"ਾਨ ":155,"com":13,"ਗਣਿ":17,"ਿਆ ":232,"ਾਦ ":29,"੦੮ ":24,"cs ":14,"ਾਣ ":28,"ਾਤ ":23,"ਖੇਡ":37,"ਖੇਤ":37,"ਾਜ ":52,"ਖੋਂ":14,"ed ":32,"ਕੌਮ":15,"ਾਗ ":23,"ਕ੍ਰ":37,"ਸੰਸ":37,"੦੦ ":21,"ਘਰ ":13,"ਾਈ ":117,"ਸੰਖ":18,"ਕਾਂ":22,"ਸੰਬ":52,"ਸੰਤ":12,"ਕਿਤ":57,"ਾਂ ":1353,"਼ੀ ":81,"ਹੋਏ":48,"ਹੋਇ":70,"ਹੋਈ":20,"ਕਾਲ":30,"ਕਾਸ":23,"ਕਾਬ":25,"ਕਾਰ":103,"ਕੀਤ":87,"ਹੋਰ":25,"ਹੋਣ":23,"ਕਿਲ":58,"ਕਿਸ":74,"ਕਿਹ":19,"ਕੁਝ":20,"ਕੁੱ":13,"dia":15,"਼ਾ ":51,"ਹਿੰ":31,"ਹੈ।":922,"ਕੇਸ":12,"ਹੁੰ":468,"ਕੋਈ":24," ਅਪ":47," ਅਨ":20," ਆਉ":20," ਅਧ":17,"ੱਖੀ":14,"ੱਖਾ":16," ਅਮ":64," ਅਰ":39," ਅਸ":17,"ੱਖਰ":18,"ਕਦੀ":15," ਅਜ":33," ਅਗ":67," ਅਕ":54," ਅਤ":411,"ੰਸਥ":15,"ਗਾ ":22,"ਕਨੀ":13,"ੰਸਾ":14,"re ":16,"ੱਚੋ":29,"ੱਛਮ":12,"ਕਤੀ":13,"ਕਤੂ":34,"ੱਜੋ":16,"rs ":13," ਉੱ":56," ਉਹ":51," ਉਸ":69," ਇੱ":255," ਇੰ":25," ਉਪ":25," ਉਨ":48," ਉਤ":19," ਏ।":18," ਇਹ":533," ਇਸ":723," ਇਲ":20," ਅੰ":217," ਅੱ":34,"ਾ। ":18," ਇਨ":39," ਇਤ":23," ਇਥ":21,"rig":16,"ਗਰ ":22," ਆਮ":22,"ੱਖਣ":15," ਆਰ":19," ਇਕ":94," ਆਦ":14," ਆਪ":76," ਆਬ":12,"ਸਟ ":13," ਕਰ":183," ੨ ":19," ਕਲ":399," ਕਹ":19," ਕਾ":86," ਕੀ":109," ਕਿ":260," ਕੁ":68," ਗਈ":32," ਕੇ":73," ਕੈ":22," ਕੋ":64," ਕੌ":24," ੩ ":14," ਕ੍":23," ਗਏ":21,"ਕਸ਼":26," ਓਲ":31," ਕਈ":21," ੧ ":21,"ry ":17,"ਸਤ ":69,"ਕਲਾ":14,"ਵਰਗ":12,"ਕਲੰ":379," ਏਫ":13," ਏਨ":15," ਏਸ":15,"ਵਰਸ":36," ਐਗ":22," ਏਲ":14,"ਵਰਤ":32,"ਵਰੀ":76," ਜ਼":109," ਜਿ":159," ਜਾ":364," ਜੁ":64," ਜੀ":148," ਜੂ":37," ਜੇ":15," ਜੋ":96," ਜੰ":39,"ਸਨ ":38,"ਕਰਕ":17," ੮ ":14,"ਕਰਦ":41,"ੱਡਾ":23,"ਕਰਨ":55," ਚਿ":16," ਚਾ":51," ਚੁ":16," ਚੀ":38," ਚੰ":37," ਚੱ":12," ਜਰ":13," ਛੋ":14,"ਕਰੀ":18," ੯ ":15,"ਕਰੋ":16," ਜਨ":89," ਜਦ":19,"ਕਲਚ":23," ੬ ":12,"ੱਤਰ":42," ਚਲ":15," ੭ ":13,"ਗੀ ":17,"ਸਭ ":25," ਗਰ":23," ਕੰ":44," ੪ ":15," ਖੇ":84," ਗਣ":16," ਖਾ":28," ਖਿ":13,"ੱਥੇ":12," ਖ਼":15,"ੱਤਾ":19," ਘਰ":13," ਗ੍":436," ੫ ":15," ਗੋ":35," ਗੁ":188," ਗਿ":86,"ੱਤੇ":24," ਤਰ":31,"ੰਖਿ":16," ਤਾ":41," ਤਿ":24,"ੰਗਾ":15,"ੰਗਰ":20," ਤਕ":27," ਤੱ":66," ਦਰ":56," ਦੂ":37," ਦਾ":950," ਦਿ":1171," ਦੀ":419," ਦੁ":51," ਦਸ":54," ਤੌ":38," ਤੋ":497," ਤੇ":160," ਟੀ":56," ਟਰ":13,"ੰਗ੍":60," ਮਈ":37," ਬੇ":15," ਬੋ":36," ਬਾ":492," ਬਿ":25," ਬੀ":32," ਬੁ":18," ਭਗ":25," ਬਹ":34," ਫ੍":14," ਪੱ":30," ਪੰ":163," ਬਲ":14," ਬਰ":25," ਬਨ":14," ਫ਼":66," ਪੜ":16," ਫਾ":12," ਫਿ":18," ਫੁ":20," ਬਣ":71," ਪੋ":18," ਪ੍":133," ਮੌ":17," ਮੋ":24," ਮੈ":37," ਮੀ":19," ਮੁ":481," ਮਾ":131," ਮਿ":97," ਮਹ":95," ਮਸ":25," ਬੰ":15,"st ":12," ਭੌ":12," ਮਨ":31," ਮਤ":12," ਭਾ":230," ਭੀ":16," ਬ੍":13," ਭਰ":19," ਨਹ":38," ਨਿ":106," ਨਾ":302," ਨੂ":313," ਨੇ":127," ਦੱ":14," ਨਵ":51,"ਗਏ ":15," ਦੇ":1425," ਦੋ":31," ਧਰ":56," ਪੁ":69," ਪੀ":18," ਪਿ":76," ਪਾ":125," ਪੈ":40," ਪੇ":13," ਪੂ":34," ਪਰ":200," ਪਹ":57," ਪਟ":13,"ਕੋ ":15," ਲੱ":19,"ਈ ":351,"ੰਦੇ":65," ਵਖ":19,"ੰਦੀ":31,"ੰਦਾ":409," ਵਰ":63," ਵਧ":14," ਵੀ":103," ਵਿ":1204," ਵਾ":793,"ੰਦਰ":40," ਵਸ":13," ਵੇ":12," ਵੈ":16," ਵੰ":18," ਵੱ":108," ਸਕ":45,"ੰਬਰ":125," ਯਾ":23," ਰਚ":14," ਯੂ":72,"ਖੇ ":23," ਮੰ":56," ਰਾ":142," ਰਿ":33," ਰਸ":75," ਰਹ":56," ਰੇ":12," ਲਈ":76," ਰੁ":23,"str":14,"ੰਪਿ":40," ਰੂ":37," ਰੋ":38," ਲਗ":21," ਰੱ":19," ਲਾ":29," ਲਿ":55," ਲੀ":380,"ਏ ":114," ਲੇ":15," ਲੈ":20," ਲੋ":37,"Oly":12,"ਗਤ ":30,"ਲੰਪ":29,"ਲੰਡ":379,"ਲੱਗ":14,"ਂ ":2409,"ੰਜੀ":16,"ੰਜਾ":127," ਸਭ":32," ਸਬ":19," ਸਮ":69," ਸਨ":75," ਸਪ":16," ਸਰ":55," ਸਟ":13," ਸਤ":61," ਸਥ":20," ਸਦ":12,"ੰਤਰ":46," ਹਰ":55," ਸ੍":21," ਸੋ":27,"ਅ ":12," ਸਾ":1296," ਸਿ":210," ਸ਼":257,"ਖੀ ":31," ਹਨ":519," ਸੇ":33," ਸੂ":56," ਸੀ":135," ਸੁ":40," ਹੋ":233,"ੰਡਲ":14,"ੰਡੀ":26," ਸੱ":24,"ਆ ":416," ਸੰ":107,"ੰਡਾ":15," ਹਾ":41," ਹਿ":46," ਹੀ":66," ਹੁ":491," ਹੇ":15," ਹੈ":1352,"ੰਡਰ":381,"ਟ ":103,"ਝ ":29," ਏ ":29,"ਜ ":145,"ਕਸ ":17,"ਚ ":1074,"ਘ ":72,"ਹਿ ":31,"ਗ ":162," ਚ ":20,"ਹਾ ":59,"ਖ ":140,"ਕ ":1139,"ਹੀ ":112,"ਓ ":12,"ੀ। ":55,"pic":12,"ਕਰ ":44,"ਵੰਡ":19,"ਰ ":1488,"ਵੱਖ":25,"ਹੇ ":27,"ਵੰਬ":36,"ਵੱਜ":17,"ਵੱਡ":34,"ਭ ":31,"ਹੈ ":423,"ਵੱਲ":20,"ਸਕਦ":19,"ਗਈ ":25,"ਮ ":350,"ਫ ":31,"ਕੇ ":100,"ਬ ":211,"ਓਲੰ":29,"ਪ ":461,"ਧ ":64,"ਨ ":1907,"ਥ ":48,"ਕਾ ":68,"ਦ ":171,"ਕਿ ":66,"ਣ ":217,"ਕੀ ":396,"ਹੋ ":30,"ਤ ":537,"ਠ ":22,"ਡ ":132,"ਖਣ ":24,"ਾ ":2802,"ਵਿਸ":21,"ਵਾਰ":49,"ਵਿਕ":13,"ੁ ":14,"ਵਾਲ":96,"ਵਾਸ":13,"ਵਿਗ":34,"ਵਿਖ":22,"ਵਿਚ":200,"ੀ ":2902,"ਵਿਦ":16,"ਿ ":127,"ਵਾਨ":14,"ਵਾਂ":742,"ਹ ":633,"ਸਰ ":20,"਼ ":152,"ਵ ":71,"ਸਾ ":23,"ਵੇਦ":48,"ਸ ":997,"ਵੇਂ":22,"ਸ਼ ":84,"ਲ ":1735,"ਸਸ ":13,"ਵਿੱ":870,"ਸੇ ":56,"ਹਨ ":79,"ਂ।":15,"ਕਨ ":15,"ੋ ":213,"ਸੀ ":89,"੍ ":22,"ਹਰ ":16,"ੇ ":2940,"ੈ ":444,"ੂ ":303,"ਕਟ ":14,"ਰਸ਼":34,"ਰਸਾ":69,"ਰਸਿ":50,"ਰਹਿ":56,"ng ":24,"ਰਹੇ":17,"nce":16,"ne ":14,"ndi":15,"ਰਾਂ":87,"ਰਾਜ":89,"ਰਾਬ":13,"ਰਾਨ":31,"ਰਿਆ":72,"ਰਾਣ":19,"ਰਾਸ":25,"ਰਾਹ":24,"ਰਿਕ":21,"ਰਾਵ":14,"ਰਾਮ":35,"nd ":32,"ਰਿਤ":27,"ਰੀਆ":20,"ਰਮਾ":139,"ਮੰਡ":22,"ਮੰਨ":14,"ਲੇ ":121,"ਰਵਾ":29,"ਰਵਰ":37,"ਰੈਲ":39,"ਰੋਜ":15,"ਰੋਮ":30,"ਰੋੜ":12,"nte":17,"ੰਕ ":58,"ns ":12,"ਰੀਸ":12,"ਰੀਬ":18,"ਰੀਕ":94,"ਰਿਸ":18,"ਰਿਹ":15,"ੰਗ ":69,"। ":1125,"ਕਈ ":21,"ਰੂਪ":26,"ੰਘ ":71,"ਰੈਗ":367,"ਰੈਕ":12,"ਰੇਗ":15,"ਰੇਜ":79,"ੰਜ ":22,"ਲਮ ":13,"ਰਕੇ":20,"of ":41,"ਲਣ ":22,"ਰਕਾ":23,"ਐਗਰ":22,"ਰਨਾ":16,"ਲਾ ":163,"ਰਦੁ":28,"ਰਦੀ":16,"ਰਦਾ":42,"ਰਦੇ":29,"ਰਮਨ":15," ਈ ":16,"ਰਬੀ":20,"ਲੀ ":116,"ਯੋਗ":18," ਆ ":21,"on ":41,"ਰਤਾ":15,"ਰਤਿ":15,"ਰਤੀ":63,"ona":13,"ons":12,"ਯੂਨ":34,"ਯੂਰ":14,"ਯੂਲ":19,"ਲੀਪ":371,"ੱਤ ":62,"ਲੀਵ":25,"ੱਦ ":13,"ਲਾਂ":56,"ਲਾਈ":52,"ਵਲ ":18,"ਲਿਆ":33,"ਲੀਅ":22,"ld ":18,"ਲੀਆ":17,"ਲਾਵ":16,"ਲਿਖ":25,"ੱਧ ":29,"ਵੇ ":16,"ਲ੍ਹ":16,"ੱਲ ":23,"ਵਾ ":26,"ਲੋਮ":22,"ਲੋਂ":20,"ਲੋਕ":25,"ਲੋਗ":23,"ਵੀ ":125,"ਲੇਖ":15,"ਲੈਂ":19,"ੰਤ ":18,"mb ":14,"ਵਖ ":12,"ੰਡ ":46,"ਲਚਰ":23,"mer":15,"ਲਗਾ":13,"ੰਨ ":21,"lym":12,"ੰਧ ":16,"।ਇ":25,"ੰਦ ":43,"ੰਥ ":14,"mpi":14,"ਰੱਖ":17,"ੱਕ ":255,"ਰੰਥ":15,"ਵਨ ":15,"ੱਖ ":91,"mu ":47,"ੱਚ ":827,"ਆਉਂ":16,"ਅਨੁ":13,"੍ਹਾ":96,"ਇਸ ":693,"ਰਾ ":103,"ਮਨੇ":20,"ਇਹ ":527,"ਮਨੁ":16,"ਮਨੀ":13,"ਅਤੇ":407,"ਰਲ ":24,"ਭਾਈ":15,"ਭਾਗ":17,"ਭਾਰ":147,"ਭਾਵ":14,"ਭਾਸ":44,"ਅਜਿ":15,"ਇਲ ":16,"ਰਨ ":81,"ਰਮ ":38,"ਅਰਥ":18,"ਅਮਰ":51,"ਯਾ ":16,"ਬੋਲ":29,"ਰਡ ":23,"ਅਪ੍":39,"ਰਤ ":82,"ਬ੍ਰ":15,"੍ਰੋ":27,"੍ਰੇ":90,"੍ਰੈ":416,"ਰਣ ":20,"੍ਰਮ":14,"੍ਰਦ":16,"੍ਰੀ":65,"੍ਰਿ":60,"੍ਰਾ":30,"੍ਰਸ":16,"੍ਰਹ":30,"ਰਥ ":20,"੍ਰੰ":13,"ਮੇਂ":24,"ਆਨੀ":21,"ਏ। ":23,"ਆਪਣ":51,"ਆਦਿ":12,"ਆਦਾ":18,"ਆਣਾ":27,"ਮੈਨ":17,"ਮਾਨ":46,"ਮਾਤ":26,"ਮਾਣ":116,"ਮਿਕ":21,"ਮਾਰ":62,"ਮਾਲ":18,"ਮਿਥ":28,"ਮਾਂ":39,"ਇਆ।":31,"ਮੁੱ":38,"ਮਿਲ":41,"ਮਿਸ":19,"ਮੀਟ":34,"ਮੁਖ":14,"ਮੁਕ":29,"ਮੁਤ":380,"ਰੋ ":14,"ਮਹਾ":43,"ਮਹਿ":32,"ਮਹੀ":13,"ਆਵਾ":13,"ਰੂ ":145,"ਭੌਤ":12,"ਆਰਾ":46,"ਰੀ ":651,"ਬੰਧ":25,"ਰੇ ":75,"ਲਈ ":78,"ਉਣ ":23,"ਮਰੀ":43,"ਇਥੇ":16,"ਬਣਾ":43,"ਇਨ੍":18,"ਪੜ੍":12,"ਫੁਟ":13,"ਫ਼ਰ":40,"ਇਣਕ":56,"ਉਸ ":51,"ਉਹ ":40,"ਈਆਂ":13,"ਇਤਿ":19,"ਮਨ ":35,"ਇਸਦ":16,"ਪ੍ਰ":176,"ਪੈਦ":15,"ਅੰਤ":31,"ਅੰਦ":15,"ਅੰਗ":91,"ਅੰਕ":65,"ਭੀ ":15,"ਇਲਾ":16,"ਈਨਾ":22,"ਰਜ ":32,"ਰਚ ":44,"ਬੀਜ":26,"ਰਗ ":14,"ਬਿੰ":25,"ਬਾਦ":22,"ਬਾਰ":32,"ਬਾਬ":12,"ਰਕ ":18,"ਬਾਕ":372,"ਬਾਲ":27,"ymp":12,"ਈਡਰ":15,"ਬਾਅ":27,"ਬਾਈ":14,"ਉਂਦ":22,"ਬਹੁ":25,"ਭਗਤ":25,"ਮੇ ":12,"ਬਲਾ":20,"ਪੱਛ":12,"ਪੰਜ":152,"ਬਰਾ":15,"ਫ੍ਰ":14,"ਮੀ ":18,"ਮਾ ":32,"ਸਮ":81,"ਸਭ":32,"ਸਬ":22,"ਸਫ":15,"ਸਪ":32,"ਸਨ":101,"ਸਵ":19,"ਸਲ":51,"ਸਰ":94,"ਾ।":27,"ਸਟ":58,"ਸਦ":49,"ਸਤ":207,"ਸਥ":50,"ਸਕ":73,"ਵੱ":108,"ਵੰ":62,"ਵੈ":22,"ਵੇ":119,"ਉਨ੍":43,"ਵਸ":16,"ਵਿ":1234,"ਵੀ":154,"ਵਾ":1015,"ਵਨ":21,"ਵਧ":14,"ਵਰ":201,"ਵਲ":39,"ਵਖ":19,"ਲੰ":416,"ਲੱ":23,"ਲੜ":14,"ੌਰ ":34,"ਲੋ":133,"ਲ੍":24,"ਲੇ":163,"ਲੈ":43,"ਲਿ":106,"ਲਾ":368,"ਲੁ":15,"ਲੀ":580,"ਲਹ":12,"ਰੱ":21,"ਰੰ":40,"ਲਵ":25,"ਲਬ":13,"ਲਮ":25,"ਲਤ":16,"ਲਣ":25,"ਲਦ":24,"ਲਚ":23,"ਲਕ":25,"ਲਗ":28,"ਰੈ":428,"ਰੋ":128,"ਰ੍":22,"ਰੀ":839,"ਰੁ":36,"ਰੂ":205,"ਲਈ":79,"ਰੇ":213,"ਰਹ":94,"ਰਸ":179,"ਰਿ":221,"ਰਾ":502,"ਮੱ":15,"ਮੰ":60,"ਰਲ":37,"ਰਵ":92,"ੀਤ":114,"ੁਆ":59,"ੀਦ":20,"ੀਬ":34,"ੀਮ":70,"ੀਨ":92,"ੀਪ":396,"ੁਖ":20,"ੀਵ":67,"ੁਕ":56,"ੀਰ":67,"ੀਲ":39,"ੇ।":14,"ੁਝ":24,"ੁਟ":25,"ੀਸ":29,"ੁਜ":22,"ੀਆ":241,"ਿਥ":45,"ਿਦ":23,"ਿਣ":20,"ੀਅ":117,"ਿਤ":204,"ੀਂ":64,"ਿਡ":14,"ਿਟ":58,"ਿਮ":51,"ਿਬ":77,"ਬਰ ":175,"ਿਪ":16,"ਿਧ":20,"ਿਨ":1162,"ੀਗ":18,"ਿਵ":98,"ੀਕ":136,"ਿਲ":265,"ਿਰ":130,"ੀਟ":47,"ਾੜ":27,"ੀਜ":44,"ਿਹ":111,"ਿਸ":263,"ਾਡ":16,"ਇੰਟ":13,"ਾਣ":249,"ਿਅ":43,"ਾਤ":101,"ਿਆ":517,"ਾਦ":96,"ਾਧ":15,"ਿਉ":16,"ਾਨ":318,"ਿਊ":33,"ਾਪ":44,"ਾਬ":594,"ਾਮ":104,"ਾਰ":660,"ਾਲ":1569,"ਾਵ":109,"ਿਖ":72,"ਿਕ":215,"ਿਗ":45,"ਾਹ":169,"ਿਚ":202,"ਾਸ":245,"ਿਜ":25,"਼ਾ":203,"਼ਿ":116,"ਾਅ":32,"਼ੀ":109,"ਾਂ":1630,"਼ੁ":43,"ਾਈ":221,"ਾਉ":53,"਼ੇ":19,"ਾਇ":185,"਼ੋ":16,"਼ੈ":21,"ਬਲ ":16,"਼੍":25,"ਾਕ":443,"ਾਗ":63,"ਾਖ":18,"ਾਜ":126,"ਾਚ":13,"਼ਨ":40,"਼ਤ":27,"਼ਟ":24,"਼ਸ":37,"਼ਹ":70,"਼ਵ":12,"਼ਰ":65,"਼ਬ":33,"਼ਮ":21,"਼ਖ":29,"ਹੱ":25,"ਹੰ":15,"ਹੂ":17,"ਹੁ":520,"ਹੈ":1355,"ਹੇ":48,"ਹਾ":329,"ੀ।":87,"ਹੀ":203,"ਹਿ":360,"ਸੰ":167,"ਸੱ":26,"ਹੋ":237,"ਹੌ":13,"ਸੂ":66,"ਸੁ":43,"ਸੀ":222,"ਸੇ":97,"ਹਨ":550,"ਸਹ":12,"ਸਸ":15,"ਸਿ":313,"ਸਾ":1477,"ਸ਼":623,"ਹਲ":14,"ਸੋ":30,"ਹਰ":67,"ਹਮ":13,"ਸ੍":26,"ਦਸ":57,"ਦਿ":1225,"ਦਾ":1748,"ਦੁ":90,"ਦੀ":615,"ਦੂ":48,"ਥੇ":53,"ਦਨ":53,"ਥੋ":13,"ਦਰ":129,"ਤੰ":44,"ਦਲ":21,"ਤੱ":67,"ਧਾ":77,"ਨਜ":12,"ਨਡ":15,"ਧੀ":16,"ਧਿ":28,"ਨਦ":13,"ਨਤ":17,"ਦੇ":1613,"ਦੋ":54,"ਨੁਸ":12,"ਧਰ":65,"ਨਕ":44,"ਤਸ":17,"ਤਵ":19,"ਤੀ":231,"ਤੂ":46,"ਤਿ":96,"ਤਾ":728,"ਣੇ":53,"ਤਨ":20,"ਤਪ":13,"ਤਤ":12,"ਤਰ":186,"ਤਲ":37,"ਤਮ":27,"ਉਹਨ":12,"ਥੀ":15,"ਥਿ":46,"ਥਾ":70,"ਤੋ":518,"ਤੇ":631,"ਨੁੱ":16,"ਤੌ":43,"ਇੱਕ":245,"ਣਕ":72,"ਨੂੰ":329,"ਡੇ":30,"ਣਾ":137,"ਣੂ":108,"ਣਿ":62,"ਣੀ":85,"ਤਕ":48,"ਨੇਂ":14,"ਟ੍":17,"ਟੇ":26,"ਨੇਜ":20,"ਟੀ":130,"ਟਿ":29,"ਡਿ":29,"ਡੀ":68,"ਨ।":476,"ਡਾ":86,"ਡਲ":20,"ਡਰ":410,"ਡਦ":12,"ਮਰ":69,"ਮਲ":18,"ਬੰ":44,"ਮਸ":29,"ਮਹ":96,"ਮੁ":499,"ਮੀ":82,"ਮਿ":154,"ਮਾ":391,"ਮੂ":19,"ਮੈ":49,"ਮੇ":59,"ਮ੍":15,"ਮੌ":19,"ਮੋ":28,"ਰਕ":76,"ਰਖ":17,"ਰਗ":45,"ਰਚ":72,"ਰਜ":81,"ਰਟ":18,"ਯਾ":37,"ਰਡ":28,"ਯੂ":73,"ਰਣ":36,"ਯੁ":14,"ਰਥ":37,"ਰਤ":198,"ਰਦ":131,"ਰਨ":116,"ਰਫ":22,"ਰਪ":20,"ਯੋ":27,"ਰਬ":46,"ਰਮ":236,"ਪੰ":164,"ਬਲ":53,"ਪੱ":37,"ਬਰ":215,"ਫ੍":15,"ਬਹ":34,"ਭਗ":29,"ਬੁ":20,"ਬੀ":120,"ਬਿ":55,"ਬਾ":578,"ਬੋ":46,"ਬੈ":14,"ਬੇ":32,"ਮਈ":41,"ਮਕ":17,"ਬ੍":15,"ਭਰ":22,"ਮਜ":12,"ਮਤ":30,"ਭਾ":256,"ਭੀ":18,"ਭਿ":14,"ਭੌ":12,"ਮਦ":18,"ਮਨ":98,"ਪਲ":21,"ਨੰ":12,"ਪਹ":57,"ਪਸ":12,"ਪਰ":222,"ਪੂ":52,"ਪੈ":44,"ਪੇ":23,"ਪੀ":37,"ਪੁ":90,"ਪਾ":168,"ਪਿ":130,"ਬਕ":380,"ਪੋ":22,"ਪ੍":176,"ਨ੍ਹ":75,"ਫਰ":17,"ਫਲ":16,"ਬਦ":46,"ਬਨ":25,"ਫ਼":106,"ਪੜ":21,"ਫਾ":21,"ਫਿ":21,"ਫੁ":23,"ਬਣ":71,"ਨਵ":102,"ਦੱ":14,"ਨਲ":14,"ਨਰ":14,"ਨਮ":39,"ਨੇ":196,"ਨੂ":341,"ਨੀ":200,"ਨੁ":33,"ਨਾ":539,"ਨਿ":163,"ਨਸ":36,"ਨਹ":40,"ਨ੍":89,"ਨੈ":12,"ਨੋ":19,"ਪਨ":15,"ਪਣ":56,"ਪਤ":28,"ਪਟ":24,"ਬਦ ":20,"ਕਰ":232,"ਕਮ":20,"੨ ":59,"ਕਲ":439,"ਕਨ":33,"ਕਦ":33,"ਕਟ":31,"ਕਤ":65,"੧ ":77,"ਕਈ":21,"ਕੱ":19,"ਕੰ":48,"ਗਲ":25,"ਗਰ":511,"੪ ":44,"ਖੋ":29,"ਖੇ":111,"ਗਦ":22,"ਗਣ":22,"ਗਤ":41,"ਖੀ":35,"ਖਾ":81,"ਖਿ":54,"ਖ਼":60,"ਕੜ":15,"ਕ੍":37,"ਗਏ":21,"ਖਰ":32,"ਕੌ":24,"੩ ":43,"ਕੋ":104,"ਗਈ":32,"ਖਦ":15,"ਕੈ":22,"ਕੇ":135,"ਕੁ":80,"ਕੂ":15,"ਖਣ":34,"ਖਤ":12,"ਕਾ":323,"ਕਿ":322,"ਕੀ":517,"ਕਹ":19,"ਕਵ":12,"ਕਸ":64,"ਏਲ":14,"ਐਗ":22,"ਪਹਿ":45,"ਏਸ":17,"ਓਲ":31,"੦ ":87,"ਜੇ":38,"ਜੈ":24,"ਜੋ":120,"ਜ਼":304,"ਜਾ":547,"ਜਿ":213,"ਜੀ":234,"ਜੁ":64,"ਜੂ":46,"ਪਿਤ":20,"ੰ ":328,"ਪਾਸ":19,"ਪਿਕ":29,"ਜਦ":23,"ਪਾਰ":18,"ਜਧ":12,"ਜਨ":116,"ਪਿਊ":14,"ਪਾਣ":18,"੯ ":52,"ਛੋ":17,"ਚੱ":12,"ਪਾਕ":32,"ਚੰ":38,"ਜਲ":16,"ਜਰ":27,"ਟਬ":13,"ਟਨ":25,"ਪਾਈ":14,"ਟਾ":78,"ਟਰ":121,"ਜੰ":41,"ੋਗਰ":27,"ਗੜ":29,"੬ ":50,"ਚਕ":12,"ਗਸ":65,"ਗਾ":75,"ਗੂ":16,"ਗੁ":197,"ਗੀ":24,"ਗਿ":132,"ਪੂਰ":40,"ਗੇ":24,"ਗ੍":505,"ਗੋ":52,"੫ ":50,"ਘਰ":19,"ਚਿ":28,"ਚਾ":99,"ਚੁ":16,"ਚੀ":48,"ਚੇ":17,"ਪਿੰ":41,"ਪੁਰ":63,"ਚੋ":42,"ਚੌ":23,"੮ ":73,"ਛਮ":12,"ਜਗ":13,"ਚਨ":19,"ਚਰ":32,"੭ ":49,"ਚਲ":24,"ਅਤ":454,"ਆਂ":297,"ਅਜ":34,"ਅਗ":69,"ਅਕ":61,"ਆਣ":33,"ਇਆ":135,"ਆਖ":12,"ਅਸ":23,"ਅਮ":113,"ਅਰ":63,"ਅਲ":18,"ਅਦ":42,"ਆਇ":12,"ਅਧ":17,"ਆਉ":22,"ਅਨ":55,"ਅਪ":47,"ਪਣੇ":34,"ਈਆ":13,"ਇਥ":21,"ਇਤ":25,"ਇਣ":62,"ਆਸ":22,"ਪਣੀ":15,"ਆਰ":95,"ਆਮ":24,"ਇਕ":101,"ਆਵ":17,"ਆਲ":16,"ਆਨ":54,"ਆਦ":35,"ਆਬ":13,"ਆਪ":78,"ਆ।":54,"ਬਾ ":22,"ਂਕ":18,"ਂਗ":31,"ਈ।":12,"ਂਟ":25,"ਂਡ":36,"ਂਸ":30,"ਂਤ":24,"ਂਦ":244,"ਉੱ":56,"ੋੜ ":16,"ਬੀ ":78,"ਏਨ":15,"ਏਫ":13,"ਇਨ":48,"ਅੱ":34,"ਇਲ":37,"ਅੰ":220,"ਈਟ":14,"ਇਹ":542,"ਮਈ ":41,"ਇਸ":741,"ਉਂ":46,"ਈਡ":27,"ਈਨ":32,"ਏ।":33,"ਬੇ ":13,"ਉਦ":21,"ਉਨ":51,"ੋਇਆ":71,"ਉਣ":28,"ਉਤ":19,"ਉਪ":26,"ੜ ":44,"ਇੱ":255,"ਇੰ":32,"ਉਸ":76,"ਉਹ":56,"ਊਟ":14,"ਪਰਮ":113,"ਨਕਸ":15,"ਪਤ ":12,"ਧਰਮ":31,"ਧਰਤ":22,"ਪਰ ":49,"ਧਾਂ":14,"ਉੱਤ":40,"ੋਬਿ":25,"ਦੁਆ":48,"ਦਿੱ":27,"ਦੁਨ":24,"ੋਮੀ":24,"ਦੂਸ":12,"ਦੂਜ":16,"ੋਮਨ":25,"੦੦":66,"੦੮":25,"੧੦":19,"੧੩":12,"੧੪":15,"੧੧":14,"੧੨":18,"੧੭":17,"੧੮":24,"੧੫":17,"੧੬":17,"੧੯":42,"੨੧":14,"੨੦":53,"ਦਾਂ":14," ੧੮":24," ੧੭":16,"ਦਾਨ":17," ੧੬":17," ੧੫":16," ੧੪":15," ੧੩":12," ੧੨":16," ੧੧":13,"ੋਲੀ":19,"ਦਾਰ":26," ੧੯":41," ੨੦":53," ੨੧":14,"ਦਿਆ":31," ੨੭":12," ੨੬":12," ੨੯":17," ੨੮":14," ੨੩":13," ੨੨":14," ੨੫":13," ੨੪":14,"ਦਾਸ":19," ੩੦":25," ੩੧":16,"ਦੀਆ":75,"ਦਿਨ":1097,"umb":16,"੍ਹ ":21," ੧੦":19,"ਦੋਂ":17,"੩੧":18,"੩੦":26,"um ":31,"੨੯":17,"੨੮":15,"੨੭":13,"੨੬":13,"੨੫":14,"੨੪":14,"੨੩":13,"੨੨":14,"ੱਤ":172,"ੱਢ":13,"ੱਡ":45,"ੱਧ":49,"ੱਦ":25,"ੱਥ":25,"ੱਗ":23,"ੱਕ":286,"ੱਖ":185,"ੱਛ":18,"ੱਜ":30,"ੰਸ":52,"ੱਚ":879,"ੱਟ":28,"ੱਠ":21,"ੱਲ":52,"ੱਸ":22,"ੰਥ":18,"ੰਤ":85,"ੰਧ":36,"ੰਦ":618,"ੰਡ":502,"ੰਬ":155,"ੰਮ":32,"ੰਨ":45,"ੰਪ":49,"ੰਕ":75,"ੰਖ":19,"ੰਗ":218,"ਦੇਸ":44,"ਦੇਵ":25,"ੰਜ":177,"ੰਟ":22,"ੰਘ":85,"ਨਵਰ":42,"ਨੀਆ":32,"ਨੀਅ":13,"ਨਿਵ":62,"ਨੀਕ":15,"ਨਿਆ":24,"ਬਕ ":378,"ਨਾਨ":32,"ਨਾਲ":179,"ਨਾਵ":16,"ਨਿਕ":18,"ਨਾਮ":38,"ੜ੍":38,"ਨਾਂ":88,"ੜੀ":29,"ੜਾ":29,"ੜੇ":20,"ty ":13,"ਨਸੰ":13,"ਨਹੀ":36,"ਏਫ ":13,"ਨਵੰ":36,"ੁਦ":13,"ੂਆ":13,"ੁਨ":42,"ੁਤ":412,"ੁਣ":26,"ੁਮ":18,"ੁਰ":279,"ੁਸ":47,"ਿੰ":258,"ੁਲ":97,"ਿੱ":1026,"ੈ।":922,"ੂਜ":17,"ੂਨ":78,"ੂਦ":14,"ੂਰ":124,"ਏਲ ":13,"ੂਬ":50,"ੂਪ":31,"ੂਸ":23,"ੂਲ":53,"ੁੰ":490,"ੁੱ":117,"ੂੰ":335,"ੇਂ":94,"ੇਕ":12,"ੇਖ":36,"ੇਦ":53,"ੇਤ":52,"ੇਡ":47,"ੈਂ":49,"ੇਟ":14,"ੇਜ":108,"ੇਗ":24,"ੇਰ":47,"ੇਲ":44,"ੈਕ":39,"ੇਵ":52,"ੈਗ":377,"ਧਾਰ":30,"ੇਨ":27,"ਧਾਨ":15,"ਧਿਆ":15,"ੈਣ":13,"ੈਦ":24,"ੇਸ":109,"ੈਟ":17,"ੈਲ":73,"ੈਰ":17,"ੈਨ":38,"ੈਸ":23,"ੋਂ":617,"ੋਇ":77,"ੋਈ":46,"tio":34,"thu":15,"ੋਟ":27,"ੌਂ":47,"ੋਡ":13,"ੋਜ":32,"ੋਧ":14,"ੋਨ":32,"ੋਪ":22,"ੋਣ":30,"ੋਤ":20,"ੋਏ":51,"ੋਗ":55,"ੋਚ":14,"ੋਕ":33,"ੌਜ":14,"ੌਤ":23,"ੋਮ":61,"ੋਬ":36,"ੋਲ":71,"ੋਰ":92,"ੋਵ":23,"ੋਹ":24,"ੋਸ":21,"ੋੜ":31,"ੌਮ":17,"ੌਰ":50,"ted":14,"੍ਹ":146,"੍ਰ":834,"ter":25,"the":71,"ਆ। ":38,"ਤੂਬ":34,"ੇਲ ":13,"ੇਰ ":12,"ਤੀਆ":19,"ੇਸ ":12,"ਤਿਹ":21,"ਤਿਆ":30,"ਤਾਨ":49,"ਤਿਕ":18,"ਤਾਬ":383,"ਨਕ ":14,"ਤਾਰ":18,"ਤਾਂ":61,"ੇਵ ":19,"ਨਮ ":32,"ਤੌਂ":25,"ਤੋਂ":485,"ੈਨ ":18,"ਤੌਰ":15,"ੈਲ ":41,"ਨਾ ":113,"ਥਾਂ":13,"ਥਿਤ":12,"ਥਿਹ":26,"ਥਾਨ":18,"ਦਸੰ":39,"ਨੀ ":107,"ੇਗਰ":13,"ਦਰਿ":26,"ਨੇ ":143,"ਤੰਬ":41,"ਤੱਕ":12,"ਤੱਤ":53,"ਂਟ ":12,"ੇਜੀ":27,"ੇਜ਼":73,"ੇਡਾ":24,"ਂਡ ":22,"ੈਂਡ":21,"ੇਡਦ":12,"ਂਗ ":18,"ੇਦਨ":48,"ੇਤੀ":16,"ੇਤਰ":23,"ੋਂ ":614,"ਤੋ ":20,"ਣਕਾ":14,"ਤਕਨ":13,"ਥੇ ":48,"ਦਨ ":52,"ੈਕਟ":16,"ੋਈ ":39,"ce ":16,"ੈਗਰ":366,"ੋਏ ":45,"ਥਾ ":23,"ੇਵਾ":19,"ੇਸ਼":80,"am ":12,"ੋਕ ":20,"al ":27,"ਣਿਤ":17,"ਣਿਆ":40,"and":32,"amu":47,"an ":23,"ੈਦਾ":18,"ਦਰ ":34,"ਣਾਇ":20,"ੌਂ ":41,"ੋਣ ":17,"ਦੋ ":25,"ਤਰਾ":24,"ਤਰੀ":36,"ੋਪ ":15,"ਦੇ ":1528,"at ":19,"ਦੀ ":510,"as ":15,"ੋਰ ":44,"ੋਲ ":12,"ਦਾ ":1619,"ati":17,"ਦਿ ":15,"ੜਾ ":14,"ੁਟਬ":13,"ੀਸਟ":12,"ੀਵਨ":13,"ੀਵਰ":32,"ੁਕਾ":27,"ਤਕ ":19,"ੜੀ ":26,"ੀਮਾ":12,"�":48,"ੁਰਦ":34,"ਡਦੀ":12,"ੜੇ ":18,"ੁਨਿ":12,"ੁਨੀ":20,"ਣੀ ":69,"ੁਤਾ":380,"ਣਾ ":86,"ਡਰਾ":13,"ਣੂ ":105,"ਣੇ ":51,"ਆਂ ":277,"ੁਸ਼":14,"ਂਦਰ":14,"ਂਦੀ":34,"ਂਦਾ":168,"ਂਦੇ":20,"ੈ।ਇ":14,"ੂੰ ":327,"ਤਰ ":83,"ਅਨ ":34,"ਡਾਂ":31,"ੁਰੂ":142,"ੁਰਾ":23,"ੁਰਸ":21,"ਿੰਦ":69,"ਿੰਡ":45,"ਿੰਘ":68,"ਿੰਗ":49,"ਡੀਅ":12,"ਿੱਤ":44,"ਿੱਧ":18,"ਿੱਖ":61,"ਅਤ ":35,"ਿੱਚ":863,"ੁਲਾ":52,"ੁਲੀ":15,"ਅਦ ":27,"ੂਰਜ":24,"ੂਰਬ":14,"ੂਬਰ":34,"ਤਾ ":184,"ਤੀ ":175,"ੂਨਿ":14,"ੂਨੀ":19,"ਤੇ ":613,"ਜੰਤ":20,"ਜੰਗ":15,"ਡਰ ":388,"ਆਨ ":22,"ੂਲੀ":19,"ਇਆ ":100,"ਆਪ ":24,"ਅਮ ":45,"ੁੱਖ":54,"ਅਰ ":17,"ੁੰਦ":474,"ਡਲ ":18,"ਟਬਾ":13,"ਡੀ ":25,"ਡਾ ":35,"ਨ। ":77,"ੇਂ ":52,"ਡੇ ":21,"ੜ੍ਹ":37,"ਟਰੀ":23,"ਟਾਂ":13,"ਟਾਇ":14,"ਅਕਤ":41,"ਅਕਾ":15,"ਅਗਸ":63,"ਆਮ ":19,"ਆਰ ":21,"ਣਕ ":58,"ਟਿਆ":13,"ਇਕ ":86,"ਟੀਮ":54,"ਟ੍ਰ":17},"n_words":[112478,136533,89577],"name":"pa"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/pol b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/pol new file mode 100644 index 000000000..139647c01 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/pol @@ -0,0 +1 @@ +{"freq":{"D":76546,"E":48349,"F":59499,"G":97533,"A":113161,"B":112599,"C":110974,"L":74803,"M":131493,"N":86269,"O":63924,"H":50582,"I":84977,"J":54373,"K":109538,"U":33818,"T":71466,"W":122172,"V":29111,"P":225853,"S":204600,"R":87715,"Y":5329,"X":17841,"Z":57656,"f":154643,"g":760584,"d":1304112,"e":3541226,"b":467514,"c":1792078,"a":3833729,"n":2529442,"o":3537464,"l":1140017,"m":1150421,"j":965827,"k":1483844,"h":558914,"i":3732766,"w":2322567,"v":42704,"u":1069834,"t":1619824,"s":1819258,"r":2204575,"p":1082020,"z":1828688,"y":1372315,"x":13069,"é":11522,"á":5335,"ü":5350,"ö":4590,"ó":396123,"ę":271422,"ć":60605,"ą":370153,"ś":279181,"Ś":15543,"ń":123462,"ł":591480,"Ł":9157,"ż":255164,"Ż":6256,"ź":20372," l":139321," m":204189," n":260999," o":286725," h":33638," i":177645," j":136928," k":213385," d":243257," e":37159," f":50076," g":203060,"р":5358," a":148427," b":95754," c":133679," z":321847," u":97002," t":172994," w":969288," p":661390," s":339763," r":209751," J":52915," K":104698," H":47495," I":52640," N":80062," O":56243," L":69035," M":123296," B":105665," C":84648," A":95983," F":55238," G":73890," D":70098," E":42554," Z":55304,"к":5011," X":11746,"и":6265,"о":7740,"н":5938," S":182443," R":76715," P":214389,"а":9102," W":115231," V":20154," U":30651,"е":5223," T":64394," ż":19337," Ż":6158,"ęśc":13317," ś":51887," Ś":15346," Ł":9064," ł":17467,"A ":12056,"Da":8795,"Cz":10287,"Co":11705,"Ce":7894,"Ch":21362,"Ci":4668,"G ":10044,"Du":4576,"Do":17200,"Dr":5145,"De":9899,"Di":5692,"GC":12708,"Fe":4746,"Eu":8774,"Ge":6043,"Ga":8896,"I ":22055,"Fr":25795,"Fo":4852,"Fi":6166,"B ":5264,"C ":19133,"Au":8116,"Ar":11839,"Ba":23485,"Am":7571,"An":13752,"Al":15057,"Bu":9080,"Br":16403,"Ca":12445,"Bi":14211,"Be":12406,"Bo":15278,"Ku":5947,"Gó":8233,"Kr":17850,"Ko":31811,"Le":13922,"Li":15420,"La":13916,"Lu":9458,"Lo":10236,"Me":12645,"NG":5663,"Mi":29200,"O ":4778,"Ma":41474,"Mu":5320,"Mo":18522,"Ni":19737,"Ne":7072,"Na":24418,"P ":7412,"No":17077,"Ol":5489,"Od":7399,"PG":5183,"Ob":6870,"Gm":6336,"Gr":14758,"Go":7919,"Ha":11794,"He":11337,"II":18254,"Hi":5668,"Ho":9461,"In":12447,"Ja":16186,"L ":4866,"Je":18291,"Jo":8139,"Ka":25307,"M ":4990,"Ki":5813,"Un":7211,"VI":4920,"W ":15791,"Tu":5606,"Tr":10180,"To":9177,"Th":7956,"Te":9915,"Ta":10132,"V ":6364,"Sz":17267,"Sy":6237,"St":34755,"Su":6926,"Wo":12341,"Ws":4692,"Wi":28290,"Wa":16039,"We":8452,"Vi":5052,"X ":6678,"Pu":5975,"Pr":25703,"S ":11205,"Pe":7756,"Pa":34023,"Po":99382,"Pi":15484,"Os":6465,"Or":5855,"Se":13365,"Sc":7388,"Si":11311,"Sk":5337,"Sp":7038,"So":10398,"Ru":5061,"Rz":5267,"Sa":22530,"Re":17869,"Ro":19242,"Ra":13392,"b ":46793,"a ":1141880,"Wy":14854,"Za":17995,"Sł":20200,"i ":569208,"bó":4844,"gd":5266,"ge":34328,"ga":71454,"ać":8134,"fi":50271,"fr":12808,"fu":7503,"fo":23920,"j ":229252,"bę":5925,"có":12082,"gw":10035,"he":43730,"ha":50953,"gn":13137,"gm":84581,"gl":15240,"bą":7905,"gi":77017,"gh":5124,"gu":37274,"gr":81461,"go":201815,"du":56828,"dw":18508,"dy":56165,"dz":249442,"g ":46202,"ea":22981,"eb":20189,"ec":208980,"ed":135395,"de":106238,"dd":7144,"di":38677,"dk":20908,"dm":14590,"dl":41406,"do":162506,"dn":125390,"dp":5891,"ds":17240,"dr":43512,"ew":111327,"eu":15671,"ev":5608,"ey":6513,"ez":85170,"fa":15386,"h ":260015,"fe":16025,"eg":232853,"ef":12705,"ee":8458,"el":150281,"ek":109837,"ej":291522,"ei":21799,"ep":45340,"eo":16834,"en":264211,"em":150465,"et":92062,"es":172911,"er":319668,"ca":105725,"e ":876959,"by":41730,"bs":19604,"br":47012,"bu":41705,"bn":8407,"bo":39861,"bl":23444,"bi":69531,"be":48450,"dc":10689,"db":7638,"da":129820,"f ":12810,"cz":335815,"cy":107837,"cu":14533,"ct":15111,"co":51690,"cn":22110,"ck":80920,"ci":275500,"cj":115414,"ch":414464,"ce":179393,"c ":34764,"az":93181,"ay":6838,"ba":43868,"d ":139962,"at":193861,"as":161357,"ar":314898,"aw":119971,"av":7852,"au":36829,"ak":99776,"al":185695,"ai":24623,"aj":148717,"ap":33608,"am":123297,"an":453452,"ac":219676,"ad":149992,"ab":34080,"ag":38473,"ah":5887,"ae":10185,"af":22452,"nu":23194,"nt":96712,"ns":36134,"nr":4954,"no":152706,"nn":38516,"ny":249928,"oe":4808,"of":20662,"oc":101234,"od":293823,"oa":8273,"ob":82692,"ię":123546,"om":108472,"on":318937,"ok":137945,"ol":232069,"oi":39360,"ją":114675,"oj":102542,"og":59938,"oh":7680,"ot":70221,"os":163642,"ov":6489,"ou":18871,"op":86592,"oo":8474,"or":254276,"ję":19551,"r ":119247,"ow":537395,"kó":27850,"oz":62053,"pe":42396,"pa":107114,"pc":8415,"pl":33619,"pn":11150,"po":424408,"ph":5594,"ił":21358,"pi":86460,"ką":16568,"iń":19637,"lo":81679,"ln":79071,"lm":9683,"ll":32626,"ls":113022,"hó":9384,"lu":76951,"lt":13727,"o ":461084,"dź":5330,"eś":75573,"mc":10115,"ma":121066,"mb":17385,"me":89660,"mi":333776,"mn":11655,"mm":6313,"mp":24445,"mo":86555,"ms":11588,"mu":41658,"ió":8421,"my":18150,"p ":18753,"na":529472,"nb":5437,"nc":75955,"nd":63112,"ne":249253,"eż":40953,"nf":7374,"ng":54651,"gł":47489,"ni":692138,"ią":60315,"nk":45573,"jw":6916,"ju":20103,"js":79998,"jn":43747,"jo":26898,"jm":12943,"dł":15854,"ki":412466,"ke":10550,"kc":19574,"ka":229229,"m ":343638,"kw":12402,"gó":15509,"ks":37081,"kt":82034,"ku":103176,"ko":241820,"kr":97482,"kl":22672,"km":9933,"eł":15052,"li":209435,"eń":19329,"lk":31238,"le":182455,"ld":11857,"lg":4525,"la":173548,"lc":6468,"lb":16636,"n ":138864,"hr":17682,"dó":7283,"ht":5694,"hu":10241,"cą":8049,"ań":46393,"ał":115023,"hi":35646,"hn":15999,"ho":81700,"id":59864,"ic":201937,"aś":6694,"ib":17573,"ia":315115,"ig":21890,"if":5037,"ie":1136068,"hy":6565,"k ":111343,"ir":31982,"is":139600,"it":68750,"iu":39428,"iv":6169,"iw":23202,"ii":58678,"ij":14562,"dą":5425,"ik":74901,"il":54561,"im":169852,"in":280897,"io":133204,"ip":17035,"aź":5844,"jc":7619,"aż":13250,"je":192771,"jd":20070,"ji":76024,"iz":35250,"l ":52041,"ja":94283,"są":9617,"tó":52700,"wz":9495,"wy":175884,"só":9957,"rę":14692,"z ":208589,"oż":86148,"wi":428233,"pł":15785,"rą":23256,"wk":11864,"wn":80692,"wo":213117,"wr":13531,"ws":100565,"wu":6452,"ró":58140,"y ":457874,"wa":271461,"oś":108251,"wc":28885,"we":125766,"oń":26624,"oł":121062,"vi":10565,"uz":15301,"uw":4835,"ve":14040,"va":7846,"x ":7519,"ui":5984,"uj":65669,"uk":36207,"ul":35319,"ue":10441,"ug":25222,"ur":117881,"us":71220,"ut":47463,"um":45758,"un":53367,"up":30095,"ty":157784,"tz":6072,"tu":85903,"tt":12443,"pó":31075,"tw":127984,"ub":63557,"ua":10045,"ud":56663,"uc":35683,"w ":734288,"to":228890,"tn":41685,"tl":10672,"ts":8380,"tr":134088,"te":190777,"kż":7374,"tk":33051,"ti":40445,"th":19993,"nę":6037,"ta":271329,"su":26228,"ss":16223,"st":440956,"sy":40789,"sz":185716,"sw":7100,"sl":4597,"sk":362869,"sn":10482,"sm":8241,"sp":72745,"so":57024,"sc":108490,"se":50637,"sh":8501,"ną":21831,"sj":10343,"si":154595,"rz":330244,"u ":285894,"mę":6084,"sa":75170,"rr":8977,"rs":83617,"rt":71318,"ru":79284,"nó":11750,"rw":35761,"ry":128901,"rp":13436,"ro":332963,"rn":56890,"rm":40806,"rl":14366,"rk":29749,"ri":79907,"kł":24507,"rg":38504,"rf":5604,"re":197175,"iż":7681,"rd":33902,"rc":41834,"jś":4511,"rb":12273,"ra":338168,"t ":152714,"lę":5780,"mó":8836,"lą":12242,"s ":109715,"kę":4736,"py":18332,"pt":9892,"pu":38310,"pr":207712,"ps":10578,"ył":33312,"yń":8163,"zą":41404,"zę":35066,"uż":24054,"wł":15632,"zó":6325,"wę":7097,"uł":11203,"wą":11216,"wó":72388,"zg":11821,"zi":142936,"sł":33435,"zb":26540,"zc":34117,"zd":18869,"ze":326759,"tę":19569,"za":220009,"yz":12669,"zw":54934,"zy":216261,"zr":6357,"zu":31373,"zt":75735,"zo":93735,"zn":149848,"zp":13878,"zk":54785,"zj":15781,"zm":18594,"zl":6622,"yg":10175,"yf":6219,"yc":219665,"yd":32633,"yb":20679,"yw":52492,"yt":47612,"ys":92766,"yr":14041,"yp":20913,"yn":66941,"ym":103256,"yl":20573,"yk":74193,"yj":45803,"tą":4964,"yż":9849,"yś":4897,"zł":13341,"ów":161116,"ób":6381,"ój":5872,"ód":78413,"óc":5492,"ór":65730,"ól":16369,"ć ":59245,"ąd":23612,"ąc":135745,"ą ":117382,"óż":8608,"ół":34199,"ęb":8256,"ęc":19527,"ęd":32895,"ęg":11685,"ęk":11873,"ęp":16514,"ęt":22906,"ęs":9306,"ę ":96973,"ęz":11858,"ęś":18258,"ęż":7758,"ąg":22092,"ąs":12009,"ąt":12097,"ąz":17763,"ąż":21246,"ł ":59292,"łu":50120,"łt":4875,"ły":40224,"łk":15386,"łn":20167,"ło":189649,"łe":22223,"łc":7515,"ń ":16610,"ła":119873,"ńs":75332,"ńc":31072,"łó":33659,"śl":22153,"śn":19502,"śr":30296,"św":24072,"śc":92180,"Św":8984,"ś ":45778,"ść":40444,"łę":5560,"łą":10057,"źn":6441,"źd":5042,"ż ":20942,"żu":6315,"ży":40208,"żo":72896,"żn":19632,"żs":5910,"że":31935,"ża":27767,"żą":12050,"ąża":15191,"ęci":10430,"ędz":16930,"ędu":4976,"ęzy":9477,"ępu":8551,"ęks":6674,"ęst":6004,"łec":8332,"ła ":38802,"łan":5477,"ład":27517,"łac":9469,"ław":16966,"łas":4900,"łoż":68106,"łoś":19952,"ły ":21321,"ływ":5534,"łu ":9627,"łoń":16090,"łud":14450,"ług":11020,"łow":21447,"łos":9246,"łon":8256,"łno":15191,"łod":6015,"łka":8122,"ło ":21533," Ga":8827," Ge":5971," I ":4633," Fo":4786," Fr":25744," Fi":5918," Ha":11737," He":11280," Go":7898," Gr":14678,"ńcó":5655," Gm":6328," Ho":9424," II":9642," Hi":5632," Je":18244," Ja":16067," In":12303," Ka":25219," Ki":5713," Jo":8117," La":13845," Le":13833," Li":15290," Ko":31759," Kr":17816," Ku":5884," Gó":8232," Ma":41192," Mi":29080," Me":12575," NG":5574," Lo":10195," Lu":9428," Ne":6981," Na":24184," Ni":19681," Mo":18451," Mu":5268," Am":7370," An":13699," Al":15025," Ba":23126," Au":8090," Ar":11761," Be":12343," Bi":14133," Bo":15194," Br":16331," Bu":9050," Ca":12220," Ce":7873,"ńcz":4853," Ci":4561," Ch":21239," Co":11557," Cz":10255,"ńce":15534," Da":8706," Di":5639," De":9843," Dr":5105," Do":16986," Du":4568," Eu":8764," Fe":4580," Wy":14786," Ws":4674," Wo":12135," Wi":28155," We":8391," Wa":15970," Sł":20157," Za":17851," a ":33564," Os":6455," Or":5834," Po":99137," Pi":15394," Pe":7708," Pa":33893," No":17025," Ol":5468," Od":7369," PG":4658," Ob":6845," Ra":13288," Ro":19091," Re":17774," Pr":25548," Pu":5949," Sz":17219," Sy":6223," Su":6907," St":33766," Ta":10078," Th":7821," Te":9806," Tr":10135,"ńst":9625," To":9099,"ńsk":65260," Ru":5052," Sa":22468," Rz":5260," Si":11239," Sc":7241," Se":13251," So":10324," Sp":6969," Sk":5318," Vi":4980," Tu":5482," W ":13679," Un":6885," ja":24161," je":81709," im":8378," in":25684," is":7255," ka":27845," ki":9981," gw":7366," j ":15130," ha":5671," he":5463," gm":81906," gr":42165," go":8008," hi":10476," hr":4991," gł":25015," ni":54044," na":181345," mu":9539," mo":21735," ok":44273," on":4611," og":5234," od":78508," of":7838," ob":36134," no":11764," le":15807," li":34396," la":36395," ku":10205," kt":33550," ks":6999," kw":7071," km":9336," kl":10638," kr":29471," ko":64410," me":15598," mi":86248," o ":18463," ma":52176," lu":42219," lo":7327," ad":8368," am":10571," an":21235," ak":7205," al":15945," au":9619," ar":12965," as":16623," ba":14299," bi":14788," be":7689," bo":7340," by":20334," bu":7038," br":13094,"łuż":7054," ca":5242," el":9782," fa":6215," fu":5153," fr":6875," fo":9292," fi":17828," ge":6292," ga":16786," i ":123913," co":7528," ce":14033," ch":18489," ci":24028," da":17665," cy":4833," cz":55270," do":83523," dn":7531," dl":8990," dr":18598," de":38500," di":6649," dw":10226," du":6950," dz":27524," dy":8440," zm":8262," zo":12577," zn":26389," zw":23230," za":89284," zd":5616," ze":19904," zb":9872," zi":4717," sł":12543," są":8630," z ":107756," wy":79384," wz":8136," wł":13150," uż":7103," ru":4802," ry":6135," rz":19343," sa":14213," se":14117," si":84234," sk":26716," sp":31645," so":11139," ra":15542," re":46718," ro":89060," pu":7297," pr":169964," os":21891," ot":4775," op":16859," or":30563," r ":7257," ję":8026," oz":4712," pe":8239," pa":50520," pl":22703," po":329900," pi":36353," wa":17275," we":29944," wc":10065," ró":17486," wr":10056," wo":81271," ws":27715," wi":85470," pł":9284," w ":591873," ty":20926," tw":5981," pó":15190," tu":7399," us":6046," ut":8073," ur":32556," uk":7357," ul":5488," ta":20050," sw":5466," sz":26144," sy":14406," st":72132," su":7093," tr":22707," to":40581," th":4944," te":42334,"łów":28362," ła":6906,"łąc":7474," Św":8979," śr":24528," św":19258," że":5562," ży":7572,"GC ":12479,"Eur":7453,"Fra":21145,"II ":13664,"Her":4920,"Gra":4795,"Gmi":6178,"Bar":4693,"Bra":4520,"Cha":6684,"Dol":5831,"Nie":14925,"Now":7712,"Nor":6043,"PGC":4549,"Pie":5284,"Par":14525,"Poł":4889,"Pro":6911,"Prz":9834,"Pod":4669,"Pol":63410,"Pow":4846,"Rad":5296,"Jan":4677,"Jes":5251,"Kar":5182,"Kon":5190,"Kra":7526,"Koś":5328,"Gór":8184,"NGC":5540,"Mar":15306,"Mon":4650,"Mie":5310,"Mis":5057,"Wys":5223,"Wie":13213,"War":8050,"Sło":18142,"Str":5084,"Sta":19220,"Sie":4994,"Sai":4713,"Sch":5152,"Ros":4617,"Uni":6296,"The":5470,"bio":14193,"bli":16339,"bor":8274,"bow":6707,"bar":9707,"bec":8656,"ber":14109,"bel":6901,"bez":6239,"bia":7547,"bie":21077,"ca ":84053,"cac":4624,"był":19691,"ce ":116313,"bro":10887,"bra":11568,"bry":5366,"brz":9909,"bsz":5466,"bst":6710,"bur":11294,"bum":8181,"bud":9663,"by ":10708,"aka":5857,"am ":8178,"akc":4640,"aki":8717,"ajo":5413,"ajm":4898,"ajw":6681,"aju":12289,"al ":15001,"aja":6999,"ajd":19542,"aje":5093,"ain":11213,"ak ":12839,"aj ":9008,"agr":6880,"ago":6833,"ają":56423,"anu":7044,"any":57351,"ano":19191,"ann":5995,"ant":15544,"ans":10106,"ane":52267,"ang":21057,"ani":105534,"ank":9718,"ana":52659,"anc":30280,"and":28542,"amo":13297,"amp":4556,"ami":37349,"ame":32849,"ama":9031,"alo":8151,"aln":38047,"all":6281,"ali":35299,"ale":28164,"ala":17506,"alb":10365,"an ":25897,"akt":18470,"ako":21085,"abi":5944,"abs":7005,"ae ":4965,"ad ":24951,"ac ":5802,"afi":15590,"aga":5833,"ado":9262,"adm":7603,"adi":7361,"ade":12127,"ady":8896,"adz":20389,"ack":10335,"acj":42190,"aci":10932,"ach":91172,"ada":31955,"acz":24570,"acy":17521,"azo":11989,"azu":9191,"azw":14194,"aza":4626,"azd":9097,"azy":7482,"az ":24099,"ba ":9607,"at ":32096,"are":9332,"ard":17168,"arc":24556,"ara":29532,"aro":21478,"arn":16904,"arm":8931,"arl":5792,"ark":13034,"ari":18485,"aru":4729,"anó":4796,"ars":25559,"art":41017,"asa":22529,"ary":12822,"arz":32133,"asi":8550,"aso":5103,"ask":9308,"ar ":9731,"api":8704,"apo":6161,"as ":15649,"aut":8273,"awa":20666,"aws":12931,"awn":15933,"awo":12547,"awi":30734,"asz":13814,"ata":29924,"ść ":40186,"ast":57235,"asy":6947,"atk":6138,"atr":8063,"ato":27910,"ate":18972,"akż":7374,"ati":9455,"aw ":7482,"atu":20800,"aty":21623,"auk":5346,"Świ":8845,"ści":91962,"śni":16799,"śli":5074,"śro":7633,"śre":20628,"ślą":5357,"świ":21339,"jeg":6331,"jej":4751,"jed":34575,"jen":6642,"jew":58578,"jes":38109,"ji ":74801,"jal":7148,"jak":18567,"jaw":9057,"aźd":4510,"je ":30364,"jdu":17294,"jmu":7356,"jna":5939,"jny":19293,"jne":11196,"jow":13446,"jon":8504,"ito":6446,"ity":14838,"isk":17265,"ist":59047,"isz":10261,"ita":8740,"ite":12873,"iwe":4858,"iwi":4661,"ius":4598,"ium":6118,"is ":13674,"ion":48352,"iop":4645,"ior":18228,"ios":6430,"iot":6025,"ipc":5025,"ikó":5855,"iow":26535,"isi":4518,"isa":8456,"iu ":24955,"ire":4546,"ira":6326,"ja ":38334,"izy":4891,"izo":6649,"izm":4986,"iza":9287,"kim":128411,"kic":24931,"kie":126958,"dłu":9193,"km ":8293,"ki ":116429,"kań":16086,"kcj":11696,"kra":24036,"kre":18070,"kry":8710,"krz":7284,"ku ":72509,"kro":6037,"kow":64383,"kos":4831,"kor":8298,"kop":10012,"kon":28370,"kom":18077,"kol":18048,"kok":4910,"klu":5529,"ko ":39683,"kle":4640,"kla":7237,"jsk":40065,"jsz":8170,"ju ":15477,"jsc":28565,"kaz":5339,"kat":10533,"kar":21380,"kan":15572,"kal":9168,"kam":6459,"kad":5909,"kac":12564,"ka ":110422,"ha ":5601,"han":8170,"har":13309,"he ":11732,"her":6722,"ał ":24279,"cą ":7445,"ań ":4989,"ałe":8027,"ała":29091,"ało":22494,"his":8897,"ały":11839,"ańc":7994,"ańs":33252,"go ":160963,"god":4635,"gni":4919,"gmi":81864,"gos":5577,"gor":5388,"gow":8194,"gu ":24037,"gro":9171,"grz":5388,"gry":6845,"gru":20718,"gra":31694,"gwi":7275,"ców":11188,"iaj":4940,"iam":4548,"ial":8076,"ian":22005,"ias":25407,"iar":9378,"iat":20282,"ic ":6481,"iac":9488,"iad":9916,"iaz":7546,"id ":16421,"ia ":151774,"iet":14221,"iew":12649,"iel":59211,"iem":53337,"ien":34053,"ier":72550,"ies":27602,"ied":28632,"ieg":53169,"iek":15875,"iej":135012,"iec":108952,"icy":13868,"ict":6284,"icj":4509,"ick":18455,"ici":5695,"ich":42480,"ice":16432,"ie ":425948,"ica":18194,"ide":5884,"ida":21189,"icz":59703,"ijs":6419,"im ":137877,"ika":22144,"ii ":57658,"ibą":4979,"iał":33757,"ik ":16857,"imp":4698,"imi":11049,"inc":8772,"ind":7280,"ina":57100,"inn":9746,"ino":8623,"int":11381,"ins":5688,"ine":11157,"ież":14661,"ing":19340,"ini":80940,"iny":19314,"iko":7564,"iki":9122,"in ":24060,"ilo":5237,"ill":10795,"ień":7511,"ilm":5161,"ili":7909,"ieś":51901,"io ":7198,"how":11191,"hol":4719,"hor":6372,"hod":42292,"hni":9648,"hra":5522,"dów":6742,"fia":9588,"ewó":56727,"ez ":38609,"ews":7573,"eze":8964,"ezi":7185,"ezj":6360,"eta":10069,"etn":9079,"esp":11621,"eso":4594,"est":61386,"esz":24722,"eto":22583,"etr":10559,"ety":8345,"ew ":5885,"ewi":12221,"ewo":9270,"ewn":8260,"ewa":5038,"er ":34400,"epa":15408,"eją":6188,"es ":24102,"epu":5035,"epr":8058,"eri":17872,"erg":8537,"ere":16329,"erc":5702,"era":33404,"erb":5967,"et ":10917,"esk":6857,"esi":11275,"esa":4705,"erz":21989,"ery":23381,"eru":5751,"erw":27139,"ert":7815,"ers":24326,"ern":18633,"erm":6952,"erp":6669,"ero":30451,"eki":4817,"eko":5980,"eks":10430,"ekt":18859,"eku":6941,"en ":29550,"ela":11200,"ele":25422,"eli":15142,"eln":10771,"elk":19485,"ell":8172,"elo":10644,"elu":7577,"els":11724,"emc":9224,"ema":7081,"eme":7011,"emo":5689,"emi":25674,"ene":12261,"ena":8388,"end":7106,"enc":29197,"eno":4952,"enn":11782,"enk":5319,"eni":82488,"egł":18236,"ens":6693,"ent":47936,"ego":161252,"egi":24719,"ej ":196844,"egu":4666,"ek ":37209,"ein":6239,"el ":16434,"ejs":51321,"ejo":11481,"ejm":7156,"eje":7376,"eka":10766,"em ":73512,"gio":21748,"gie":12191,"gic":6767,"gii":7756,"gia":4982,"bą ":6293,"gi ":9182,"gen":12957,"gel":5153,"gar":6319,"gat":9377,"gaj":4881,"gal":8113,"gan":14815,"ga ":14947,"fun":4925,"fra":5853,"for":16996,"fic":8573,"fil":7378,"fik":6148,"ać ":7866,"czą":12269,"da ":43439,"czł":5966,"de ":15481,"dby":5063,"czę":22437,"dal":5635,"daj":6034,"dar":8045,"dan":24834,"daw":15145,"dcz":6407,"ctw":8655,"cy ":54622,"cus":4654,"cym":5360,"cyj":21911,"cyc":12366,"cz ":10143,"czy":47263,"czk":8277,"czn":94844,"czo":18714,"cza":38835,"cze":61835,"cki":56501,"chó":9144,"co ":6133,"cni":7419,"cią":23459,"cne":4800,"cny":4546,"cow":30428,"cję":4623,"cez":4969,"ch ":250098,"cer":7119,"ces":6923,"cen":13171,"cej":5254,"cel":7686,"ceg":6128,"ci ":63750,"cha":21398,"cia":18501,"cie":119729,"che":16574,"chi":12341,"cho":63783,"chn":12122,"chr":6017,"ciw":5743,"cja":35582,"ciu":5042,"cin":7038,"cio":9246,"cka":9993,"cji":61836,"ed ":7038,"ebi":5142,"ec ":12319,"dzą":8566,"ega":9608,"edl":5574,"edn":51333,"ede":12015,"eda":5582,"edz":17029,"edy":9486,"eds":6095,"ecj":5624,"eck":33379,"ech":31282,"eci":73659,"ece":7263,"ecz":26497,"ect":5183,"ecn":7076,"dyn":9974,"dys":5848,"dyc":5708,"dy ":20176,"dzy":15488,"dzt":56173,"dzo":7609,"dzk":13570,"dzi":114188,"dze":17343,"dza":11866,"dor":6162,"dom":7183,"dol":8096,"dok":4665,"doz":5829,"dow":41632,"dos":5363,"dmi":12552,"dna":7598,"dne":6153,"dni":85396,"dno":17791,"dny":5925,"dob":7583,"dst":8461,"duj":19180,"duk":7030,"dra":4842,"drz":4777,"du ":16409,"dro":12893,"dru":8195,"dia":9387,"der":13407,"del":4853,"dek":8141,"den":21584,"dem":8020,"dep":15043,"dle":22301,"dla":14281,"dko":7298,"do ":56353,"dio":7032,"die":6315,"rga":13673,"rgi":6819,"ret":5375,"res":16392,"rez":11929,"rg ":8389,"rdz":8372,"rea":6346,"rec":6681,"red":24223,"rej":11845,"reg":27968,"rem":8867,"ren":18517,"rek":5432,"rep":5124,"rcz":7138,"re ":17858,"rci":7329,"rch":9881,"rce":4547,"rca":6614,"raw":21807,"raz":29604,"rd ":6953,"ras":7862,"rat":14245,"raj":22570,"rai":5724,"ran":52894,"ram":15553,"ral":18585,"rak":14728,"rab":9860,"raf":17050,"rad":12311,"rac":33149,"rpn":4743,"ros":15610,"rot":7718,"rom":11621,"ron":23271,"rop":15650,"roz":22873,"row":46481,"rob":7374,"rod":59324,"roc":14309,"roj":6342,"roi":15518,"rol":7056,"rok":41872,"rog":11103,"rno":5279,"rny":6200,"rna":10748,"rne":9659,"rni":18640,"ro ":7330,"rma":13967,"reś":7847,"rmi":12636,"rla":5043,"rki":6506,"rka":6181,"riu":5278,"rii":14143,"rin":4886,"ria":19003,"kła":22407,"ric":4906,"rie":5586,"rwo":5268,"rws":10740,"nów":11177,"rz ":14438,"ryb":4752,"ryc":13818,"rug":6274,"rud":6357,"ruc":5354,"rup":16289,"run":6993,"rum":5890,"ruk":5290,"rus":7391,"rwa":7707,"rwc":4554,"ry ":30832,"rsk":40769,"rsz":11669,"rta":19705,"rst":9077,"rto":10205,"rte":6255,"rti":6031,"rtu":4870,"rty":7882,"rt ":8136,"ru ":8305,"rzę":9880,"sad":8969,"sam":12218,"san":8261,"sar":4951,"sa ":26422,"rzą":15714,"rze":166268,"rza":14480,"rzc":6541,"ryw":7519,"rys":7800,"ryt":14172,"ryk":17536,"rym":6312,"ryn":5422,"rzy":76075,"rzo":14189,"ną ":19254,"si ":6951,"sie":37561,"sia":7216,"sk ":6051,"sin":6607,"se ":4707,"sce":55140,"sch":21250,"sco":24974,"ser":11407,"sen":9224,"spo":28928,"spr":6284,"spe":6485,"spi":8532,"sow":15205,"son":7183,"sok":5885,"się":66198,"sob":7483,"su ":8612,"skł":11877,"st ":49786,"ski":241685,"sko":33991,"skr":5762,"sku":9283,"ska":44791,"sią":6562,"sz ":5749,"syn":5333,"sys":6083,"sza":29086,"stę":16122,"sze":30322,"szc":22167,"szp":5112,"szo":8648,"szt":14601,"szk":19152,"szy":32568,"ste":40839,"sta":110434,"stn":10874,"sto":55229,"sti":7248,"stk":11925,"stu":7827,"spó":13799,"stw":35135,"str":55283,"sty":30683,"sy ":5848,"tak":16147,"tal":13415,"tac":30341,"tad":4771,"taw":14561,"tat":11340,"tar":27950,"tan":40782,"tam":18213,"te ":12262,"ta ":47407,"jęz":8303,"pa ":7030,"ową":6832,"ję ":5820,"pca":4745,"par":31402,"pas":19500,"pac":4930,"pad":8610,"pal":4646,"pan":7407,"ką ":14644,"pań":7582,"pec":4830,"per":13425,"pej":4544,"pla":21906,"ple":4628,"ińs":18739,"pie":29091,"iłk":7468,"pio":5728,"pir":4743,"pis":14610,"poz":13437,"pow":94565,"por":15922,"pop":9036,"pot":7235,"pos":20600,"poj":4594,"pom":22714,"pon":6930,"pok":5372,"pol":56274,"poc":15903,"pod":44935,"pił":8661,"po ":9878,"pni":8916,"pub":6917,"pra":25179,"prz":116916,"pu ":5270,"pre":13822,"pro":44748,"put":4642,"puj":8407,"poł":82723,"py ":16720,"ląs":7826,"mów":5303,"ra ":38610,"ngi":4912,"ni ":23063,"nge":9484,"ią ":10996,"neg":51936,"nej":47963,"nek":13069,"nem":5441,"ner":9906,"net":21971,"nes":4536,"ndy":5147,"ng ":20546,"eży":7778,"nci":16716,"ncj":34860,"nce":9629,"ne ":77120,"eż ":13347,"ndr":6665,"ndo":5824,"ndi":8916,"nde":9089,"nda":6965,"nak":5404,"nal":20391,"nam":4778,"nan":15192,"nap":5117,"nar":14632,"nac":26022,"nad":18221,"nag":7300,"naj":37748,"nd ":10560,"nau":6824,"nat":12135,"nas":8986,"naz":14802,"naw":6217,"na ":315412,"moż":6857,"nyc":66044,"ny ":143123,"noś":21837,"nty":9827,"nto":7930,"ntu":6194,"ntr":10458,"nta":17677,"nte":16419,"nst":10393,"nu ":12191,"nt ":17005,"ns ":4556,"noc":23507,"nom":6299,"nos":13706,"nor":4839,"now":33236,"nne":10038,"nna":4663,"nni":6637,"nię":6603,"nny":11159,"głó":21438,"no ":23520,"nki":7495,"nkc":4543,"nka":8221,"nku":6543,"nko":6939,"eżą":8181,"iąg":20115,"iąz":16848,"nii":15486,"nie":303754,"nic":58316,"nia":115515,"niz":10946,"niu":18651,"nis":21291,"nio":33347,"gło":21325,"nim":8023,"nin":5902,"nik":44866,"ogr":14773,"ogi":15434,"ogo":4557,"oga":7462,"ją ":20069,"oid":31094,"ok ":8415,"ojs":6215,"ojn":8775,"oje":68149,"jąc":92228,"oce":7209,"och":19137,"oci":8093,"ock":7255,"ocn":14524,"obs":6969,"oby":5467,"ode":8229,"odk":11049,"odl":22987,"odo":21990,"odp":5300,"odn":35244,"ods":5690,"odr":4605,"ocz":25360,"of ":6324,"odc":6738,"odb":6509,"oda":13640,"odz":61637,"ody":9005,"odu":13447,"ofi":6001,"ięk":9725,"ięc":10576,"ięd":13216,"ięt":12440,"od ":47389,"obo":8696,"obr":12863,"obl":4516,"obn":4740,"obi":10703,"obe":11907,"nym":35914,"ię ":65182,"owy":75588,"osó":4510,"ków":24138,"ows":40460,"own":11322,"owo":53873,"owi":138750,"ozy":6621,"ozw":5341,"ozn":9119,"osł":6618,"ozb":6448,"oty":9500,"ote":7310,"otr":5518,"oto":11888,"otn":8681,"osz":15296,"ost":51897,"ota":6378,"osi":14132,"osk":7450,"ose":9237,"osp":5848,"oso":13740,"oró":5598,"owc":6201,"owa":124010,"owe":69144,"opo":27225,"opi":9321,"ope":10070,"opa":11132,"os ":8863,"opu":5185,"opr":8595,"or ":15758,"ork":4605,"orm":16889,"orn":6157,"oro":17951,"orc":4621,"ord":8495,"ore":9264,"org":11803,"ori":12364,"osa":8380,"ort":15205,"ors":22187,"oru":7711,"orz":34348,"ory":13310,"ora":31522,"ola":10017,"on ":32944,"oli":42609,"ole":26115,"ols":92465,"oln":14866,"olo":22365,"olu":5605,"oka":12522,"om ":7335,"oki":5566,"okr":39604,"oko":19282,"ogó":4810,"oku":40113,"ona":86386,"ond":4877,"one":29526,"oni":52759,"onk":6206,"onn":4626,"ono":16680,"ons":8848,"ont":10876,"onu":6969,"ony":38958,"oma":14351,"ome":9149,"omi":22956,"omp":9870,"omo":23578,"omu":5636,"la ":29248,"le ":27634,"lac":9698,"lak":7036,"lan":38327,"lam":5773,"lar":10967,"lat":37023,"las":14320,"ld ":4729,"lbu":8442,"koł":12944,"kul":5213,"kuj":7417,"kwi":7243,"krą":16281,"koś":9426,"kró":6396,"kte":5141,"ksz":11351,"ksi":5778,"kty":11231,"ktr":5362,"ktu":7021,"kto":8566,"krę":7083,"gól":4564,"gór":7545,"któ":37445,"lok":4711,"lon":16670,"log":15244,"lot":5895,"low":11925,"lno":13692,"lni":16273,"leż":15711,"lne":15681,"lny":18798,"lna":11882,"lud":5047,"lub":38824,"lsk":52175,"lu ":15294,"lsc":50391,"li ":18475,"lew":7878,"les":10216,"let":6569,"ler":6678,"lem":11032,"len":14544,"lek":14961,"lej":10577,"leg":25572,"lec":7985,"lla":5033,"lle":8878,"lli":5642,"lko":12509,"eńs":10006,"lka":5102,"lki":9010,"ll ":4740,"lit":23937,"lis":17192,"lip":7716,"lin":28801,"lim":6337,"liz":9545,"liw":7216,"lic":38891,"lia":7515,"eń ":8305,"lik":8729,"lii":5868,"ma ":13583,"mac":9833,"eś ":42823,"maj":8752,"mar":13792,"mas":6086,"mal":6141,"man":12874,"maz":13085,"mat":15538,"me ":5269,"eśc":9065,"eśn":12795,"eśl":8074,"mcz":8811,"met":12557,"mer":18450,"men":33777,"lut":5364,"hód":6854,"mpi":5561,"miń":6040,"moc":8677,"mod":4841,"mon":7419,"mow":13205,"mor":22691,"mu ":12663,"msk":7954,"my ":8132,"muj":8914,"mun":5245,"muz":6245,"mał":6431,"mi ":36519,"min":109517,"mis":7482,"mit":5081,"mic":8508,"mia":35513,"mie":85656,"mię":17160,"mni":5567,"wą ":9465,"wód":59175,"wór":6020,"źdz":4969,"zta":5990,"ztw":56537,"zu ":8060,"zuj":5309,"zur":6895,"zy ":52536,"zwa":16748,"zwi":19757,"zwy":6194,"zyw":7464,"zys":27664,"zym":15419,"zyn":18487,"zyk":17972,"zyl":5653,"zyj":5225,"zyc":26077,"zyd":4698,"zył":4808,"zi ":13438,"zał":9317,"zgr":4705,"zec":34126,"zed":16305,"zeg":13280,"zej":12005,"zeb":5093,"zdo":9053,"zes":26033,"zez":38687,"zew":14699,"zen":40191,"zem":9711,"zel":6475,"zek":13631,"zer":16763,"ze ":43444,"zch":5824,"zbi":11943,"zcz":25210,"zac":28997,"zaw":17852,"zaj":18917,"zam":9131,"zan":18287,"zak":6986,"zal":7485,"zar":15092,"zap":6541,"zas":21035,"zny":34365,"zos":17618,"zon":31868,"zow":26765,"zpo":4827,"ześ":12448,"zmi":5909,"zna":56249,"zno":5266,"zne":31393,"zni":17047,"zm ":5171,"zka":12896,"zko":15029,"zki":16987,"zeń":5484,"zib":8100,"zia":21275,"sła":11498,"zie":58529,"zin":14757,"sło":8768,"zio":8015,"słu":9392,"zja":5084,"zji":8382,"yty":7484,"ytu":9487,"yto":6663,"źni":4961,"yte":4862,"yta":5297,"ysz":7085,"yst":44231,"yso":5982,"ysp":7012,"ysk":11600,"tęp":15379,"za ":37664,"yzn":5243,"ywa":26508,"ywi":7128,"ywn":5067,"yce":6751,"ych":133947,"yci":10363,"ycz":50193,"yda":15003,"żaj":15742,"yck":5423,"ycj":6652,"że ":16017,"yjs":11565,"yka":23821,"ym ":69059,"yki":7812,"ykl":4610,"yko":9261,"yn ":8183,"yli":7761,"ymi":14584,"yms":4916,"yna":17425,"yni":13954,"yno":4822,"żen":5078,"yk ":13655,"yjn":27661,"tów":16736,"tór":35547,"są ":7387,"ożo":65228,"oży":4895,"oże":6845,"wy ":42246,"wsp":8605,"wsz":18473,"wst":10921,"wsc":10075,"wsk":48535,"rąż":16283,"wys":19278,"wym":21711,"wyk":10398,"wyn":5788,"wyd":14033,"wyb":6431,"wyc":28770,"sów":5741,"woś":26886,"wo ":32774,"wna":7537,"wne":21421,"wni":31749,"wią":20802,"wno":4837,"wka":4779,"wrz":6674,"wod":23078,"wię":20120,"wny":9160,"wow":8334,"wor":17209,"wol":5953,"woj":77026,"wcz":7095,"ośl":6671,"wch":7307,"we ":41958,"ośc":57589,"wca":6919,"wer":9502,"wej":33041,"weg":17678,"wed":4775,"wał":10230,"ość":33539,"wi ":5607,"pły":9060,"wis":10022,"wiz":5342,"wie":266248,"wid":6688,"wic":20177,"win":12633,"wia":38637,"wa ":75032,"wan":92067,"wal":11772,"waj":5843,"wat":12396,"war":32065,"wac":6719,"róż":7313,"wad":9110,"rów":28327,"ród":6783,"ról":5670,"oła":8333,"oło":72193,"ołe":8524,"ołu":20038,"ońc":21153,"ver":4892,"uzy":7699,"usk":8960,"usz":14475,"ust":14884,"ute":10402,"utw":6376,"uto":11126,"us ":13666,"ura":9619,"ure":5261,"urg":10533,"uro":16796,"urs":7537,"ury":7673,"urz":9377,"ują":40031,"upa":5160,"ur ":29893,"upy":9651,"umi":4996,"ume":5036,"unk":16732,"uni":8824,"und":6279,"une":6969,"uko":7594,"um ":20351,"uka":4715,"ult":6004,"uli":7259,"ula":8673,"uje":18646,"uja":4953,"ugi":6634,"ucz":7047,"udn":21514,"uch":15770,"udo":10709,"udz":6914,"ub ":30727,"pół":22236,"ubl":8802,"ube":7781,"tyw":7322,"tyj":4614,"tyk":20395,"tyl":6759,"tym":7939,"tyn":8462,"typ":6891,"tys":5969,"tyt":6677,"twó":5271,"ty ":25638,"twa":27679,"tur":19565,"tun":9184,"tyc":48848,"two":26167,"pól":4883,"twi":61091,"tre":5469,"tra":36373,"tri":6420,"tru":11588,"tro":23044,"trz":32044,"tu ":25361,"try":9123,"to ":54716,"tni":28308,"toc":7538,"toi":15874,"tos":10191,"tow":38410,"tom":6513,"ton":10929,"tok":8683,"tol":14627,"tor":34275,"top":9511,"tin":4571,"tio":8819,"tki":10465,"tko":7816,"tka":9207,"tle":5081,"tem":19837,"ten":10208,"tej":7771,"tek":9091,"tel":10074,"kże":7372,"teg":14724,"tec":7568,"ter":68917,"the":6053,"tał":27215,"żąc":10258,"zło":10911,"ył ":11114,"ży ":9032,"zęś":17553,"życ":6860,"yła":8647,"żyn":4577,"żyw":6989,"yły":6907,"yńs":6994,"żni":7269,"żon":68291,"zęd":7177,"zęs":4784,"ższ":5421,"ząd":13275,"ząc":15081,"zą ":5842,"ząt":4518,"uży":12473,"zów":5144,"wła":9785,"óżn":6877,"ół ":8476,"ółn":14744,"ów ":112668,"óra":6553,"óre":15215,"órn":8319,"óry":15904,"ór ":5776,"ówk":5666,"ówn":37744,"ódz":62547,"ód ":10612,"ób ":4595,"óln":9187,"ągu":15768,"ądz":6409,"ącz":8602,"ący":47223,"ące":25280,"ąca":47593,"ązk":9275,"ąza":4528,"ąsk":8772,"ątk":5004},"n_words":[44927968,50956492,36530760],"name":"pl"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/por b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/por new file mode 100644 index 000000000..bbdf3ed0e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/por @@ -0,0 +1 @@ +{"freq":{"D":84998,"E":149956,"F":100967,"G":92106,"A":261572,"B":132089,"C":229572,"L":100908,"M":162595,"N":83569,"O":115743,"H":53006,"I":86169,"J":66643,"K":27233,"U":54108,"T":95611,"W":30243,"V":63770,"Q":7457,"P":198289,"S":200312,"R":102796,"Y":7968,"X":13707,"Z":9504,"f":420930,"g":646820,"d":3123972,"e":5421795,"b":522239,"c":1736812,"a":5855900,"n":2824771,"o":4680584,"l":1547279,"m":2105049,"j":94292,"k":164391,"h":490405,"i":3472398,"w":44026,"v":454134,"u":1899338,"t":2255026,"s":2945228,"r":3035316,"q":191465,"p":1075380,"z":175309,"y":94919,"x":113550,"²":81071,"É":13693,"Á":9519,"í":209507,"ê":67610,"é":451892,"è":5136,"ç":214936,"ã":317848,"â":37738,"á":187832,"à":26465,"ü":5538,"ú":40758,"ô":23605,"õ":33734,"ó":129413," l":122890," m":228220," n":368310," o":307851," h":135081," i":114948," j":44060," k":90787," d":1636882," e":668130," f":265709," g":86172," a":553690," b":90195," c":638137," u":471782," t":166023," v":73530," q":119308," p":552163," s":358148," r":175170," J":65167," K":25787," H":50638," I":64806," N":77349," O":109788," L":96197," M":155484," B":122895," C":211790," A":232527," F":95595," G":81500," D":78496," E":140343," Z":9058," Y":7429," X":9721," S":182999," R":96218," Q":6965," P":187689," W":28455," V":54881," U":50226," T":85637," á":66191," à":25954," é":287636," ú":5989," Á":9484," É":13626,"A ":78627,"Da":9542,"Cu":6462,"Cl":8427,"Co":62457,"Cr":10302,"Ce":12150,"Ch":23975,"Ci":8714,"Ed":5016,"Do":10375,"De":23490,"Di":17511,"GC":5835,"Fe":14358,"Fa":9224,"Eu":7410,"Es":76180,"En":6707,"Em":8917,"El":11312,"Ge":12507,"Ga":11449,"I ":12898,"Fu":6893,"Fr":18796,"Fo":24543,"Fl":6042,"Fi":9055,"C ":14112,"Au":8700,"Ar":20685,"At":7248,"As":11784,"D ":5749,"Ba":33758,"Ag":5894,"Ab":6380,"Ac":5079,"Am":13589,"An":22486,"Al":38766,"Bu":7329,"Br":31392,"Ca":66526,"E ":5464,"Bi":7032,"Be":17271,"Bo":16310,"Le":17360,"Li":18877,"La":20252,"Lu":9478,"Lo":21075,"Me":18166,"NG":5897,"Mi":22675,"O ":59245,"Ma":62167,"Mu":14513,"Mo":23160,"Ni":6791,"Ne":10091,"Na":16341,"P ":5903,"No":30608,"Ol":8785,"Gi":5566,"Gr":19098,"Go":9769,"Gu":13341,"Ha":12782,"He":10653,"II":8816,"Hi":6333,"Ho":11804,"In":21460,"Ja":20297,"Je":5208,"Jo":23876,"Ju":10807,"Ka":6332,"Um":5798,"Un":17690,"Tu":6480,"Tr":12997,"To":12084,"Th":10714,"Ti":5247,"Te":19234,"Ta":10759,"UA":15545,"V ":6036,"St":11159,"Su":24311,"Wi":7399,"Sã":16301,"Wa":7041,"Vi":19753,"Va":11369,"Ve":14368,"Pr":23453,"S ":9133,"Pe":21497,"Pa":48708,"Pl":5522,"Po":57527,"Pi":15167,"Os":8721,"Or":9792,"Se":27899,"Sc":6387,"Si":12578,"Sh":5677,"So":14955,"Sa":39239,"Re":33199,"Ri":19155,"Ro":19693,"Qu":6140,"T ":5229,"Ra":8949,"b ":50847,"a ":2181662,"i ":168232,"ge":70306,"ga":87148,"bé":16913,"fl":8986,"fi":74478,"fr":59032,"fu":27785,"fo":117850,"dá":5256,"he":73854,"ha":210111,"gn":21302,"cê":5480,"gl":18191,"cç":8441,"gi":116568,"gh":7414,"gu":120239,"gr":61974,"cí":25911,"go":74169,"du":48733,"g ":26553,"ea":109055,"eb":27192,"ec":114155,"ed":73900,"de":1384296,"di":203085,"dm":36748,"do":671969,"ds":6146,"dr":29810,"ew":5596,"ex":56960,"eu":52678,"ev":46416,"ey":9665,"ez":25288,"fa":47754,"h ":22234,"fe":50703,"eg":161615,"ef":22289,"ee":12045,"el":215678,"aç":106998,"ej":12312,"ei":173784,"ep":64753,"eo":27810,"en":615409,"em":301673,"et":118849,"es":604827,"er":508227,"eq":14954,"aí":13564,"ca":322979,"e ":2017914,"bs":7191,"br":100433,"bu":28485,"bo":46844,"bl":22439,"bi":100249,"be":49470,"da":652111,"f ":9921,"cu":52185,"ct":31468,"cr":50241,"co":536282,"ck":15123,"cl":33604,"ci":328384,"ch":65018,"ce":215952,"c ":14270,"az":18902,"ay":13866,"ba":74690,"d ":43293,"at":195898,"as":441529,"ar":395911,"aq":7417,"av":49201,"au":56223,"ak":8531,"al":413966,"ai":134662,"aj":6551,"ao":31258,"ap":60289,"am":235425,"an":557322,"ac":100712,"ad":561485,"ab":137795,"ag":58484,"ah":7769,"ae":25110,"af":14102,"nu":24993,"nt":522402,"ns":188107,"no":344725,"nn":15103,"nz":5976,"ny":7562,"nv":17155,"oe":16285,"of":27077,"oc":103353,"od":80574,"oa":21115,"ob":40172,"om":360608,"on":341990,"ol":141927,"oi":109737,"oj":7341,"og":52000,"oh":5263,"ot":49005,"m²":81019,"os":507875,"ov":77341,"ou":126561,"op":64022,"oo":11470,"or":489375,"r ":303972,"ox":5797,"ow":11301,"oz":5717,"pe":192004,"lá":12510,"pa":207724,"pl":31072,"lé":9270,"lê":6741,"po":262183,"ph":9247,"pi":69522,"lo":175844,"lm":34639,"ll":48668,"ls":10434,"lp":6052,"lv":20781,"lu":42856,"lt":38629,"ly":6623,"o ":2000634,"ma":495019,"mb":74173,"iã":65284,"me":284803,"iá":6420,"iç":26049,"mi":135455,"mm":5698,"mp":92721,"mo":132550,"mu":111484,"p ":8620,"na":437221,"nc":193122,"nd":299787,"ne":119195,"nf":17343,"ng":76996,"nh":95890,"ni":224974,"nj":6755,"nk":6105,"ju":23595,"fí":5753,"jo":21637,"ki":12050,"ke":10814,"ka":8676,"m ":610401,"ko":5815,"gé":5229,"km":88160,"gê":12280,"li":257137,"lh":65430,"le":173629,"ld":17597,"lg":14230,"lf":5772,"la":234272,"lc":7172,"lb":14242,"n ":112737,"ht":6380,"hu":13446,"hi":44146,"dê":5692,"ho":87126,"dé":6382,"id":307392,"ic":326922,"ib":24713,"ia":390572,"ig":76460,"if":27051,"ie":76108,"k ":20205,"ir":178791,"is":322059,"it":260738,"iu":12350,"iv":114919,"ix":17582,"ik":5904,"eç":8830,"il":161901,"im":114838,"in":395415,"io":223313,"ip":55696,"je":12713,"iz":80563,"l ":281164,"ja":26393,"xi":25832,"tê":5442,"xo":8355,"té":18873,"xp":7291,"tí":13967,"tó":26791,"xt":10508,"z ":28371,"xc":16696,"xa":14045,"tã":10541,"tâ":11963,"tá":22795,"xe":8953,"sã":39079,"wi":7047,"sé":18935,"sí":5599,"ró":40309,"y ":44219,"wa":10938,"sá":5639,"ré":9925,"rç":11146,"vi":94338,"rã":8523,"vr":9835,"rí":29707,"rê":8332,"vo":58913,"uz":14799,"ux":5541,"uv":5858,"ve":130840,"rá":18536,"va":112071,"x ":15240,"ui":98859,"uj":5584,"ul":126725,"ue":171782,"ug":35554,"ur":125836,"us":87304,"ut":96190,"um":493013,"un":209874,"up":26206,"ty":5162,"tu":132302,"tt":15069,"pó":5919,"ub":41087,"ua":116112,"ud":26863,"uc":23327,"w ":7530,"pú":7028,"to":326748,"pé":22989,"tl":9288,"ts":8324,"tr":260066,"te":557844,"ti":259190,"th":25055,"ta":456660,"su":99840,"ss":133040,"st":452789,"sl":7670,"sk":8628,"sm":23244,"sp":74972,"so":134893,"sq":6495,"sd":6659,"sc":72024,"se":292294,"sh":13868,"si":227032,"u ":130375,"sa":133204,"sb":7374,"rr":74864,"rs":43158,"rt":193480,"ru":48286,"rv":18129,"ry":9625,"ní":7223,"rq":17132,"rp":10793,"ro":344915,"rn":53960,"rm":73617,"né":7825,"rl":15891,"nç":36309,"rk":7248,"ri":409856,"nã":10618,"rg":47427,"rf":6634,"ná":10363,"re":480208,"rd":53701,"rc":51264,"rb":27665,"ra":596837,"t ":61702,"mú":6929,"qu":189373,"mí":22028,"mé":15139,"má":8216,"mã":9155,"s ":1150995,"pt":9571,"pu":45299,"ló":14756,"lí":26351,"pr":175784,"ps":6678,"zi":14725,"ze":25298,"vá":5473,"za":80538,"zo":10261,"ví":24973,"ya":6552,"ys":5731,"yr":7114,"uí":16711,"uê":10113,"uç":8683,"² ":81055,"É ":12059,"ã ":5975,"ál":15193,"ác":6980,"ád":5021,"áv":6927,"áx":6998,"ár":84913,"át":10444,"ás":9114,"âm":6223,"ân":30468,"ão":308442,"à ":22252,"á ":25281,"ós":7667,"ôm":5559,"ôn":14217,"ói":30866,"óg":6061,"ód":6423,"ór":23808,"óp":8429,"ón":16555,"ól":8310,"ív":5979,"ín":37401,"ím":8935,"íp":23888,"ío":18396,"ít":18007,"ís":21982,"íf":5629,"íl":22187,"íc":11953,"íd":15269,"çõ":21574,"çã":131394,"ên":31853,"êm":5074,"ês":26627,"él":7493,"ém":24476,"én":6312,"és":8228,"ét":9564,"ér":30738,"éd":7542,"éc":31275,"ço":21084,"ça":38992,"é ":308148,"ún":5650,"ús":10148,"úb":7903,"õe":33653," Ga":11344," Ge":12440," Fo":24420," Fu":6872," Fr":18748," Fi":9007," Fl":5988," Ha":12738," He":10614," Go":9722," Gr":18935," Gu":13279," Gi":5513," Ho":11760," Hi":6304," Je":5193," Ja":20267," In":21384," Ka":6274," Jo":23796," Ju":10788," La":20143," Le":17264," Li":18789," Ma":61882," O ":56830," Mi":22595," Me":18100," NG":5699," Lo":21011," Lu":9458," Ne":9995," Na":16245," Ni":6760," Mo":23061," Mu":14430," A ":56821," Am":13551," An":22425," Al":38669," Ag":5878," Ac":5031," Ab":6362," Ba":33333," Au":8681," At":7218," As":11678," Ar":20591," Be":17207," Bi":6949," Bo":16224," Br":31284," Bu":7302," Ca":66026," Ce":12123," Ci":8645," Ch":23864," Cl":8347," Cr":10239," Co":62169," Cu":6320," Da":9487," Di":17388," De":23395," Do":10149," El":11281," Es":76102," En":6655," Em":8884," Eu":7403," Fe":14330," Fa":9149," Wi":7332," Sã":16295," Wa":6979," a ":159392," Os":8676," Or":9772," Po":57372," Pl":5480," Pi":15147," Pe":21311," Pa":48469," No":30533," Ol":8779," Ra":8887," Qu":6094," Ro":19582," Re":33096," Ri":19127," Pr":23377," Su":24284," St":10640," Ta":10684," UA":14219," Th":10656," Ti":5222," Te":19124," Tr":12898," To":12004," Sa":39159," Sh":5584," Si":12511," Sc":6287," Se":27797," So":14864," Va":11341," Ve":14300," Vi":19683," Tu":6372," Um":5787," Un":17669," ja":9410," im":11343," in":69292," il":7613," it":11439," jo":14428," ju":16927," ha":94775," gr":27016," go":7301," gu":5619," hi":11250," ho":15720," ne":9802," na":144146," mu":41919," mo":24736," on":8262," oc":7515," of":9658," ob":9893," nu":6152," no":190063," le":13833," li":23905," la":21762," gê":9642," km":87834," me":40602," mi":24825," o ":110021," ma":77227," lu":6557," lo":47174," ag":9251," ab":11690," ac":15052," ad":42206," am":26285," an":52016," ao":28506," ap":22430," al":29345," av":5103," au":17149," ar":22234," at":33443," as":63845," ba":35433," bi":6595," be":6338," bo":7718," br":28760," ca":66098," e ":241281," er":11510," et":6896," es":129714," en":44317," em":145368," el":17511," fe":16956," fa":35767," ex":43118," fu":24478," fr":49866," fo":99597," fi":29419," ge":13813," ga":14076," cl":11956," co":383123," cr":20621," ce":57678," ch":14448," ci":62716," da":258975," cu":12445," do":238864," de":1021034," di":92269," ed":7807," du":15330," sa":10534," se":193144," si":34152," so":24812," qu":119214," mú":6854," ra":8844," re":136757," nã":9894," ri":7562," ro":14358," pu":7134," pr":135007," lí":6039," os":51421," ou":60851," op":5907," or":37748," pe":115763," pa":93579," pl":9433," po":171127," pi":7518," sã":13196," sé":13507," va":8521," ve":22883," vo":11121," vi":22819," us":9297," ut":7175," um":444668," un":7084," ta":23369," su":56894," tr":33259," to":19262," th":6383," ti":9760," te":60106," É ":12023," à ":21932," ár":53832," ál":7915," é ":284550,"GC ":5727,"Est":57555,"Esp":12609,"Eur":5804,"Ele":5431,"Em ":5626,"Ger":5645,"Fra":12238,"Foi":10640,"For":9044,"II ":6274,"Gra":10045,"Int":5948,"Amé":5088,"Bai":6138,"Bar":6969,"Ale":12779,"Alt":5502,"Ant":8344,"Cal":7739,"Cam":11986,"Cas":10156,"Car":12659,"Cat":5648,"Can":7596,"Bra":20750,"Den":4991,"Chi":5974,"Cen":6997,"Cha":10337,"Cor":7280,"Com":13375,"Col":5164,"Con":24999,"Dis":5047,"Nov":9350,"Nor":13657,"Os ":6443,"Per":7552,"Par":15095,"Pau":10573,"Pal":5074,"Pro":8377,"Pol":9021,"Pos":21873,"Por":13937,"Jan":9313,"Jos":5715,"Jog":5307,"Lan":5276,"NGC":5668,"Man":7960,"Mar":25108,"Mon":7943,"Min":6224,"Mun":8484,"São":16298,"Sul":8673,"UA ":15445,"Sai":5389,"San":15530,"Rio":11763,"Val":5795,"Vil":5627,"Ver":7558,"Uni":16626,"Ter":5697,"The":7418,"Tra":5593,"bit":68890,"bil":5849,"bo ":5900,"bli":15859,"bol":16054,"bor":6814,"be ":8829,"ban":15903,"bal":9064,"bai":9744,"bas":9817,"bar":9261,"ber":18628,"bel":6221,"ca ":99422,"car":23995,"cas":22552,"cat":6662,"can":45210,"cap":11240,"cad":24057,"cam":12174,"cal":52109,"ce ":17573,"bri":17515,"bro":31772,"bra":35217,"bre":13206,"bur":6170,"bum":7625,"am ":33009,"aix":9798,"al ":180975,"ain":14382,"aio":19228,"air":8502,"ais":60324,"aia":5333,"ago":14405,"anu":5896,"ano":74765,"ant":129336,"ans":13455,"ane":21736,"ang":13849,"anh":31372,"ani":21090,"ana":43001,"anc":58051,"and":76029,"amo":8042,"amp":20451,"ami":6934,"ame":89963,"amb":25048,"ama":26496,"ao ":25066,"alt":10265,"alo":6981,"alm":23414,"all":8441,"alg":7598,"alh":11152,"ali":86609,"ald":5965,"ale":20569,"ala":17691,"an ":23333,"aba":10377,"abe":9561,"abi":55871,"abo":5404,"abr":10253,"ae ":16585,"aca":7889,"ab ":40485,"ai ":5437,"aga":6957,"age":17901,"ado":217915,"adr":8357,"adm":35408,"adi":9559,"ade":147619,"adu":9382,"aco":11338,"aci":33260,"ach":9385,"ace":11134,"ada":120249,"act":10015,"até":8607,"ató":5142,"ba ":7163,"aqu":7206,"amí":18994,"arg":7520,"are":23525,"ard":21302,"arc":12276,"ara":72529,"aro":8382,"arn":4993,"arm":6518,"arl":7205,"anç":24866,"ari":33288,"arq":9519,"arr":16718,"art":76275,"asa":6049,"asi":39800,"asc":20114,"ase":9902,"ar ":59582,"apa":10937,"alá":8272,"ape":8629,"api":9537,"apo":6995,"apr":7853,"as ":272706,"ava":17923,"aut":16096,"arç":7034,"avi":9973,"ave":10994,"ata":23226,"ast":51032,"ass":26073,"atr":16524,"ato":21654,"ate":18241,"ati":65753,"atu":18602,"aul":12887,"aus":5992,"jet":6359,"jan":5629,"jog":9592,"ito":67486,"itu":23834,"ism":9783,"isp":8481,"iss":14904,"ist":137228,"ita":115808,"ite":14296,"iti":9264,"ivr":6273,"ivo":19750,"isã":7956,"iva":52169,"ivi":13782,"ive":20602,"ipo":7067,"is ":98587,"ion":54065,"ior":20141,"ios":21003,"ipa":29796,"ipe":6360,"ir ":14429,"irr":7079,"iro":63701,"iri":6848,"ise":5201,"isc":10067,"isa":6981,"iu ":6072,"ire":22818,"ira":48023,"ja ":10608,"ixa":7209,"itâ":5590,"iz ":5440,"iza":68411,"km ":6889,"ki ":6235,"km²":80918,"gên":12105,"jul":5237,"jun":11429,"ha ":54934,"ham":13772,"han":7220,"har":10472,"has":8814,"hab":92261,"he ":16106,"hei":5849,"hec":22728,"her":9140,"hin":8200,"his":10200,"ho ":40610,"go ":31208,"cçã":8036,"gna":9579,"giã":60677,"gos":20347,"gov":5137,"gru":8390,"gra":31116,"gre":13275,"cíp":21053,"gui":6993,"gua":14762,"gue":29368,"gun":46422,"guê":7234,"iai":5206,"iam":5743,"ial":29154,"ian":36430,"ias":36377,"iad":18351,"ibu":6231,"ibe":5599,"ia ":236755,"ien":14065,"ier":7590,"ies":5878,"ied":5977,"iaç":6604,"ife":6300,"ifi":12350,"icu":5216,"ico":76077,"ici":43382,"ich":7968,"ice":7761,"ie ":27537,"ica":143651,"ido":58535,"idi":8244,"ide":55475,"ida":173600,"il ":28740,"im ":15779,"ige":5893,"iga":14060,"igi":13843,"igu":5678,"icí":20778,"igo":8521,"ign":14724,"imo":12687,"imp":12501,"ime":38876,"imi":7471,"inc":33960,"ind":23589,"ina":69514,"ino":22963,"int":49765,"ins":15328,"inf":7949,"ine":18603,"inh":19122,"ing":32761,"ini":53005,"inu":8866,"ila":11890,"in ":16212,"ilo":7283,"ill":18435,"ilm":5403,"ilh":18906,"ili":24989,"ile":27199,"ima":19294,"io ":111339,"hom":5231,"hos":8051,"hor":13996,"hum":7243,"fes":5911,"fer":17361,"fei":6807,"fam":20697,"ext":9301,"ez ":8287,"exp":6312,"exi":7134,"exc":16402,"eze":10386,"eta":21527,"ete":19661,"eti":12522,"esp":45070,"est":117047,"ess":36172,"eto":18111,"etr":18837,"eve":21643,"eva":5679,"evi":13265,"eus":10550,"eró":29181,"erí":19798,"ey ":6913,"er ":64588,"epa":35649,"açõ":12626,"eon":5303,"es ":232451,"epr":6051,"enç":6954,"eri":53238,"erg":9605,"ere":26129,"erc":25527,"erd":8470,"era":58345,"et ":10811,"equ":14020,"aís":9202,"esm":7907,"esi":25700,"esc":27105,"esd":5456,"ese":28703,"eu ":29870,"esa":56958,"erv":11462,"err":29563,"ert":32707,"ers":31036,"ern":27425,"erm":19525,"ero":27972,"en ":19630,"ela":57757,"ele":31916,"eli":10608,"elh":19021,"ell":12189,"elo":35477,"eo ":6077,"emb":29421,"ema":25633,"eme":11201,"emo":8721,"emi":9916,"emp":20050,"ene":11086,"enh":10752,"ena":27141,"end":70599,"enc":33249,"eno":17065,"eni":7335,"env":8603,"ens":111144,"ent":263509,"açã":84894,"ecç":6791,"ego":8230,"egi":67782,"egr":7999,"egu":58530,"eia":6927,"eis":10113,"eir":97869,"eio":5873,"ein":12110,"eja":8929,"el ":27319,"eit":17574,"em ":185457,"gin":9613,"gio":6344,"gic":7282,"gia":12807,"gen":19808,"ger":11186,"gem":16786,"ge ":8655,"gad":9856,"gas":7737,"gar":10290,"gal":15478,"gan":11614,"ga ":19137,"fut":9060,"fun":15140,"fra":39155,"fre":11644,"for":36958,"foi":67238,"bém":15726,"fic":31195,"fil":13806,"fin":10276,"fis":5455,"da ":386105,"de ":1113463,"dad":172007,"dal":5052,"dae":8716,"das":50851,"dan":7654,"dam":5121,"cul":25961,"cto":6036,"cti":5064,"cta":7890,"cur":7265,"cla":7926,"clu":9168,"cli":8238,"co ":77432,"con":114590,"col":16761,"com":260529,"cor":23539,"cos":23065,"cre":8780,"cri":27018,"cro":6255,"cea":7114,"ch ":7362,"cer":21587,"ces":47284,"ceu":5073,"cen":80958,"caç":9087,"cel":14050,"cei":7700,"cha":18824,"cia":84536,"ck ":7938,"cie":24606,"cid":84373,"che":14945,"chi":8861,"cim":6171,"cis":5750,"cin":23953,"cio":45369,"cip":32198,"ebo":13090,"ead":6607,"ean":5576,"eal":11859,"eat":4993,"ea ":57325,"efe":11937,"ei ":8171,"ega":11879,"edi":19796,"ede":22533,"eda":8333,"edo":8760,"ecl":7415,"eci":35040,"ece":14294,"ecu":5255,"ect":14984,"eco":11351,"dur":9714,"duz":6967,"dor":36541,"don":5597,"dos":101787,"diç":6127,"dmi":36030,"dua":7331,"dri":7071,"dra":5496,"dre":6857,"dro":6768,"dic":13696,"did":7827,"dia":53753,"der":26564,"des":61760,"dez":6564,"dec":9473,"def":5074,"dei":8639,"del":8957,"den":70173,"dem":10237,"dep":38994,"do ":499886,"div":11366,"din":7506,"dio":15896,"dir":15370,"dis":34873,"dit":6840,"dif":6362,"rga":9198,"ri ":5474,"rgi":6642,"rge":9033,"não":10106,"rgo":7927,"ret":18367,"res":88172,"rev":9016,"rg ":6617,"rea":66834,"ref":8795,"rec":27943,"red":8922,"rei":27335,"reg":80521,"rem":9993,"ren":24469,"raç":16220,"rel":14080,"nár":5684,"rep":8548,"rda":6649,"rdo":6927,"rdi":10382,"rde":15782,"re ":57889,"rci":7180,"rce":9738,"rca":20138,"rd ":8761,"rar":6504,"ras":65057,"rat":52626,"rav":11402,"rbi":16469,"rba":5129,"rai":12729,"rag":7162,"ran":101236,"ram":28519,"ral":30318,"rab":8082,"raf":5059,"rad":42430,"rac":11489,"rs ":6575,"ros":32986,"rot":8757,"rom":13204,"ron":14637,"rop":15939,"rou":5772,"rov":31049,"rod":14281,"roc":11812,"rol":6958,"rof":9288,"nçã":8381,"rog":7781,"rno":11572,"rna":23454,"rne":8579,"rmo":8053,"ro ":148425,"rma":34000,"rme":10601,"rmi":14095,"nça":24469,"riz":8006,"rio":44890,"rit":46897,"ris":18600,"rig":17891,"ril":10251,"rin":40225,"rim":24339,"ria":73821,"rib":7744,"ric":60975,"rid":13442,"rie":17826,"rup":9891,"rus":5606,"rva":5441,"rvi":6787,"ry ":6483,"rsi":7243,"rso":14017,"rta":49041,"rto":14307,"rte":57600,"rti":26907,"rtu":25752,"rt ":7638,"rqu":17086,"rro":14834,"rri":9266,"rre":21970,"rra":23654,"sad":9694,"san":5546,"sas":9730,"sar":5392,"sa ":76681,"sid":59438,"sic":18066,"sia":15495,"sit":17633,"sis":13892,"sin":13902,"sio":8799,"sil":41142,"sim":8594,"sig":13420,"scr":14392,"scu":5033,"sde":5601,"se ":99012,"sca":8201,"sce":12058,"sci":8690,"sco":17645,"ser":25139,"ses":9941,"set":9939,"seu":20458,"seg":45509,"sed":9373,"sen":34160,"sem":9716,"sel":5712,"spo":14510,"spe":12903,"spi":7965,"spa":15990,"sol":6214,"son":13806,"sor":8549,"sos":34321,"soa":5579,"soc":9148,"sob":10181,"st ":5646,"squ":6464,"smo":15213,"so ":33266,"ssã":5427,"stá":10797,"stã":5171,"stó":7858,"sse":16316,"ssa":18526,"sso":30852,"ssi":23013,"ssu":30134,"ste":119936,"sta":117494,"spé":16790,"sto":24915,"sti":39339,"stu":7367,"str":101454,"sua":22858,"sub":11326,"sui":27030,"sul":9138,"sup":6250,"sur":5128,"tai":5662,"tal":56545,"tad":72109,"tat":5635,"tas":21431,"tar":22207,"tan":74838,"tam":58144,"te ":182044,"ta ":108579,"pa ":8506,"pe ":6181,"par":108733,"pas":6728,"pac":5622,"pal":27847,"pan":19668,"láx":5857,"pec":9282,"pen":12180,"per":70169,"paí":6811,"pet":6411,"pes":15522,"pel":52058,"pla":10972,"ple":7590,"plo":5321,"pic":9020,"pin":7594,"pio":22913,"pir":7271,"pit":9245,"por":117200,"pop":23863,"pos":31387,"pon":14947,"pol":21044,"pod":12218,"po ":20718,"lês":5033,"pub":5596,"lít":10135,"pri":47853,"pre":42479,"pro":71854,"put":8461,"pul":26066,"mão":6273,"mér":6337,"míl":18580,"qua":26640,"que":121041,"qui":34023,"ra ":178784,"mús":6480,"ngo":5638,"ngl":12535,"ngu":12950,"ni ":5382,"nge":10906,"nga":5764,"nho":23066,"nha":43874,"nhe":24382,"nei":17925,"naç":10350,"nen":5777,"ner":21401,"net":5963,"nes":11864,"ng ":14902,"nco":14783,"nci":80668,"ncl":5010,"nce":69648,"nch":7394,"nca":5561,"ne ":24199,"ndr":9286,"ndo":94739,"ndi":27820,"nde":77208,"nda":61455,"nal":50464,"nam":7322,"nan":6772,"nar":8444,"nac":9251,"nad":24850,"nag":7446,"nai":6712,"nd ":10811,"nat":14635,"nas":35071,"na ":240257,"ny ":5694,"nsã":7776,"nvo":7994,"nve":5937,"num":5422,"nut":6804,"nto":104039,"ntu":19077,"ntr":64145,"nti":32354,"nta":52915,"nte":218759,"nso":37106,"nst":25404,"nse":18037,"nsi":55540,"nsa":5243,"nt ":11783,"ns ":20234,"nom":29572,"not":5470,"nos":46255,"nor":21961,"nov":11058,"nne":6439,"no ":209889,"nid":27726,"nic":53412,"nia":29100,"niz":6361,"niv":8244,"nis":48078,"nio":9439,"nim":8021,"nin":5656,"ogr":11168,"ogi":9366,"ogo":16032,"oga":7825,"oi ":78403,"ois":10929,"oje":5415,"ol ":15035,"oce":8227,"oci":14692,"oco":7976,"oca":52787,"ode":20265,"odi":6628,"odo":29483,"of ":5154,"oda":5699,"oes":5612,"odu":11939,"ofi":9565,"oa ":8425,"obr":14956,"oví":22195,"ote":8672,"oto":8649,"ost":25890,"ota":9466,"osi":9200,"oss":38213,"oso":8522,"ovi":11009,"ovo":6748,"ova":12269,"ove":21270,"ous":5680,"our":9672,"out":17508,"opo":7367,"ope":8960,"opa":6108,"os ":396479,"opu":24150,"oló":8455,"olí":12107,"or ":155288,"orm":37181,"orn":14580,"oro":7726,"orr":17850,"ord":17760,"ore":31129,"org":12371,"ori":29601,"ou ":76190,"osa":9113,"ort":72366,"m² ":81009,"orb":15491,"ora":44778,"ola":17798,"on ":35303,"oli":16249,"ole":10370,"olo":20061,"olu":6559,"olv":8428,"om ":129315,"ona":61961,"ond":42834,"onc":16183,"one":12259,"onh":24723,"ong":8421,"oni":11825,"ono":11037,"ons":37243,"ont":48875,"oma":22403,"ome":35533,"omb":7493,"omi":12319,"omp":29869,"omo":47819,"omu":62085,"la ":68801,"le ":30025,"lac":17518,"lad":10810,"lag":5216,"lan":32402,"lam":5387,"lar":20429,"lat":13280,"las":19631,"ld ":5145,"lbu":8512,"lon":10273,"lor":10947,"loc":44637,"log":14014,"los":17433,"lme":28363,"lti":6810,"lto":6807,"ltu":6502,"lub":6858,"lta":10527,"lho":31407,"lhe":5407,"lha":24850,"lgu":5605,"lev":8296,"les":20832,"let":10999,"ler":5749,"lem":18432,"len":11746,"laç":21723,"lei":31609,"leg":6064,"lec":6739,"lo ":60493,"lla":8917,"lle":13121,"lli":8289,"ll ":7390,"lit":15034,"lis":21665,"lio":5219,"lin":27495,"lim":6007,"liz":58462,"liv":7687,"lic":27450,"lid":13334,"lia":47125,"lig":7684,"ma ":312319,"mai":41100,"mad":18812,"mar":24207,"mas":19571,"mal":6120,"man":38877,"mat":11364,"mba":7627,"mbi":6786,"mbr":26443,"mbo":5222,"me ":30188,"med":7143,"met":15815,"mes":16176,"mer":33993,"mem":6344,"mel":7946,"men":135706,"mei":21546,"maç":6372,"mbé":15876,"lva":5641,"lve":5109,"lvi":6861,"mpi":7951,"mpe":15384,"mpr":13673,"mpo":26049,"mpl":10714,"içã":16989,"mod":7097,"mon":12314,"mor":10927,"mos":10632,"mpa":8900,"mui":6353,"mul":5806,"mun":87543,"ião":65139,"min":67980,"mil":11247,"mis":7225,"mit":9135,"mic":17167,"mia":5205,"mo ":71790,"vín":22165,"zem":7471,"zaç":7006,"zad":51320,"zon":5106,"uíd":7919,"uçã":7240,"za ":11487,"uês":7863,"tón":8038,"tór":13405,"tão":9310,"tân":11804,"tár":6234,"té ":9213,"xim":6106,"xia":6380,"xa ":5938,"xce":15412,"tá ":7267,"séc":5490,"sér":7647,"são":39006,"río":17761,"rói":28842,"róp":5175,"via":10682,"vil":9868,"vim":5528,"vid":18086,"vis":17869,"rço":7357,"vo ":18229,"vol":13908,"vos":6610,"rão":7259,"vez":5961,"ver":46986,"ves":7125,"vei":6022,"ven":17920,"vem":8996,"vel":15436,"ve ":14933,"val":11487,"van":5589,"var":6549,"vas":5897,"vad":9906,"va ":59685,"uzi":7134,"utó":6849,"usi":7047,"use":5760,"usa":11181,"ust":14662,"uss":6347,"uti":10782,"ute":14945,"uta":12601,"utu":10263,"uto":22443,"utr":11202,"us ":31309,"ura":55930,"ure":6495,"urg":9235,"uri":7874,"uro":13305,"ur ":5714,"upe":7143,"upo":9984,"uma":271540,"ume":7805,"unt":10008,"uni":47036,"und":70729,"una":50258,"unh":9065,"um ":201899,"ult":13394,"ulo":24134,"uli":6278,"ulh":9149,"ula":44299,"uil":6385,"uin":8363,"uip":5474,"uis":7425,"uia":5524,"uit":14697,"ul ":16765,"ui ":29672,"uga":10215,"ugu":19601,"uda":6128,"ude":5928,"ubr":7378,"uca":5380,"ue ":100430,"uer":13174,"ues":23125,"udo":7316,"uen":9436,"uel":7358,"púb":6723,"ua ":33662,"uas":11459,"uar":8119,"ual":23558,"uan":11328,"ubl":7183,"ube":7379,"uai":5297,"uad":12055,"tur":41731,"tus":5101,"tui":5138,"tul":5524,"tub":7669,"tua":23176,"tud":7868,"tug":23030,"tre":31460,"tra":95106,"tri":60532,"tru":9663,"tro":48136,"péc":16451,"to ":188185,"tod":9530,"tou":5354,"tos":40605,"tom":5946,"ton":10767,"tor":47860,"til":14634,"tig":9433,"tir":6653,"tit":12090,"tis":7919,"tin":26516,"tim":13089,"tip":5927,"tio":9200,"tia":5519,"tic":53927,"tid":12974,"tiv":62127,"tem":39133,"ten":72655,"tei":7527,"taç":9386,"tel":22078,"teg":5010,"teb":12305,"tec":8043,"th ":5190,"tes":82988,"ter":103003,"the":7042,"ço ":13183,"ém ":22415,"édi":7117,"éci":19647,"écu":6135,"éti":5315,"éri":21433,"ênc":16544,"êne":10481,"ês ":26475,"ção":131304,"ão ":306157,"ça ":19591,"çad":10194,"áti":8887,"áve":5112,"áxi":6942,"álb":7607,"áli":5630,"ári":27812,"áre":51471,"âni":17684,"úsi":6572,"úbl":7260,"ões":32837,"ôni":11441,"óri":16535,"óno":6648,"óni":7908,"óid":28287,"íti":12961,"íst":6738,"ínc":23886,"íng":5418,"íli":21725,"íod":17716,"ípi":21652,"ís ":6687,"íci":9019,"íde":5475,"çõe":21567},"n_words":[49778514,58587553,42469388],"name":"pt"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ron b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ron new file mode 100644 index 000000000..a5c7b8d49 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ron @@ -0,0 +1 @@ +{"freq":{"D":14206,"E":15258,"F":12709,"G":12710,"A":32029,"B":21807,"C":31096,"L":13478,"M":26711,"N":11195,"O":8313,"H":8411,"I":15485,"J":5893,"K":4820,"U":8262,"T":15341,"W":4878,"V":8350,"Q":589,"P":22438,"S":30214,"R":23700,"Y":1325,"X":1901,"Z":1899,"f":89747,"g":84289,"d":270437,"e":933940,"b":76172,"c":339926,"a":811577,"n":568157,"o":427370,"l":434670,"m":224465,"j":16485,"k":15291,"h":47000,"i":839847,"w":7236,"v":72644,"u":459551,"t":525861,"s":321476,"r":567673,"q":978,"p":199529,"z":55715,"y":12885,"x":14642,"²":280,"Î":4242,"É":135,"ß":93,"î":69716,"í":464,"é":1581,"è":290,"ç":171,"ä":380,"ã":94,"â":33080,"á":1243,"à":152,"ü":921,"ú":132,"ö":583,"ó":581,"ñ":107,"Ă":92,"ă":161614,"ā":266,"ć":89,"ı":136,"ī":130,"ş":69795,"ł":112,"ō":143,"š":140,"ţ":70418,"ū":99,"ǎ":351,"Ș":1233,"Ț":844,"ə":124,"ˈ":89,"́":280,"μ":153,"ν":326,"ο":443,"ι":274,"κ":132,"λ":209,"δ":99,"ε":222,"η":124,"α":406,"γ":123,"ά":91,"ί":118,"ό":118,"σ":174,"ς":360,"ρ":245,"π":122,"υ":100,"τ":203," l":54431,"ь":237," m":47832," n":26804," o":49358,"я":249," h":3267," i":28305," j":7583," k":2023,"ы":136," d":156105," e":67780,"х":112," f":51072,"ц":117," g":13468,"ч":249,"р":882," a":134125,"с":828," b":11159,"т":574," c":116614,"у":311," y":145," x":142," z":3353," u":43415," t":26873," w":1170," v":14303,"і":84," q":90," p":90611," s":84706," r":35629,"К":133,"Н":83,"М":137,"П":110,"Б":103,"А":114,"В":101," J":5857," K":4744," H":8304," I":15348," N":11099," O":8211," L":13327," M":26422," B":21644," C":30661,"Р":101," A":31745,"С":176," F":12566," G":12513," D":13925," E":15142,"л":649," Z":1885,"к":766," Y":1319,"й":327," X":1885,"и":1244,"п":176,"о":1327,"н":924,"м":284," S":29902,"г":187," R":23579,"в":707," Q":580,"б":205," P":22131,"а":1480," W":4821,"з":146," V":8268," U":8214,"е":1081," T":15157,"д":332," î":68405," Ă":90," É":134," Î":4219," ţ":2046," ş":40504,"ה":105,"ו":138,"א":92,"ל":89,"י":166," Ș":1227," Ț":843,"ר":104,"و":163,"ي":302,"ل":318,"م":220,"ن":216,"د":146,"ح":87,"ب":195,"ا":469,"ع":89,"س":117,"ر":219," А":114," Б":103," В":101," К":131," М":137,"A ":4154," П":110,"F ":568,"Da":2015,"Cu":1954,"Cy":113,"Cl":1608,"Co":8574,"Cr":1776,"Ce":2628,"Ch":2680,"Ci":1438,"G ":509,"Ec":471,"Ed":733,"Ea":729,"Du":1500,"Do":1908,"Dr":850,"De":3817,"Di":2658,"Fe":1913,"H ":435,"Fa":1302,"Eu":3402,"Ev":451,"Ex":957,"Er":513,"Et":184,"Es":2728,"En":827,"Em":497,"Ep":280,"Ei":240,"El":1974,"Ef":84,"Eg":290,"Ge":3177,"Cá":254,"Câ":416,"Ga":1765,"I ":3107,"Fu":513,"Fr":2787,"Fo":1889,"Fl":1292,"Fi":1643,"Bâ":129,"B ":735," Р":100," С":176,"C ":1390,"Av":423,"Au":2210,"Aw":103,"Ar":4794,"At":636,"As":1391,"D ":881,"Ba":4270,"Az":208,"Ae":279,"Af":611,"Ag":465,"Ah":119,"Ab":553,"Ac":3223,"Ad":1097,"Am":1924,"An":3647,"Ap":1490,"Ai":410,"Ak":87,"Al":4305,"Bu":3694,"Br":3092,"Ca":7562,"E ":767,"Bi":3068,"Be":2955,"Bo":2204,"Bl":574,"Ku":328,"Ky":124,"Kn":99,"Kl":149,"Kr":348,"Ko":662,"Le":1965,"Gă":138,"Li":3218,"N ":854,"La":3044,"Lu":1753,"Ly":104,"Ll":318,"Lo":1983,"Me":2961,"Mi":4169,"O ":1394,"Ma":9710,"Mc":201,"My":160,"Mu":2543,"Mo":4971,"Ni":1761,"Ne":2385,"Na":2454,"P ":736,"Q ":153,"Nu":750,"No":2851,"Ol":1045,"Om":198,"On":376,"Oh":91,"Oc":1033,"Od":206,"Of":171,"Oa":113,"Ob":305,"Gi":853,"Bă":725,"Gh":757,"Gl":444,"Gr":2243,"Go":1170,"Gu":1179,"Gy":91,"J ":354,"Ha":2364,"Dâ":128,"He":1745,"Că":581,"Hi":659,"Ho":1571,"Hr":249,"Hu":882,"Hy":112,"K ":358,"Ib":100,"Ia":1254,"Id":117,"Ie":183,"Ig":92,"Io":1307,"Im":1022,"In":3678,"Il":431,"Iu":1265,"Iv":162,"Is":1017,"It":790,"Ir":549,"Ja":1638,"L ":645,"Iz":203,"Ji":337,"Je":630,"Jo":1867,"Ju":935,"Ka":1128,"M ":833,"Kh":125,"Fă":159,"Ki":625,"Ke":541,"Ut":114,"Ur":420,"Up":83,"Um":91,"Un":5673,"Ul":182,"Pă":635,"Uc":368,"W ":229,"Ty":98,"Tu":1266,"Tr":2949,"To":1782,"Th":2212,"Ti":1500,"Te":2836,"Pâ":232,"Ta":1163,"V ":1269,"Sw":112,"Sz":144,"Sy":285,"St":5254,"Su":2579,"Wr":229,"Wo":691,"Wi":1273,"Ră":813,"Wh":234,"Wa":1039,"Sâ":220,"We":859,"Y ":147,"Vo":713,"Vr":133,"Vu":111,"Râ":933,"Vi":1974,"Vl":297,"X ":1079,"Va":2283,"Ve":1567,"Lă":421,"Pu":736,"Pr":4511,"S ":1482,"Pe":2677,"Pa":6072,"Pl":931,"Po":3427,"Pi":1539,"Ph":445,"Os":331,"Ot":294,"Ou":154," ا":202,"Ov":120,"Op":423,"Or":1772,"R ":901,"Kö":111,"Sf":926,"Se":3730,"Sc":1718,"Si":2479,"Sh":841,"Nă":243,"Sm":167,"Sl":471,"Sk":113,"Sp":3075,"So":2382,"Ru":1542,"U ":435,"Sa":3082,"Re":6657,"Ri":1089,"Mă":769,"Rh":203,"Ro":9754,"Qu":329,"T ":645,"Mü":187,"Ra":1639,"Wü":172,"b ":5072,"a ":212743,"Ye":128,"Tă":194,"Ya":168,"Yo":679,"Yu":120,"Z ":124,"Tâ":356,"Să":464,"Vă":154,"Za":383,"Ze":392,"Zi":317,"Vâ":376,"Zo":278,"i ":179645,"gd":205,"ge":13414,"câ":4391,"ga":11234,"gb":146,"fl":4423,"ff":711,"bâ":136,"fi":21259,"fr":4539,"fu":3903,"ft":996,"fo":28249,"j ":2040,"gy":251,"dâ":214,"he":10237,"ha":6256,"gn":1318,"gm":382,"gl":4043,"gi":18379,"gh":4326,"bă":2234,"gg":253,"gv":296,"gu":7182,"gt":188,"gs":381,"gr":9341,"cî":121,"go":3415,"dt":248,"du":15963,"dv":200,"dw":264,"dy":391,"dz":86,"g ":5818,"ea":59379,"eb":4646,"ec":30872,"ed":13772,"de":117725,"dd":311,"dg":263,"di":66800,"dh":111,"dj":215,"dm":1691,"eM":86,"dl":291,"do":13587,"dn":210,"ds":959,"dr":6694,"ew":1340,"ex":7454,"eu":5496,"ev":8185,"ey":1419,"ez":15187,"fa":8662,"h ":3714,"fe":10587,"eh":1815,"eg":14417,"ef":4744,"ee":3471,"el":50297,"ek":775,"ej":687,"ei":30112,"ep":15349,"eo":6294,"en":63988,"em":24435,"et":20416,"es":79718,"er":87843,"ca":58257,"e ":363120,"by":328,"bs":1372,"br":14880,"bu":7988,"bt":195,"bn":117,"bo":5650,"bl":6057,"bm":100,"bi":12351,"bb":308,"bc":108,"bd":241,"be":6318,"db":261,"da":18159,"f ":3092,"cz":119,"cy":195,"cv":646,"cu":45953,"ct":20001,"cs":291,"cq":100,"cr":11320,"co":42083,"cm":243,"cn":187,"ck":2747,"cl":5298,"ci":32813,"ch":13925,"ce":51893,"cc":2745,"c ":18619,"aP":84,"aC":95,"az":9879,"ay":1659,"ba":11641,"d ":22818,"at":93723,"as":21874,"ar":105841,"aq":90,"ax":1099,"aw":499,"av":8565,"au":21651,"ak":1416,"al":87116,"ai":18198,"aj":3933,"ao":374,"ap":15113,"am":19806,"an":87690,"ac":26532,"ad":16915,"aa":641,"ab":6836,"ag":7060,"ah":1692,"ae":3048,"af":7326,"nu":32036,"nt":67674,"ns":20163,"nr":1134,"np":113,"no":17936,"nn":2298,"q ":85,"nz":1824,"ny":836,"nw":156,"nv":2089,"oe":1765,"of":5818,"oc":21548,"od":10761,"oa":21531,"ob":5951,"om":43493,"on":56179,"ok":801,"ol":30865,"oi":8296,"oj":309,"og":8118,"oh":1090,"m²":273,"ot":11364,"os":27341,"ov":12192,"ou":7338,"op":17725,"oo":1964,"or":85929,"r ":49086,"ox":1908,"ow":1237,"oz":3227,"oy":555,"pe":42586,"lâ":532,"pa":25762,"pc":98,"pl":7066,"lé":112,"po":22942,"ph":1089,"pi":11751,"lo":40730,"ln":822,"lm":3343,"ll":6217,"ls":1221,"lp":822,"lv":2229,"lu":48097,"lt":11451,"lz":261,"ly":862,"o ":37058,"mc":90,"ma":44395,"mb":17891,"eş":9887,"hă":248,"me":40474,"mf":257,"eţ":7364,"ml":160,"iè":112,"mi":28493,"mn":4278,"mm":955,"mp":17238,"mo":11698,"mt":225,"ms":601,"mu":21624,"my":299,"p ":5018,"na":37617,"nb":568,"nc":20662,"nd":32264,"ne":45632,"nf":4807,"ng":14388,"nh":479,"ni":65371,"nj":736,"nk":1221,"nl":1126,"nm":330,"ju":7523,"jo":2219,"jl":509,"bţ":531,"ki":1735,"kh":269,"fă":1862,"cş":118,"gâ":388,"kf":113,"ke":1642,"ka":1464,"m ":15258,"ky":316,"ks":661,"kt":260,"ku":385,"ko":995,"kr":318,"kk":161,"cţ":4949,"kl":292,"km":1457,"li":54376,"lh":237,"gă":2958,"lk":383,"lj":135,"le":70613,"ld":4148,"lg":2038,"lf":1236,"hâ":94,"la":55152,"lc":2339,"lb":4110,"n ":164001,"hr":1429,"hs":252,"hw":257,"ht":1909,"hu":2313,"că":22340,"hi":13680,"hn":1591,"ho":3277,"hl":404,"hm":291,"id":10613,"ic":65212,"ib":4937,"ia":63950,"dă":2289,"ih":1392,"ig":9132,"aş":9011,"if":6185,"ie":62856,"hy":354,"k ":4658,"iq":165,"eî":135,"ir":13340,"is":36911,"it":62439,"iu":24448,"iv":15138,"iw":97,"ix":744,"ii":33158,"ij":1160,"aţ":19894,"ik":1190,"il":42983,"im":26881,"in":122257,"io":22518,"ip":8638,"je":1168,"fâ":980,"ji":658,"iz":12018,"iy":146,"l ":109782,"ja":1735,"pţ":503,"să":10006,"xi":3113,"xo":371,"té":92,"tî":216,"xp":1513,"xt":2105,"xu":441,"ww":338,"z ":3980,"xc":491,"xa":1180,"tâ":2269,"xe":1609,"oş":1503,"ră":15639,"wi":755,"oţ":1099,"sé":93,"wn":249,"wo":518,"sî":86,"wr":185,"ws":439,"vy":161,"y ":7000,"wa":1979,"sâ":398,"we":941,"vl":85,"ré":180,"nţ":14138,"vi":18551,"râ":2794,"nş":236,"vu":1822,"vr":1272,"rî":85,"vs":260,"rí":114,"vn":113,"vo":6165,"uz":4516,"uy":132,"ux":811,"uw":93,"uv":2854,"uu":147,"ve":20356,"va":13083,"x ":3188,"ui":36731,"uj":940,"mţ":245,"uk":412,"ul":105505,"ue":3558,"uf":779,"ug":3958,"pă":8327,"uh":313,"ur":41535,"us":16414,"ut":20794,"um":22214,"un":77098,"uo":207,"up":12202,"ty":1026,"tz":478,"tu":41090,"tt":2205,"tw":494,"tv":129,"ub":9499,"ua":12620,"ud":10993,"uc":12122,"w ":1362,"to":36489,"tn":678,"tm":622,"tl":1983,"ts":1249,"tr":54687,"tp":270,"pâ":2492,"tf":804,"te":135412,"td":104,"lţ":1071,"tk":89,"ti":57663,"th":5025,"v ":5358,"tb":1584,"tc":809,"ta":57242,"su":20142,"sv":111,"ss":3065,"st":121541,"sy":354,"sz":231,"sw":164,"sl":2146,"sk":1369,"sn":714,"sm":3046,"sp":10131,"so":10359,"sr":365,"sd":200,"sc":21675,"sf":2108,"se":33580,"sh":1776,"nă":16784,"sg":163,"si":25637,"rz":902,"u ":55858,"sa":21555,"sb":549,"rr":1909,"rs":9764,"rt":23612,"ru":36664,"rv":2469,"rw":210,"ry":1487,"rp":2476,"ro":43127,"rn":8536,"rm":17803,"né":122,"rl":4592,"nç":103,"rk":1642,"rj":246,"ri":114051,"mă":7183,"rh":1830,"rg":8792,"rf":1291,"nâ":643,"re":125851,"rd":9049,"rc":6829,"rb":4129,"ra":67426,"t ":87746,"qu":761,"mé":97,"iţ":6799,"mâ":11991,"lă":11508,"iş":3714,"s ":29143,"px":1165,"py":91,"pt":7489,"pu":17959,"pp":664,"pr":42710,"ps":1182,"ză":8661,"zâ":331,"uţ":3113,"xă":383,"uş":1691,"vă":2660,"zz":266,"sţ":297,"zf":124,"vâ":2188,"rş":635,"zg":128,"uă":2010,"zi":14356,"zb":1622,"zd":236,"ze":7824,"vá":88,"za":10358,"zv":1283,"zy":102,"zu":1714,"zt":122,"zo":3689,"zn":131,"rţ":3519,"zm":105,"zl":93,"tă":34729,"ye":514,"yc":205,"yd":240,"ya":763,"yb":116,"yw":120,"yu":112,"yt":228,"ys":611,"yr":295,"yp":159,"yo":376,"yn":435,"ym":285,"yl":584,"yi":202,"² ":275,"Î ":96,"În":3944,"Îm":147,"án":283,"ác":265,"ár":117,"ás":83,"âl":535,"âm":971,"ân":23884,"âi":324,"âu":2278,"ât":1719,"âr":2512,"à ":112,"á ":120,"アアア":92,"ón":162,"ó ":105,"în":66365,"ín":93,"îi":280,"îl":220,"îm":1778,"ía":115,"î ":282,"âş":625,"él":95,"én":106,"és":86,"ér":215,"ée":141,"èr":89,"é ":392,"ăc":1712,"ăd":1353,"ăi":1593,"ăj":113,"ăg":390,"ăm":1728,"ăn":1902,"ăl":2480,"ăr":15029,"ăp":813,"ăv":254,"ău":2670,"ăt":8950,"ăs":5402,"ăz":2233,"ăb":253,"Ă ":96,"ă ":108634,"ün":238,"ür":317,"ör":105,"ön":99,"öl":118,"îş":473,"ăţ":4694,"ăş":1107,"şo":1467,"şt":10708,"şu":3626,"şi":42994,"şn":265,"şm":86,"şa":1934,"şc":1152,"şe":2787,"ş ":4403,"şă":140,"ţe":5578,"ţi":45859,"ţu":4697,"ţa":7179,"ţ ":1101,"ţă":5758,"ア":157,"ǎ ":253,"Ți":110,"Ța":292,"Ș ":94,"Și":132,"Șo":113,"Șt":390,"Ț ":94,"Șc":133,"Șa":135,"Șe":144,"Ță":266,"之":98,"三":194,"丁":102,"ος":175,"ος ":175,"ς ":359,"ν ":94,"α ":133,"アア":124,"ск":290,"та":92,"ст":158," Ga":1748," Câ":415," Ge":3154," Cá":254," I ":808," Fo":1868," Fu":504," Fr":2770," Fi":1622," Bâ":129," Fl":1278," Ha":2353," He":1731," Dâ":128," Gy":84," J ":235," Go":1158," Gr":2202," Gu":1163," Bă":725," Gh":755," Gi":841," Gl":431," Ig":92," Ie":183," Id":117," Ib":97," Ia":1248," K ":217," Hy":109," Hu":880," Hr":248," Ho":1557," Că":576," Hi":652," Ji":335," Je":625," L ":250," Ja":1632," Iz":203," Iu":1263," Iv":159," Ir":548," Is":1004," It":785," Im":1017," In":3630," Io":1287," Il":430," M ":262," Ka":1125," Ke":531," Ki":614," Kh":124," Fă":159," Jo":1852," Ju":930," N ":206," La":3007," Le":1942," Gă":138," Li":3175," Kl":144," Kn":98," Ko":661," Kr":346," Ku":321," Ky":124," Mc":200," Ma":9571," O ":853," Mi":4107," Me":2921," Lo":1967," Ll":318," Ly":104," Lu":1743," Ne":2351," P ":197,"а ":320," Na":2442," Ni":1749," Mo":4944," My":159," Mu":2527," A ":2659," B ":442," C ":439," Ap":1483," Am":1916," An":3623," Ak":86," Al":4275," Ai":406," Ag":455," Ah":117," Ae":277," Af":571," Ac":3199," Ad":1079," Ab":530," Ba":4239," D ":276," Az":205," Aw":102," Av":410," Au":2198," At":631," As":1386," Ar":4774," Be":2935," Bi":3051," Bl":566," Bo":2181," Br":3074," Bu":3675," E ":267," Ca":7457," Ce":2586," Ci":1423," Ch":2660," Cl":1578," Cr":1755," Co":8451," Cu":1909," Cy":110," F ":199," Da":1990," Di":2603," De":3729," Dr":841," Do":1853," Du":1487," Ea":726," Ec":468," Ed":725," G ":189," El":1961," Ei":240," Eg":286," Ef":83," Et":180," Es":2724," Er":511," Ep":280," En":810," Em":492," Ex":936," Eu":3393," Ev":441," Fe":1900," Fa":1274," H ":241," Să":460," Tâ":354,"к ":95," Wr":229," Wo":669," Wi":1265," Ră":813," Wh":231," We":849," Sâ":220," Wa":1026," Y ":114,"й ":231," Zo":278," Ze":389," Vâ":375," Zi":312," Za":381," Yu":120," Yo":676," Ya":164," Tă":194," Ye":128," Wü":172,"о ":126,"н ":131," Vă":153," a ":36875," R ":300,"в ":116," Kö":111," Ou":147," Ov":103," Os":331," Ot":292," Or":1764," Op":422," Po":3392," Pl":908," Pi":1531," Ph":433," Pe":2652," Pa":6041," Q ":118," Nu":741," No":2833," Ol":1044," On":368," Om":193," Oh":91," Od":204," Oc":1030," Of":168," Ob":298," Oa":113," Mü":186," Ra":1619," T ":190," Qu":324," Ro":9725," Re":6614," Ri":1081," Mă":767," Rh":203," S ":442," Pr":4358," Pu":723," Lă":359," Sz":142," Sy":283," Sw":111," Su":2564," St":5193," Ta":1158," V ":299," Th":2181," Ti":1481," Pâ":232," Te":2810," Tr":2917," To":1756," Ru":1539," Sa":3068," U ":212,"е ":128," Sh":834," Nă":243," Si":2443," Sc":1686," Se":3700," Sf":922," So":2361," Sp":3054," Sk":111," Sl":463," Sm":160," Va":2273," X ":295,"и ":98," Ve":1551," Vi":1939," Râ":933," Vl":295," Vo":709," Vu":110," Vr":132," Tu":1248," Ty":98," W ":133," Uc":367," Pă":634," Ul":182," Um":91," Un":5644," Ur":414," Ut":114," ja":470," l ":435," iz":399," io":137," ip":103," im":2637," in":15177," il":210," iu":2496," is":1936," it":606," ir":289," ka":124," m ":620," fă":1009," ki":195," gâ":148," jo":1049," ju":5955," ha":692," he":341," gi":362," gh":227," bă":568," gl":415," gr":4643," cî":96," go":322," gu":1027," ia":2677," id":624," ie":296," dă":97," aş":533," că":5014," hi":694," ho":634," hr":508," ht":170," ni":1017," ne":2985," na":3334," p ":138," mu":6108," mo":5925," ol":415," om":2225," on":472," oc":2425," od":198," of":2241," oa":721," ob":2230," nr":213," nu":8582," no":5141," le":5248," gă":633," li":8299," n ":4015," la":23505," km":1385," me":7797," eş":107," mi":5999," o ":24882,"я ":186," ma":19097," lu":7950," lo":8243," ae":559," af":3722," ag":621," ab":871," ac":11612," ad":3606," am":3470," an":10041," ap":7602," ai":935," aj":609," al":27010," av":3789," au":7831," ax":133," ar":7993," at":2213," as":3512," d ":818," ba":2886," az":461," bi":2225," be":668," bo":1156," bl":302," bu":1418," br":1785," ca":30202," e ":424," c ":92," er":1837," et":1185," es":44667," en":2470," em":716," ep":805," ei":565," el":3115," ef":535," eg":319," fe":3014," fa":5201," eu":1087," ev":1448," ex":4580," fu":2227," fr":3215," fo":24062," fl":777," fi":11367," ge":4653," câ":3570," ga":964," i ":494," cl":2039," cm":100," co":29681," cr":3733," cc":163," ce":15081," ch":1829," ci":2979," f ":104," da":4946," cu":21872," do":6118," dr":1888," de":93131," di":45684,"ч ":147," ec":2186," ed":1091," ea":295," eb":276," du":3328,"ль":104," vă":281," zo":1012,"ла":120,"ли":124,"ко":168," ze":739," zb":153," zi":1040," zf":120," vâ":719,"ка":188,"ки":145," tă":177," să":3897,"ин":138,"ик":85," ww":167,"ий":142," tâ":352,"ич":160,"ри":89,"ро":151,"ра":156,"ре":83,"ос":104,"ор":119,"ол":94,"ов":307," uş":254,"но":129,"ни":117,"на":162," ru":1689," sa":12280," sf":678," se":17401," sc":5833," si":9687," sh":138," nă":1457," sl":456," sp":5202," so":3426,"ви":183,"во":101," ra":2561," re":17790," ri":1713," mă":1822," ro":8367," pu":4423," pr":28214," ps":399," s ":2092," px":1165," lă":254," mâ":207," os":197," ot":110," op":1754," or":11013,"ан":170," ox":160,"ал":98," pe":25650," lâ":421," pa":9591,"ар":142," pl":2462," po":12520,"ая":98," pi":2615," wa":449," sâ":329," we":213," wr":124," wi":111," ră":1828," x ":110," va":2539," ve":4691," uz":162," vo":2209," vr":384," vu":171," râ":1545," vi":3164," uc":310,"ес":86,"ер":137,"ен":133," tu":1391," us":154," ut":956," ur":2048," um":561," un":37329," ul":1504," pă":1596," ta":986," st":9754," su":13217,"ев":109," tr":8292," to":2637," th":2187," ti":4195," te":6492," pâ":1627,"Țăr":258," Î ":96," Îm":146," În":3919," în":65579," îl":200," îm":1722," îi":236," î ":223," îş":424," Ă ":90," ţa":471," şt":950," şo":136," şi":37976," şc":219," şe":338," şa":764," ţi":391," ţe":161," ţă":1008," Ță":265," Ța":292," Ți":110," Șe":142," Șc":133," Șa":134," Ț ":92," Șt":387," Șo":113," Și":132," Ș ":91,"ال":185,"ي ":110,"ن ":132,"AS ":90,"BC ":103,"Feb":468,"Fed":536,"Fel":141,"Fer":333,"Fes":98,"Bâr":109,"Fil":558,"Fin":381,"Fir":91,"Fie":114,"Ext":451,"Fam":192,"Fan":103,"Fal":98,"Far":165,"Fac":313,"Fab":84,"Era":97,"Eri":131,"Est":2527,"Eur":3119,"Eva":149,"Eve":110,"Eug":130,"Exp":186,"Exi":117,"Exc":103,"Evu":86,"El ":710,"Ele":546,"Enc":124,"Eng":174,"Ene":132,"Emi":260,"Elv":237,"Eli":210,"Epi":189,"Ent":184,"Câm":221,"Cân":103,"Các":221,"Ger":1707,"Geo":684,"Gen":482,"Gla":99,"Ghe":506,"Băl":198,"Ghi":176,"Băt":252,"Gil":105,"Gir":238,"Giu":159,"Gaz":102,"Gal":559,"Gam":141,"Gav":159,"Gar":269,"Gab":147,"Fun":252,"Fru":86,"Fro":141,"Flo":463,"Fla":640,"Fra":1957,"Fri":249,"Fre":285,"Fon":202,"Fot":362,"For":809,"Fox":86,"II ":1544,"Dâm":116,"Căl":223,"His":116,"Hil":108,"Hel":236,"Hei":175,"Hea":139,"Hen":243,"Hes":101,"Her":541,"Hal":221,"Hai":98,"Han":325,"Ham":243,"Har":682,"Hau":104,"Gur":143,"Guv":353,"Gua":120,"Gui":207,"Gre":662,"Gri":261,"Gra":547,"Gru":280,"Gro":360,"ţă ":4334,"Glo":227,"Goo":112,"Gol":285,"Got":84,"ţăt":101,"Gor":250,"ţăr":1089,"ţăm":207,"Inv":138,"Ioa":445,"Inf":292,"Ini":100,"Int":1173,"Ins":803,"Ion":531,"Ios":98,"Ior":163,"Ili":165,"Ill":92,"Inc":150,"Ind":606,"Imp":850,"In ":158,"Iaş":404,"Ier":125,"Ian":535,"Ial":83,"Hun":383,"Hum":90,"IX ":412,"Hug":91,"IV ":391,"IT ":137,"Hor":215,"Hou":138,"Hot":160,"Hom":127,"Hon":117,"Hol":365,"Hr ":133,"Arg":385,"Arh":350,"Are":1696,"Arc":194,"Ard":100,"Ara":584,"Arm":402,"Ari":241,"Apo":195,"Apr":477,"Ate":96,"Atl":247,"Ast":296,"Ass":154,"Asi":398,"Aso":236,"Art":517,"Au ":88,"Avi":111,"Ave":127,"Aut":413,"Aus":786,"Aur":237,"Apă":85,"Aug":551,"Bai":170,"Bal":441,"Ban":574,"Bab":153,"Bac":358,"Bad":439,"Baz":111,"Bay":92,"Bar":873,"Bat":155,"Bas":347,"Bav":161,"CD ":118,"Abr":91,"Aca":558,"Act":175,"Ada":136,"Ace":1958,"Acc":188,"Adu":103,"Adm":250,"Ado":166,"Adr":161,"Ade":100,"Afa":103,"Aer":222,"Age":153,"Afr":381,"Agr":117,"Air":208,"Al ":217,"Ala":198,"Alb":1104,"Alg":107,"Ali":309,"Alc":89,"Ale":1016,"Alf":175,"Alt":180,"Alm":145,"All":248,"Alp":203,"Ame":1318,"Amb":85,"Ama":153,"Ang":951,"Ani":130,"Ana":326,"And":938,"Ant":732,"Ann":166,"Apa":378,"But":87,"Bus":115,"Buz":155,"Bul":406,"Bun":176,"Bur":449,"Buc":1806,"Bud":195,"Bru":284,"Bră":148,"Ca ":119,"Cab":93,"Cal":738,"Cam":777,"Cas":1102,"Car":1723,"Cau":101,"Cat":1040,"Can":883,"Cap":564,"Bea":150,"Bet":104,"Ber":735,"Ben":285,"Bel":1128,"Bib":207,"Bil":178,"Bih":202,"Bis":1833,"Bir":155,"Bio":98,"Blo":128,"CN ":94,"CO ":85,"Bla":274,"Bre":357,"Bra":1081,"Bro":311,"Bri":819,"Bog":147,"Boe":111,"Bol":190,"Bon":168,"Boo":93,"Bor":292,"Bos":170,"Bot":287,"Bou":149,"Cuv":164,"Cur":363,"Cup":386,"Cul":405,"De ":453,"Dez":104,"Der":87,"Det":101,"Des":342,"Dev":138,"Deu":92,"Del":231,"Dem":343,"Den":254,"Dep":258,"Dea":199,"Dec":652,"Dam":105,"Dan":549,"Dar":174,"Dat":151,"Dav":338,"Dac":187,"Dal":97,"Chr":305,"Che":298,"Chi":1153,"Cip":91,"Cin":138,"Cio":191,"Cit":251,"Ciu":252,"Civ":93,"DN ":145,"Cle":88,"Cla":363,"Cea":181,"Ceh":224,"Cel":451,"Cen":839,"Cet":187,"Cer":452,"Cha":723,"Cri":558,"Cra":341,"Cre":321,"Cu ":179,"Cru":182,"Cro":263,"Cli":120,"Clo":93,"şă ":93,"Clu":841,"Coc":83,"Coa":119,"Cod":224,"Cop":211,"Cos":228,"Cor":1033,"Com":2355,"Col":727,"Coo":87,"Con":2677,"Cou":282,"Cot":116,"Cov":111,"Ea ":436,"FA ":238,"Egi":189,"FI ":85,"Edu":88,"Edi":420,"Eco":139,"Ech":197,"ţur":116,"Eas":194,"ţui":121,"ţul":4343,"FC ":245,"ţar":732,"ţat":1470,"Deş":155,"ţe ":1287,"ţa ":4852,"Dia":147,"Dic":236,"Dis":609,"Dir":129,"Dio":102,"Din":623,"Dim":132,"Die":129,"Div":260,"ţit":365,"ţiu":2393,"ţir":210,"Duc":160,"ţin":4093,"ţio":5262,"Dup":205,"ţil":2341,"ţim":464,"Dun":357,"Dum":429,"ţii":7297,"ţif":426,"EX ":88,"Dur":97,"ая ":95,"ţia":6859,"ţie":10551,"ţei":1511,"ţen":180,"ţel":1678,"ţes":190,"Dre":250,"Dra":255,"ţi ":5299,"Doi":184,"Dob":158,"Dou":102,"Dol":170,"Don":271,"Dom":358,"Dor":224,"ţea":461,"Nea":360,"Neg":223,"Nev":114,"Neu":159,"Net":137,"Nep":85,"Nas":96,"Nat":327,"Nav":140,"Nig":112,"Nic":784,"Nis":298,"Nin":99,"Nik":102,"Naţ":910,"New":711,"Nap":289,"Nam":92,"Num":477,"OS ":93,"Nou":391,"Nov":172,"Nor":1220,"Not":118,"Noi":520,"Nob":138,"Înc":117,"Oct":512,"Înt":212,"Ode":88,"PC ":107,"Oce":295,"Împ":136,"Obe":86,"În ":3310,"Oto":155,"Olt":287,"Oli":317,"Ola":252,"Ono":115,"One":96,"Ope":278,"Ora":462,"Ort":215,"Osc":136,"Ord":181,"Ori":268,"Org":211,"Peş":117,"Plo":152,"Ple":87,"Pla":572,"Pin":170,"Pit":107,"Pir":96,"Pie":423,"Pic":155,"Pia":306,"Pho":97,"Phi":218,"Ped":83,"Per":522,"Pet":738,"Pen":513,"Pel":85,"Pe ":267,"Pat":391,"Pas":174,"Par":3240,"Pav":117,"Pau":327,"Pac":294,"Pan":274,"Pap":271,"Pal":567,"Pub":157,"Pur":83,"Put":143,"Pro":1436,"Pri":1498,"Pre":1075,"Pru":161,"Pra":285,"Pod":203,"Poa":126,"Pol":793,"Pom":101,"Pon":142,"Poi":169,"Pot":185,"Pos":133,"Pop":623,"Por":507," ال":165,"Lăc":323,"SA ":143,"Rac":113,"Rad":382,"Rai":238,"Ram":106,"Mün":150,"Ran":107,"SD ":117,"Que":155,"Isa":101,"Irl":266,"Ita":687,"Isl":175,"Isr":173,"Ist":357,"Ira":132,"Iug":109,"Iva":127,"Iul":580,"Iun":435,"Izv":134,"Jae":83,"Jac":383,"Jap":315,"Jan":217,"Jam":257,"Jer":140,"Jea":190,"Jim":122,"Jos":531,"Jon":151,"Joh":545,"Joc":288,"Jud":261,"Jus":113,"Jur":102,"Jul":125,"Jun":115,"Kal":121,"Kan":96,"Kat":124,"Kar":336,"Ken":149,"Kir":86,"Kin":185,"Kie":90,"Kon":94,"Kos":163,"Kre":87,"Kra":118,"Lew":83,"Lev":90,"Let":83,"Les":120,"Leo":277,"Len":176,"Lei":93,"Leg":332,"Lee":87,"Lea":120,"Lau":147,"Laz":87,"Le ":90,"Las":86,"Lat":109,"Lar":154,"Lam":95,"Lan":338,"Lac":259,"Lab":85,"La ":1181,"Lle":258,"Lib":362,"Lic":139,"Lie":89,"Lig":414,"Lim":410,"Lin":461,"Lis":431,"Lit":301,"Liv":198,"MI ":96,"Lux":121,"Lup":107,"Lum":137,"Lun":558,"Lud":146,"Luc":356,"Lou":179,"Lov":137,"Los":244,"Lot":89,"Loc":483,"Lor":132,"Lon":361,"Meh":106,"Men":147,"Mem":162,"Mel":209,"Mes":271,"Mer":299,"Met":461,"Mec":135,"Med":595,"Mex":216,"Man":1131,"Mal":342,"Mar":4668,"Mas":368,"Mag":383,"Mad":271,"Maj":121,"Mai":903,"Mac":356,"May":100,"Max":155,"Mau":132,"Mat":338,"Mod":176,"Mol":1838,"Mon":1277,"Mos":318,"Mor":392,"Mou":115,"Mot":179,"Mih":609,"Mik":106,"Mij":92,"Mid":157,"Mig":86,"Mic":936,"Mit":232,"Mir":321,"Mis":279,"Mil":373,"Min":651,"Muz":367,"Mun":1060,"Mul":94,"Mur":508,"Mus":300,"NU ":88,"Săl":172,"Săr":113,"Târ":305,"XX ":206,"XV ":95,"Wre":180,"Wor":386,"Wol":146,"Whi":111,"Răd":101,"Răz":528,"Răs":89,"Wil":518,"Win":333,"Wie":86,"Wit":97,"ère":85,"Web":84,"Wes":374,"Sân":132,"Was":121,"War":230,"Wat":92,"Wal":290,"Vra":93,"ée ":112,"Vol":202,"Voi":185,"Vis":124,"Vit":135,"Vla":243,"Ziu":91,"Zon":137,"Zee":92,"Vâl":191,"Vâr":128,"âşt":551,"Yor":388,"You":200,"на ":94,"Stă":112,"Sys":110,"Stî":142,"Sur":132,"Sus":204,"Sul":83,"Sup":346,"Sun":219,"Sue":270,"Sud":589,"Suc":243,"Sub":164,"Str":664,"Stu":292,"Sti":105,"Sto":394,"Sta":2644,"Ste":728,"Teh":119,"Tea":170,"Tec":113,"Ten":121,"Tem":164,"Teo":264,"Tel":395,"Tan":144,"Tat":111,"Tar":189,"Tai":83,"Tal":112,"UA ":470,"Sfâ":498,"Shi":108,"She":197,"Năs":219,"Sho":130,"Sha":300,"Sim":365,"Sil":252,"Sig":138,"Sit":102,"Sis":180,"Sir":233,"Sin":438,"Sie":127,"Sib":370,"Sfi":241,"Sez":141,"Ser":760,"Sev":325,"Sf ":135,"Scr":179,"Sep":495,"Sen":217,"Sel":98,"Sem":99,"Sec":315,"Sea":111,"TV ":299,"Spa":2255,"Spi":211,"Spe":223,"Spr":121,"Spo":178,"Sof":165,"Soa":134,"Soc":483,"Sou":289,"Sov":352,"Sol":260,"Som":154,"Son":175,"Sor":138,"Sla":128,"Slo":264,"Roş":199,"Rus":998,"Sai":239,"Sam":225,"Sal":380,"Sab":86,"Se ":674,"Sco":358,"Sci":132,"Sch":680,"Sca":185,"Sax":130,"Sav":134,"Sat":330,"Sau":85,"Sar":201,"San":758,"ови":108,"TA ":103,"Rez":129,"Res":168,"Ret":90,"Rev":440,"Măn":337,"Măr":265,"Rhe":108,"Riv":111,"Rin":182,"Ric":330,"Rap":96,"Ref":116,"Rec":405,"Red":97,"Rei":117,"Reg":1929,"Rem":121,"Ren":298,"Rel":102,"Rep":1978,"Rea":273,"Rol":118,"Rob":343,"Roc":197,"Rod":127,"Roy":87,"Rot":120,"Ros":294,"Rom":7794,"SS ":239,"SO ":102,"Reş":139,"Vel":106,"Ven":242,"Vec":214,"ски":101,"Vas":382,"Van":141,"Val":1157,"Var":247,"Vic":330,"Vie":288,"Vir":168,"Vil":251,"Vin":215,"Râu":810,"Ver":423,"Ves":364,"Păm":274,"Păd":123,"Ung":582,"Uni":3993,"Un ":792,"VD ":93,"Ucr":344,"VI ":204,"Tex":109,"Ter":953,"Tes":175,"Pân":88,"Pâr":129,"Tha":108,"The":1600,"Thi":130,"Tho":227,"Tib":83,"Tim":723,"Tin":109,"Tit":147,"Tir":112,"Top":132,"Tor":259,"Tok":94,"Tol":279,"Tom":280,"Ton":126,"Tot":116,"Tou":121,"Tru":137,"Tro":183,"Tri":361,"Tre":328,"Tra":1888,"Tur":781,"Tul":107,"Tun":93,"Tud":91,"вич":136,"biz":191,"bis":684,"bit":942,"biu":329,"bio":569,"bir":494,"baţ":118,"bil":3719,"bin":1111,"bii":385,"beş":168,"bo ":147,"blu":442,"şa ":427,"blo":266,"ble":593,"bli":4345,"bla":309,"boa":326,"bol":798,"boi":1231,"bog":143,"biş":155,"biţ":97,"şe ":206,"şca":505,"şal":128,"şan":384,"şap":297,"bon":331,"bom":116,"bor":1299,"bot":233,"bos":94,"bov":171,"şar":126,"şas":296,"bou":197,"box":118,"şat":99,"be ":463,"ban":1063,"bal":2277,"bai":156,"baj":238,"bac":607,"bab":295,"án ":151,"baz":1371,"bat":704,"bas":635,"bar":766,"bdi":107,"bea":119,"bi ":576,"bei":94,"bee":100,"bec":120,"ber":2623,"ben":568,"bel":997,"bes":190,"bet":600,"bia":703,"bib":169,"bic":703,"bie":1278,"áce":223,"şnu":136,"buţ":387,"buş":122,"şoa":686,"şor":235,"şov":403,"ca ":12197,"car":20537,"cas":995,"cat":4867,"cau":568,"can":4982,"cap":1522,"caz":602,"cav":140,"cac":106,"cab":250,"cad":1721,"cam":769,"cal":7164,"caf":88,"cai":123,"şu ":299,"ce ":13744,"bri":8393,"bro":479,"şco":241,"bra":1280,"bre":732,"bu ":154,"şea":100,"bru":3685,"şed":992,"bso":227,"bse":314,"şez":265,"şev":87,"bst":592,"şel":294,"şef":250,"şer":161,"şen":171,"şi ":40695,"bur":1502,"bul":939,"bun":893,"bum":1812,"bui":746,"buc":290,"but":536,"bus":305,"buz":102,"şcă":238,"şie":311,"şii":223,"by ":257,"şia":83,"bră":230,"şit":599,"şir":239,"şin":563,"şil":101,"aka":186,"am ":1398,"ake":307,"aki":175,"ajo":811,"aju":1101,"al ":30968,"aja":297,"aje":549,"adă":644,"ail":713,"aim":241,"ain":2042,"aio":622,"air":263,"ais":301,"ait":135,"aiu":141,"ak ":275,"aie":333,"aid":284,"aic":780,"aib":127,"aia":581,"ahn":102,"ahi":154,"acă":1581,"ahu":103,"aho":221,"aj ":993,"adâ":150,"ârâ":145,"aha":317,"agl":117,"agm":128,"agh":501,"abă":348,"agi":1223,"agr":589,"agu":482,"agn":543,"ago":775,"anu":8793,"anz":399,"any":226,"ano":1227,"ann":872,"ant":7062,"ans":5187,"ane":4573,"ang":1746,"anh":83,"ani":17950,"anj":319,"ank":595,"ap ":209,"ana":3541,"anc":4078,"and":7634,"amu":1451,"amm":250,"amo":500,"amn":539,"amp":1577,"ams":162,"ami":2968,"ame":7488,"amb":1018,"ama":1598,"alz":98,"alv":263,"alu":3357,"alt":3527,"als":199,"alp":187,"alo":2252,"aln":118,"alm":409,"all":1429,"alk":125,"alg":190,"agă":206,"ali":13360,"alc":1323,"ald":503,"ale":15313,"alf":367,"ala":3376,"alb":2405,"an ":14955,"aku":88,"ako":128,"acţ":1206,"ârş":461,"aba":554,"abe":900,"abi":2311,"abl":317,"abo":655,"abr":755,"abs":332,"abu":239,"ae ":1225,"aca":773,"aaa":86,"aal":84,"aar":122,"ad ":1372,"ânt":3632,"şur":726,"ânu":94,"ânz":207,"şul":2492,"âns":100,"ac ":1040,"ştr":244,"âmt":99,"şti":6783,"şte":3540,"âmp":537,"âng":896,"âne":1748,"şta":102,"ând":5547,"âni":6072,"ab ":204,"ânc":472,"âna":293,"afr":149,"aft":132,"aff":130,"afe":369,"afi":1982,"afl":2509,"ai ":11311,"aga":899,"age":1103,"afu":111,"âur":92,"âul":1913,"aen":112,"ael":563,"aes":133,"aer":621,"ah ":371,"âte":342,"afa":1595,"ado":765,"ârs":182,"adr":1167,"ârt":98,"adm":1348,"adj":104,"adi":2476,"ârz":238,"âu ":266,"ade":2813,"ag ":301,"ână":2880,"adt":92,"adu":1730,"aco":1240,"acl":100,"ack":689,"aci":1819,"ach":1150,"ace":7711,"ât ":1298,"acc":1560,"ârb":268,"ada":3740,"ârf":276,"ârg":288,"af ":209,"acv":115,"ârn":129,"act":5256,"acu":1523,"ârl":126,"acr":543,"azo":188,"azi":1570,"arţ":1475,"azu":425,"aze":593,"avâ":822,"aza":1518,"azd":83,"azz":139,"avă":214,"asă":1423,"axi":362,"axo":262,"az ":338,"axa":101,"atâ":459,"ată":12359,"âi ":95,"ays":88,"aya":143,"aye":215,"ân ":1771,"âlc":198,"ba ":2953,"âmb":183,"ază":4808,"âln":280,"âin":172,"at ":24564,"amă":335,"arh":1164,"arg":1153,"arf":116,"are":42152,"ard":2497,"arc":2307,"arb":848,"ara":6502,"arp":413,"aro":1047,"arn":629,"arm":1225,"arl":2466,"anç":90,"ark":583,"ari":10760,"aru":1463,"arv":129,"arr":585,"ars":566,"art":13731,"au ":13208,"asa":2050,"ary":262,"arz":166,"asi":2001,"ană":4433,"ash":375,"asc":1871,"ase":2773,"aso":520,"asn":213,"asp":360,"ask":118,"asm":175,"asl":121,"ar ":8918,"apa":2757,"ape":1246,"api":1462,"aph":142,"apl":456,"apo":1977,"app":137,"apr":2890,"aps":139,"apt":1565,"apu":270,"as ":1819,"ală":6884,"ava":1432,"ax ":193,"auz":385,"aux":116,"aut":2879,"avr":217,"avo":325,"anţ":3393,"avi":1654,"anş":96,"ave":2326,"ay ":775,"awa":162,"avy":131,"avu":1095,"ară":4267,"av ":216,"ata":4096,"asu":901,"ast":6214,"ass":610,"asy":113,"atm":162,"alţ":185,"atl":201,"atr":2501,"ato":5035,"ate":24962,"atf":138,"atc":92,"ati":8684,"ath":466,"aw ":115,"aua":249,"auc":144,"att":328,"ats":134,"atu":9240,"aul":521,"aum":109,"aun":296,"aur":1060,"aus":649,"aud":358,"aug":1299,"apă":1796,"amţ":177,"Wür":170,"ка ":90,"ий ":128,"ич ":137,"jec":116,"jel":228,"jen":194,"fâr":376,"fân":580,"ji ":99,"jat":278,"jap":309,"jar":183,"jan":170,"jaz":89,"je ":321,"joa":246,"joc":694,"joz":167,"jos":164,"jor":690,"jit":146,"jin":221,"jaţ":96,"bţi":531,"jo ":103,"jlo":496,"itm":199,"itl":818,"itr":663,"ito":6294,"itu":8009,"itt":280,"its":137,"itz":191,"ity":420,"iub":117,"iuc":160,"iua":221,"iud":230,"ipă":404,"isk":89,"ism":2124,"isl":772,"iso":596,"isn":143,"isp":881,"iss":507,"isr":101,"isu":227,"ist":19214,"iv ":3796,"ita":17021,"itc":116,"ite":7821,"ith":307,"iti":4614,"ivo":234,"ivu":281,"ius":647,"iur":519,"ium":322,"iul":7954,"iun":9474,"iva":1811,"ix ":362,"ivi":3232,"inţ":4376,"ive":4336,"ipr":212,"ipo":338,"ipp":144,"ipu":386,"ips":239,"ipt":541,"ipi":1233,"aţă":1525,"ipl":436,"is ":3857,"ion":10900,"iop":116,"ior":1475,"ios":402,"iot":422,"iou":159,"iog":188,"iol":1112,"ipa":2480,"ipe":948,"iov":274,"ir ":799,"iru":345,"irs":100,"irt":172,"iro":730,"irm":483,"eîn":134,"irk":94,"irl":333,"iri":2227,"isi":1374,"ish":315,"ină":2514,"isf":103,"ise":3028,"isc":2092,"isa":444,"iu ":4493,"iqu":132,"ilă":788,"inâ":388,"ire":5707,"imă":577,"irg":179,"ira":895,"irc":947,"it ":8220,"ünc":112,"iză":370,"ja ":337,"ită":7145,"ixt":86,"isă":796,"ixe":89,"iz ":119,"ivă":1340,"izu":147,"izv":208,"izo":952,"izi":2792,"ize":859,"iza":6312,"kil":158,"kin":314,"kir":111,"kis":140,"km ":1110,"ki ":642,"făc":542,"făr":519,"kel":127,"ken":233,"kes":118,"ker":360,"ket":144,"fă ":122,"gân":291,"kfu":88,"ke ":452,"kra":120,"kre":109,"kt ":111,"kov":198,"km²":262,"kol":93,"ks ":224,"făş":535,"cţi":4945,"ko ":243,"jut":351,"jus":113,"jul":508,"jun":382,"jum":207,"jur":1124,"jud":4033,"juc":683,"kar":128,"kan":145,"kai":124,"kad":96,"ka ":524,"ha ":718,"ham":492,"han":1154,"hai":779,"hak":92,"hal":402,"hau":169,"har":1141,"has":93,"hat":192,"hae":287,"hag":86,"hab":90,"he ":3331,"hel":915,"hei":851,"hee":120,"hed":164,"hea":469,"hez":295,"hev":85,"het":520,"hes":378,"her":1057,"heo":670,"hen":622,"hem":280,"că ":14688,"hi ":1098,"dân":197,"căi":96,"căl":499,"căd":116,"căz":100,"căp":117,"căs":168,"căr":2073,"cău":418,"căt":3820,"hie":477,"hid":863,"hic":510,"hib":86,"hia":1153,"hip":1598,"hio":209,"hin":1334,"him":1433,"hil":698,"hii":152,"hiu":429,"hiv":233,"his":738,"hit":1266,"hir":636,"hiz":150,"hn ":414,"hle":150,"ho ":172,"gma":139,"go ":432,"gme":179,"glo":451,"gle":2336,"gli":771,"gn ":157,"gla":327,"gog":138,"goa":126,"gnu":85,"gno":150,"gni":185,"câş":533,"gne":487,"gna":170,"geş":236,"gs ":160,"gol":308,"gon":427,"gos":413,"gor":814,"got":99,"gov":160,"gu ":263,"gro":318,"gru":1821,"gra":4239,"gri":471,"gre":2106,"gto":159,"gui":168,"gum":179,"gul":1451,"gua":163,"gue":323,"gy ":135,"gră":290,"guv":925,"gur":1708,"gus":1778,"gvi":266,"iam":458,"ial":8383,"ian":7496,"ias":341,"iar":3383,"iau":106,"iat":2458,"ic ":11072,"iab":156,"iac":516,"iad":260,"iag":132,"ibl":375,"ibi":1287,"ibo":95,"ibr":438,"ibu":1167,"iaz":367,"id ":1405,"iba":208,"ibe":1115,"ia ":37192,"iet":2227,"ieu":92,"iev":591,"iew":117,"iez":102,"iel":766,"iem":1503,"ien":2907,"iep":154,"ier":4481,"ies":1526,"ied":283,"ief":128,"iei":9680,"aş ":2678,"ig ":320,"iec":2094,"ifu":325,"ifo":500,"ifr":208,"iff":103,"ife":1805,"ifi":2918,"dă ":1783,"ifa":105,"icr":452,"ics":163,"ict":2757,"icu":1908,"ico":2006,"ick":421,"icl":554,"ici":10582,"ich":1701,"ice":8554,"ie ":34669,"ica":13932,"idu":1244,"idr":458,"ido":239,"idi":1327,"idg":110,"ide":3884,"ida":1312,"if ":119,"iic":157,"iaş":207,"iaţ":1579,"idă":222,"iin":4917,"iil":3254,"iit":1059,"il ":2791,"ija":114,"iji":265,"ijl":490,"ijo":87,"im ":1225,"ika":140,"aţa":1077,"aşe":616,"ige":485,"aşc":90,"aşa":330,"iga":1279,"ii ":23496,"igm":125,"igh":1464,"igi":3078,"aşi":1717,"icâ":83,"igu":863,"aşu":2407,"aşt":704,"igr":211,"aşo":348,"igo":379,"ign":421,"dăc":87,"iha":624,"ică":10472,"ihi":105,"dău":132,"iho":423,"dăr":156,"ik ":233,"imo":864,"imn":359,"imm":132,"imp":4726,"ieş":578,"imf":123,"ime":4318,"ieţ":356,"imi":3490,"ip ":1099,"inc":6719,"ind":7549,"ina":7598,"imu":2173,"inn":213,"inm":129,"ino":1626,"int":13234,"ins":3523,"inf":1447,"ine":10869,"inh":83,"ing":4928,"ini":7437,"inl":374,"ink":229,"ioa":4790,"ioc":312,"iod":317,"inu":2953,"inv":735,"iny":91,"inz":228,"iko":237,"icţ":367,"aţi":16926,"iki":186,"ike":152,"aţe":270,"ila":1467,"ilb":98,"in ":44693,"ilo":9977,"ill":1766,"ilm":2143,"igă":285,"ilh":99,"ili":9285,"ild":180,"ile":12078,"ima":4046,"imb":4580,"io ":1569,"ily":129,"ilt":143,"ilu":581,"ilv":1166,"hiş":314,"how":106,"hol":376,"hom":292,"hon":245,"hos":162,"hot":319,"hou":159,"hov":191,"hoo":89,"hop":132,"hor":542,"hoe":88,"hoc":86,"hni":581,"hno":368,"hne":86,"heţ":86,"hul":158,"hua":109,"htt":211,"hte":132,"hro":140,"hre":117,"hri":377,"ht ":1261,"hra":577,"hiţ":84,"hy ":109,"hwa":155,"hum":1416,"hus":146,"hur":185,"fi ":1715,"ffe":164,"ffi":135,"feu":99,"fet":117,"fes":1040,"fer":4398,"fec":1006,"fed":383,"feb":993,"fem":538,"fen":538,"fel":943,"fib":88,"fia":458,"faz":136,"fas":102,"fat":182,"far":402,"fap":490,"fam":1470,"fan":745,"fal":367,"fai":144,"fac":2220,"fab":663,"ff ":157,"fe ":258,"euş":129,"eză":2753,"fa ":130,"exu":301,"ext":1548,"etă":1447,"exa":920,"ez ":2054,"ews":115,"exp":1323,"epţ":305,"esă":354,"exi":1412,"exc":376,"exe":917,"ezv":899,"ezu":584,"evă":275,"eza":830,"ezo":739,"eze":4121,"ezi":2997,"erţ":230,"eta":3771,"epâ":360,"ete":2601,"etc":489,"eti":2973,"eth":248,"etn":363,"esp":1890,"eso":846,"est":55654,"esu":952,"ess":1010,"ev ":251,"euc":86,"eud":222,"epă":213,"eum":115,"eul":878,"eun":627,"eto":805,"etr":2728,"ets":89,"ett":511,"etu":1024,"etw":102,"ew ":746,"eve":1810,"eva":1191,"evo":1396,"enţ":4104,"evi":2580,"eut":437,"eur":1309,"eus":264,"ex ":508,"ewi":114,"eră":1931,"evr":439,"ey ":1079,"ewa":103,"epe":1003,"epi":751,"eph":288,"er ":7653,"epa":1109,"eot":142,"eos":392,"eor":2351,"eom":197,"eol":739,"eop":176,"eon":471,"elă":165,"eiţ":151,"es ":5970,"ept":3637,"epu":3456,"epl":448,"epp":122,"epo":532,"epr":2782,"erk":178,"erl":756,"eri":23643,"erg":1582,"emă":409,"erh":102,"ere":9729,"erf":436,"erc":1961,"erd":628,"era":10049,"erb":1083,"et ":2968,"esk":95,"esl":106,"esf":637,"enă":298,"esh":139,"esi":1831,"esb":88,"esc":5445,"ese":2325,"eu ":1098,"esa":2035,"erz":182,"ery":156,"erv":1894,"eru":1701,"erw":96,"err":761,"ert":2020,"ers":6219,"ern":5307,"erm":6392,"erp":946,"ero":1890,"eki":83,"ecţ":1050,"en ":4825,"elb":109,"ela":2761,"eld":314,"elf":84,"ele":22448,"eli":2942,"elg":1037,"egă":470,"elm":166,"eln":87,"ell":1629,"elo":7272,"elu":2902,"elv":133,"els":286,"elt":287,"eo ":496,"emb":7566,"ema":2057,"eme":3406,"emn":2329,"emo":1281,"ehă":102,"emi":3276,"emu":1154,"emp":1201,"ems":94,"ep ":186,"ene":5641,"enh":144,"eng":1760,"enb":358,"ena":2023,"end":1865,"enc":997,"eno":950,"enn":450,"enk":132,"eni":7113,"enu":3506,"ens":2167,"ent":26508,"enr":218,"eoa":176,"enz":462,"eog":396,"eod":283,"eoc":172,"egl":156,"ego":650,"egn":92,"ege":2159,"ecâ":351,"egi":6402,"egh":185,"egr":796,"egu":603,"ehn":787,"eho":111,"ehe":163,"ehi":357,"ecă":398,"ek ":382,"eic":203,"eia":920,"eis":644,"eir":131,"eim":251,"eil":863,"ein":887,"eii":140,"edă":119,"eaţ":502,"eie":409,"eid":483,"eig":145,"eaş":214,"eja":336,"el ":7309,"eit":209,"eiu":167,"eke":85,"em ":1443,"eju":102,"giz":650,"giu":3192,"git":384,"gis":1283,"gir":91,"gil":280,"gim":999,"gaţ":227,"gip":292,"gin":3668,"gio":683,"gid":91,"gie":1712,"gic":1515,"gii":481,"gia":2426,"bău":105,"băr":238,"ght":1266,"băt":475,"băn":99,"ghi":1143,"ghe":1448,"gha":167,"cât":1186,"gi ":458,"câi":94,"cân":2264,"câm":225,"gen":4213,"geo":702,"get":450,"ger":3349,"ges":353,"gh ":216,"bă ":1169,"gea":351,"geb":118,"gem":253,"gel":950,"gda":132,"ge ":2096,"gaz":511,"gby":87,"gas":177,"gar":1662,"gau":115,"gat":2233,"gaj":154,"gam":133,"gal":1275,"gan":2759,"ga ":1522,"îşi":423,"fuz":427,"fur":551,"fus":129,"ful":658,"fun":1914,"ftw":294,"ft ":458,"fra":2347,"fre":553,"fri":632,"fiţ":85,"fro":290,"fru":551,"for":8285,"fos":13009,"fot":1551,"fon":2006,"fol":2314,"flă":1101,"fiş":196,"feţ":166,"foc":121,"foa":663,"fle":282,"fla":1128,"fli":157,"flu":1381,"flo":329,"fic":5576,"fie":1608,"fig":239,"fii":4052,"fil":2800,"faţ":1332,"fin":1931,"fir":582,"fis":97,"fit":276,"fiu":394,"fix":216,"fiz":803,"cuţ":360,"da ":5431,"dba":199,"de ":81669,"dac":568,"dad":169,"dal":1004,"dai":112,"daj":204,"dag":131,"dae":325,"dat":5418,"dar":2392,"dap":257,"dan":788,"dam":518,"day":88,"dav":93,"dau":120,"cup":2017,"cun":3394,"cul":7448,"cum":2248,"cui":2182,"cuf":114,"cub":97,"cuc":191,"cua":310,"ctu":3820,"ctr":1989,"cto":4340,"cti":3912,"cte":2267,"cta":977,"coţ":184,"cră":288,"cy ":117,"cve":360,"cvi":112,"cva":166,"cus":289,"cur":6209,"cut":5650,"cuv":696,"ctă":260,"Șco":105,"cks":236,"ckh":87,"cla":1563,"cle":639,"clu":1691,"cli":610,"clo":419,"ceş":351,"cmi":98,"co ":1054,"cni":95,"cod":494,"coe":86,"cof":296,"cog":235,"coa":845,"cob":156,"coc":134,"con":13122,"coo":319,"col":4664,"com":13771,"cor":2665,"cos":422,"cop":2252,"cov":597,"cot":422,"cou":153,"cs ":186,"clă":363,"cqu":87,"ct ":2355,"cre":3245,"cra":1687,"cri":4361,"cru":523,"cro":1167,"cu ":14527,"cci":346,"cca":249,"cce":1997,"cea":5425,"cez":1350,"ch ":1051,"cev":105,"cer":3600,"ces":6831,"cet":999,"ceu":226,"cen":3570,"cep":2469,"cem":1612,"cel":8680,"cei":1228,"ceh":124,"cee":645,"ced":641,"ci ":3845,"Ști":135,"cha":1202,"Ște":246,"chw":220,"chu":202,"cia":8398,"ck ":1749,"cie":2502,"cid":710,"cic":613,"che":3039,"chl":127,"chi":6835,"cho":240,"chn":170,"chs":144,"cht":297,"ciz":320,"civ":411,"caţ":977,"cil":1200,"cim":273,"cif":735,"caş":448,"cii":3633,"cir":703,"cis":679,"cit":1218,"ciu":1361,"cin":2022,"cio":753,"cip":3172,"cm ":96,"cke":198,"ed ":964,"eba":172,"ebe":338,"ebi":493,"ebo":152,"ebr":2253,"ebu":793,"ec ":965,"eac":1155,"eag":683,"eae":329,"ead":219,"eak":166,"ean":4116,"eal":2295,"eam":780,"ear":779,"eas":2985,"eap":381,"eav":360,"eat":1944,"eau":812,"eaz":4296,"eb ":255,"ea ":37128,"efi":943,"efl":126,"efo":468,"efa":467,"efe":1778,"eff":109,"ei ":24037,"ega":2463,"eft":125,"efu":229,"eek":131,"een":318,"eel":266,"eea":861,"eed":149,"eer":336,"eep":102,"eet":278,"edi":6693,"ede":2885,"eda":988,"eg ":239,"edu":500,"edo":913,"edr":363,"ecl":455,"eck":180,"ech":2954,"eci":4375,"ece":4160,"eca":1262,"ee ":711,"ef ":336,"ecv":378,"ecu":2928,"ect":7556,"ecr":556,"eco":3176,"dwi":90,"dwa":128,"dy ":306,"dve":124,"dur":1540,"dut":183,"dus":2699,"duş":94,"dor":982,"dop":268,"don":1156,"dom":1511,"dol":361,"dox":527,"dow":256,"dov":2135,"dou":2054,"dos":139,"ds ":634,"diţ":1218,"diş":157,"deţ":4616,"dmi":1594,"dne":111,"doa":843,"dob":218,"doc":617,"dof":143,"doi":1173,"Țar":280,"dun":278,"dum":103,"dup":2223,"dui":145,"dul":3772,"dub":195,"dua":160,"duc":3456,"dri":740,"dra":1452,"dt ":159,"dre":2042,"du ":925,"dro":713,"dru":1503,"dge":174,"dic":3233,"did":167,"dia":4181,"der":5158,"des":4508,"det":654,"deu":131,"dev":1104,"dez":1907,"deb":451,"dea":1065,"ded":225,"dec":2801,"def":691,"dee":144,"deg":147,"dej":85,"dei":744,"del":2089,"den":4447,"dem":1462,"dep":2099,"deo":975,"di ":446,"dle":126,"dla":95,"deş":387,"do ":923,"dja":87,"div":1213,"diu":1854,"diz":147,"dim":595,"din":41384,"dio":1557,"dip":176,"dir":1178,"dis":3885,"dit":1572,"die":1235,"dif":1731,"dig":295,"dii":366,"daţ":232,"dil":110,"rgu":556,"rhe":302,"rj ":109,"rha":273,"rcă":369,"rhi":1066,"măr":2035,"măs":677,"măt":499,"măn":620,"rfu":326,"rga":2411,"ri ":15694,"rgi":1524,"rgh":746,"rbă":345,"rge":1425,"rgo":215,"ret":2582,"res":5915,"rev":1477,"reu":1156,"rew":92,"rez":5275,"rey":127,"mă ":3118,"rfa":103,"rfe":202,"rfi":117,"nân":632,"rfo":213,"rdu":767,"rds":382,"rg ":1476,"reb":516,"rea":18674,"ree":777,"ref":1708,"rec":5448,"red":1424,"rei":3494,"rej":104,"reg":5973,"rem":2573,"ren":2941,"rek":143,"rel":3576,"rer":308,"reo":342,"rep":4378,"rf ":235,"rda":852,"rcu":1210,"rct":172,"rdo":623,"rdi":1685,"rde":964,"re ":51071,"rbu":436,"rco":232,"rci":1263,"rch":609,"rce":1470,"rca":1029,"ray":96,"raz":629,"rd ":3327,"rap":865,"rar":2929,"ras":1358,"rat":9747,"rau":625,"rav":765,"rbi":1165,"rbo":575,"rba":839,"rbe":545,"rc ":287,"raj":371,"rai":1767,"rah":296,"rag":920,"ran":9556,"ram":2869,"ral":5890,"rak":183,"rab":1135,"raf":2847,"rae":350,"rad":3282,"rac":2468,"rpu":387,"rpr":755,"rpo":278,"rs ":1565,"rpe":182,"rpa":307,"rpi":136,"ror":724,"ros":1102,"rot":1489,"rom":6745,"ron":3428,"roo":164,"rop":6403,"roz":338,"rou":752,"rov":4132,"row":176,"rox":732,"rob":828,"roa":1307,"rod":3362,"roc":2541,"roi":1094,"rol":1987,"rof":1423,"roe":237,"roh":90,"rog":1247,"rno":327,"rnu":701,"rp ":237,"rna":2969,"rne":1758,"rni":1303,"reţ":1190,"rmo":436,"rmu":522,"ro ":2108,"rma":9885,"rme":3062,"reş":4337,"rmi":1348,"rls":94,"rlo":266,"rgă":207,"rli":413,"rld":353,"rle":420,"rla":2658,"rn ":698,"rks":134,"rke":254,"rm ":799,"riz":1053,"rl ":211,"rip":540,"rio":5018,"rir":448,"rit":7787,"ris":4701,"riv":1528,"riu":2574,"rdă":172,"rig":3530,"raş":5092,"rij":321,"rii":7673,"ril":8587,"rik":126,"raţ":2453,"rin":9619,"rim":5400,"ria":7770,"rib":1255,"ric":11723,"rid":1224,"rie":15408,"rif":356,"rk ":829,"roş":363,"rsă":312,"rui":1637,"rug":366,"rud":206,"ruc":1749,"rur":434,"rup":3037,"run":754,"rum":1184,"rul":9603,"ruz":121,"rux":123,"rus":1703,"rut":1017,"rva":737,"rvi":837,"rve":659,"rvo":119,"ry ":1178,"rsk":120,"rsi":1656,"rso":2085,"rsc":90,"rsa":860,"rnă":515,"rsh":97,"rse":1189,"rta":3149,"rst":426,"rsu":1104,"rto":1146,"rte":6836,"rth":550,"rti":6445,"rua":1449,"rts":182,"rtr":166,"rtu":1485,"rtt":156,"riţ":1112,"riş":356,"rmâ":178,"rt ":2203,"rro":293,"rmă":1457,"rri":340,"rre":470,"rra":339,"ru ":12849,"rry":345,"sc ":2232,"sab":243,"sac":340,"sad":91,"sag":137,"sai":83,"saj":124,"sal":1207,"sam":459,"sbe":121,"san":693,"sau":8354,"sat":4809,"sas":155,"sar":1304,"sa ":3104,"ón ":120,"ruş":110,"rze":109,"rtă":914,"rzi":434,"sha":218,"sho":144,"năr":653,"năs":2089,"năt":775,"she":136,"scă":1232,"shi":636,"năl":262,"si ":1523,"sfâ":443,"siv":865,"sie":984,"sid":975,"sic":666,"sib":419,"sia":1164,"sk ":250,"nău":325,"sit":6826,"siu":1567,"sir":294,"sis":2018,"sip":93,"sin":2491,"sio":987,"sil":2030,"sim":1237,"sih":314,"sii":129,"sif":302,"sig":587,"scr":3431,"scu":7764,"sbu":216,"se ":12289,"sca":1105,"sce":729,"sci":701,"sch":1873,"sco":2491,"sex":343,"sey":122,"ser":5132,"ses":902,"set":368,"seu":253,"sfa":100,"sez":381,"sh ":403,"nă ":12507,"sfi":168,"sfe":495,"sfo":294,"sea":1239,"sei":529,"see":104,"sed":775,"sec":2976,"seb":398,"sep":1669,"seo":135,"sen":1576,"sem":2294,"sel":1265,"spu":788,"spo":1513,"spr":1609,"spe":3508,"spi":782,"spa":1327,"sou":172,"sov":534,"sol":1405,"som":99,"son":2390,"sop":133,"sor":985,"sos":101,"sod":147,"sof":666,"soa":1403,"soc":1613,"su ":139,"sra":283,"st ":20718,"ss ":769,"sli":132,"slo":207,"slu":183,"sla":1454,"sle":117,"ski":424,"sfă":558,"sko":122,"sm ":736,"ska":303,"sna":139,"sni":276,"sne":177,"smo":155,"seţ":118,"smu":996,"so ":251,"sma":281,"seş":442,"smi":416,"sme":397,"soţ":294,"stâ":421,"stă":4284,"sse":604,"ssa":443,"sso":336,"ssi":591,"ssu":98,"ste":53928,"spâ":306,"stf":531,"sta":11097,"stm":85,"sto":3769,"sti":8907,"stl":380,"stu":4079,"str":12855,"sty":123,"sud":1668,"sue":207,"sub":3715,"suc":517,"spă":179,"suf":275,"sul":3772,"sum":370,"sup":2843,"sun":3645,"sut":208,"sus":705,"sur":1681,"suv":86,"sy ":155,"tai":479,"taj":164,"tal":7011,"taf":116,"tag":288,"tab":988,"tac":696,"tad":477,"tc ":460,"tba":1494,"tax":122,"tav":190,"tau":320,"tat":21973,"tas":470,"tar":6168,"tap":132,"tan":6974,"tam":968,"tch":206,"te ":79600,"suş":110,"ta ":8238,"oză":144,"pa ":2141,"oxă":260,"pe ":11904,"par":10822,"pat":2004,"pas":403,"pay":83,"pac":752,"pad":108,"pab":102,"pag":502,"pal":1642,"pai":83,"pap":190,"pam":183,"pan":5506,"phe":183,"pha":169,"pho":127,"phi":253,"pi ":238,"ph ":186,"lân":506,"pea":2043,"pec":3297,"ped":445,"pen":9052,"per":11036,"pet":1065,"pes":1059,"pei":1300,"pel":911,"pla":2428,"pli":1624,"ple":1254,"plo":453,"plu":926,"phy":102,"pia":1002,"pid":288,"pic":1543,"pie":1703,"pii":550,"paţ":844,"pil":610,"pin":728,"pio":918,"pir":800,"pis":848,"pit":1452,"piu":839,"poz":1416,"por":4692,"pop":3746,"pov":414,"pot":1327,"pos":1095,"poi":429,"pog":111,"pom":116,"pon":1731,"pol":4578,"poa":1462,"poe":647,"poc":495,"pod":314,"ps ":147,"ppe":285,"peş":178,"po ":105,"pta":1006,"pse":287,"psi":410,"pso":85,"ptu":1231,"pub":3609,"pte":2615,"pti":445,"pto":319,"pra":2308,"pt ":1178,"plă":316,"pru":251,"psa":94,"pri":13510,"pre":11982,"pro":14449,"pră":140,"ptă":561,"pur":1199,"pus":1351,"put":2590,"pun":2005,"pul":6398,"px ":1151,"puş":180,"puţ":344,"mân":11918,"lă ":9449,"iş ":380,"lăc":209,"lăd":384,"lăr":280,"lău":157,"lăt":576,"işa":158,"işc":590,"işe":100,"işi":457,"işo":462,"işn":143,"işu":248,"işt":1090,"iţe":420,"iţi":4507,"iţa":1141,"lăţ":94,"iţă":635,"qua":125,"que":368,"qui":218,"ra ":10628,"rb ":100,"ngo":269,"ngi":1205,"ngl":3065,"ngv":280,"ngu":1282,"ngr":328,"ngt":167,"ngs":258,"ni ":7085,"nge":1701,"ncâ":95,"ngh":727,"nga":1437,"nha":227,"ncă":762,"neg":502,"nei":3106,"nel":2471,"nen":1433,"nem":658,"nep":189,"neo":674,"ner":4256,"net":2067,"nes":1905,"nev":324,"neu":474,"ng ":2660,"nea":6161,"nec":713,"ned":727,"nee":362,"nef":188,"nfi":1313,"nfo":1463,"nfl":766,"nfr":253,"nfu":123,"ney":389,"nez":1743,"nex":158,"nfa":94,"nfe":701,"ncr":242,"nct":978,"nco":1033,"nci":6536,"ncl":974,"nce":5421,"nch":1298,"nca":697,"ne ":15507,"nbu":225,"ndu":3412,"ndr":2268,"nds":282,"ndo":1104,"ndi":3514,"nde":6309,"ndb":189,"nda":4140,"ncy":92,"ncu":853,"nal":8677,"nam":764,"nan":953,"nap":143,"nar":3126,"nac":272,"nad":606,"nag":295,"nah":123,"nai":648,"naj":750,"nc ":203,"nbe":172,"nd ":10185,"nav":597,"nau":373,"nat":5278,"nas":876,"naz":192,"na ":10566,"muş":108,"moţ":117,"nyi":101,"ntă":3762,"nz ":336,"ntâ":712,"nsă":705,"noţ":101,"ny ":515,"noş":120,"nvi":271,"nux":134,"nve":1249,"nva":170,"nul":11142,"num":9716,"nun":659,"nui":2359,"nus":463,"nut":1282,"nuu":86,"nuv":87,"nur":524,"nua":2364,"nue":133,"nuc":341,"nty":205,"nto":1327,"ntu":5345,"nts":104,"ntr":20429,"nti":5120,"nth":232,"nta":5926,"nte":13468,"nsu":2110,"nsn":130,"nsm":304,"nsp":737,"nso":628,"nst":5554,"nsf":385,"nse":1387,"nsh":116,"nsi":3286,"nsl":126,"nsk":220,"nsc":408,"nsa":2214,"nu ":2393,"nru":101,"nri":188,"nre":465,"nt ":10809,"niţ":1334,"niş":600,"ns ":1634,"noc":153,"nod":134,"noa":802,"nob":170,"nog":217,"nol":681,"noi":1449,"nop":228,"nom":2958,"non":580,"not":496,"nos":3264,"nor":3599,"nov":557,"nou":744,"noz":170,"nr ":214,"nne":796,"nna":357,"nno":163,"nni":320,"nny":106,"nme":156,"nma":86,"neţ":165,"neş":1107,"nli":309,"ngă":685,"nn ":394,"nla":407,"no ":1211,"nlo":244,"nkf":88,"nke":129,"ncţ":1362,"nki":120,"nka":125,"nkt":91,"înţ":344,"nje":175,"nja":194,"nju":195,"nii":3788,"ndă":489,"naş":348,"nig":141,"nif":691,"nie":6578,"nid":183,"nic":6607,"nib":123,"nia":13403,"nk ":409,"niz":1868,"nix":112,"niu":1843,"niv":2033,"nis":4310,"nit":7595,"nir":583,"nio":766,"nim":2048,"nin":1227,"naţ":2629,"nik":97,"nil":2118,"ogr":2357,"ogu":334,"ogi":3138,"ogl":113,"ogo":258,"ogn":118,"oga":345,"ogd":87,"oge":523,"oi ":1939,"ohi":99,"oho":87,"ohn":440,"oha":219,"ocă":128,"ohe":86,"ois":381,"oir":138,"oiu":600,"oit":118,"oin":312,"oaţ":87,"oil":1036,"oaş":230,"odă":270,"înă":265,"oii":90,"oic":184,"oid":249,"oie":2586,"ok ":171,"oia":306,"obţ":455,"ol ":1950,"oiz":87,"oce":1371,"och":606,"oci":2584,"ock":1201,"ocl":282,"ocm":112,"oco":593,"împ":1524,"ocr":595,"obs":247,"obu":209,"oe ":171,"oca":5500,"occ":161,"îmb":234,"ode":1683,"odi":1388,"înv":645,"odo":1005,"înt":5727,"înr":506,"îns":1196,"odr":168,"ocu":4799,"înl":252,"oct":1467,"îng":438,"înf":1221,"of ":1300,"înd":673,"înc":2936,"îna":811,"oda":803,"oel":100,"oem":170,"oes":95,"oet":442,"oen":174,"ody":97,"odu":3682,"og ":550,"ofi":1691,"ofu":93,"oft":569,"ofo":587,"oez":194,"off":117,"ofe":1241,"ofa":91,"nzâ":121,"ob ":212,"îl ":203,"nză":237,"oc ":1888,"oap":522,"oan":2626,"oam":565,"oal":517,"oai":251,"oad":3000,"oac":410,"în ":51095,"oba":769,"od ":1364,"oar":8811,"oas":2028,"oat":2201,"obo":275,"obr":179,"obl":493,"obi":2216,"obe":608,"nza":270,"nze":236,"nuă":93,"nzi":410,"nzo":124,"nvă":302,"îi ":276,"otă":208,"oya":123,"oxi":1058,"oxe":145,"oz ":239,"ows":299,"own":215,"oră":461,"owi":83,"ovă":83,"orţ":934,"ozo":459,"oze":129,"ouă":1877,"ozi":1701,"oza":446,"otu":494,"oua":772,"ow ":278,"olţ":86,"oti":981,"oth":247,"ote":1814,"ott":429,"ots":89,"otr":617,"oto":1723,"ost":14678,"osu":176,"ota":1624,"otb":1480,"ov ":924,"osi":2418,"osh":105,"onă":692,"ose":1383,"osf":245,"osp":184,"oss":270,"osm":217,"osl":251,"oso":685,"osn":103,"oy ":170,"owa":92,"owe":145,"ovi":5242,"onţ":708,"ovo":380,"ovs":162,"ouv":83,"ox ":338,"ova":2953,"ove":2093,"orâ":88,"oug":124,"oui":176,"oul":710,"oun":598,"oup":188,"ous":347,"our":791,"out":476,"opo":1954,"opp":88,"opi":1812,"opl":160,"ope":4845,"oph":214,"opa":1115,"os ":2802,"opu":4445,"opr":1065,"opt":660,"ops":95,"oon":154,"ool":264,"ook":218,"ood":367,"or ":26373,"oot":145,"oor":339,"oop":114,"ork":590,"orl":449,"orm":7578,"orn":1037,"oro":968,"orp":872,"orr":316,"orc":286,"ord":5185,"ore":2827,"orf":352,"org":3181,"omă":1147,"ori":16103,"orj":132,"ou ":829,"osa":293,"osc":3302,"ort":5002,"ors":359,"orv":285,"oru":3894,"ory":244,"olă":311,"omâ":10245,"m² ":271,"ot ":1395,"orb":953,"ora":7147,"ola":2095,"old":2473,"olc":184,"on ":8021,"olj":96,"oli":6258,"oll":628,"olk":148,"olf":429,"ole":2350,"olg":83,"ols":165,"olt":1104,"olm":146,"oln":127,"olo":7169,"oly":117,"olu":4417,"olv":270,"om ":2396,"oki":92,"oke":139,"ona":10266,"ond":4478,"onc":1725,"onf":1659,"one":3635,"ong":702,"onj":211,"oni":6032,"onl":252,"onn":355,"ono":3183,"ons":6444,"ont":4103,"onu":2421,"onv":453,"ony":208,"onz":212,"oma":4275,"oo ":114,"ome":3698,"omb":2289,"omi":3631,"omm":249,"omp":6241,"omn":706,"omo":1504,"omu":6796,"op ":1017,"la ":23354,"lb ":181,"le ":40374,"lce":389,"lca":429,"lcl":134,"lch":83,"lci":164,"lcu":522,"lco":212,"lf ":227,"lde":317,"lda":182,"ldo":2003,"ldi":182,"ldu":132,"lab":636,"lac":1028,"lad":507,"lae":470,"lah":161,"lag":391,"laj":309,"lai":336,"lal":366,"lan":7785,"lam":2475,"lap":209,"lar":3822,"lat":4828,"las":2223,"lax":136,"lau":569,"lav":737,"lay":251,"lba":949,"ld ":1067,"lbe":538,"lbi":174,"lbo":115,"lbu":1909,"ky ":197,"kso":178,"lpi":329,"lph":128,"ls ":385,"lpt":166,"lon":2782,"lom":608,"lop":364,"loo":88,"lor":17380,"lod":381,"loc":8139,"log":3938,"loi":220,"los":2548,"lot":440,"lou":173,"lov":661,"low":107,"loz":395,"lni":416,"lne":136,"loa":1027,"lob":416,"lmo":117,"lmi":101,"leţ":90,"lme":740,"leş":291,"lma":385,"lna":86,"lmu":506,"lth":83,"lti":1438,"lto":515,"ltr":114,"ltu":1401,"lud":310,"luc":1053,"lub":644,"lua":671,"lug":175,"lue":1286,"lsi":131,"lso":99,"lst":136,"lta":1833,"lte":3356,"lu ":1358,"lse":84,"lsa":93,"liţ":378,"ía ":107,"liş":264,"lt ":1778,"găt":711,"gău":109,"găr":308,"găs":508,"lhe":118,"lcă":318,"lj ":83,"lgo":101,"lge":272,"lgi":975,"lbă":158,"li ":1453,"lga":583,"lfu":196,"lfo":121,"gă ":1042,"lfa":415,"lez":1735,"ley":333,"lex":1098,"leu":326,"lev":1072,"les":2557,"let":1046,"ler":1357,"leo":330,"lep":98,"lem":2259,"len":1650,"lek":93,"lel":1961,"lei":1502,"leg":2868,"lef":302,"lee":148,"led":336,"lec":2987,"leb":331,"lea":5194,"lls":187,"llu":109,"lly":238,"lo ":746,"lla":922,"lle":1509,"lli":1027,"llo":392,"ln ":118,"lm ":1367,"ll ":1537,"lit":10843,"lis":3477,"lir":181,"lip":665,"lio":847,"lin":3950,"lim":4821,"liz":3596,"liv":266,"liu":800,"lic":6840,"lid":584,"lia":5811,"lib":815,"lk ":118,"lik":113,"laţ":3598,"lil":379,"lii":609,"lig":1016,"laş":630,"lie":5757,"lif":704,"ma ":3957,"mb ":1486,"mac":332,"mai":9505,"maj":528,"mad":521,"mae":84,"mag":1419,"mar":6545,"mas":1035,"mal":1356,"mam":301,"man":9186,"max":174,"mat":6955,"mba":2864,"mbl":374,"mbi":1641,"mbe":588,"mbr":9100,"mbo":699,"me ":5049,"mbu":511,"med":2490,"meg":129,"mea":1453,"mec":632,"eş ":976,"met":2646,"mes":1043,"mer":5757,"mem":2715,"mel":4206,"men":12391,"mei":953,"hă ":127,"mez":105,"mex":145,"mfo":85,"luz":516,"lva":1356,"lve":558,"lvi":203,"lul":6901,"luj":787,"lui":26427,"lup":481,"lun":1806,"lum":1944,"lut":376,"lus":1014,"lur":909,"lux":157,"luv":232,"ly ":423,"ltă":720,"luţ":840,"mpi":1771,"mpe":1922,"mpr":847,"mpo":2882,"mpl":2315,"mpu":2400,"mps":120,"mpt":100,"ms ":246,"mog":102,"moc":469,"mob":459,"mod":2074,"mon":3526,"mom":281,"mol":693,"mov":314,"mor":1244,"mos":450,"mot":668,"mou":110,"mpa":3076,"mnâ":163,"miş":960,"miţ":248,"mto":98,"mst":145,"mnă":376,"moş":151,"my ":245,"mur":1183,"mus":438,"mut":273,"mpă":755,"mul":9511,"mun":7969,"muz":1842,"eşt":6641,"eşu":215,"eşa":195,"mi ":621,"eşi":561,"mbă":561,"eşe":1204,"min":5735,"mio":138,"mil":3851,"mir":1594,"mis":1523,"mit":6241,"miu":551,"miz":90,"mix":115,"eţ ":436,"mic":3196,"mia":589,"mig":156,"maş":321,"mif":173,"mie":1057,"mid":167,"maţ":1711,"mij":400,"mii":918,"mo ":311,"mn ":1067,"eţu":4047,"eţi":1636,"eţe":1089,"eţa":97,"mm ":112,"moa":417,"mnu":348,"mni":697,"mna":983,"mne":568,"mmy":134,"mp ":917,"mmo":100,"mma":189,"meş":407,"mme":257,"ăţă":263,"vă ":1622,"văr":375,"văz":128,"sţi":293,"văţ":340,"ziţ":770,"zvo":1221,"zua":152,"zur":207,"zul":782,"zut":213,"zz ":105,"rşi":489,"zi ":1628,"vâr":386,"vân":1791,"zec":677,"zei":499,"zea":690,"zdu":96,"uă ":1773,"zeu":674,"zes":98,"zen":2310,"zel":386,"zer":601,"ze ":1470,"zbo":1342,"zbu":165,"zf ":120,"zac":138,"zah":127,"zam":95,"zan":432,"zar":1712,"zau":120,"zat":4549,"zoa":213,"zot":117,"zor":484,"zom":97,"zon":1721,"zol":318,"zof":297,"rţă":100,"zo ":122,"rţe":443,"rţa":169,"rţi":2629,"rţu":83,"rţ ":87,"uăz":94,"zib":96,"zia":1295,"zie":586,"zid":234,"zic":2773,"zii":433,"zin":2192,"zim":92,"zil":806,"zaţ":846,"zio":247,"zir":91,"zis":507,"zit":1014,"ziu":1413,"yst":189,"ysi":92,"ys ":152,"tăţ":3951,"yon":90,"za ":1974,"ywo":86,"ye ":94,"tă ":27261,"yer":209,"ya ":253,"yan":149,"yn ":128,"yle":187,"yo ":86,"yne":94,"tăl":523,"tăn":89,"tăm":184,"tăz":367,"tăt":383,"tăr":1670,"tăp":108,"yin":96,"tîn":184,"xt ":219,"xtr":935,"xtu":126,"xte":487,"xti":276,"xpr":511,"xpo":137,"xpl":405,"xpe":325,"xon":265,"ăţi":4022,"ăţe":252,"ăşe":185,"ăşi":118,"ăşo":168,"ăşu":379,"ăşt":194,"xul":217,"xua":180,"săm":195,"săn":94,"săi":149,"tât":368,"târ":286,"tân":1123,"să ":6878,"tâi":116,"tâl":280,"tâm":92,"xem":547,"xer":167,"xec":276,"xel":184,"pţi":497,"xis":976,"xil":150,"xim":851,"xid":122,"xic":439,"xig":85,"săr":830,"săs":204,"săp":211,"săt":291,"său":989,"xcl":154,"xce":187,"xe ":275,"xat":91,"xan":620,"xac":149,"ww ":168,"www":168,"oţi":926,"oţe":90,"wn ":181,"ws ":286,"wre":154,"wor":208,"woo":193,"răş":270,"răţ":90,"sân":187,"ră ":10046,"wer":171,"wel":112,"wei":114,"web":177,"oş ":108,"răb":152,"răd":292,"răc":168,"răg":121,"răj":88,"răi":753,"răn":163,"răm":369,"oşt":362,"oşu":230,"oşa":206,"oşi":435,"sâr":193,"wis":119,"wig":94,"wic":83,"win":151,"rău":112,"răs":796,"răt":330,"răr":765,"răz":877,"wa ":123,"wan":150,"wal":599,"way":113,"war":714,"viţ":222,"viş":91,"vro":102,"vri":167,"vre":765,"vra":124,"vsk":216,"vut":1014,"vul":660,"vy ":150,"via":1245,"nţ ":202,"vio":597,"vir":425,"vaţ":256,"vil":1004,"vin":4712,"vig":218,"vii":288,"vic":1489,"vid":1022,"vie":1344,"viz":1818,"viu":343,"vit":1797,"vis":1422,"nţa":4036,"nţe":2750,"nţi":4753,"nţu":270,"vo ":269,"veţ":303,"veş":233,"voa":145,"voc":768,"vod":247,"voi":344,"vol":2372,"von":307,"vor":1265,"vot":169,"vos":108,"nţă":2104,"vi ":279,"rât":86,"râu":1467,"râr":88,"vez":158,"ver":5755,"ves":2284,"vet":135,"râm":188,"rân":915,"vei":383,"veh":194,"veg":396,"ven":3368,"vel":1246,"vea":1522,"ved":733,"vec":1443,"ve ":2034,"val":1848,"van":2141,"var":1789,"vat":1229,"vas":355,"vaz":94,"vac":381,"vad":175,"vai":89,"uză":207,"uzâ":97,"va ":4378,"usţ":288,"uzu":128,"uzi":2633,"uvâ":532,"uze":512,"uza":616,"ută":2040,"uxe":267,"usă":1693,"uz ":167,"ură":2750,"upă":3161,"ux ":398,"uvi":580,"unţ":1150,"uve":1576,"urâ":83,"ună":2252,"ush":108,"usi":1228,"use":1795,"usc":466,"usa":280,"uu ":89,"usu":380,"ust":4305,"uss":282,"uso":94,"ulţ":391,"uth":338,"uti":1787,"ute":2406,"uta":1302,"utt":99,"uts":136,"utu":1616,"uto":3287,"utr":237,"us ":5190,"ulă":561,"ut ":7246,"urb":404,"ura":6173,"urd":294,"urc":802,"ure":4226,"umă":1226,"urg":1586,"uri":11434,"urk":100,"urm":1472,"urn":1161,"uro":4600,"urp":138,"urr":101,"urs":2050,"urt":1427,"uru":770,"ury":127,"urz":103,"unz":236,"upa":1044,"ur ":1460,"păş":90,"upi":117,"upe":1889,"upo":171,"upr":3078,"upl":134,"upt":549,"upu":1021,"ump":261,"umu":1472,"umi":4694,"umo":274,"umn":200,"uma":1213,"umb":1802,"ume":7127,"unt":4936,"uns":365,"unu":4147,"unk":173,"uni":10730,"uno":4024,"unn":89,"unc":3006,"und":2612,"una":3959,"ung":1996,"une":10686,"up ":833,"ucţ":871,"um ":3644,"ulu":21791,"ult":5763,"uls":125,"ulp":273,"ulo":572,"ulm":181,"ull":195,"uli":2417,"ugă":238,"ulg":558,"ule":2260,"ulc":332,"ula":6764,"ulb":106,"un ":26513,"uid":145,"uie":791,"uaţ":284,"uil":227,"uin":534,"uir":346,"uis":305,"păt":304,"păs":368,"uk ":108,"mţ ":178,"uia":763,"uit":3995,"ul ":62901,"ucâ":92,"ugh":328,"ugi":103,"ugb":125,"uge":384,"ugo":240,"ufu":127,"ui ":29161,"uga":410,"păi":109,"ucă":1628,"păd":164,"păr":2478,"păm":252,"ugu":1856,"uha":84,"uj ":675,"uco":175,"ucr":1114,"uct":1068,"ucu":1790,"uda":563,"ude":4922,"udi":2446,"ubo":209,"ubm":96,"ubs":626,"ubt":149,"ubu":425,"uca":1046,"ue ":469,"uce":1968,"ucc":519,"uci":711,"uch":237,"ucl":385,"uck":119,"uer":254,"ues":246,"pă ":4354,"uff":102,"ufe":113,"ufi":109,"ufl":99,"udu":394,"udo":402,"ug ":96,"ued":469,"uea":236,"uen":1166,"uel":339,"ub ":2463,"tuţ":713,"ua ":1456,"uat":4356,"uar":3767,"ual":1937,"uan":471,"ubi":491,"ubl":4031,"ube":197,"uba":209,"ubc":93,"ubd":102,"ud ":2013,"uad":93,"uc ":293,"tze":90,"tyl":114,"tuş":101,"ty ":780,"twa":283,"trâ":424,"tur":9303,"tus":270,"tut":920,"tui":1608,"tul":18833,"tun":827,"tum":175,"tua":5218,"tud":1979,"tue":106,"tug":400,"tz ":249,"two":138,"toţ":88,"tră":1759,"toş":149,"ts ":552,"tiţ":743,"tiş":169,"tre":13329,"tt ":332,"tra":10048,"tri":7435,"tru":15106,"tro":4167,"tu ":332,"tsc":140,"tsu":91,"tst":102,"tta":206,"tte":678,"tti":236,"ttl":111,"tto":150,"ttp":214,"tts":95,"teş":321,"tme":92,"tma":135,"to ":1187,"tmo":189,"tni":304,"tne":121,"tp ":211,"tna":149,"tno":89,"tof":98,"tod":1039,"toc":696,"toi":238,"tog":562,"tob":142,"toa":4019,"tou":153,"tov":167,"tos":511,"tot":1088,"tox":87,"tom":2691,"ton":3163,"tol":1579,"tor":17808,"top":634,"tr ":2261,"tii":1559,"til":2704,"taţ":1027,"tif":641,"tie":3100,"taş":87,"tig":849,"tir":1365,"tit":3982,"tis":1483,"tin":5976,"tim":3231,"tip":1320,"tio":2187,"thu":1487,"tia":853,"tib":219,"tic":12965,"tid":1357,"tiz":272,"tiu":313,"tiv":7387,"lţi":875,"tli":252,"tlu":762,"tla":333,"tle":501,"tem":5382,"ten":2986,"teo":833,"tep":232,"tei":2254,"tej":251,"tel":8378,"tee":83,"tef":321,"teg":901,"teh":698,"tea":10690,"teb":131,"tec":1715,"ted":479,"pân":2359,"tfo":164,"tfe":489,"tfa":104,"th ":1080,"tez":721,"tex":467,"tev":339,"teu":83,"tet":387,"tes":961,"ter":17000,"ti ":4750,"pâr":90,"tho":249,"thr":172,"the":1255,"thi":201,"tha":314,"ăpi":117,"ăr ":639,"ărg":110,"ări":6448,"ărc":171,"ăre":1669,"ărb":346,"ăra":1104,"ăpu":119,"ăpt":200,"ălă":333,"ămâ":1238,"ăsp":468,"ăsu":674,"ăst":933,"ăta":498,"ăte":138,"ăpâ":120,"ăti":182,"ălţ":396,"ăto":3911,"ăro":211,"ăru":1791,"ărt":197,"ărs":101,"ău ":1645,"ăsc":1578,"ăse":603,"ănă":998,"ăsi":241,"ăut":251,"ărâ":207,"ătu":1360,"ătr":2034,"ăud":174,"ăul":112,"ăsă":746,"ără":1000,"ăzu":203,"ărţ":804,"ăzi":480,"ăze":118,"ăzd":88,"ăzb":1237,"ătă":689,"ăuţ":165,"ăce":168,"ăca":435,"ăci":357,"ăcu":469,"ăde":218,"ădi":504,"ădu":392,"ăi ":268,"ăia":213,"ăie":323,"ăcă":141,"ăl ":131,"ăin":267,"ăit":151,"ădă":164,"ăil":231,"ăgă":140,"ăle":134,"ălc":90,"ăld":111,"ăla":258,"ălb":84,"ăma":126,"ămi":144,"ăli":530,"ălu":247,"ăne":410,"ănc":84,"ăni":157,"ză ":7802,"zăr":410,"zăt":197,"zău":117,"zân":327,"ürt":162,"uş ":157,"xă ":377,"uţi":2814,"uşu":97,"uşt":92,"uşo":225,"uşe":140,"uşc":117,"uşi":662},"n_words":[8213281,9706468,7977386],"name":"ro"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/rus b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/rus new file mode 100644 index 000000000..228e71e1b --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/rus @@ -0,0 +1 @@ +{"freq":{"D":12949,"E":10306,"F":8444,"G":9635,"A":18320,"B":11812,"C":18729,"L":10133,"M":18025,"N":9350,"O":8480,"H":7852,"I":36250,"K":4555,"U":4649,"T":15138,"W":7160,"V":11078,"P":15071,"S":24620,"R":10933,"X":14985,"f":12270,"g":18709,"d":30289,"e":107154,"b":13058,"c":32324,"a":88793,"n":72221,"o":77565,"l":46717,"m":27155,"k":11440,"h":29689,"i":78874,"w":9055,"v":9950,"u":33414,"t":65000,"s":53078,"r":72396,"p":19491,"z":3846,"y":15658,"x":6168,"́":88446,"ь":418052,"э":80439,"ю":190059," o":3966,"я":756306,"ш":164289,"щ":122233,"ъ":10879,"ы":569718,"ф":163421,"х":364215,"ц":246632,"ч":362951,"р":2010938," a":3919,"с":1933070,"т":1865754,"у":741481," t":5450,"ё":73990,"И":44043,"Л":43881,"К":96587,"Н":57501,"М":84561,"П":106733,"О":53561,"Б":68591,"А":88041,"Г":58489,"В":87514,"Е":15516,"Д":50036,"З":22723,"Ж":9219,"Ш":21342," H":6358," I":14743,"Ю":9600," N":6330,"Я":13672," O":4736," L":7278,"Э":22580," M":13492,"Т":45273," B":8977,"У":23856," C":13678,"Р":75819," A":12906,"С":148731,"Ц":10320," F":6714,"Ч":15862," G":7609,"Ф":36383," D":9169,"Х":20421," E":6845,"л":1373509,"к":1271742,"й":669125,"и":2990916," X":9849,"п":840034,"о":3520831,"н":2386826,"м":997958,"г":667312," S":16699,"в":1520663," R":8106,"б":419069,"а":2917550," P":10356," W":6218,"з":510343,"ж":242497," V":5002,"е":2737376,"д":981077," T":11223," А":74197," Б":66425," В":84271," Г":55440," Д":46951," Е":13561," Ж":8620," З":21445," И":40121," К":90300," Л":41939," М":81442," Н":51890," О":47190," П":101697,"Co":3768,"I ":12785," б":96560," а":114180," г":188817," в":459004," е":32581," д":177939," з":81625," ж":31277," й":4814," и":369580," л":56771," к":233167," н":240854," м":177553," п":455990," о":265653," Р":63171," С":125419," Т":41894," У":21149," Ф":32286," Х":19430," Ц":9599," Ч":15364," Ш":14654," Э":20859," Ю":9415," Я":13422,"C ":3880," т":131031," у":81588," р":185096," с":401251," ц":26307," ч":72261," ф":71734," х":30938," ш":31141," ю":9238," я":35568," э":51707,"Ma":3809,"II":10412,"VI":3879,"Th":4668,"X ":5588,"S ":3829,"a ":12175,"i ":4290,"he":9109,"g ":4678,"ea":4162,"ec":3745,"de":5482,"h ":4087,"el":5609,"en":10589,"et":4586,"es":8452,"er":17575,"e ":29556,"f ":4058,"ch":4543,"ce":3891,"c ":3917,"d ":10245,"at":8929,"as":4202,"ar":11277,"al":8675,"am":4333,"an":13622,"ac":3987,"nt":7777,"ns":3721,"of":4484,"om":4497,"on":14150,"ol":4531,"os":3740,"ou":4174,"or":10679,"r ":11184,"ll":5038,"o ":6694,"ma":4022,"me":5234,"na":4836,"nd":7645,"ne":5797,"ng":6066,"ni":4386,"m ":5088,"li":5421,"le":7129,"la":5868,"n ":18576,"ic":8588,"ia":4454,"ie":3873,"k ":4036,"is":6529,"it":5343,"il":4505,"in":14086,"io":6997,"l ":9526,"y ":8801,"ve":4522,"x ":4062,"ur":4265,"us":4229,"to":4590,"te":9298,"ti":9123,"th":7132,"ta":6068,"st":7180,"ro":7763,"ri":8232,"re":8155,"ra":7850,"t ":13376,"s ":22614,"́в":5893,"́д":3913,"́й":4535,"́м":3791,"́л":9850,"́н":15831,"́р":9052,"́с":4186,"́т":6032,"К ":4112,"О ":4223,"А ":10572,"В ":18440,"ья":15305,"ью":22763,"эл":12007,"эк":10864,"эр":3980,"эн":8177,"эт":23791,"юб":4435,"юг":4684,"юд":5402,"юз":4895,"юл":6476,"юн":7127,"юр":4992,"юс":3863,"ют":24842,"юч":8444,"ющ":38941,"яж":4621,"яе":26767,"яд":10334,"яв":18798,"яб":17686,"ян":29130,"ям":15306,"ял":9628,"яз":22046,"ях":9639,"яс":6449,"ят":41978,"яр":7070,"яю":12156,"ящ":14702,"щи":42463,"ще":53089,"ща":18897,"ъе":8051,"ый":115257,"ык":21356,"ые":44083,"ыд":3688,"ыв":20957,"ыш":9845,"ыч":6916,"ых":88893,"ыт":10971,"ыс":15933,"ыр":7427,"ып":8198,"ын":9614,"ым":40979,"ыл":22285,"ьк":10517,"ьд":4034,"ье":17860,"ьз":12362,"ьб":9420,"ьш":16573,"ьс":28658,"ьт":14115,"ьн":93902,"ьм":17794,"хе":5192,"хи":15842,"хн":9628,"хо":65229,"хр":8875,"хс":5190,"ху":8026,"фф":4256,"ха":22339,"ци":120621,"цк":12640,"цо":4729,"цу":6546,"ца":29752,"це":46729,"чл":3954,"чн":40293,"чи":44063,"чк":5394,"чт":9754,"цы":8412,"че":142550,"ча":74585,"шо":6953,"шн":6580,"шк":7840,"шл":7340,"ши":40508,"шт":17550,"ше":40253,"чё":6388,"ша":19003,"ск":366421,"см":15604,"сл":64229,"со":139920,"сн":41282,"ср":13223,"сп":78471,"св":31144,"рё":5020,"сб":4953,"се":102280,"си":96102,"рш":7321,"ры":45781,"рь":12146,"са":63371,"ря":46850,"рр":14529,"рс":52200,"рт":57700,"ру":105041,"рх":14747,"рц":4365,"тн":65472,"тм":3983,"тл":9354,"тк":17989,"тс":84335,"тр":155968,"то":273813,"те":235202,"тд":4232,"тв":124455,"сё":6893,"ти":199676,"сы":9941,"сь":18264,"та":266195,"ся":89398,"тб":4549,"су":38119,"сф":3977,"сс":88379,"ст":540751,"сч":5733,"сш":4240,"сх":8473,"сц":3788,"ур":58652,"уп":39068,"ут":30026,"ус":56106,"ум":19318,"ул":47107,"ун":41314,"уи":4250,"уз":23986,"ук":30175,"уд":42687,"уг":33231,"уж":19840,"уе":15435,"уа":10851,"тя":20201,"уб":26698,"ув":5212,"ты":37440,"ть":74835,"тч":3850,"тт":6006,"ту":57964,"фу":8016,"фр":15690,"фо":29756,"фи":45878,"фе":25068,"фа":16306,"ую":32657,"ущ":17182,"уч":38493,"уш":8215,"ух":10059,"ёт":8989,"ён":22517,"ёр":12412,"ёл":4881,"ём":5538," II":3728," Ma":3710,"а ":616120,"Р ":10559,"С ":6434,"Ис":5682,"Ин":6739,"к ":120218,"Из":4203,"Ив":3823,"й ":507309,"Ле":11105,"Ли":8362,"Ла":6540,"Ку":8515,"Ко":21705,"м ":237652,"Кр":10087,"Ки":8491,"Ка":27548,"л ":64722,"На":20616,"Не":6593,"Ни":9075,"Му":3926,"Мо":21246,"о ":404148,"Ма":25177,"Ми":12922,"Ме":9781,"Ло":5700,"н ":135483,"Лу":3901,"Па":15703,"Пе":17521,"Пи":4313,"Пл":3876,"с ":91974,"По":29660,"р ":85184,"Ос":6849,"Ор":3751,"От":4582,"Об":5237,"Он":3901,"Ол":8342,"Но":9337,"п ":8470,"в ":366455,"Ам":4416,"Ан":11755,"Ал":14756,"Ав":5862,"Ба":12391,"Ар":8812,"б ":7229,"д ":64292,"Во":11807,"Ве":14286,"Ви":9847,"Га":7333,"Бо":12192,"г ":35799,"Бр":14227,"Бе":12321,"Би":3781,"Ва":10241,"Бу":4848,"Ди":3742,"Дж":8980,"Де":6705,"ж ":6087,"До":7659," Th":4595,"Ев":5669,"Ге":11433,"Гр":11587,"Го":10198,"е ":450788,"Да":6449,"и ":574901,"За":11852,"з ":53551,"ь ":133456,"е́":15696,"ы ":130752,"и́":16589,"ё ":6265,"Яв":5487,"ю ":63842,"я ":490850,"Эт":4232,"Ст":11217,"Су":5933,"Та":9444,"Ти":3758,"Те":7001,"ф ":6051,"То":6501,"Тр":6028,"Ту":4280,"Ук":4529,"х ":211491,"Пр":23361,"Ра":11292,"Ре":10364,"Ри":7652,"СР":8553,"т ":206463,"Ро":21953,"Ру":5315,"СС":13685,"СШ":6418,"Са":18244,"Св":4560,"Си":8236,"Се":17477,"у ":114144,"Со":23127,"Це":5862,"ш ":6132,"а́":24040,"Че":6673,"ША":6418,"ц ":11865,"Фр":9086,"Фе":6645,"Фи":4961,"Ха":6486,"ч ":21859,"Хо":3899,"ль":255358,"лы":10808,"лю":22731,"мб":8994,"ля":104684,"ма":130982,"лё":9664,"ме":172608,"ми":140084,"мл":6471,"лл":23806,"лн":13959,"ло":163517,"лс":10825,"лт":4507,"лу":35325,"ла":158459,"лж":4211,"ле":205849,"лд":3683,"лг":5390,"лк":10879,"ли":255185,"км":7931,"кн":9321,"кк":4284,"кл":31050,"кр":60959,"кс":31731,"ко":383857,"кт":66101,"ку":41628,"кц":9152,"ка":219076,"кж":14683,"ки":210538,"кв":18587,"ке":35320,"йн":21970,"йо":19765,"йр":3918,"йк":4778,"йл":4612,"йш":7189,"йс":69884,"йт":6056,"ия":163126,"ию":29435,"ищ":4465,"иш":6262,"у́":5838,"йд":4105,"ио":61311,"ип":31810,"им":121890,"ин":226639,"ик":130372,"ил":122490,"ии":133366,"ий":180537,"иц":62824,"ич":108247,"иф":12791,"их":84356,"ит":178471,"иу":4714,"ир":73443,"ис":176435,"ри":235653,"рк":23089,"рл":11046,"рм":37955,"рн":63599,"ро":363111,"рп":4622,"ра":429505,"рб":11729,"рв":24770,"рг":34028,"рд":18157,"ре":279331,"рж":10477,"пь":4901,"пы":11436,"пр":223152,"пп":19192,"пт":6272,"пс":5990,"пу":32229,"пи":56651,"пн":7871,"по":247631,"пл":31561,"ою":7698,"оя":26385,"па":81900,"пе":95232,"ощ":8932,"ош":11972,"оч":34323,"оц":13939,"оэ":5861,"ос":271102,"ор":307758,"оп":60188,"оо":12934,"ох":15431,"оф":19467,"оу":5082,"от":162519,"ок":93705,"ол":228863,"ом":207667,"он":199509,"ож":50393,"оз":54318,"ои":31770,"ой":205541,"ов":359690,"нё":5120,"ог":196172,"од":289964,"ое":90767,"ня":35079,"оа":5488,"об":119246,"нь":18690,"ны":243593,"нц":33951,"нч":4962,"нт":90634,"нс":97833,"нф":7203,"ну":26904,"но":402371,"нн":163382,"нр":4657,"нк":27682,"нз":4096,"ни":399245,"не":163042,"нг":32092,"нд":56240,"мё":3976,"нв":7556,"на":409072,"мя":17291,"мь":4683,"мы":32208,"му":54274,"мс":10476,"мп":42062,"мо":86128,"мн":19897,"мм":15488,"ге":39235,"гд":7818,"ги":64206,"гн":5587,"го":307537,"гл":27873,"гм":4198,"гр":76619,"гу":22493,"дв":21897,"да":163117,"вг":7437,"ве":186015,"ви":112054,"вк":13130,"вл":60895,"вм":3919,"вн":71300,"во":212143,"вп":4179,"вр":34804,"вс":46803,"ву":21309,"вт":16905,"вх":16990,"вш":21902,"вы":73241,"вь":4164,"га":61976,"вя":19117,"вё":4031,"би":27123,"бе":43659,"бр":63607,"бн":9059,"бо":89921,"бл":44500,"бу":21528,"бс":7153,"ва":210954,"бы":35755,"бъ":8402,"бщ":13191,"ад":83035,"ае":38603,"аж":22477,"аз":106308,"аб":41193,"ав":144996,"аг":30571,"ам":106564,"ан":372615,"ап":45088,"аи":20853,"ай":49922,"ак":101386,"ал":220430,"ах":49626,"аф":15259,"ач":35451,"ац":44113,"ас":161556,"ар":181597,"ау":19997,"ат":182329,"ба":30240,"ая":142316,"аю":29293,"ащ":9761,"аш":12824,"зс":6594,"зр":12483,"зу":17726,"зк":4107,"зи":46141,"зо":48202,"зн":42107,"зм":17172,"зл":7624,"ив":68972,"иг":39987,"зя":3693,"иа":42640,"иб":20393,"иж":14048,"из":124756,"ид":43626,"ие":128645,"зы":33503,"жо":5749,"жс":4009,"жу":6473,"жи":33668,"жн":29430,"за":99672,"зв":49033,"жё":3790,"зг":3804,"зд":32492,"зе":22277,"еф":7165,"еу":4109,"ет":190550,"ес":211743,"ер":322951,"еп":23032,"ео":22288,"ен":392846,"ем":131477,"ел":205217,"ек":97566,"ей":99541,"еи":5939,"ез":47927,"еж":36786,"ее":34825,"жд":33436,"же":89890,"жа":21003,"ея":12292,"ещ":8165,"еч":24475,"еш":11291,"ех":17181,"ец":24531,"дс":40426,"др":39150,"ду":60618,"дн":71944,"дм":11329,"дп":4848,"до":102671,"ди":135662,"дл":31466,"дк":7688,"де":155382,"дд":3909,"о́":17497,"дж":10265,"еб":21454,"ев":101298,"дё":3920,"ег":62011,"ед":133360,"дь":6956,"еа":12623,"дя":7893,"дш":3897,"ды":16920," Яв":5485," ар":13568," ба":10710," ав":18221," ад":9137," ал":10374," ак":9085," ан":12535," ам":9443," ап":7635," бу":7250," ва":6199," бы":23597," би":6156," бе":13045," бр":8596," бо":19871," бл":6242," вт":4810," вх":16859," га":5609," вы":32582," ви":13232," ве":27020," во":59783," вс":13316," вр":12829," вл":4862," вк":4169," вн":5530," дв":15611," да":12181," гу":4609," го":108387," гл":8578," гр":29774," ге":11208," ги":5523," ед":6587," ег":8307," до":35767," др":17969," ду":6602," де":43890," ди":14485," дл":25835," же":14087," за":57830," зв":5213," жи":10062," зн":7274," иг":13915," из":63621," ил":26819," ин":23235," им":21022," ис":39365," их":4602," ию":10395," ка":46349," ки":10920," кр":19920," ко":101579," кн":6962," км":7101," кл":11050," ку":8839," ла":5400," ли":22008," ле":16122," ло":3818," ме":49176," ми":21788," лю":4902," ма":35222," мо":29145," мн":7010," му":26862," ни":8598," не":49337," на":155501," но":20718," ок":24600," он":5812," од":28184," об":63971," от":54560," ор":15811," ос":31704," оп":15294," по":164771," пл":14871," пи":11060," пе":48196," па":21414," Ре":10285," Ра":11205," Ро":21862," Ри":7649," Пр":23192," Пе":17464," Па":15586," с ":51024," По":29407," Пл":3863," Пи":4292," От":4556," Ос":6825," Ор":3729," Те":6933," Ти":3719," То":6441," Тр":5998," Ст":11107," Су":5919," Та":9379," Св":4548," Си":8202," Се":17430," у ":4211," Со":23029," Ру":5277," СС":6857," СШ":6404," Са":18190," Фр":9072," Фи":4937," Фе":6613," Ук":4507," Ту":4270," Це":5856," Хо":3885," Ха":6470," Че":6653," Эт":4213," Ба":12348," Ар":8769," в ":244550," Ан":11697," Ам":4402," Ал":14708," Ав":5843," Ва":10204," Бу":4830," Бо":12018," г ":7009," Бр":14207," Бе":12299," Би":3719," а ":10629," Ев":5656," Ди":3719," Дж":8956," Де":6645," До":7584," Га":7281," Ве":14245," Ви":9808," Во":11759," Да":6384," Ге":11389," Го":10155," Гр":11539," Ис":5607," Ин":6668," к ":15541," Ки":8443," Ка":27418," и ":157390," За":11752," й ":4397," Ив":3814," Из":4180," Му":3903," Мо":21203," о ":7496," На":20476," Не":6542," Ни":9034," Но":9287," Об":5188," Он":3896," Ол":8330," Ко":21565," Кр":10028," Ку":8476," Ла":6504," Ле":11080," Ли":8319," Ло":5687," Лу":3887," Ма":25091," Ме":9720," Ми":12850," В ":17470,"II ":7232," ра":87254," ре":41392," ро":33130," пр":177960," пс":3748," пу":8711," св":25177," си":22645," се":47025," сл":16395," см":6218," ск":7720," сп":19254," ср":11080," сн":4707," со":89660," ру":13053," са":14863," ти":6431," те":38937," то":20252," тр":22707," ст":53938," су":12938," та":27006," ук":4204," ус":11044," уп":6557," ур":3864," ун":4890," ул":9872," ту":5700," фо":12379," фр":10534," фу":6744," фе":9085," фи":20989," фа":9016," уч":17593," хр":4873," хо":7233," ху":6092," ха":4633," ци":3784," це":18264," чт":6942," чи":6042," че":25547," ча":26885," ша":3808," шт":13545," эк":9725," эл":8825," эт":18390," юг":4276," ян":5667," яз":10931," яв":12558,"аз ":5770,"ад ":7406,"Явл":5341,"ав ":5373,"ам ":14841,"ан ":31178,"ак ":26116,"ал ":21311,"ай ":4239,"авш":9597,"авт":9645,"ага":8115,"аго":7572,"ада":10767,"ади":12630,"аде":10895,"адм":7561,"адн":6641,"адь":3777,"аем":7453,"ает":25830,"аже":6271,"ажд":5556,"аба":3999,"або":17739,"абр":6755,"ава":11200,"авн":21035,"авл":26690,"авс":4043,"аво":12671,"аве":7803,"авг":5378,"ави":21691,"ало":13331,"алл":5996,"ала":22307,"али":48595,"але":13975,"амм":7674,"амо":8686,"амы":4469,"аля":5952,"ама":7226,"аль":73407,"ами":28699,"аме":19983,"анн":37419,"ано":18426,"анс":39188,"ант":20680,"анц":15483,"аны":7448,"ань":4229,"ана":29768,"анд":25091,"анг":9722,"ани":99562,"ане":11955,"анк":9278,"азр":7025,"азо":13307,"азн":9789,"азл":4533,"ази":10605,"азе":3818,"азд":5347,"азв":17619,"аза":10657,"аин":6236,"аиб":4114,"азы":8101,"айс":4889,"айо":18909,"айн":4793,"акт":16378,"ако":12308,"акж":14674,"аки":5796,"ака":8072,"ах ":31165,"ас ":6451,"ар ":4822,"ат ":18392,"ая ":136821,"ба ":4571,"Пол":8430,"Пор":6259,"При":5525,"Пре":6670,"Про":7157,"Рос":14485,"Рас":4325,"Рес":3751,"Сан":8587,"ССС":5587,"ССР":7399,"США":6399,"Сос":6600,"Сов":3947,"Сев":6002,"Сер":4458,"Ста":4121,"Укр":4080,"Фед":3907,"Фра":5981,"ША ":6384,"а́н":5689,"лам":6144,"лан":15129,"лас":29897,"лат":7877,"ме ":7744,"ля ":50911,"ма ":24448,"лав":17972,"лаг":7649,"лад":11258,"лы ":5725,"ль ":38018,"кую":3788,"кус":4925,"кул":8752,"ктя":6372,"кци":8948,"кре":6974,"кра":17934,"кри":5557,"кру":16231,"кро":7021,"лу ":5744,"кры":6225,"кса":6759,"кси":5075,"кта":5223,"кте":4216,"кти":10807,"кто":14126,"ктр":8094,"кту":4971,"кла":9863,"кло":3891,"ло ":19382,"клю":8248,"кни":4141,"ког":53446,"ков":40843,"ком":58598,"кон":29711,"коп":5499,"кор":15168,"кос":5742,"кот":33255,"кое":17818,"кой":65146,"кол":25577,"кие":12731,"кин":10160,"ким":14411,"кий":81796,"ких":35222,"ле ":19103,"кже":14673,"ли ":56435,"ква":7601,"ках":4702,"кат":7467,"кар":8017,"кам":8824,"кан":23037,"как":20319,"кал":11552,"каз":10972,"кая":36891,"каб":6283,"кад":5211,"ла ":40418,"йши":4432,"йся":5983,"йск":44468,"йст":14738,"кт ":8556,"ку ":9345,"йны":8079,"кс ":4079,"йон":18007,"ко ":19496,"км ":4431,"ки ":43486,"ке ":21167,"иям":6120,"иях":4963,"нва":6008,"од ":33146,"ная":57610,"нах":9504,"нац":5517,"нау":8200,"нач":22853,"ог ":6440,"нан":6213,"нам":8570,"нал":25338,"нат":9581,"нас":17157,"нар":16443,"нап":11298,"над":9721,"нак":5181,"наи":4066,"наз":20814,"нде":5878,"нда":8693,"нгл":9288,"нге":3994,"нга":3873,"ое ":58821,"ней":12822,"нек":4897,"нем":9855,"нен":19222,"нер":13236,"нес":9300,"нет":5791,"нег":6018,"нев":4773,"нее":5864,"нди":11172,"ндо":5836,"ндр":8570,"нив":5586,"нии":26244,"низ":11864,"ник":36850,"ний":18207,"ниг":4932,"ние":74066,"ок ":21671,"ой ":187929,"ны ":35382,"нь ":8902,"ня ":11152,"мый":5262,"мых":5149,"мыш":3735,"ов ":92702,"нт ":11498,"мпо":5172,"мпи":13008,"мпе":6698,"мпа":7653,"мот":4724,"ну ":6285,"мпь":3765,"мск":6474,"мун":14544,"мул":3800,"муз":9742,"мик":7960,"мил":4443,"мии":4851,"мич":7046,"мин":28165,"мир":17908,"мит":4140,"но ":62002,"мму":3810,"мно":11450,"мод":4772,"мог":5035,"мов":6153,"мой":4768,"мож":6250,"мон":9329,"мом":4520,"мол":6893,"мос":8228,"мор":8527,"нд ":4096,"мац":4061,"ляю":8990,"мая":9013,"лял":3785,"мал":9300,"ляе":22475,"мат":21959,"мас":5866,"ляр":4924,"мар":12011,"ман":23543,"люч":8195,"мец":4888,"мес":13130,"мет":17123,"мен":50820,"ни ":19557,"мер":29417,"мез":5962,"меж":12542,"мед":8168,"не ":38359,"лён":4990,"мы ":9798,"льн":93765,"на ":153332,"мя ":11127,"льм":14104,"льк":7925,"льз":12358,"льд":3831,"льб":7821,"лья":5362,"льш":14923,"льт":14050,"льс":23881,"лощ":4920,"му ":16323,"лок":5500,"лог":21990,"лод":5038,"лож":18221,"лор":4516,"лос":11300,"лот":8157,"лом":9527,"лон":6111,"лов":35245,"луч":9778,"луж":6113,"лся":9183,"лиг":4087,"лив":6013,"лиз":10430,"лии":15024,"лим":9347,"лий":6287,"лик":17837,"лез":6815,"лей":13214,"лев":9323,"лег":4328,"лед":13548,"лее":8350,"лес":4757,"лер":5420,"ми ":51806,"лен":60261,"лем":10309,"лек":22756,"лет":13846,"лли":5515,"лла":3879,"лле":7201,"лиц":18482,"лич":17052,"лис":14036,"лит":29052,"лин":18545,"лия":7551,"лко":3705,"пас":4125,"оящ":5066,"ояб":5483,"пад":12246,"пал":13951,"рг ":4862,"оян":3986,"пан":12047,"пар":16176,"ре ":17661,"ра ":44965,"оюз":3745,"пий":7004,"пио":5573,"пис":24111,"пла":9596,"пле":8010,"ро ":9844,"пло":9025,"пед":4071,"ри ":19004,"пер":55359,"пес":4491,"печ":4195,"пец":6528,"ори":37323,"орд":5846,"оре":20523,"орг":13852,"орс":6547,"оро":76961,"орм":17625,"орн":11312,"опу":5280,"ора":20394,"опе":10688,"опи":6454,"опо":11431,"опр":11046,"оор":3720,"опа":4525,"отд":3834,"оте":8329,"отк":7498,"отл":4401,"оти":8154,"ото":45196,"отн":11373,"отр":8447,"осу":15201,"отв":5315,"ота":11881,"осе":5320,"оси":7543,"оск":15979,"осл":18494,"осн":17062,"осо":11923,"осп":4485,"осс":25551,"ост":122012,"ору":9047,"орт":19622,"оры":19028,"оря":6038,"осв":3854,"омм":4672,"оми":12071,"оме":14471,"ома":19204,"оля":5909,"оль":52719,"олу":10916,"олн":13122,"по ":36706,"оло":54184,"олл":5951,"олж":3930,"оле":21412,"оли":27404,"ола":9666,"окр":16259,"окт":7805,"оку":5419,"око":16003,"ооб":4126,"онс":12501,"онт":8231,"онц":5168,"они":16817,"онк":3985,"оно":19353,"онн":16949,"она":44812,"онд":5190,"оне":18296,"омо":11288,"омп":18935,"ому":11330,"оше":5000,"пы ":9126,"очи":4013,"оче":6235,"очн":15161,"оща":4802,"офе":5906,"офи":7745,"оты":3797,"оце":7042,"оци":5856,"охо":7896,"нят":6570,"няе":3761,"ова":79059,"обы":7576,"общ":12061,"объ":7061,"обр":22953,"обо":16065,"обн":4315,"обл":17532,"оби":5216,"обе":11035,"ных":63297,"ные":28042,"ным":27407,"ный":86741,"па ":9132,"оит":3855,"оис":6658,"оим":4265,"ойс":6061,"ойн":7471,"оке":4198,"ока":10728,"ожи":4007,"ожн":11252,"озд":12188,"озв":5021,"ози":6006,"озн":9808,"оиз":10355,"одн":39144,"оди":52480,"оду":22578,"одр":3912,"одс":13394,"одо":20011,"оды":5756,"оед":4040,"оев":9413,"одя":6688,"оен":8911,"оек":3819,"оже":24113,"ожд":8010,"ове":40857,"овк":4823,"овл":5356,"ови":24912,"ово":42247,"овн":14676,"овр":5254,"овс":17603,"овы":17385,"ога":5667,"овя":4334,"огд":4881,"оги":20707,"огл":3937,"ого":132906,"огр":15611,"ода":58550,"оде":17121,"от ":31995,"ноя":6122,"нос":44637,"нор":3684,"нол":4077,"ном":37955,"ной":71982,"ное":29866,"ног":57728,"нод":4260,"нов":54046,"нны":69394,"нно":59505,"ор ":24212,"нни":6472,"нна":20166,"нко":5353,"он ":29089,"нкт":5008,"нка":4499,"ом ":104456,"ния":84752,"нию":8268,"нир":5623,"нис":17636,"нит":8771,"ним":17208,"нин":5963,"нич":11022,"них":9088,"ниц":23421,"нце":5996,"нци":17698,"нцу":5080,"ную":9327,"нфо":3773,"нтя":5255,"нут":4116,"нта":17028,"нте":10866,"нти":10987,"нто":10091,"нтр":15601,"нск":63751,"нст":16529,"сам":12116,"сан":12409,"ряд":7767,"сат":6375,"сво":14816,"те ":15248,"све":4519,"свя":9460,"сев":8467,"сел":21166,"ти ":46330,"сен":10794,"сем":7371,"сет":3970,"сер":16452,"сис":11359,"сит":9045,"сий":14008,"сии":9496,"син":6230,"сил":7978,"сим":6904,"скв":8290,"ски":131938,"ска":46869,"сли":3844,"сле":23336,"сла":10537,"ску":8391,"ско":157451,"сме":6005,"слу":9361,"сло":15249,"то ":29238,"сня":3968,"соб":15821,"сов":27452,"соз":9281,"сок":8059,"сом":3851,"сно":26195,"тр ":8572,"сны":3885,"спе":13580,"спа":4761,"спи":4683,"сос":21656,"сор":6482,"соо":5100,"сон":7291,"соц":4226,"сре":10218,"ту ":8116,"спу":6484,"спо":39170,"спр":6952,"рри":9506,"роц":5562,"рош":3692,"рот":12263,"роф":6754,"рох":5095,"роп":12392,"рос":28947,"ст ":16255,"рта":13460,"рст":15956,"рто":4691,"рти":13560,"рск":18805,"рсо":4243,"рси":7173,"рую":4208,"рту":7614,"рук":7417,"руг":20792,"руд":5213,"руж":6808,"руп":20038,"рус":13228,"рхи":6150,"сь ":14955,"ся ":83299,"та ":65491,"рыт":4303,"рых":5096,"рый":5524,"рые":4885,"тв ":5853,"рад":12120,"раж":10828,"раз":53144,"раб":18768,"рав":32412,"рам":17118,"ран":56502,"раи":8567,"рай":21830,"рак":10369,"рал":23925,"рах":8851,"раф":10748,"рац":10644,"рас":32059,"рат":31627,"рая":5022,"ращ":3710,"рбу":3964,"рва":4083,"пью":3789,"реб":6936,"рев":19639,"рег":20011,"ред":53953,"реа":5135,"рет":10005,"рес":14958,"реп":5228,"си ":5105,"рен":15519,"рем":25502,"рел":11664,"рек":12317,"рей":7082,"рез":11794,"реж":11533,"ржа":3754,"реч":6532,"рво":6073,"се ":6838,"рвы":9033,"рга":14493,"рге":4800,"рги":4021,"рия":13567,"рию":4048,"рио":6627,"рим":11681,"рин":20707,"рик":20481,"рил":3781,"рии":19852,"рий":6871,"рич":8657,"рит":22893,"рир":3686,"рис":16618,"рка":4003,"риа":11930,"риг":4581,"рив":4645,"рид":5404,"риз":6655,"ск ":4696,"рни":9740,"рна":12681,"рок":11103,"рол":12179,"ром":23332,"рон":16716,"рож":7867,"роз":4092,"рои":18841,"рой":14224,"ров":68815,"рог":16486,"род":57888,"рое":10921,"рны":14512,"рно":18416,"рла":4760,"рко":4371,"рми":8750,"рма":15602,"со ":3903,"ппы":6617,"пра":26585,"при":52484,"пре":53035,"ру ":6954,"про":87029,"поп":4906,"пор":17269,"пос":28755,"пот":5403,"поэ":3864,"ппа":6927,"рт ":5103,"The":3957,"под":23464,"пов":12924,"пон":8324,"пом":6183,"пол":68859,"пок":4701,"поз":9391,"пуб":8028,"пус":5784,"пут":5691,"пул":3714,"ры ":15775,"са ":16206,"ря ":29812,"рь ":4987,"вар":15705,"ват":16606,"вая":7821,"ваю":8055,"ге ":6711,"вае":10913,"вав":4587,"ван":65485,"вал":18282,"быт":4123,"быч":3846,"был":18105,"га ":14808,"бъе":7043,"бще":10673,"вы ":7062,"бур":7473,"бря":21845,"вто":16228,"все":9508,"вск":27242,"вст":7859,"вра":8893,"вре":17466,"вро":6581,"вол":13485,"вок":4441,"вой":25086,"вои":3759,"воз":12251,"вое":18754,"вод":28316,"вог":6893,"вов":10300,"вны":14251,"вор":11524,"вос":15224,"воп":3740,"вом":8183,"вни":4616,"вне":8106,"вна":13669,"вно":25418,"вля":30877,"вле":21719,"вла":3874,"го ":153532,"вкл":4066,"вка":4191,"вич":20022,"вия":4450,"виж":4984,"вил":7784,"вин":10044,"вис":5933,"вит":12981,"вид":14202,"вес":15630,"вет":22334,"вер":37523,"вен":36297,"ги ":6381,"вел":6076,"век":17069,"вед":16797,"вгу":5781,"ва ":46587,"ающ":19084,"ают":9616,"ачи":5855,"бы ":3828,"ащи":4099,"аще":3705,"ауч":3787,"аук":4642,"афи":6466,"ахо":7975,"ача":13504,"аче":11447,"аци":41912,"апр":13134,"апа":11764,"апо":3746,"апи":8487,"арх":7888,"арс":18625,"арт":22698,"арь":4529,"аря":9072,"аре":7851,"ард":6979,"ара":21925,"арн":5879,"арм":4715,"аро":18219,"ари":19835,"арл":4156,"арк":7904,"асс":17733,"аст":73387,"ась":5439,"ата":17783,"аси":4710,"асе":9811,"асл":4318,"асп":18234,"асн":7236,"ату":10612,"аты":6297,"ать":13519,"ате":41110,"ати":28209,"атн":5152,"ато":21641,"атр":7249,"бол":22933,"бом":6832,"бой":5049,"бор":14402,"бот":13748,"бно":3859,"бро":3695,"бри":6979,"бре":4187,"бра":24036,"бла":17775,"бли":15168,"бле":4490,"во ":31067,"ви ":4378,"бес":5023,"бер":15432,"бел":4899,"бит":4733,"бил":3862,"ве ":17457,"даю":4004,"дах":4951,"дан":21423,"дам":3898,"дар":18766,"дат":8984,"дви":7106,"дал":8909,"дав":5333,"ев ":8761,"дек":7455,"дей":9763,"дем":5618,"дел":26493,"ден":32485,"дер":21083,"ей ":52679,"дес":4085,"дет":5015,"дея":8136,"дву":4656,"дво":4445,"ее ":25157,"ез ":4626,"ды ":12967,"дь ":4234,"ех ":3705,"дст":24032,"дск":13686,"дро":6400,"дру":10418,"дре":7577,"дра":7639,"ет ":49624,"дун":5024,"ец ":6315,"ен ":23878,"дия":4777,"диц":4594,"ем ":32646,"диа":3739,"див":3812,"дим":5230,"дин":31699,"ел ":6867,"дио":3858,"дис":4374,"дит":31866,"дии":5066,"дил":7726,"ек ":8976,"дны":11957,"дож":6200,"дов":21587,"дос":6949,"дор":10512,"дол":8011,"док":5562,"дон":5574,"дом":8881,"дна":11456,"дни":9495,"дне":7494,"ер ":23656,"дно":27634,"для":23991,"дми":9130,"вып":7258,"вый":9785,"вым":6060,"вых":10632,"выс":8860,"al ":4210,"да ":70397,"вяз":5698,"гал":7699,"вят":8003,"ган":16467,"гар":4062,"де ":21659,"гда":5300,"вую":5927,"вхо":16916,"вше":5430,"вша":3781,"вши":12432,"вые":6905,"гон":3740,"гол":6702,"гос":13811,"гот":3744,"гор":32983,"гов":9981,"год":69990,"гру":17285,"ду ":34904,"гро":3890,"гра":40520,"гре":6189,"гус":6354,"ген":9872,"гер":7302,"ди ":8816,"гии":7384,"гио":11815,"гич":7565,"гих":4581,"гла":12247,"до ":13248,"гли":6452,"жан":5670,"еят":7722,"за ":17832,"еще":5057,"жит":5272,"жив":7938,"жис":4312,"жес":7568,"жет":3940,"жду":12980,"жел":6716,"жен":38841,"жде":11274,"жда":4735,"жск":3945,"жно":12596,"жни":4413,"жны":6194,"жур":3704,"ежи":6716,"ежд":16924,"еду":5404,"едс":18751,"еза":4036,"езн":5938,"езо":10562,"езд":5637,"ези":9501,"ева":10267,"еви":11883,"еве":16643,"еат":3835,"дящ":4359,"его":29841,"еда":12960,"еде":22810,"еди":27267,"едо":10112,"едн":12312,"евн":10381,"же ":22970,"ево":16350,"евр":9678,"евс":6183,"евы":4574,"еге":5203,"еги":14109,"ент":47594,"енс":9645,"енц":4019,"ени":132856,"ено":11907,"енн":84711,"ена":18893,"емя":7341,"ене":16352,"енд":7186,"емь":4324,"емы":10998,"еор":5073,"ены":6940,"ень":8052,"епо":3992,"ерх":5155,"ерр":10216,"ерс":17748,"ерт":9897,"ерл":3718,"ерм":10872,"ерн":25326,"еро":19985,"ери":40656,"ерк":7071,"ерг":7482,"ерж":8654,"ере":44413,"ера":37126,"ерв":20819,"ерб":7899,"ейн":5541,"ейс":18646,"еки":4636,"еко":11088,"ект":27081,"екс":15558,"ейш":5926,"ека":19196,"ели":21048,"ело":19740,"еле":41611,"ела":9361,"емл":3751,"емо":8767,"еми":9433,"ему":3888,"емп":6664,"ель":74971,"еме":23861,"еля":16614,"ема":12283,"елё":3840,"ехн":5852,"ецк":9009,"еци":7333,"еча":3853,"ечн":3687,"ече":11632,"еше":3757,"есе":5474,"еск":73489,"есн":5953,"есп":9644,"есс":15061,"ест":79162,"еся":5372,"ета":21699,"ети":10490,"ете":10421,"етр":11442,"ето":9221,"етн":10174,"етс":48640,"еты":4087,"ибо":7839,"иве":7414,"иви":3809,"ива":16306,"иал":20951,"иан":8939,"иже":6481,"идо":4070,"иев":3803,"ием":14066,"ией":9608,"игр":16265,"иго":4097,"ида":4859,"иде":14015,"иво":7871,"ивн":17940,"ивш":6456,"ига":5856,"иги":5053,"икл":4956,"икр":3804,"ико":26837,"ике":6203,"ики":16651,"ика":34115,"ийс":37107,"изм":10707,"изо":8828,"изн":6897,"изи":10371,"изд":4964,"иза":12843,"изв":18761,"ион":41500,"инц":6456,"ины":10703,"иня":5979,"иод":4236,"ине":14798,"ини":31286,"инн":3826,"ино":20897,"инс":24611,"инт":7204,"инф":4063,"ина":38691,"инд":6333,"инг":12127,"ими":15581,"име":21870,"имс":3708,"имо":9905,"имп":12615,"има":14708,"иль":23825,"или":46988,"иле":5170,"илс":4907,"илл":5632,"ило":11583,"ила":9561,"иси":5473,"иса":15121,"исх":5676,"ист":74674,"исс":10637,"исп":16317,"исо":5087,"исл":10745,"иск":11427,"ити":13816,"ите":56212,"ита":24816,"ись":6230,"иту":6461,"ито":18876,"итс":8689,"ипа":14414,"ипе":3791,"ира":11140,"ире":4647,"иру":8486,"ири":4818,"иро":27497,"иха":3800,"ихо":4447,"ице":7291,"ица":16979,"ици":25302,"ицы":6049,"ить":5325,"ифи":3877,"ичи":6000,"ичн":11017,"ича":4726,"иче":66707,"июн":5092,"июл":5316,"ка ":55202,"ив ":4402,"зав":10564,"ид ":4294,"зви":4153,"зве":16359,"зва":15033,"зац":9007,"зат":4555,"зап":11760,"зан":11015,"зам":3927,"зак":6826,"зде":5994,"зда":15915,"ие ":94285,"зво":7967,"ий ":139271,"зер":5619,"ии ":131775,"зем":4097,"из ":38626,"зид":4005,"зил":7018,"ил ":8940,"ик ":27882,"ин ":25833,"им ":24359,"зия":4934,"зит":4573,"зме":6834,"зли":4448,"зна":20529,"зни":4774,"зно":8729,"ир ":5392,"зны":4336,"зов":19642,"ис ":4567,"зон":5974,"зор":7083,"ит ":29545,"зра":8237,"зск":6535,"их ":71178,"зуе":5324,"ич ":17567,"зыв":8397,"ию ":18909,"зык":19420,"ия ":146910,"ьшо":3872,"ьши":3819,"ьше":5810,"ьян":5268,"ьют":3946,"ьма":3914,"ьна":7658,"ьни":4302,"ьно":44690,"ьны":33869,"ько":6149,"ion":5234,"ьзу":6190,"ьзо":5415,"ьту":4384,"ьст":6382,"ьск":16866,"ям ":5239,"ют ":10384,"эко":4504,"эле":8958,"это":14311,"ых ":86372,"he ":5907,"ыва":15848,"ье ":4950,"ые ":43888,"ыл ":8892,"ым ":27422,"ый ":115051,"ычн":4405,"ья ":5879,"ью ":17235,"ьбо":5724,"ьев":4427,"ьер":4030,"ьм ":7924,"ыка":9496,"ыла":5382,"ыми":11026,"ыпу":5527,"ысо":4693,"ённ":14954,"er ":6599,"es ":4533,"яза":3917,"яет":23887,"язы":12445,"явл":14387,"ябр":17050,"ях ":9267,"ютс":8148,"юте":4109,"юща":7138,"ющи":22555,"юще":8725,"юча":3971,"юля":5121,"ят ":7009,"юня":4749,"яют":4520,"яющ":7517,"яще":6980,"ящи":4896,"янс":6220,"янв":5611,"яни":5071,"ями":7921,"ярн":3999,"ято":4282,"яти":7069,"яте":9306,"уще":14055,"уча":15033,"учн":4074,"учи":4977,"уче":7765,"фес":5738,"фев":5319,"фер":4649,"ующ":10346,"фин":4428,"физ":4024,"фил":15705,"фик":3811,"фиц":4922,"фре":4266,"фра":6501,"фор":17745,"фон":4486,"ца ":19779,"це ":5162,"хан":4526,"хар":5112,"хра":4915,"хно":4200,"хни":3959,"хож":3747,"хов":4677,"ход":41602,"цы ":7957,"худ":5932,"сск":14412,"сси":32096,"ссо":7973,"сса":7005,"ссе":5970,"стн":20518,"сто":67851,"стр":70127,"ств":108223,"сте":31686,"сти":71515,"ста":85694,"сст":5885,"суд":15247,"сть":44809,"сты":4236,"сту":9860,"сущ":7215,"схо":7227,"ты ":16675,"ть ":55254,"тав":37473,"так":23239,"тал":22250,"там":8524,"тан":36504,"тай":3709,"тат":27244,"уг ":6960,"тар":13509,"тбо":4051,"тву":7862,"сёр":3801,"тво":31741,"тви":10153,"тве":41916,"тва":21790,"тех":6332,"тем":17566,"тел":76816,"тео":3852,"тен":11539,"тер":49417,"теп":3783,"тет":16644,"тек":8246,"тей":6713,"тив":26421,"тие":8972,"ук ":4128,"тка":5169,"тич":24503,"тия":7560,"тии":4630,"тий":5054,"тин":12258,"тик":14625,"тил":7099,"тир":5823,"тис":5149,"тип":5281,"тит":7029,"тки":3943,"тно":26382,"ток":11951,"тол":12417,"той":7374,"тны":17802,"тов":29921,"тог":9531,"тни":13284,"тна":5384,"ут ":4381,"тре":17053,"тра":54933,"три":18286,"тор":95430,"том":20153,"тон":9780,"ус ":4688,"точ":11868,"тоя":12927,"тст":5913,"тся":53866,"тро":41481,"тру":10653,"тск":19176,"туг":4888,"туп":6027,"тур":21906,"тью":9623,"тый":5760,"ую ":18777,"уго":4888,"уги":7037,"уга":8925,"уда":16459,"тяб":11568,"убл":8850,"убе":4682,"узы":8785,"узс":4917,"уже":5996,"ует":9543,"уем":3815,"уди":4265,"удо":10125,"уме":6894,"уль":15447,"уля":5536,"ули":11772,"укт":4529,"уко":4826,"ука":4047,"упп":14974,"упн":6779,"упр":5417,"ура":6947,"ург":8767,"уре":4620,"унк":5527,"уна":6858,"уни":18074,"уст":16092,"усс":16109,"ута":4019,"уры":4919,"урн":11401,"уро":5529,"уск":4624,"ших":7365,"шир":4576,"шин":5562,"ший":10857,"шен":11201,"шая":6983,"шта":14038,"щих":9037,"щие":5309,"щий":14604,"щин":3869,"щее":7976,"щей":4091,"щег":3871,"щен":12451,"щес":17297,"щая":10075,"щад":4691,"on ":6654,"цен":15360,"чи ":4183,"цел":4906,"цев":3998,"цес":4907,"цер":5569,"циа":13419,"ций":4974,"ции":29185,"цие":3800,"цип":12774,"цио":18812,"ция":20642,"ча ":3694,"цар":3955,"цуз":4865,"цко":4797,"цки":5412,"чем":5556,"чен":25493,"чел":10826,"чес":78218,"чер":6254,"чет":6065,"чле":3904,"чин":7894,"чив":3802,"чис":7524,"чит":8014,"ше ":5808,"чаю":4561,"час":36891,"чат":3981,"чал":9929,"чае":6846,"чны":14169,"чно":19736,"что":8092,"tio":4098,"Кар":6020,"Кра":3888,"Кор":4309,"Кон":5008,"Мар":7555,"Мин":4281,"Мос":11770,"Нас":4395,"Ник":4718,"Нов":5069,"Оли":6672,"Пар":6298,"СР ":8410,"Пет":6304,"Пер":7246,"Але":6898,"Бра":9561,"Бол":4163,"Бел":4463,"Вел":5787,"Гра":3978,"Гер":5952,"Джо":3835,"Евр":4076},"n_words":[36763344,40893832,29165701],"name":"ru"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/slk b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/slk new file mode 100644 index 000000000..97f988076 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/slk @@ -0,0 +1 @@ +{"freq":{"D":6323,"E":4459,"F":4516,"G":4726,"A":10071,"B":10822,"C":7078,"L":6128,"M":12887,"N":7988,"O":4702,"H":6933,"I":5526,"J":8422,"K":8631,"U":2767,"T":8739,"W":2331,"V":8838,"P":14691,"S":17764,"R":6826,"Z":3853,"f":24135,"g":31408,"d":146397,"e":441234,"b":79948,"c":129399,"a":438168,"n":323513,"o":480147,"l":181843,"m":157226,"j":124158,"k":216062,"h":115571,"i":290888,"w":4336,"v":227972,"u":141151,"t":244072,"s":230794,"r":287939,"p":133920,"z":92877,"y":75446,"x":5807,"²":567,"í":50255,"é":45424,"ä":4507,"á":98447,"ý":65120,"ú":38043,"ô":6119,"ó":12207,"ď":2808,"Č":2146,"č":43571,"ĺ":1392,"ľ":19160,"ň":4992,"Ž":835,"ž":30532,"ť":13944,"Š":1929,"š":30141,"Eur":843," l":8693," m":31843," n":43761," o":37444," h":15481," i":8376," j":50814," k":41715," d":25382," e":6213," f":10527," g":4634," a":59730," b":16567," c":8497," z":33097," u":8583," t":26154," v":69047," p":76912," s":70586," r":25827," J":8409," K":8577," H":6876," I":5508," N":7962," O":4629," L":6098," M":12833," B":10746," C":6977," A":10024," F":4466," G":4666," D":6268," E":4439," Z":3841,"и":615,"о":715," S":17653," R":6787,"а":792," P":14620," W":2297," V":8804,"е":558," U":2760," T":8683," ú":5607," ď":577," č":11970," Č":2146," ž":4854," Ž":833," Š":1929," š":8376," ľ":2475,"Fra":832,"A ":1884,"Da":900,"Co":1488,"Ce":608,"Ch":1551,"Do":1311,"De":1168,"Di":711,"Fa":561,"Eu":967,"Ge":866,"Ga":734,"I ":1477,"Fr":1190,"Fi":588,"II ":663,"C ":1204,"Au":625,"Ar":1181,"D ":632,"Ba":1863,"Am":652,"An":1498,"Al":1539,"Bu":812,"Br":2094,"Ca":1126,"Bi":824,"Be":1438,"Bo":1866,"Kr":1442,"Ko":2065,"Le":1477,"Li":1427,"La":1055,"Lu":551,"Lo":964,"Me":2050,"Mi":1818,"O ":889,"Ma":4427,"Mo":1742,"Ni":925,"Ne":1824,"Na":2123,"P ":647,"No":1174,"Ob":931,"Gr":1156,"Ha":1121,"He":1131,"Ho":1814,"Hr":608,"In":1551,"Ja":1230,"Je":4572,"Jo":995,"Ju":970,"Ka":2174,"Tu":851,"Tr":1334,"To":1259,"Th":927,"Ti":635,"Te":1474,"Ta":1216,"V ":2449,"St":2440,"Sv":647,"Su":614,"Wi":788,"Vy":658,"Vo":610,"Vi":1001,"Va":862,"Ve":1362,"Má":761,"Pr":3288,"S ":1036,"Pe":1293,"Pa":2196,"Pl":567,"Po":4755,"Pi":686,"Or":779,"R ":612,"Se":1430,"Sc":541,"Si":786,"Sl":3359,"Sp":1454,"So":1120,"Ru":1051,"Sa":1654,"Re":1050,"Ná":658,"Ri":640,"Ro":1422,"Ra":1481,"b ":2037,"Zá":884,"a ":144799,"Za":604,"Ze":702,"i ":37987,"fy":881,"ge":3887,"ga":3383,"bý":960,"fi":7159,"fr":2471,"ač":5846,"fu":1355,"aď":870,"ft":581,"fo":3584,"bí":670,"j ":28903,"cú":1023,"gy":705,"aľ":716,"dá":2384,"he":5122,"ha":6720,"gn":1011,"gm":704,"gl":1862,"gi":5874,"gh":727,"gu":2013,"gr":4226,"cí":1219,"go":2083,"du":5115,"dv":2815,"dy":3861,"dz":7413,"g ":2452,"ea":2540,"eb":13761,"ec":10112,"ed":25726,"de":19219,"di":12919,"dk":1536,"dm":1805,"dl":3720,"do":19760,"dn":17745,"dp":1210,"ds":3840,"dr":7033,"ew":678,"ex":2935,"eu":1904,"ev":7688,"ey":664,"ez":6532,"fa":1707,"h ":31639,"fe":2493,"bá":980,"eh":6797,"eg":2721,"ef":1680,"ee":903,"el":18740,"ek":12213,"ej":29432,"ei":1554,"ep":6024,"eo":3559,"en":52359,"em":14359,"et":17096,"es":24526,"er":36633,"ca":6242,"e ":118531,"by":4846,"bs":2133,"br":6137,"bu":4959,"bn":3071,"bo":22917,"bj":2626,"bl":4818,"bi":5066,"bc":1208,"bd":823,"be":9106,"dc":900,"db":1133,"da":10163,"f ":1519,"cu":1353,"ct":1197,"co":4858,"cn":1009,"ck":22292,"ci":21044,"ch":49042,"ce":12657,"c ":5075,"az":7180,"ay":741,"ba":5147,"d ":13711,"at":24996,"as":19402,"ar":21528,"ax":910,"av":19342,"au":4063,"ak":14537,"al":32605,"ai":1980,"aj":18129,"ao":743,"ap":5241,"am":14227,"an":46975,"ac":10837,"ad":20535,"ab":3624,"ag":2783,"ah":4710,"ae":1120,"af":1683,"nu":6191,"nt":13652,"ns":14480,"ič":3422,"jí":607,"no":31919,"nn":5955,"nz":946,"ny":10740,"hľ":938,"oe":798,"ká":9527,"of":3569,"oc":9865,"od":30890,"oa":684,"ob":22771,"jú":8749,"om":35081,"ké":8895,"on":18042,"ok":25444,"ol":27522,"oi":991,"oj":9152,"og":4545,"oh":6762,"ot":13213,"m²":561,"os":25341,"ov":73503,"ou":15818,"op":7814,"oo":910,"jč":568,"or":43666,"kú":2339,"r ":14190,"kô":554,"kó":650,"ow":1410,"oz":12370,"pe":7850,"lá":5471,"pa":10171,"ký":14124,"pl":7248,"lé":1049,"pn":1091,"po":39723,"ph":797,"pi":7377,"eň":1574,"lo":31336,"ln":9477,"hé":650,"lm":1360,"ll":2885,"ls":1845,"lu":4726,"lt":2514,"ly":3287,"o ":72538,"ma":12807,"mb":3559,"hý":981,"me":31227,"iá":2685,"ml":855,"eš":1638,"mi":19191,"mn":3217,"mm":559,"mp":2180,"mo":13618,"ií":1342,"ms":1427,"mu":6601,"ió":1393,"my":3831,"p ":1992,"na":48626,"nc":6297,"nd":6014,"ne":40950,"nf":1138,"ež":4352,"ng":5209,"ni":32826,"nk":4794,"jv":2323,"eď":654,"ju":2887,"eč":2428,"js":2102,"jn":2178,"jo":2645,"jm":1649,"jk":595,"ki":2025,"dľ":1507,"ke":14025,"gá":620,"kc":1532,"dĺ":1132,"ka":21392,"m ":45126,"ky":12637,"kt":22417,"ku":19211,"kv":1473,"ko":41039,"kr":12909,"kl":6886,"km":4376,"kn":913,"li":23938,"lh":1065,"lk":2208,"há":3987,"le":30292,"eľ":8588,"ld":1271,"la":30632,"lb":1616,"n ":17290,"hr":6312,"dí":2091,"hv":2290,"ht":1214,"hu":6079,"hi":3695,"hn":2117,"ho":33938,"hl":4308,"hm":1007,"id":6006,"ic":28125,"ib":2309,"dý":547,"ia":31792,"ih":1011,"ig":2598,"if":1907,"eá":715,"ie":44145,"hy":2860,"dô":739,"k ":16704,"ir":3821,"is":15561,"it":16315,"iu":3712,"iv":6007,"eó":677,"aš":705,"ii":2337,"ij":1891,"ik":11705,"il":11847,"im":4228,"ať":2167,"in":30878,"io":5948,"ip":2091,"je":54049,"až":3807,"ji":2876,"iz":4693,"l ":16112,"ja":8703,"xi":1668,"té":3643,"tí":5214,"tó":2119,"xt":831,"sú":8148,"z ":10294,"ož":4892,"tá":7149,"oš":1310,"wi":924,"sé":733,"sí":1587,"rč":1607,"ró":1912,"vy":11079,"rô":641,"vz":3443,"y ":38794,"rú":2323,"rý":5792,"wa":909,"we":537,"sá":670,"vl":2565,"ré":5591,"vk":1421,"nš":1355,"vi":16426,"vu":2054,"vr":2972,"vs":3111,"rí":8465,"vn":10339,"vo":27546,"uz":979,"uv":941,"oľ":2603,"ve":29704,"rá":15217,"vc":1194,"va":30715,"x ":1187,"ui":653,"uj":8555,"uk":2909,"ul":5494,"ue":827,"ug":1127,"uh":4698,"ur":8100,"us":8894,"ut":6390,"um":6737,"un":5022,"up":5983,"ty":4889,"pô":2385,"tz":568,"tu":8639,"tt":1333,"tv":9012,"ub":3487,"ua":850,"ud":5636,"uc":2067,"w ":706,"to":52129,"tn":7740,"tm":1030,"tl":2323,"ts":3310,"tr":24800,"oč":7254,"pí":1372,"pá":1327,"te":28885,"tk":5618,"ti":28975,"th":2145,"v ":48812,"ta":24342,"su":4004,"sv":4018,"ss":1524,"st":58751,"sy":3565,"sl":11132,"sk":44161,"sn":3377,"sm":2199,"sp":10573,"so":10148,"nč":1255,"sc":2214,"sf":608,"se":10443,"sh":654,"si":7301,"rz":1417,"u ":50841,"nú":2094,"sa":16525,"ný":22118,"rr":843,"rs":6494,"rt":4523,"ru":10434,"rv":5009,"nó":730,"ry":3916,"ní":8389,"rp":1158,"ro":47621,"rn":10561,"rm":4664,"né":16353,"rl":1127,"rk":2824,"ri":34707,"jš":2481,"rh":695,"iž":1338,"rg":3525,"rf":643,"ná":21179,"re":40029,"rd":2875,"rc":3598,"rb":1553,"ra":41482,"t ":11585,"mô":731,"mí":2439,"mé":722,"iť":1158,"iš":1309,"má":4691,"mä":1078,"lý":1452,"s ":19518,"lú":1099,"py":785,"pt":2178,"pu":2861,"ló":2004,"lí":2945,"pr":41771,"ps":1762,"zý":682,"zá":7603,"zé":647,"už":5423,"vš":2161,"yč":534,"zí":915,"uš":1188,"vý":14470,"sť":7157,"Hor":544,"zh":1017,"vä":2642,"zi":7079,"rš":1164,"zb":854,"zd":5109,"ze":5890,"vá":7870,"za":12274,"yz":1332,"zv":3082,"zy":2080,"zs":1637,"uč":1098,"zr":1156,"zu":1736,"zo":9017,"zn":10586,"ví":1466,"zp":940,"zk":1321,"vé":4595,"zm":4191,"zl":2181,"yh":649,"uá":1391,"yc":3925,"yd":1380,"tý":3031,"yb":1209,"tú":3411,"yv":2400,"yt":2758,"ys":5625,"yr":1431,"yp":2058,"yn":1959,"ym":2723,"yl":992,"yk":2457,"yj":557,"zť":610,"yš":1686,"ším":570,"šír":654,"šíc":1062,"ťou":1264,"² ":565,"ťah":745,"ťaž":646,"ší ":1009,"Bra":1002,"Bol":718,"ám":3217,"án":4821,"áp":2703,"áj":1169,"ák":2947,"ál":8570,"áh":1148,"áb":1278,"ác":7329,"ád":5449,"ä ":797,"áz":2921,"áv":6149,"ár":8087,"át":6184,"ás":2422,"á ":30384,"ôs":1461,"ôr":598,"óg":1873,"ód":1271,"ór":1755,"óp":1200,"ón":3191,"óm":1121,"ív":4551,"íz":1142,"ín":4699,"ím":4401,"íp":1003,"ír":2051,"ít":2918,"ís":3116,"ík":3632,"íl":827,"íc":3944,"íd":1198,"í ":13762,"áž":617,"áš":773,"ém":3465,"én":937,"ét":1878,"ér":2157,"äč":1548,"éd":556,"éc":848,"éh":11280,"áľ":830,"é ":23043,"áč":817,"ät":901,"äz":636,"úč":2819,"ýk":611,"ôž":785,"ýc":17590,"ýz":1464,"ýv":2338,"ýs":969,"ýr":1274,"ým":8307,"úz":3206,"ý ":29957,"úp":696,"ún":866,"úl":805,"úv":565,"út":1527,"ús":2474,"úr":2901,"úh":1142,"úd":1600,"úb":634,"úc":5635,"ú ":11007,"íš":617,"ôz":595,"ôv":1382,"íž":736,"Nem":547,"Nac":597,"ýš":544,"Če":1109,"či":6991,"čk":1668,"čl":1517,"če":6035,"ča":9218,"ď ":922,"č ":1105,"čn":7371,"čo":2826,"čt":541,"ču":1013,"ďa":1413,"čš":1550,"čí":3126,"Nov":633,"ľ ":1691,"ľa":5647,"ľk":2350,"ľm":577,"ľn":1481,"ľo":3506,"ľs":1492,"ľu":1677,"ĺž":1136,"ň ":1274,"š ":574,"ší":3431,"ťo":1542,"Par":649,"ťa":2465,"ť ":9577,"še":3604,"ša":1343,"šo":1393,"šp":1178,"šn":1118,"šk":1726,"ši":5749,"št":7288,"Št":611,"ňa":1527,"ňo":1237,"ňu":845,"Poľ":669,"Pro":592,"Pre":892,"Pod":721,"žs":1011,"žu":918,"žn":3570,"žo":977,"že":5249,"žd":912,"ža":964,"žk":1609,"ži":6988,"ž ":2893,"ží":3206,"Má ":570,"SA ":809,"Rak":660,"šš":674,"Je ":3173,"Kar":601,"Mes":567,"Mal":724,"Mar":1239,"Mic":549,"áľo":612,"ého":11278,"čít":911,"čís":890,"ém ":887,"éck":749,"Veľ":631,"čuj":916,"čná":722,"čné":1259,"čný":1760,"étk":856,"äčš":1545,"ému":984,"éri":720,"Zem":545,"ďal":723,"Str":817,"Sta":811,"Spo":812,"Slo":2603,"Rus":613,"čši":967,"The":619,"Tur":593,"šet":1217,"šen":585,"štr":907,"šti":599,"šta":1049,"šov":613,"ško":920,"šia":856,"šie":2695,"štá":2185,"átu":553,"bje":988,"áte":733,"bja":1624,"átk":775,"átn":563,"áto":1594,"ást":705,"bil":932,"bo ":9920,"ávi":600,"bli":1892,"ávn":1077,"bla":1662,"áva":2985,"bod":650,"bol":6856,"boj":571,"ázv":643,"ázo":1232,"bor":1466,"bov":774,"áln":5252,"álo":634,"be ":819,"áme":834,"ákl":1321,"ban":633,"bal":748,"áko":904,"án ":994,"áns":810,"bdo":679,"áno":783,"ámy":668,"ár ":1209,"bec":1805,"ber":2830,"ben":812,"bez":962,"ápa":2237,"árs":742,"bia":583,"bie":1078,"át ":1099,"áro":2670,"árn":1647,"ára":896,"ách":1879,"áci":4745,"ádz":3180,"ca ":4873,"ál ":697,"ce ":4495,"bri":844,"bro":596,"bra":2640,"bre":863,"bu ":703,"bný":856,"bsa":802,"bur":546,"bum":1025,"bud":728,"by ":1911,"ábo":552,"byv":1443,"aka":544,"am ":1578,"ake":675,"aji":1734,"ajm":1012,"ajn":753,"ajs":1164,"ajv":1703,"al ":3190,"ak ":1606,"ahu":1045,"ahr":640,"aho":724,"aj ":3272,"adá":567,"ajú":4186,"anu":914,"any":631,"ano":1953,"ann":2369,"ant":2498,"ans":3130,"ane":1786,"ang":1885,"ani":9481,"ank":901,"ana":1968,"anc":2108,"and":2251,"amo":1677,"amn":620,"ami":3340,"ame":3786,"ama":959,"alo":3047,"ali":4506,"ale":12669,"ala":2255,"alb":970,"an ":2683,"akt":2087,"ako":5403,"abs":539,"ae ":616,"aca":545,"ad ":2628,"ac ":550,"afi":807,"ado":1644,"adr":867,"adl":645,"adn":3195,"adi":1835,"ade":3266,"adu":813,"aco":855,"aci":1802,"ach":4201,"ace":1242,"ada":1861,"azo":539,"arš":738,"aze":872,"asť":2479,"azy":1600,"axi":588,"atí":1130,"az ":763,"azé":596,"ba ":1862,"azý":599,"at ":1606,"are":1302,"aná":2114,"ard":1508,"arc":1318,"ara":2212,"aro":2009,"ané":3292,"ark":750,"ari":2403,"aní":1813,"ars":1457,"art":1675,"asi":1254,"aný":3599,"aso":888,"asn":1265,"ar ":1338,"akú":915,"alá":536,"apo":817,"apr":1545,"as ":1458,"alý":759,"ava":2084,"aut":1518,"avs":622,"avo":3114,"avn":2304,"avi":3514,"ave":2415,"avy":1063,"avu":898,"av ":719,"ata":1116,"ast":8626,"atn":905,"atk":1336,"atr":1680,"ato":2184,"ate":5705,"ati":5001,"aur":606,"až ":1038,"jeh":1159,"jej":1018,"jed":5235,"jek":1206,"jem":636,"jen":1683,"ji ":665,"ažd":650,"jad":617,"jav":2393,"jan":692,"jaz":1897,"je ":42288,"jne":544,"jov":1599,"jom":624,"jin":1578,"itn":565,"ito":1341,"itu":927,"its":591,"ity":888,"isk":1618,"isl":1645,"iso":851,"ist":5989,"ita":1760,"ite":3279,"iti":1519,"ivo":1530,"ius":597,"ium":775,"iva":615,"ivi":709,"ive":1126,"is ":1825,"ion":1878,"iou":1025,"iov":556,"iro":841,"iné":635,"isc":586,"iný":615,"iu ":2243,"iná":2028,"it ":625,"izá":1011,"ja ":1196,"itý":663,"ité":878,"itá":857,"eór":603,"izo":825,"izm":1796,"ivá":562,"úry":632,"úsk":784,"úst":1144,"dĺž":1131,"úto":587,"km ":3082,"ki ":721,"úra":899,"dľa":1494,"ked":587,"keh":993,"kej":7958,"ke ":2633,"kci":1471,"kra":3230,"kre":4381,"kt ":843,"ku ":12244,"kro":679,"kri":597,"koz":582,"kov":7957,"km²":548,"kou":1936,"kos":1132,"kor":769,"kop":788,"kon":5151,"kom":7319,"kol":2625,"úzs":928,"úze":2017,"koc":987,"kni":537,"ko ":9276,"kla":4718,"jvo":598,"juh":1174,"jsk":1191,"jst":719,"ečn":971,"ju ":598,"jmä":776,"kat":1398,"kar":683,"kan":1054,"kal":813,"kam":835,"juž":746,"ka ":13070,"jvä":876," Ga":726," Ge":865," Fr":1186," Fi":580," Ha":1115," He":1127," Gr":1147," Hr":606," Ho":1810,"ha ":1403," Je":4569," Ja":1224," In":1544,"cúz":960,"han":1109," Ka":2166,"hal":560,"har":1373," Jo":992," Ju":970," La":1046," Le":1473," Li":1420," Ko":2060," Kr":1440," Ma":4398," Mi":1809," Me":2047,"he ":1247,"dá ":670," Lo":960," Lu":549," Ne":1808," Na":2120," Ni":923," Mo":1735,"dáv":586,"her":779,"hem":744," Am":651," An":1497," Al":1528," Ba":1854," Au":624," Ar":1172," Be":1433," Bi":821," Bo":1848," Br":2086," Bu":806,"his":874,"hit":630," Ca":1107," Ce":603," Ch":1547," Co":1476," Da":898," Di":709," De":1164," Do":1293,"hla":2518," Eu":965,"ho ":17722," Fa":559,"gli":887," Wi":780," Vy":655," Ze":700," Za":604,"gió":559,"gov":534,"údi":539," a ":25661," Zá":880,"úci":2715,"úca":1146,"gra":2234,"úce":1226," Or":774," Po":4736," Pl":565," Pi":684," Pe":1292," Pa":2173," No":1171," Ob":929," Ra":1479," Ro":1415," Re":1042," Ná":657," Ri":640," Pr":3280,"gus":545,"gré":723," Má":761," Sv":647," Su":611," St":2410," Ta":1213," V ":1733," Th":921," Ti":628," Te":1468," Tr":1332," To":1247," Ru":1047,"úhv":785," Sa":1649," Si":774," Sc":533," Se":1428," So":1114," Sp":1448," Sl":3357," Va":861," Ve":1359," Vi":989," Vo":610," Tu":845," ja":3535,"iam":1045,"ial":965,"ian":2212," až":955,"iar":1167," je":43951,"iat":1943," in":4275,"iac":3458,"iad":1663,"ibl":710," dĺ":994," ka":3354," m ":975,"ĺžk":983," ke":682," ju":2279," ha":599," he":772," gr":1776,"ia ":16846," dô":541," k ":1516," id":930," ic":916," hi":1068," hl":2110," hm":698," ho":3959," hr":2464," hu":1376," hv":1179,"iet":1590,"iev":722," ni":2558,"iez":1705,"iel":2995," ne":6825,"iem":1362,"ien":1741," na":26193,"ier":2554,"ies":2613,"ied":1764," my":693,"ieh":899,"iek":2897," mu":967," mo":3923," mn":871," ok":5647," oc":805," od":6282," of":678," jú":829," ob":11824,"ifi":1055," no":2104," le":2787," li":2051,"ick":16621," la":1441," kv":711," ku":1362,"ici":1650," kt":14067,"ich":3629,"ice":1897," kn":595,"ie ":19237," km":3854," kl":1191,"ica":2319," kr":5176," ko":7181," me":12179," mi":3009," o ":2049," ma":5130,"idl":708,"ide":1943,"ida":634," lo":1116," ab":764," am":1765," an":2592," ap":672," aj":2712," ak":5587," al":12145," au":1810," ar":1452," at":917," as":1460," ba":944,"il ":2232," bi":1273," be":1234," bo":7806," bl":568,"ieč":555," by":978," bu":1277," br":1360,"ať ":1963,"im ":540,"ika":2006,"ii ":2231,"ik ":1390,"imo":583," en":822,"ime":618," el":1140," ek":582,"imi":618," fe":960,"inc":1687,"ind":914,"ina":4033," fa":975," ex":1042," fu":1061,"inn":1036," fr":1747,"ino":2279," fo":1624,"int":1331,"ins":1181,"inf":730,"ine":3297,"iež":1149,"ing":1758," fi":2971,"ini":1596,"ink":652," ge":918," ga":535," bý":593,"iká":1538,"inu":1322,"iny":3026," fy":712,"iko":1475,"ikl":600," ce":3110,"ike":783," ch":2700," ci":1436,"ila":1287," da":904,"in ":1617,"iky":1322,"iku":1353," do":7552," dn":677,"ilo":2707," dl":624,"ill":858," dr":3425,"iln":537,"ilm":766," de":4244,"ili":1886," di":2885,"ieľ":575," dv":1786," du":557," vý":6398," zm":1324," zl":1104," zo":2693," zn":2605," zr":719," zv":1435,"hok":654,"hol":1107,"hom":770," za":7013," zd":916,"hos":535," ze":560,"hov":3246," vä":714,"hor":2878,"dí ":1492,"hod":4341," tý":674,"hnu":694," z ":7975," sú":8023,"huj":767,"hud":1122," vš":1583," už":616," zá":4976,"hu ":2863,"hro":776,"hra":2720," ru":986," sa":11939," se":4266," sc":711,"hyb":690," si":1947," sm":780," sl":4314," sk":5136," sp":8017," so":2515," mô":637," ra":2110," re":5038," ná":5061," ri":1768," ro":13226," pr":34757," ps":641," s ":5627,"hy ":1193," má":2179," os":2878," ot":721," op":1633," or":1845," oz":1525," pe":1662," lá":612," pa":3109,"hrá":1069,"hve":833,"hvi":1289," pl":3456," po":28142," pi":764," vy":7755," rô":570," vz":3164," sí":744," va":859," ve":5421," rá":581," vn":537," vo":6181," rí":775," vr":1254," vi":1930," vl":2079," ty":876," pô":1710," tv":1722," tu":1188," us":808," ur":1335," um":1379," un":575," ta":2281," v ":29073," sy":2275," st":8244," sv":3511," su":1035," pí":654," tr":3662," to":6094," th":647," ti":1601," te":5857," Če":1108,"far":539," čí":1229," čo":669,"ext":753,"ez ":733," če":1631," čl":1364," či":2100,"exi":778," ča":4766,"ezd":2253,"evá":647,"eze":538," ďa":573,"eta":1992,"ete":2049,"eti":2038,"etn":619,"etk":1257,"esp":670,"esn":932,"eso":1170,"est":8782,"esu":1559,"eto":2278,"etr":1705,"ets":539,"erá":1903,"eve":2813,"eva":786,"evo":552,"evn":668,"evi":600,"eur":694,"er ":5579,"epa":610,"eol":809,"es ":3178,"ept":842,"epu":784,"epl":609,"epo":608,"epr":993,"eri":5783,"ejš":2097,"erg":805,"ená":3253,"ere":1934,"era":3225,"et ":1437,"emí":1248,"esk":2173,"esi":987,"ený":3926,"ese":2018,"esa":609,"erz":959,"erv":1342,"eru":692,"ení":1974,"ert":777,"ers":1662,"ern":3749,"ené":2633,"erm":1031,"ero":3934,"eko":1708,"ekt":4312,"eku":666,"en ":3989,"ela":1378,"ele":4527,"eli":2168,"eln":1067,"elk":666,"ell":742,"elo":1876,"els":755,"emb":1776,"ema":956,"eme":4087,"emo":708,"emi":2282,"ene":3296,"ena":1245,"end":639,"enc":1378,"eno":3633,"enn":1593,"enk":694,"eni":7601,"ens":6528,"ent":6824,"eká":616,"eob":637,"egi":891,"ej ":24245,"eho":5071,"ek ":1552,"eja":658,"el ":2590,"ejo":597,"eke":577,"eka":784,"em ":1276,"git":547,"gie":653,"gic":1619,"gia":694,"gen":1449,"geo":632,"býv":889,"gal":592,"gan":1363,"fyz":775,"fun":734,"fra":1611,"ače":897,"ači":550,"ačo":893,"ačn":1506,"aču":636,"for":2552,"fic":1396," ľa":1263,"fil":2159,"fik":1059,"fin":689," ľu":1198,"da ":3499,"de ":4522,"dal":718,"daj":777,"dat":690,"dan":1747,"ňov":688,"ňuj":774,"cko":2082,"chá":3113,"cky":1826,"ciá":1302,"cií":762,"cká":2980,"cké":4043,"com":638,"cov":2204,"cou":843,"cký":6183,"ch ":28988,"cer":678,"ces":1333,"cen":1906,"cel":1592,"ci ":4101,"cha":2180,"chu":807,"chy":636,"cia":4155,"cie":3755,"cic":1003,"che":1676,"chl":672,"chi":1393,"cho":6193,"chn":823,"chr":824,"cii":806,"ciu":1018,"cio":1122,"cke":2891,"ed ":1409,"ebe":670,"ebo":10260,"ebr":822,"ec ":2815,"edk":836,"edm":627,"edn":6191,"edi":1893,"ede":2996,"eda":1823,"edz":3180,"edy":1130,"eds":867,"edo":1996,"eck":2662,"ech":1905,"eci":648,"ece":694,"ecn":583,"dy ":3344,"drá":560,"dvo":1617,"dzi":3041,"dze":584,"dza":3109,"dor":670,"dop":717,"dom":1779,"dol":1125,"dok":1204,"dov":3715,"dos":1422,"dpo":810,"dmi":940,"dna":890,"dne":4630,"dni":563,"dno":4328,"ôzn":583,"dob":3335,"dst":1631," ús":674," úz":1992,"duk":644,"duc":748,"dné":1797,"dra":864,"dná":1325,"dre":621,"du ":2083,"dro":1109,"dní":530,"dru":2904,"dsk":1498,"dný":2826,"ôso":1218," úč":553,"dic":713,"dia":1795,"der":1566,"dec":966,"dej":622,"del":1924,"den":5230,"dep":553,"ňa ":821,"dla":715,"do ":3088,"dlo":1153,"dlh":673,"dli":698,"div":859,"din":1669,"dio":707,"dis":1227,"die":2214,"ôvo":1350,"rga":1225,"ri ":3554,"rgi":554,"rge":623,"ižn":609,"ret":2145,"res":5921,"nás":953,"rev":1170,"náv":764,"náz":1745,"rez":1012,"reb":974,"rea":838,"nác":533,"rec":1162,"red":6538,"rej":1959,"reg":962,"reh":593,"nám":1836,"rem":1118,"ren":3464,"rek":894,"rel":975,"nál":1168,"nár":2386,"rep":1499,"óri":1260,"ná ":9951,"re ":5558,"rch":2256,"raz":2538,"rd ":682,"ras":1183,"rat":3414,"rav":4611,"óps":667,"môž":675,"raj":2984,"ran":7562,"ram":1814,"ral":930,"rak":1723,"raf":1089,"rad":3121,"rac":1364,"rs ":542,"ros":1960,"rot":1344,"rom":3824,"ron":1914,"rop":884,"roz":4727,"rou":580,"rov":10282,"rob":1537,"rod":4794,"roc":1978,"ní ":2500,"roj":1677,"rol":693,"rok":6707,"rof":585,"rog":1008,"rno":1434,"rny":1014,"rna":1377,"rež":722,"rne":2865,"rni":769,"rmo":565,"jší":951,"nét":1209,"ro ":773,"rma":1073,"riá":846,"néh":4120,"rka":749,"né ":10505,"rio":767,"rit":1644,"ris":1567,"rig":582,"jši":1295,"ril":574,"rik":952,"rin":1063,"rim":561,"ria":5593,"rib":817,"ric":4203,"rid":872,"rie":6455,"rk ":572,"nóm":573,"ruh":2733,"rum":558,"ruk":768,"rus":1271,"rva":761,"rvk":581,"rve":789,"rvo":671,"ry ":2619,"rsk":3778,"rný":683,"rst":1039,"rto":675,"rti":742,"roč":900,"ním":1698,"ník":2268,"rmá":1093,"níc":1168,"rt ":585,"rné":631,"ru ":1693,"sad":597,"sah":1086,"sam":778,"nýc":6239,"óno":796,"ným":3498,"san":671,"sa ":11522,"ruž":608,"ný ":12353,"ón ":764,"nú ":1355,"rvá":821,"ógi":1295,"rvý":709,"rzi":638,"si ":1248,"sie":988,"sia":1333,"sil":824,"se ":2313,"sch":1140,"sev":1936,"ser":859,"sed":553,"sep":711,"sen":856,"sel":864,"spo":4892,"spr":1629,"spe":1357,"spi":721,"skú":704,"ský":5535,"sov":2280,"ské":3823,"son":682,"ská":3010,"sok":687,"soc":946,"sob":2176,"su ":2117,"st ":1149,"slo":4792,"slu":716,"sky":4413,"sla":2054,"sle":1956,"ski":627,"skl":733,"sko":6875,"skr":1088,"sku":6994,"ska":3470,"ske":5984,"sno":764,"sne":932,"so ":1147,"sme":1025,"stí":1337,"sté":1586,"stá":1256,"syn":543,"sys":1453,"ste":3353,"sta":10107,"stn":2428,"sto":7431,"sti":10473,"stv":3596,"stu":2162,"spô":638,"str":11165,"sts":614,"sve":2116,"svo":1166,"tak":1277,"tal":2000,"tad":583,"tav":3617,"tat":1770,"tas":556,"tar":2723,"tan":2795,"te ":3202,"ta ":5658,"ký ":7646,"kús":915,"ouž":1757,"ozá":729," št":4899,"pa ":715," šk":769," šp":1040," Št":611,"kú ":741,"osť":3922,"pe ":579,"lá ":591,"kýc":4322,"kým":2061,"par":1586,"pat":1317,"pad":2850,"pal":635,"pan":1020,"pev":859,"láv":675,"lác":551,"pec":635,"lád":794,"pen":751,"lán":627,"lár":543,"per":2191,"lát":631,"pel":545,"pla":2526,"ple":978,"pln":576,"plo":927,"ply":661,"pie":636,"pin":2362,"pis":1414,"pit":610,"poz":1867,"pr ":604,"por":2069,"pop":662,"pov":2089,"pou":1725,"pot":3320,"pos":2178,"poj":1973,"poh":1271,"pom":1667,"pon":991,"pok":841,"pol":5900,"poc":543,"pod":5807,"po ":2974,"psk":735,"pub":965,"pte":802,"poč":2131,"pra":4417,"lín":914,"prv":2306,"pri":8032,"pre":12441,"pro":5879,"lóg":1712,"poľ":636,"prá":2352,"prí":5030,"lý ":669,"má ":1849,"mä ":776,"mál":594,"mác":652,"iť ":1130," ži":2499," že":1412,"mí ":997,"ra ":5741,"eži":1187,"ngl":1479,"ni ":1003,"nge":617,"ncú":959,"neh":1387,"nej":10418,"nen":2040,"nem":1523,"nep":832,"ner":1759,"net":1021,"nes":1971,"nev":549,"ež ":1107,"ng ":1176,"nec":565,"nfo":594,"nač":2104,"nez":594,"nco":652,"nci":2449,"nce":985,"ne ":14236,"ndr":573,"ndo":698,"ndi":836,"nde":718,"nda":660,"nak":996,"nal":1254,"nam":2854,"nan":1218,"nap":1468,"nar":576,"nac":1381,"nad":1643,"naj":5055,"nd ":984,"nav":578,"nat":1148,"nas":648,"naz":679,"na ":25237,"mys":1196,"ión":1128,"mož":865,"nyc":1783,"ntá":825,"nož":749,"ny ":7794,"nut":1486,"nto":1924,"ntu":602,"ntr":1488,"nti":2074,"nta":1252,"nte":2106,"nst":911,"nsk":12019,"nný":1960,"nu ":2533,"ičn":889,"nt ":1523,"noh":590,"nom":6261,"not":1866,"nos":7269,"nor":620,"nov":6617,"nou":2761,"nne":1300,"nno":871,"nič":860,"no ":2111,"nka":1319,"nky":647,"nko":836,"eží":971,"nie":10761,"nic":3941,"nia":4773,"niz":1417,"niu":577,"niv":740,"nis":1117,"nit":919,"nin":802,"nik":3242,"ogr":1539,"ogi":1853,"ohr":721,"ohu":747,"oho":1731,"oha":677,"oj ":736,"ok ":6372,"ohy":806,"ojv":611,"ojo":1042,"ojn":974,"oji":587,"oje":2846,"oja":533,"ol ":4900,"oce":1370,"och":5397,"oci":1231,"ock":745,"obs":891,"oby":2302,"ká ":7010,"ode":2380,"odi":1507,"odo":2687,"odp":783,"odn":6582,"ods":1082,"odr":641,"of ":750,"oda":688,"kál":578,"ody":570,"odv":550,"odu":1909,"kác":693,"hľa":877,"ofi":1501,"júc":4607,"oba":663,"od ":5680,"obo":1131,"obr":1755,"obl":2050,"obn":2229,"obj":2245,"obi":1583,"obd":699,"obc":1130,"obe":3213,"nym":950,"jú ":3234,"owi":541,"ový":6197,"ozm":884,"ové":3486,"ozn":2417,"ozl":939,"ozo":2454,"ozd":725,"ová":4125,"otv":654,"otk":570,"oti":1114,"ote":984,"otr":702,"oto":4368,"otn":953,"ost":12819,"ota":944,"ov ":17465,"osi":598,"osk":702,"osp":667,"osl":1521,"oso":997,"orú":1676,"orý":4753,"ovi":5011,"ovn":3441,"oré":3735,"orí":947,"ovo":4172,"ovs":2190,"ova":12599,"ovc":817,"orá":2973,"ove":10952,"opo":1188,"opi":803,"ope":1090,"opa":913,"os ":1011,"oló":1594,"opr":1001,"olí":768,"or ":2600,"ork":577,"orm":2535,"orn":2464,"oro":4190,"ord":568,"ore":3404,"oná":934,"org":1589,"ori":3545,"ou ":11758,"osa":791,"ort":1007,"ors":1188,"oru":1061,"onó":542,"ory":689,"omá":669,"m² ":561,"ora":1870,"ízk":541,"íto":1670,"ola":3491,"on ":2680,"oli":3155,"olk":708,"ole":1539,"oln":999,"olo":6182,"oly":771,"olu":1129,"oka":1003,"om ":22923,"ké ":4451,"ísl":936,"oke":803,"odľ":1432,"okr":4784,"íta":936,"oko":5187,"okt":536,"oku":4912,"ona":1883,"ond":761,"onc":866,"one":891,"ívn":1999,"oni":1442,"onk":548,"ono":1770,"ons":933,"ont":1301,"oma":1179,"ome":2634,"omi":1538,"kéh":4205,"omp":910,"omn":567,"omo":2048,"omu":756,"íva":2087,"la ":7993,"íms":589,"ína":690,"íns":810,"ím ":3028,"íka":561,"íko":789,"ín ":1967,"le ":3820,"eľ ":1241,"íro":535,"ísa":578,"lad":4725,"ípa":543,"laj":540,"lan":3456,"lam":627,"lat":2521,"las":3716,"lav":3631,"lbu":1038,"krá":1832,"kva":670,"kut":584,"kup":2670,"kum":749,"kul":1450,"kuj":582,"ky ":10576,"íck":596,"ích":1516,"íci":652,"ídl":750,"ktr":1255,"kti":779,"kto":15825,"ík ":1507,"ktú":719,"kyc":690,"ktí":857,"lok":542,"lon":552,"lom":1766,"loh":1318,"log":1964,"los":1486,"lov":10431,"loz":1479,"lno":1179,"lež":1031,"lne":3312,"lny":1606,"lič":614,"lna":768,"loč":1880,"lsk":1225,"íc ":720,"lné":534,"liž":568,"lu ":1579,"lný":723,"li ":2968,"lez":532,"lex":642,"eľs":559,"les":1366,"let":1210,"ler":562,"eľo":2345,"eľm":560,"len":3929,"eľn":732,"eľk":1782,"lek":1883,"lej":738,"led":1215,"hád":2792,"lec":545,"leb":10035,"eľa":1087,"lo ":4534,"eň ":963,"lle":613,"lli":641,"lko":992,"lit":2952,"lis":1429,"lin":2535,"liz":1155,"liv":1148,"lic":2198,"lia":1970,"lik":1405,"lie":1755,"ma ":1882,"hý ":549,"maj":736,"mag":530,"mar":970,"mal":1423,"man":1923,"mat":2750,"mbe":991,"mbr":959,"me ":2180,"med":3229,"mec":1667,"met":2730,"mes":5087,"mer":6360,"iál":1808,"mel":722,"men":7980,"ly ":1425,"lož":1837,"ltú":839,"mpl":621,"moc":890,"mod":1086,"mon":943,"mom":711,"mov":2255,"mor":1939,"mos":887,"mot":1139,"mu ":3156,"msk":1141,"my ":1946,"mus":1219,"mun":908,"mi ":7759,"min":2367,"mil":710,"mit":579,"mic":1764,"mia":681,"mie":3132,"ií ":1338,"mno":1169,"Čes":624,"výr":1121,"výs":904,"výv":564,"vým":1096,"výz":1213,"sť ":5294,"sťo":1256,"čas":7534,"zná":1803,"čen":2971,"čes":715,"zsk":1303,"či ":954,"zvy":552,"zuj":707,"čia":1892,"čit":761,"čin":1952,"čka":799,"zyk":1455,"člo":565,"čo ":704,"čle":748,"čeľ":579,"čov":1446,"vý ":3640,"čno":1723,"čne":1110,"výc":4086,"zi ":1861,"zač":716,"vác":643,"zdr":695,"zen":1178,"zem":2639,"vár":636,"zer":667,"vá ":4679,"zdi":837,"zde":597,"zaj":992,"zan":554,"zal":1158,"zar":737,"zos":869,"zor":857,"zof":1473,"zov":2409,"zo ":1433,"väč":1491,"zme":835,"véh":1297,"zna":5129,"zmu":1473,"zmy":578,"zne":607,"zni":1787,"vé ":2772,"zko":574,"zlo":1388,"zdí":688,"väz":626,"zin":1015,"zik":680,"zit":695,"yva":1437,"ytv":779,"yst":2333,"yso":679,"ysl":1049,"za ":3910,"yzi":807,"ych":3717,"tým":683,"yda":835,"uár":767,"túd":552,"tý ":1101,"túr":2064,"týc":709,"ym ":918,"yko":908,"tín":557,"tív":2085,"tém":1500,"tí ":1453,"ože":1844,"ožn":749,"oži":948,"tár":638,"tát":2299,"táv":759,"tác":584,"tál":1075,"súč":1671,"té ":1097,"xis":565,"súh":1058,"sús":702,"sú ":2895,"tá ":794,"sér":579,"síd":652,"rče":541,"rči":735,"vzť":595,"vzn":1177,"vzd":855,"vyr":543,"vyd":936,"vys":1291,"vyt":825,"vyv":562,"rú ":1621,"rý ":3747,"vyš":1099,"rýc":1417,"rís":711,"rít":1609,"ríp":667,"rím":628,"rík":630,"vní":633,"vné":1199,"vrc":1038,"vst":887,"vsk":2197,"vu ":969,"vný":1142,"vuj":550,"vy ":2098,"voľ":584,"róp":1084,"rôz":582,"via":1774,"vil":1662,"vať":944,"vin":2530,"vic":742,"vid":1528,"vie":3018,"nšt":824,"vit":1615,"vis":1230,"važ":892,"ré ":3238,"vla":1346,"ráľ":818,"veľ":1567,"vo ":5058,"réc":806,"réh":740,"vne":2233,"vna":1235,"vno":1530,"vny":872,"rí ":1490,"voc":735,"vod":4147,"voj":3988,"vol":995,"vom":1769,"vor":3219,"vot":802,"vos":2079,"vov":1480,"vou":852,"vlá":818,"vi ":826,"vez":833,"ver":4560,"ves":693,"oľs":926,"rát":1564,"vet":2834,"ráv":2279,"vej":3167,"ven":6559,"rán":812,"oľn":609,"vel":598,"rál":1811,"vek":1439,"ved":2502,"vec":641,"rác":1499,"rá ":3488,"ve ":3005,"val":2956,"van":10444,"var":1669,"vat":3033,"vac":763,"vaj":1282,"va ":7123,"urč":1357,"uró":1104,"usk":1487,"ust":1684,"uti":837,"ute":592,"uto":2154,"us ":3503,"uri":613,"uro":616,"ujú":3483,"upi":2474,"ulá":681,"upe":584,"upn":539,"umb":576,"ume":1559,"unk":1091,"uni":1311,"ukt":726,"um ":2635,"ult":1375,"ulo":557,"uli":689,"uhu":583,"uje":4632,"uho":1552,"ugu":540,"ude":572,"uch":1187,"uh ":722,"udo":1777,"ubl":1069,"tvá":863,"typ":873,"ty ":3084,"očí":1245,"trí":632,"tvo":4048,"trá":1603,"tve":851,"tva":2149,"tur":912,"tuj":829,"tup":1550,"pôv":1057,"pôs":1202,"pís":996,"tná":587,"oče":1143,"tre":4383,"tra":5412,"oča":775,"tné":1110,"oči":806,"tri":3765,"tru":1300,"tro":6109,"očn":2672,"tu ":3234,"tný":1463,"tsk":2708,"toč":963,"to ":9348,"tne":1495,"tno":1220,"toc":600,"tou":572,"tov":6017,"tos":575,"tom":2788,"ton":1192,"tok":6341,"tol":1656,"tor":19018,"top":560,"tký":805,"tik":2033,"tif":575,"tie":2901,"tit":878,"tis":1709,"tin":2110,"tio":893,"tia":1542,"tic":5672,"tiv":708,"tko":851,"tka":2298,"tli":832,"tky":1006,"tla":755,"teľ":4587,"tem":1660,"ten":2822,"tep":676,"tej":1310,"tek":1233,"tel":2263,"tec":925,"ted":826,"tex":545,"ter":5642,"ti ":7610,"tač":896,"ží ":1158,"žív":1856,"zťa":609,"yšš":666,"úča":1833,"zýv":664,"ľko":705,"ľom":604,"ľký":597,"ľov":2803,"žin":599,"žil":543,"živ":1147,"žit":1013,"žia":1434,"žij":593,"žov":702,"žno":718,"žne":1488,"že ":2141,"ľav":960,"ľad":1602,"žen":2262,"ľa ":2178,"zác":1029,"záv":683,"záp":1954,"zák":1752,"uži":784,"ýra":532,"užn":1127,"ýro":660,"ým ":5866,"ými":2162,"ôže":563,"ých":17568,"žsk":553,"ľsk":1094,"ľud":1147,"zém":590,"vše":1630,"uží":1835,"ýzn":1190,"ýva":1701},"n_words":[5274251,6043345,4170145],"name":"sk"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/slv b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/slv new file mode 100644 index 000000000..cb9617131 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/slv @@ -0,0 +1 @@ +{"freq":{"D":7697,"E":4326,"F":7483,"G":7482,"A":12478,"B":11289,"C":8095,"L":10635,"M":14480,"N":8171,"O":6564,"H":9046,"I":7126,"J":7268,"K":11757,"U":2722,"T":7824,"W":1905,"V":10234,"Q":288,"P":16672,"S":26591,"R":9751,"Y":433,"X":356,"Z":6077,"f":21271,"g":83131,"d":174445,"e":575804,"b":82172,"Fed":58,"c":56405,"a":599039,"n":410604,"o":476628,"l":247955,"m":151651,"j":244223,"k":242702,"Fel":92,"h":59332,"i":522865,"w":2524,"v":222867,"Fer":370,"u":129396,"t":241091,"s":268170,"r":314054,"q":489,"p":164089,"z":94676,"y":6418,"x":1284,"²":123,"Î":185,"É":129,"Á":62,"Fil":230,"í":2013,"Fin":151,"ë":81,"ê":309,"é":3055,"Fir":82,"è":584,"ç":174,"ä":365,"â":114,"á":3560,"à":133,"ü":557,"ú":870,"ø":79,"ö":488,"ô":419,"ò":234,"ó":1670,"ē":62,"đ":109,"Đ":87,"ā":111,"ć":1063,"Č":1470,"č":56247,"ŕ":73,"ő":245,"ł":69,"ō":86,"Ž":2008,"ž":30614,"Š":2528,"š":51762,"Fak":387,"Fal":70,"Far":111,"Eri":80,"Est":69,"Eti":62,"Ern":82,"Eur":142,"Eva":78,"Evr":794,"Ein":58,"́":345,"Ele":144,"Eko":86,"μ":124,"ν":240,"Ena":60,"ο":342,"ι":214,"κ":105,"λ":169,"δ":61,"ε":131,"η":95,"α":330,"β":59,"γ":116,"ά":79,"ί":88,"Emi":63,"Eli":70,"ό":99,"σ":119,"ς":264,"ρ":222,"π":98,"φ":61,"υ":78,"τ":148," l":19333,"ь":113," m":28795," n":57198,"я":125," o":41952," h":4815,"ш":89," i":55210," j":67383," k":54205,"ы":63," d":42036,"ф":78,"х":75," e":9710,"ц":79," f":9447," g":14912,"ч":253,"р":642,"с":417," a":19069," b":18884,"т":428," c":4312,"у":369," y":127," x":151," z":31775," u":19039," t":27202," w":136," v":56888," p":90919," s":76633," r":20918,"HK ":93,"И":69,"К":110,"Н":65,"М":132,"П":82,"Б":103,"А":111,"Г":80,"В":98,"Д":60," J":7259," K":11717," H":8994," I":7097," N":8139," O":6489," L":10542," M":14428," B":11242," C":8027,"С":106," A":12432," F":7459," G":7430," D":7664," E":4306,"л":503,"к":526," Z":6067,"й":182," Y":432," X":347,"и":1084,"п":111,"о":912,"н":714,"м":224,"г":177," S":26492," R":9719,"Ger":142,"в":657," Q":287,"б":103," P":16617,"а":1195,"з":72," W":1888,"Geo":282," V":10198,"Gen":320," U":2704,"е":796,"д":264," T":7802," č":5716," Č":1467," Đ":87,"Gla":255,"Gia":71,"HL ":80," Á":62,"Gio":131," É":127," Î":185,"Gir":61,"Giu":113," ž":7506," Ž":2008," Š":2526," š":7903,"ա":58,"Gan":63,"Gal":184,"Gam":76,"Gar":174,"Gab":108,"و":76,"ي":148,"ل":189,"م":127,"ن":117,"Fun":63,"د":71,"ب":101,"ا":258,"ر":124,"Flo":89,"Fla":62," А":111," Б":103," В":98," Г":71,"Fra":1714," Д":60," И":69," К":110,"Fri":169," М":132," Н":65,"A ":1521," П":82,"Fre":167,"For":1812," α":63,"F ":287,"Da":1043,"Cu":190,"Cv":64,"Cy":61,"Cl":275,"Co":1643,"Cr":347,"Ce":1243,"Ch":1233,"Ci":465,"G ":285,"Ed":331,"Ea":63,"Dv":143,"Du":856,"Do":1622,"Dr":1054,"De":1300,"Di":918,"Fe":729,"H ":307,"Fa":834,"Eu":245,"Ev":1000,"Er":320,"Et":115,"Es":220,"En":413,"Em":164,"Ep":63,"Ei":124,"El":403,"Ek":172,"Eg":130,"Ge":887,"Ga":902,"I ":771,"Fu":219,"Fr":2141,"Fo":2047,"Fl":225,"Fi":681,"B ":327," С":104,"II ":321,"C ":846,"Av":1043,"Au":489,"Ar":1294,"At":316,"As":365,"D ":417,"Ba":1844,"Az":412,"Af":338,"Ag":178,"Ah":87,"Ab":563,"Ac":172,"Ad":372,"Am":987,"An":1820,"Ap":398,"Ai":256,"Aj":81,"Ak":264,"Al":2250,"Hit":92,"Bu":797,"Br":2247,"Ca":1535,"E ":345,"Bi":1004,"Hid":63,"Be":2195,"Bo":1910,"Hil":81,"Bl":438,"Bj":272,"Hip":72,"Kv":109,"Ku":509,"Kn":259,"IE ":65,"Kl":445,"Kr":2275,"Ko":3816,"Le":3189,"Lj":1723,"Li":1298,"N ":264,"La":1624,"Lu":757,"Ly":76,"Lo":1512,"Me":2219,"Dž":96,"Mi":1869,"Ml":211,"O ":680,"Ma":6025,"Mc":133,"Mu":580,"Mr":101,"Mo":2460,"Nj":399,"Ni":828,"Já":138,"Ne":1598,"Na":2980,"P ":622,"Hel":136,"Ny":85,"Hei":136,"Nu":95,"No":1554,"Ok":258,"Ol":321,"Om":113,"On":187,"Og":200,"Oh":58,"Oc":80,"Od":1568,"Hen":142,"Her":380,"Ob":922,"Gi":553,"Gl":510,"Gr":1909,"Go":1659,"Gu":367,"Gv":83,"Gy":129,"Cô":91,"J ":297,"Ha":1563,"He":1085,"Hi":543,"Ho":701,"Hr":4064,"Hu":331,"K ":438,"Ib":78,"Id":108,"Ig":180,"Im":513,"In":1624,"Il":230,"Iv":415,"Is":1036,"It":703,"Ir":277,"Ja":1804,"L ":443,"Iz":883,"Ji":68,"Je":1541,"Jo":1290,"Hab":58,"Ju":2001,"Hal":126,"Haj":64,"Ka":2508,"Han":157,"M ":389,"Ham":119,"Har":293,"Ki":622,"Győ":92,"Hau":402,"Ke":544,"Us":272,"Ur":262,"Up":188,"Um":80,"Un":907,"Uk":147,"Ul":103,"W ":109,"Ty":77,"Tu":672,"Tr":1582,"To":1468,"Th":691,"Ti":704,"Te":1011,"Ta":1070,"V ":1619,"Côt":91,"Sw":66,"Sz":701,"Sy":147,"St":3308,"Sv":2528,"Su":652,"Wo":195,"Wi":724,"Wh":64,"Wa":405,"We":272,"Vz":150,"Vo":999,"Vr":488,"Vs":193,"Vu":139,"Vi":1620,"Vl":200,"X ":215,"Va":913,"Ve":3902,"Má":81,"Pt":177,"Pu":321,"Pr":3992,"S ":1529,"Pe":1571,"Pa":2197,"Gui":73,"Lé":59,"Pl":789,"Po":5526,"Pi":1027,"Ph":198,"Os":738,"Ot":263," ا":112,"Op":322,"Or":646,"R ":294,"Oz":78,"Se":2093,"Sc":592,"Si":1170,"Sh":254,"Sn":82,"Sm":234,"Sl":6573,"Sk":484,"Sr":839,"Sp":1374,"So":1617,"Ru":971,"Grč":81,"U ":245,"Sa":2421,"Re":3735,"Rd":107,"Ri":922,"Rh":128,"Ro":1660,"Qu":211,"T ":330,"Ra":1534,"Mü":85,"Gre":332,"Gri":94,"Gra":810,"Grb":113,"b ":3960,"Gru":126,"Gro":222,"a ":211856,"Yo":229,"Gle":73,"Z ":240,"Glo":95,"Gol":160,"Gor":907,"Gos":120,"Za":1749,"Zd":593,"Ze":881,"Zi":330,"Zg":337,"Vé":82,"Zm":60,"Zl":152,"Zo":102,"Zn":141,"Zu":99,"God":61,"Zr":80,"Zv":306,"i ":134220,"gd":128,"ge":5872,"ga":24650,"fj":134,"Inf":332,"fl":264,"ff":331,"fi":4842,"fs":419,"fr":3897,"ač":5802,"fu":678,"ft":369,"fo":2045,"Int":382,"fn":91,"j ":12717,"gy":387,"dá":73,"he":3525,"ha":5343,"gn":1368,"gm":166,"gl":6996,"gi":8855,"gh":503,"gg":192,"gv":88,"gu":2562,"gt":124,"gs":203,"bč":5121,"gr":10356,"cí":78,"go":15666,"dt":312,"du":5066,"dv":5016,"dw":173,"dy":144,"dz":369,"g ":4531,"Ima":116,"ea":2500,"eb":7309,"ec":6168,"ed":29381,"de":25427,"Ili":79,"dd":738,"dg":429,"di":24057,"dh":181,"dk":1177,"dj":1456,"dm":1512,"dl":1112,"do":16087,"dn":14568,"dp":1050,"ds":3632,"dr":13867,"ew":457,"ex":237,"eu":1040,"ev":19283,"ey":856,"ez":12153,"fa":2439,"h ":28964,"aú":301,"Ind":547,"fe":2538,"bá":91,"eh":4032,"eg":21346,"ef":1414,"ee":651,"Ime":316,"el":42176,"ek":16159,"ej":9407,"ei":1868,"ep":9382,"eo":3145,"en":61076,"em":38275,"et":32921,"es":22879,"er":40015,"ca":8624,"bz":65,"e ":176361,"bv":197,"by":89,"bs":2013,"br":6519,"bu":2540,"bt":104,"bn":3084,"bo":9119,"bj":937,"bk":143,"cL":77,"bl":11842,"bm":547,"bh":211,"bi":17028,"bb":158,"bd":603,"be":10505,"dc":181,"db":1176,"da":28148,"f ":2764,"cz":61,"cy":123,"cv":189,"cu":951,"ct":549,"cs":478,"cq":69,"cr":248,"co":5124,"cm":121,"cn":95,"ck":1329,"cl":245,"ci":15112,"ch":3183,"ce":12343,"cc":353,"c ":6745,"az":10124,"ay":618,"ba":6779,"d ":25792,"at":30196,"as":24786,"ar":39381,"ax":151,"aw":283,"av":30027,"au":2021,"ak":12407,"al":45711,"ai":1701,"aj":23033,"ao":367,"ap":6069,"am":13386,"an":71011,"ac":6592,"ad":26926,"aa":226,"ab":7824,"ag":7152,"ah":7624,"ae":1031,"af":1621,"nu":5151,"nt":10999,"ns":25512,"ič":13659,"nr":295,"np":329,"no":51231,"nn":1495,"nz":984,"ny":526,"nw":82,"jó":58,"nv":255,"oe":569,"ká":135,"of":3946,"oc":3247,"od":39028,"oa":584,"ob":20785,"om":19239,"on":23036,"ok":14837,"ol":27351,"oi":2548,"oj":11831,"og":11726,"oh":1523,"m²":117,"ot":18168,"os":30813,"ov":55859,"ou":2158,"op":10262,"oo":1164,"or":35498,"jč":131,"r ":20683,"ox":97,"kó":141,"ow":586,"kö":75,"oz":8175,"oy":187,"pd":65,"lá":269,"pe":10198,"pa":26706,"Igr":74,"pc":146,"pl":6471,"lé":474,"pn":2144,"po":53400,"ph":657,"pi":10229,"pj":64,"pk":185,"lo":38721,"ln":9297,"lm":1635,"hé":133,"ll":3272,"ls":3383,"lp":1148,"lv":458,"lu":4829,"lt":2975,"lz":195,"ly":422,"hô":58,"Idr":67,"o ":117173,"mc":91,"md":104,"ma":23441,"mb":4609,"dž":1661,"iá":58,"me":39489,"mf":152,"mk":917,"iè":113,"ml":1947,"mi":12739,"eš":4276,"mj":85,"mn":2345,"mm":463,"mp":2668,"mo":14761,"hč":66,"mr":915,"mt":95,"ms":4458,"mv":69,"mu":5539,"my":115,"p ":1343,"na":91417,"nb":277,"nc":8502,"nd":6315,"ne":43250,"já":118,"nf":942,"ež":5003,"ng":4878,"nh":345,"ni":72174,"nj":24738,"nk":3254,"ić":821,"nl":278,"nm":267,"jv":1409,"jt":127,"ju":14494,"eč":5728,"js":10383,"jp":458,"jn":4767,"jo":15551,"jl":168,"jm":397,"jk":398,"kj":752,"ki":56467,"kh":121,"ke":31686,"kd":477,"kc":1346,"ka":42561,"fü":98,"m ":32866,"jz":162,"ky":130,"ks":2035,"kt":5285,"ku":8273,"kv":2313,"ko":52366,"gí":90,"kr":10395,"kk":78,"kl":5176,"km":1749,"gé":62,"kn":1425,"dš":398,"li":49096,"lh":245,"lk":2648,"lj":32952,"le":34235,"há":163,"ld":976,"lg":1256,"lf":539,"hâ":70,"la":37335,"lc":2469,"lb":823,"n ":53330,"hr":1878,"hs":96,"dí":74,"hw":70,"ht":692,"hu":981,"hj":61,"hk":1523,"hi":3365,"hn":1375,"ho":9636,"hl":379,"dè":58,"dé":139,"hm":293,"id":5268,"ic":16189,"ib":3404,"ia":4880,"ih":24332,"ig":5375,"if":1125,"ie":2994,"hy":222,"dú":72,"k ":19129,"iq":110,"ir":15616,"dč":73,"is":20587,"it":17935,"iu":664,"iv":10504,"ix":194,"aš":9037,"ii":2454,"ij":44668,"ik":30544,"il":26890,"im":25029,"in":69797,"io":5253,"ip":4264,"jc":271,"jb":886,"je":114329,"jd":485,"až":1346,"bš":153,"ji":18381,"jh":438,"iz":20523,"l ":16581,"ja":44343,"tä":161,"pš":106,"xi":105,"té":252,"tí":147,"tó":164,"ww":69,"z ":12173,"xa":126,"ož":4663,"tá":178,"nž":333,"wi":424,"oš":3587,"sé":150,"wn":164,"wo":138,"sí":94,"rč":573,"ws":163,"ró":226,"rô":65,"vz":2935,"y ":2958,"wa":490,"sá":124,"we":348,"rè":76,"vl":5625,"vm":123,"ré":314,"vj":1191,"vk":1293,"vh":61,"nš":866,"vi":26446,"vg":688,"vt":1201,"vu":1200,"vr":6944,"vs":7139,"vp":572,"rí":254,"vn":18643,"vo":20029,"uz":834,"ux":225,"uv":1705,"uu":61,"ve":45929,"rá":407,"vd":234,"vc":816,"vb":122,"va":33280,"x ":755,"mš":2061,"ui":868,"uj":5428,"uk":2181,"ul":7777,"ue":1036,"uf":172,"ug":6200,"lž":478,"uh":1992,"ur":10254,"pč":78,"us":9210,"ut":2587,"um":3595,"un":5703,"uo":144,"up":17758,"ty":284,"tz":304,"tu":11745,"tt":1249,"tw":125,"pó":70,"tv":10431,"ub":7050,"ua":3183,"ud":8270,"uc":1029,"w ":442,"to":33340,"tn":10733,"pé":68,"tm":2491,"tl":2152,"ts":2917,"oč":7724,"tr":18852,"tp":111,"tg":72,"tf":115,"te":38423,"pá":79,"td":278,"tk":3275,"tj":2887,"lš":176,"ti":34585,"th":1742,"v ":46495,"tc":114,"ta":42943,"su":2438,"sv":4904,"ss":1521,"st":64846,"sy":100,"sz":642,"sw":95,"sl":11373,"sk":60513,"sn":5408,"sm":2123,"sp":12768,"so":15794,"nč":1620,"sr":3075,"sd":114,"sc":1363,"sf":304,"se":40074,"sh":762,"sj":389,"kš":233,"si":9098,"rz":2218,"u ":23884,"sa":10107,"sb":1404,"mč":427,"rr":991,"rs":12425,"rt":8497,"ru":11754,"rv":10562,"rw":89,"nó":68,"ry":877,"ní":142,"rp":731,"ro":31529,"rn":11113,"né":172,"rm":4944,"rl":1460,"rk":7297,"nç":122,"rj":7769,"jš":3373,"ri":44436,"rh":1257,"rg":4613,"iž":2554,"rf":351,"ná":202,"re":43763,"rd":5068,"rc":1442,"rb":2537,"ra":68896,"t ":20636,"qu":409,"mí":90,"lč":258,"mé":211,"iš":12414,"má":431,"s ":18299,"px":59,"pt":1806,"pu":4524,"ló":186,"pp":444,"lí":193,"pr":43317,"ps":1569,"Hum":81,"yő":97,"vž":60,"zá":92,"už":4277,"vš":416,"uš":1692,"Hrv":3876,"yí":60,"Hra":77,"rž":2418,"zz":215,"vč":549,"zg":2406,"Hor":93,"zh":2141,"zi":10015,"rš":3989,"zb":1418,"zc":70,"zd":3868,"ze":5649,"vá":315,"za":21344,"Hon":64,"Hok":73,"Hol":102,"zv":5632,"zs":530,"zr":2612,"uč":1996,"zu":2176,"zt":382,"zo":6065,"zn":9166,"ví":186,"zp":931,"zk":568,"zj":291,"zm":3200,"vé":151,"zl":2570,"ye":263,"yc":118,"yd":123,"ya":395,"yt":90,"ys":299,"Hoc":85,"yr":276,"yp":87,"yo":155,"yn":206,"ym":124,"yl":250,"yk":172,"yj":189,"yi":151,"Arg":159,"Arh":66,"Are":64,"Ard":164,"šču":315,"Ara":107,"Arm":203,"ščo":81,"ščn":64,"Ari":101,"šči":1771,"Apo":252,"šče":2731,"šča":1225,"Atl":156,"Ast":131,"Ass":80,"Art":149,"Avt":105,"Avs":709,"Ave":81,"Auv":73,"Aut":64,"Aug":99,"zš":796,"Azi":191,"Azu":144,"Bak":78,"Bal":229,"Ban":193,"Bab":79,"Bad":69,"Bar":430,"Bat":109,"Bas":111,"Bav":61,"Aba":278,"Ada":80,"Ado":61,"Afr":271,"Air":92,"Al ":78,"šće":104,"Aka":59,"Akv":95,"Ala":127,"Alb":257,"Ali":77,"Ale":389,"Alf":117,"Alt":76,"All":122,"Alo":87,"Alp":662,"Ame":656,"Ama":87,"Ang":426,"Ana":133,"And":409,"šč ":144,"Ant":584,"Ann":63,"Buz":68,"Buk":74,"Bur":210,"Bud":88,"Bru":110,"Bož":77,"² ":120,"DA ":787,"DD ":66,"Cal":180,"Cam":157,"Cas":187,"Car":397,"Cat":66,"Can":211,"Cap":85,"Bea":66,"Bes":153,"Ber":630,"Beo":125,"Ben":301,"Bel":559,"Biz":86,"Bje":262,"Bil":214,"Bis":245,"Bit":75,"Bio":71,"Blo":64,"Ble":72,"Bla":204,"Bre":545,"Bra":506,"Bro":313,"Bri":606,"Boh":133,"Bog":157,"Bol":225,"Boj":60,"Bon":91,"Bor":510,"Bos":176,"Bou":105,"Îl":184,"Der":74,"Des":135,"Dev":75,"Dek":70,"Del":334,"Dem":64,"Den":114,"Deb":67,"Dam":75,"Dan":339,"Dar":97,"Dav":176,"Dal":121,"Chr":147,"Che":154,"Chi":125,"ám":76,"án":655,"Cit":86,"áj":126,"Cir":117,"ák":172,"ál":309,"ác":115,"ád":136,"áz":116,"áv":123,"ár":751,"át":278,"ás":315,"ât":67,"Châ":62,"Cla":118,"Cel":355,"Cen":243,"Cer":450,"Ces":88,"à ":58,"á ":69,"Cha":633,"Cre":137,"Cor":603,"Com":262,"Col":181,"Con":211,"Cou":99,"ós":120,"ót":110,"óv":101,"ôm":59,"ôn":89,"Duš":60,"ód":99,"ór":148,"ón":273,"óm":66,"ól":124,"ók":78,"ó ":118,"Drž":130,"ív":88,"íz":94,"ín":324,"ír":134,"ít":126,"ís":96,"ík":80,"íl":246,"íj":224,"íd":88,"ía":72,"Egi":80,"ên":58,"êr":99,"éz":94,"ék":134,"él":241,"éj":87,"ém":138,"én":587,"és":167,"ét":261,"ér":344,"év":100,"éd":144,"ée":75,"Edw":93,"èn":67,"èr":126,"ço":94,"é ":306,"ät":162,"Do ":87,"ć ":449,"Dia":61,"Dic":151,"Dis":100,"Dir":87,"Dio":72,"Din":68,"Die":63,"Div":106,"Dub":388,"Dun":175,"ün":108,"ür":209,"Dvo":99,"Dru":220,"ún":88,"új":321,"úr":86,"Dre":102,"Dra":452,"íš":61,"Dob":200,"ôt":129,"ör":97,"Dou":72,"Dol":339,"Don":353,"Dom":230,"Dor":129,"Ned":79,"Nea":69,"Nem":513,"Nek":87,"Nev":71,"Neu":84,"Jás":105,"Nep":74,"Nas":351,"Nat":199,"Nav":148,"Nic":123,"Niz":179,"Nik":208,"OJ ":106,"New":248,"Nap":119,"Nar":283,"Nam":213,"Nan":68,"Nag":201,"Nah":254,"Naj":294,"Nad":104,"Na ":449,"ći":324,"OV ":124,"ća":95,"će":161,"Či":127,"Če":527,"Ča":315,"Ču":69,"Čr":316,"či":13203,"čj":3069,"čk":2033,"čl":1507,"če":9878,"ča":7103,"čb":207,"č ":3958,"đe":65,"Đu":65,"čn":11436,"čo":315,"čr":1069,"ču":2190,"čv":95,"Nji":74,"Nje":320,"Nov":818,"Nor":440,"Not":61,"Odv":1174,"Ogr":131,"Obč":247,"PL ":89,"Okr":139,"Nyí":60,"Obs":170,"Obi":89,"Obr":75,"Obo":60,"Od ":141,"Île":184,"Oto":151,"Oli":186,"Ont":118,"Ope":134,"Ore":118,"Org":93,"Ost":65,"Osj":214,"Osm":58,"Osn":93,"Po ":423,"š ":428,"Pli":67,"Ple":143,"Pla":466,"Pin":72,"Pik":79,"Pit":66,"Pis":66,"Pir":250,"Pie":165,"Phi":96,"Ped":76,"Per":309,"Pes":215,"Pet":518,"Pen":134,"Pel":66,"šč":6357,"šć":151,"Pat":125,"Pas":151,"Par":669,"Pav":183,"Pau":156,"Pad":61,"Pac":78,"Pan":157,"Pap":82,"Pal":206,"Pak":100,"še":3798,"ša":2845,"šo":760,"šp":1066,"šn":1922,"šk":22840,"šl":713,"ši":4197,"šj":684,"šv":183,"šu":178,"št":5493,"Še":283,"Ša":280,"Šm":149,"Šo":105,"Ši":182,"Šk":346,"Šu":75,"Št":406,"Šv":259,"Šp":321,"Pož":327,"Ptu":112,"Pro":707,"Pri":1370,"Pre":1114,"Prv":307,"Pru":73,"őr":96,"Pra":329,"Pod":622,"Pok":159,"Pol":1336,"Pom":102,"Pon":195,"Pog":199,"Poi":167,"Poj":93,"Pot":652,"Pos":334,"Pov":181,"Pop":91,"Por":385,"Poz":75,"žr":68,"žu":4511,"žn":3757,"žo":181,"žc":62,"žb":1014,"že":6604,"žd":91,"ža":4974,"žk":205,"žj":1185,"žl":145,"žg":130,"ži":6432,"Žu":1147,"Ža":131,"Ži":199,"Že":372,"RS ":268," ال":88,"ž ":1046,"Rac":68,"Rad":357,"Ram":58,"Mün":75,"Ran":79,"Rak":65,"Que":120,"Irs":68,"Ita":679,"Isl":158,"Ist":728,"Ira":123,"Inš":104,"Iva":381,"Izv":187,"Izr":254,"Izd":68,"Jac":161,"Jad":111,"Jav":92,"Jar":108,"Jap":208,"Jan":529,"Jam":191,"Jak":171,"Jel":130,"Jer":198,"Jes":136,"Jez":169,"Jea":145,"Izš":73,"Je ":506,"Jos":354,"Jor":75,"Jon":77,"Joh":406,"Jug":908,"Jud":70,"Jup":160,"Jur":234,"Jul":171,"Jož":199,"LA ":59,"Juž":280,"Kam":278,"Kal":271,"Kap":166,"Kan":372,"Kat":241,"Kas":83,"Kar":544,"Kaz":101,"Kav":68,"Ker":149,"Ken":111,"Kis":102,"Kir":77,"Kit":180,"Kin":85,"Klo":59,"Kli":73,"Kle":103,"Kla":125,"Kon":517,"Kom":582,"Kol":204,"Kos":201,"Kor":867,"Kop":552,"Kov":80,"Kot":149,"Koz":113,"Knj":131,"Kob":74,"Koc":70,"Kre":107,"Kra":1273,"Kri":388,"Krk":87,"Kro":118,"Krš":94,"Koš":77,"Koč":102,"Kul":64,"Kun":76,"Kur":69,"Kva":82,"Lev":100,"Let":1929,"Les":99,"Leo":137,"Len":143,"Lau":76,"Law":92,"Le ":107,"Lag":58,"Lah":83,"Las":91,"Lat":85,"Lar":113,"Lam":67,"Lan":280,"Lab":97,"La ":179,"Lju":1716,"Lib":144,"Lig":77,"Lim":128,"Lin":177,"Lip":125,"Lit":222,"Luk":154,"Lui":81,"Lun":67,"Lud":105,"Luc":114,"Lou":148,"Lov":122,"Los":65,"Lot":115,"MS ":61,"Loi":123,"Log":104,"Lor":123,"Lon":188,"Lok":174,"Lič":69,"Lež":206,"Meh":106,"Men":114,"Mel":123,"Mes":284,"Mer":173,"Met":220,"Med":836,"Mač":73,"Mez":77,"Man":399,"Mal":462,"Mar":2349,"Mas":191,"Mag":152,"Mad":1011,"Maj":111,"Mak":235,"Mai":69,"Mac":176,"McL":66,"Max":58,"Mau":68,"Mat":387,"Mla":152,"Mod":111,"Moh":80,"Moj":64,"Mol":94,"Mon":601,"Mos":493,"Mor":297,"Mou":64,"Mot":314,"Mih":227,"Mik":175,"Mic":218,"Mit":62,"Mir":154,"Mis":119,"Mil":386,"Min":343,"NK ":115,"Mur":270,"Mus":87,"Moš":81,"çoi":67,"Wor":66,"Wol":82,"Wik":71,"Wil":329,"Win":160,"ère":90,"Wes":77,"War":73,"Wal":129,"Vzh":106,"Vse":94,"Vrb":98,"Vra":69,"Vrh":141,"Vol":145,"Voj":511,"Vod":126,"Viš":166,"Več":124,"Vis":126,"Vit":109,"Vla":188,"Zla":131,"čuj":826,"čun":696,"Vél":58,"čut":108,"črk":423,"čre":113,"črt":288,"éte":58,"črn":193,"ču ":419,"Zna":123,"Zdr":568,"ény":95,"Zap":71,"Zar":126,"Zas":101,"Zav":104,"Zag":314,"Zah":111,"Zak":109,"Zal":123,"ékt":72,"én ":269,"éli":106,"Zgr":67,"Zgo":249,"éra":62,"Zim":226,"Zel":179,"Zem":564,"ов ":64,"Zač":142,"之":72,"三":107,"Zad":119,"Za ":213,"Yor":161,"на ":82,"Szo":98,"Sza":480,"Sys":60,"Sve":2328,"Sup":72,"Sud":142,"Str":416,"Stu":150,"Sti":77,"Sto":225,"Sta":2102,"Ste":244,"Teh":61,"Ten":108,"Tem":109,"Teo":88,"Tel":99,"Tek":83,"Tam":78,"Tan":81,"Tar":117,"Tak":138,"Tal":65,"Ta ":195,"Sko":62,"Skr":66,"Sku":204,"Ska":62,"Sha":82,"Sim":142,"Sil":93,"Sis":205,"Sir":188,"Sin":157,"Sib":59,"Sez":419,"Ses":154,"Ser":176,"Sev":340,"Sen":145,"Sel":241,"Sem":91,"Sei":131,"Sed":75,"Srb":301,"Sre":466,"TV ":116,"Sv ":98,"Spa":211,"Spl":481,"Spi":65,"Spe":164,"Spr":96,"Spo":313,"Sod":63,"Sok":63,"Soc":117,"Sob":124,"Sou":80,"Sov":270,"Sol":119,"Som":85,"Son":199,"Sop":149,"Sor":59,"Sla":201,"TO ":84,"Slo":6226,"Sli":73,"So ":69,"Rož":72,"Rus":577,"Rud":148,"Sai":290,"Sam":204,"Sal":223,"Sad":71,"Sco":63,"Sch":394,"Sav":417,"Sat":60,"Sau":74,"Sar":260,"San":495,"ови":138,"Rač":75,"SI ":76,"Res":82,"Rev":59,"нов":79,"Rim":348,"Rib":92,"Ric":128,"ät ":150,"Ras":66,"Rav":91,"Raz":271,"Rde":102,"SG ":79,"Rec":63,"Red":122,"Rei":91,"Reg":444,"Ren":132,"Rek":120,"Rep":2306,"Rog":117,"Rob":196,"Roc":78,"Rod":85,"Rou":102,"Ros":172,"Ron":234,"Rom":237,"SS ":448,"SO ":89,"Vel":2994,"Ven":157,"ски":72,"Vas":75,"Van":123,"Val":340,"Var":221,"Vid":128,"Vic":103,"Vie":59,"Vir":205,"Vil":211,"Vik":75,"Vin":206,"Ver":276,"Ves":184,"Ukr":102,"Uni":842,"Ura":80,"Ust":217,"Upo":141,"Trž":77,"Ter":179,"The":362,"Tho":193,"Tih":67,"Tim":73,"Tis":131,"Tir":83,"To ":334,"Top":167,"Tor":193,"Tok":64,"Tol":157,"Tom":179,"Ton":82,"Tou":87,"Tru":58,"Trs":127,"Tro":210,"Trn":82,"Tri":282,"Trg":65,"Tre":271,"Tra":244,"Tur":330,"Tuk":62,"ši ":887,"šev":379,"šem":193,"šel":270,"šen":350,"šes":555,"šer":80,"šeg":118,"šek":215,"ša ":1145,"še ":1531,"šar":175,"šav":187,"šah":216,"šaj":99,"šal":222,"šan":614,"Šve":109,"Švi":128,"što":95,"štr":65,"šte":2122,"šti":888,"šta":268,"šuj":72,"štv":1659,"štu":262,"švi":77,"šve":96,"špa":358,"šov":61,"špo":639,"št ":64,"šu ":58,"ško":7029,"šlj":265,"šla":312,"вич":166,"šo ":156,"šić":67,"šni":492,"šnj":513,"šne":308,"šna":327,"šič":190,"šno":281,"šol":499,"šic":246,"šib":61,"šin":843,"šil":171,"šim":108,"šik":69,"ših":534,"šit":122,"šir":718,"šje":233,"šja":121,"šji":274,"ška":2789,"ški":6172,"ške":6766,"́н":79,"cLa":71,"bju":136,"bje":482,"bja":288,"áto":72,"biz":60,"bis":206,"bit":738,"biv":1271,"bio":487,"bir":767,"ász":140,"bil":9355,"bim":90,"bin":672,"bij":500,"bo ":1111,"blj":4814,"blo":131,"ble":384,"bli":5531,"bn ":78,"bla":906,"bod":537,"bok":127,"bol":2141,"boj":794,"bog":423,"boh":73,"bič":489,"bno":809,"bna":528,"bni":923,"bne":712,"bmo":523,"biš":76,"bon":136,"bom":159,"bor":1964,"áza":65,"bot":328,"bos":204,"bov":492,"bou":88,"áln":82,"be ":2097,"bam":109,"ban":872,"bak":214,"bal":951,"baj":107,"áko":72,"bah":107,"bac":170,"án ":124,"baz":156,"bav":207,"bat":235,"bas":207,"bar":1233,"ánt":85,"bdo":308,"áno":61,"ány":67,"bde":133,"azš":326,"ánd":61,"bda":111,"bi ":1760,"bej":129,"beh":88,"ár ":304,"bec":216,"ber":3398,"ben":1839,"bel":842,"bez":109,"bes":1297,"bet":155,"baú":258,"bho":160,"bia":67,"bib":116,"bic":125,"áro":114,"ári":73,"áci":80,"buš":62,"ca ":7059,"car":308,"cas":90,"cat":115,"can":153,"cam":193,"cal":177,"cah":276,"ce ":3980,"bri":1142,"bro":951,"brn":171,"bra":2116,"bre":1080,"bu ":321,"brs":91,"bru":767,"bsk":752,"bso":165,"bse":534,"bst":433,"boč":145,"bur":549,"bul":151,"bum":224,"buj":619,"bud":138,"buc":60,"bus":181,"bve":153,"by ":66,"bož":173,"aka":2233,"am ":1501,"ake":764,"akc":307,"aki":595,"ajk":170,"ajl":126,"aji":853,"ajo":3508,"ajp":438,"ajm":203,"ajn":1032,"ajs":1806,"ajt":95,"aju":1775,"ajv":1227,"al ":5680,"ajb":861,"aja":4631,"ajd":410,"ajc":106,"aje":1321,"ajh":414,"ail":145,"ain":656,"air":120,"ais":193,"ak ":1483,"ahk":1261,"ahl":62,"ahi":99,"ahu":67,"aht":170,"aho":1733,"aj ":3209,"agy":182,"aha":1141,"agl":148,"agm":59,"agi":325,"agr":2630,"agu":186,"agn":486,"ago":1560,"anu":2488,"anz":168,"ano":4496,"ann":617,"ant":2576,"ans":8949,"ane":3760,"ang":2192,"anh":58,"ani":12168,"anj":11003,"ank":1463,"ap ":82,"ana":5327,"anc":5066,"and":2328,"amu":229,"amm":99,"amo":2039,"amn":424,"amp":456,"ams":594,"amk":68,"ami":1934,"adž":1259,"ame":3673,"amb":620,"ama":1428,"ao ":196,"alv":164,"alu":459,"alt":357,"als":1671,"alp":219,"alo":3988,"aln":5663,"alm":581,"all":563,"alk":590,"alg":235,"ali":12519,"adš":352,"alj":2204,"alc":1638,"ald":278,"ale":2748,"alf":59,"Šam":81,"ala":5384,"alb":313,"an ":7080,"aks":331,"akr":499,"aku":1530,"akt":954,"ako":3028,"akn":93,"akl":239,"aba":528,"abe":1164,"abi":922,"abl":2808,"abn":285,"abo":950,"abr":232,"abs":510,"abu":83,"ae ":446,"aca":87,"ad ":1592,"ac ":892,"ab ":93,"afo":67,"afr":130,"aft":161,"afs":248,"aff":75,"afe":70,"afi":418,"ai ":215,"aga":832,"age":434,"ael":296,"ah ":2832,"afa":85,"ado":1208,"adr":500,"adl":177,"adk":221,"adn":2260,"adm":341,"adg":67,"adj":251,"adi":2931,"add":208,"adc":70,"ade":1675,"ag ":119,"adz":178,"ads":309,"adu":492,"aco":154,"ack":237,"aci":3927,"ach":405,"ace":463,"acc":103,"ada":12281,"adb":350,"af ":280,"act":73,"azn":554,"azm":458,"azp":368,"azo":464,"arš":186,"azi":1682,"azl":1367,"azk":65,"azv":987,"azu":362,"azr":436,"azt":209,"azs":228,"aze":313,"azg":172,"aza":617,"Špa":241,"azb":60,"azd":489,"avč":119,"azz":92,"az ":748,"ayl":61,"aye":106,"Šta":81,"Šte":144,"ba ":1670,"Štu":63,"at ":1858,"arh":471,"arg":219,"are":1974,"ard":2757,"arc":477,"arb":245,"ara":3352,"arp":61,"aro":2967,"arn":2439,"arm":683,"arl":640,"anç":98,"ark":1199,"arj":3449,"ajš":619,"ari":4347,"aru":188,"arv":516,"arr":314,"ars":3622,"art":3803,"au ":230,"asa":521,"ary":261,"akš":197,"asi":1326,"ash":118,"asc":90,"asb":1150,"ase":7736,"aso":654,"asn":756,"asp":358,"ask":223,"asm":118,"asl":1005,"ar ":4861,"apa":403,"Šen":181,"ape":643,"api":1573,"aph":75,"apn":71,"apl":264,"apo":1357,"app":73,"apr":1152,"aps":75,"apt":76,"apu":142,"as ":2234,"avc":158,"avb":92,"ava":3257,"ax ":66,"aux":63,"aut":447,"avs":1220,"avt":891,"avr":171,"Ško":256,"avo":1996,"avn":8963,"avk":259,"avl":3158,"avi":5083,"anš":152,"avj":154,"avg":550,"ave":2196,"Šma":126,"ay ":236,"awa":58,"avz":193,"avu":60,"arč":77,"awn":81,"anž":60,"av ":1266,"ata":1793,"asu":583,"ast":7399,"ass":309,"anč":577,"atm":280,"atn":621,"atk":2238,"atl":115,"atr":682,"ato":4303,"ate":7456,"alš":59,"ati":8392,"atj":90,"ath":285,"att":232,"ats":603,"atu":979,"aul":252,"aum":70,"aun":59,"aur":182,"aus":178,"aud":100,"auk":85,"ος":138,"ος ":138,"ς ":264,"ν ":77,"Zve":255,"α ":118,"еви":63,"ий ":84,"ич ":167,"až ":103,"jeg":1394,"jej":1047,"jed":501,"jec":86,"jep":94,"jer":828,"jek":653,"jel":447,"jem":3606,"jen":7756,"jez":1544,"jes":258,"jet":1512,"jev":3484,"jač":189,"ji ":9921,"aža":200,"ažd":84,"aže":590,"ažj":94,"aži":70,"ažn":142,"jhe":109,"jhn":247,"jad":100,"jat":493,"jas":144,"jav":1972,"jap":253,"jar":116,"jal":4024,"jak":772,"jan":7670,"jam":569,"jah":261,"jaj":1388,"jaz":69,"jbo":832,"jce":82,"je ":90645,"izš":397,"jci":81,"jde":159,"jda":105,"jna":637,"ješ":262,"jmo":79,"jni":1155,"jne":1049,"jič":83,"jno":1777,"eč ":1193,"jol":65,"jon":462,"jos":83,"jor":101,"jpo":317,"jpr":102,"ск":123,"jiv":675,"jit":167,"jis":201,"jim":790,"jin":1168,"bšk":61,"jik":186,"jil":336,"jaš":1441,"jij":72,"jig":518,"jih":2539,"jic":888,"те":99,"ječ":100,"ст":65,"ул":59,"jn ":65,"jko":128,"jka":118,"jo ":14224,"jma":181,"jlo":62,"itn":496,"itm":98,"itl":62,"itk":153,"itr":810,"ito":1788,"itv":1047,"itu":620,"itt":146,"its":553,"itz":130,"ity":105,"isk":1191,"ism":148,"isl":637,"iso":1260,"isn":596,"isp":122,"iss":283,"inč":105,"isu":398,"ist":8943,"isz":119,"iv ":665,"ita":4085,"itd":78,"ite":3294,"ith":151,"iti":3232,"itj":163,"ivo":647,"ivn":1608,"ivu":289,"inž":250,"ius":336,"ium":162,"iva":2833,"ix ":146,"inš":354,"ivi":1461,"ivj":69,"ivk":187,"ivl":505,"ive":1813,"ipr":269,"ipo":673,"ipp":99,"ipu":59,"ips":60,"ipt":181,"ipi":261,"ipl":628,"is ":1968,"ion":2321,"iop":95,"ior":98,"ios":95,"iot":214,"iog":97,"iok":133,"iol":587,"iom":79,"ipa":1086,"ipe":338,"iov":126,"ir ":1030,"iru":579,"irs":381,"irt":62,"iro":1658,"irn":1433,"irk":3666,"iri":1414,"irj":549,"isi":572,"ish":146,"ise":765,"isc":429,"isa":2843,"iu ":69,"iqu":102,"ilč":111,"ire":909,"irg":67,"ira":3405,"irc":132,"it ":737,"ünc":71,"ivč":108,"ür ":68,"ivš":143,"ja ":24669,"iz ":4501,"izu":488,"izv":2556,"izr":1033,"izs":209,"izp":299,"izo":951,"izn":244,"izm":1841,"izl":440,"izk":366,"izj":155,"irš":113,"izi":2488,"izh":387,"izg":268,"ize":500,"izd":905,"izb":341,"iza":2030,"kaš":110,"kih":6752,"kij":103,"kim":1029,"kil":157,"kie":91,"kiv":97,"kin":454,"kip":232,"kir":103,"kis":399,"kit":420,"kaž":123,"kje":723,"km ":698,"ki ":46414,"ked":200,"keg":3700,"kej":985,"kem":8923,"kel":218,"ken":160,"kes":145,"ker":562,"ket":264,"kev":340,"key":87,"kač":293,"ke ":15947,"kci":1307,"kda":435,"kra":4811,"krb":350,"kre":318,"kt ":433,"ksa":263,"kse":141,"ku ":1833,"kro":1818,"krv":182,"kri":2242,"koz":528,"kov":6012,"km²":98,"kot":4172,"kos":954,"kor":1260,"kop":980,"koo":149,"kon":3042,"kom":2571,"kol":3036,"kok":1914,"koj":101,"koh":100,"kog":105,"kof":1624,"kod":500,"ks ":201,"kmu":212,"kme":268,"kmo":345,"koc":91,"kob":135,"kne":116,"kni":115,"knj":1121,"klu":447,"ko ":24162,"kma":99,"kle":646,"kla":1462,"klo":710,"kli":1093,"klj":712,"jvo":146,"jut":62,"jus":126,"jul":555,"jun":698,"jur":257,"jve":859,"jvi":346,"joč":433,"jub":2164,"juj":406,"jug":1198,"jud":1091,"jsk":8627,"jst":1435,"ečj":1199,"ečk":404,"eči":887,"ečn":355,"ečo":63,"eču":68,"ju ":6445,"jse":265,"jiš":131,"eča":390,"eče":1036,"již":650,"kaz":528,"kav":355,"kat":5637,"für":83,"kar":3117,"kas":410,"kap":270,"kan":1808,"kal":3239,"kam":632,"kaj":559,"kak":434,"kah":366,"kai":81,"kad":433,"kac":404,"juž":772,"ka ":23634,"juč":601,"jze":62," Ga":900," Ge":881," I ":207," Fo":2042," Fu":219," Fr":2139," Fi":677," Fl":224," Ha":1561," He":1083," Cô":91," Gy":129," J ":84," Go":1655," Gr":1898," Gu":360," Gv":83," Gi":550," Gl":510," Ig":179," Id":108," Ib":77," K ":116," Hu":329," Hr":4060," Ho":699,"ha ":480," Hi":543," Ji":67," Je":1541," L ":110," Ja":1800," Iz":882," Iv":415," Ir":276," Is":1032," It":703," Im":512," In":1618," Il":228,"ham":322,"han":759," M ":155,"hai":79," Ka":2499,"haj":1477,"hal":392," Ke":540,"hau":83," Ki":619,"har":950,"has":60,"hat":80," Jo":1288," Ju":1997,"haf":95,"hae":137,"hab":68,"had":64," N ":83," La":1551," Le":3180," Li":1291," Lj":1723," Kl":443," Kn":255," Ko":3810," Kr":2271," Kv":109," Ku":508," Mc":133," Ma":6006," O ":269," Ml":210," Mi":1860," Dž":96," Me":2209,"he ":889," Lo":1511," Ly":76," Lu":757," Já":138," Ne":1590,"а ":247," P ":279," Na":2970," Nj":398," Ni":827," Mr":101," Mo":2454," Mu":575,"hek":94,"hel":368,"hei":125,"heb":110," A ":314,"het":73,"hes":152,"her":719,"heo":145,"hen":330,"hem":187,"hi ":171," B ":212," C ":442," Ap":398," Am":984," An":1817," Ak":264," Al":2235," Ai":256," Aj":81," Ag":178," Ah":85," Af":338," Ac":171," Ad":366," Ab":561," Ba":1832," D ":134," Az":412," Av":1041," Au":488," At":316," As":363," Ar":1291," Be":2192,"hie":110,"hid":239,"hic":86," Bi":1002,"hia":98,"hip":210,"hio":70," Bj":272,"hin":407,"him":147," Bl":437," Bo":1900,"hil":201,"hik":78,"hij":109," Br":2242," Bu":794,"his":178,"hit":605,"hir":188," E ":92," Ca":1521," Ce":1243," Ci":464," Ch":1220," Cl":266," Cr":346," Co":1629," Cu":189," Cv":64," Cy":61," F ":123," Da":1039," Di":915," De":1297," Dr":1054,"hkr":181," Do":1606,"hko":1232," Du":855," Dv":142," Ea":63,"hn ":214," Ed":330," G ":65,"hla":193," El":398," Ek":172," Ei":122," Eg":129," Et":115," Es":219," Er":320," Ep":63," En":408," Em":164," Eu":245," Ev":1000," Fe":726,"ho ":80,"hma":181," Fa":830," H ":159,"gma":95,"go ":1697,"glo":304," Z ":182,"gle":2479,"gli":810,"glj":228,"gla":2978," Wo":190," Wi":722," Wh":62," We":269," Wa":403,"й ":140," Vz":150,"gog":353," Zr":80," Zu":99,"god":1736," Zv":306,"gob":81," Vé":82," Zm":60," Zl":152," Zo":102," Zn":141," Zd":593," Ze":880," Zg":337,"gič":79,"gno":136," Zi":327,"gni":103,"gnj":147," Za":1745,"gne":563,"gna":300," Yo":229,"gs ":62,"о ":66,"goz":506,"goj":282,"н ":123,"gom":421,"gol":311,"gon":470,"gos":3146,"gor":2864,"got":348,"gov":2780,"gu ":806," a ":458,"р ":62,"gro":564,"grm":63,"gru":125,"bču":59,"grs":221,"gra":6878,"grb":61,"bči":4969,"gri":272,"gre":942," R ":122,"в ":115," Oz":78," Os":737,"gto":98," Ot":263," Or":643,"goč":401," Op":320," Po":5507," Lé":59," Pl":785," Pi":1026,"gul":122," Ph":190,"gua":77," Pe":1565,"gub":149," Pa":2188,"gue":188," Ny":85," Nu":95," No":1550," Ol":321," Ok":257," On":182," Om":107," Oh":58," Og":200," Od":1566," Oc":80," Ob":907," Ra":1525," Mü":85," T ":114," Qu":210,"új ":254,"goš":89," Ro":1658," Re":3734," Rd":107," Ri":916," Rh":128," S ":293," Pr":3986,"gur":145,"gus":676," Pt":177," Pu":321,"gun":145," Má":81," Sz":701," Sy":146," Sw":66," Sv":2526," Su":652," St":3290," Ta":1068," V ":1176,"gya":99," Th":689," Ti":702," Te":1006," Tr":1582,"gyk":115," To":1461," Ru":970," Sa":2415," U ":88,"е ":69," Sh":246," Si":1155," Sc":584," Se":2090," So":1610," Sp":1368," Sr":838," Sk":482," Sl":6566," Sm":233," Sn":82," Va":911,"и ":110," X ":144," Ve":3898," Vi":1616," Vl":200," Vo":997," Vu":138," Vr":488," Vs":192," Tu":669," Ty":77,"grš":1077," Uk":147," Ul":103," Um":80," Un":907," Up":188," Ur":251," Us":272," ja":3029," l ":65,"iam":240,"ial":1334," iz":12947,"ian":961," ji":1172,"ias":76,"iar":121," je":57692,"iat":484," io":104," ip":64," im":7503," in":30104," il":218,"ic ":1048,"iac":130," is":755," it":1465,"iag":159," ir":117,"ibl":600," fü":65,"ibi":274," ka":7604,"ibo":889," m ":545,"ibn":134,"ibr":170," kj":700," ki":23502,"ibu":174," ke":816," jo":1895,"id ":690,"iba":621,"ibe":314," ju":3473," ha":275," he":621," gi":540," gl":3153," gr":2915," go":2718,"ia ":1100," gu":114," k ":178," ib":60," id":224," ig":1379,"ib ":92," hi":1051," hk":181," hl":97," ho":1169," hr":955," hu":193,"iet":196,"ieu":64," nj":2131," ni":1612,"iel":266," ne":7311,"ien":545," na":42601,"ier":585,"ies":172,"ied":168,"ieg":71,"и́":65," mu":575," mr":220,"ig ":209," mo":4823," mn":787," mm":80," ok":4185," ol":657,"ifu":62," om":674," on":135," og":566," oh":232,"ifo":187," oc":331," od":6669," of":580," ob":12756,"ifr":67,"ife":161,"ifi":406,"ih ":22740," nu":342," no":2512," np":247,"ifa":63," le":11324," lj":1128,"icr":71,"ics":75,"ict":217," li":1970,"icu":137,"icn":80," n ":309,"ico":974,"ick":188," la":3283," kv":554," ku":716,"ici":3252,"ich":665,"ice":3027," kn":1159,"ie ":718," km":1016,"ica":6322," kl":1067," kr":5141," ko":11511," me":12878," dž":64,"idu":106," mi":1837,"ids":75," ml":614,"я ":69,"idr":346," o ":887,"ido":732," ma":6202,"idn":485," lu":270,"idi":434,"idg":71,"ide":1356,"ida":711," lo":1132," af":94," ag":154,"aša":593," ab":327," ac":59," ad":284,"aše":251," am":1331,"ašk":6766," an":2354,"aši":200," ap":760,"ašn":368,"iin":107," ak":715,"iim":2227," al":6858," av":1858," au":60," ar":1254," at":457,"ašt":146," as":1847," d ":320," ba":1756," az":58,"il ":5175,"ija":12085," bi":10040,"ije":12707," be":1503,"iji":5965," bo":2432," bl":915,"ijo":6465,"ijs":4363," bu":186,"iju":165," br":1850," ca":173," e ":85,"im ":3856,"ika":6461,"ige":666,"iga":1104,"aš ":78,"igl":183,"igh":214,"igi":601,"igu":193,"igr":1537,"igo":249,"ign":280,"ij ":2784,"т ":70," b ":94,"ihe":100,"iha":530,"ihi":87,"iho":729,"ik ":9136,"у ":103," c ":70," er":65,"imo":1733,"imn":223," et":360," es":185," en":4762,"ims":2333," em":109," ep":251,"imp":926,"imf":91," el":1413,"ime":9448," ek":723,"imk":790,"imi":2451,"ip ":337," fe":1007,"inc":748,"ind":925,"ina":10483," fa":1370,"imu":325,"а́":109," ev":586," fu":480,"inn":113," fr":3146,"ino":5575,"ašč":462," fo":718,"int":1271,"ins":4445,"inf":316," fl":126,"ine":5190,"inh":91,"ing":1310,"inj":1193," fi":2355,"ini":4151,"ink":465," ge":1321," ga":4003,"iod":295,"inu":433," i ":115,"inv":62,"inz":59," cl":64,"iko":4804," cm":100,"ikl":979," co":254,"iki":3287," ce":2735," ch":72,"ike":4355," ci":552,"ila":7057,"ilb":66," f ":61,"in ":31978," da":5215,"ikv":58," cv":150,"ikt":162,"iku":799,"ikr":245,"iks":94," do":7621," dn":241,"ilo":4202,"ill":1121,"ilk":457," dr":7206,"iln":1875,"ilm":587,"ilh":107," de":11720,"ilj":766,"ili":2960,"ild":76,"ilc":146," di":5516,"ile":1135,"ima":2334,"imb":293,"ч ":172," ed":1001,"io ":829," dv":2054," du":1905,"ils":366,"ilt":85,"ilu":372,"ilv":125,"ль":58," vč":201," zm":655," zl":487,"ла":90," zo":151," zn":3542," zu":280,"ле":83," uč":541," zr":511,"ли":66," zv":1609,"hok":781,"hol":497,"hom":250,"hon":167," za":14763,"ко":128,"hos":66," zd":1135,"hot":761," ze":976," zb":804,"hov":2393,"ку":58,"hop":61," zi":186,"hor":342," zg":1780,"ка":91,"ки":115,"hod":3942,"hni":523,"hno":289,"hnu":58,"hna":106,"hne":92," z ":4835,"ин":98,"ик":81,"ий":90," ož":121,"ич":191,"ри":87,"ро":86,"ра":120,"ре":58,"htt":71,"hto":63,"htn":72,"hte":153," už":81,"ор":104,"ол":82,"ов":288,"hu ":190,"hrv":430,"но":113,"hro":110,"hre":73,"ни":87,"hri":399,"ht ":188,"на":128,"hra":653,"hiš":212," ru":1131," u ":188," sa":1902," se":18649," sc":148," si":3326," sh":137," sn":739," sm":996," sl":6094," sk":4932," sr":1993," sp":10659," so":10507,"ви":220," t ":95," ra":7736," re":7014," rd":178," ri":2298," ro":2318," pt":209," pu":582," pr":31964," ps":336," s ":4586," px":59,"hy ":96,"ва":103,"ад":75," os":4746," ot":1470,"hum":246," ov":185,"hun":84,"hus":107," op":2076," or":2176,"hur":142,"ан":143,"ак":68," oz":3235," pe":3830," pa":8196,"ар":96," pl":2669," po":40217," pi":2589," y ":101," vz":1551," x ":129," va":2039," ve":6450," uv":1301," vn":129," vo":6456," vp":464," vr":2767," vs":3256," vi":2299," vk":283," vl":673," vm":85," ud":201,"ет":79,"ер":77,"ен":63," tv":236," tu":5865," us":2479," ut":152," ur":2875," up":8796," um":682," un":617," uk":539," ul":238," ug":179," ta":4305," v ":29906," st":7117," sv":3870,"о́":61," su":765,"ев":143," oč":210," tr":3796," tl":193," to":2461," th":371," ti":1200," tk":120," te":8405,"fi ":65,"ffe":78,"ffi":69,"fes":342,"fer":516,"fed":154,"feb":634,"fen":145,"fek":403,"fel":89," Ča":315," Či":126," Če":525,"faz":112,"fat":64,"far":143,"fan":669,"fak":920,"fal":122,"ff ":62,"fe ":105," Đu":65,"fa ":189,"aúj":298," ču":115," čr":759,"eyr":71," Ču":69,"exa":83,"ez ":873," Čr":316," če":1273," čl":1304," či":437," ča":1729,"ezu":507,"eza":1493,"ezd":639,"ezn":2303,"ezo":3022,"eví":88,"euč":161,"eze":1111,"erš":61,"ezi":1770,"eta":9837,"ete":2260,"etd":101,"etj":1541,"eti":2887,"elš":67,"eth":104,"etn":3058,"etl":581,"etk":435,"esp":164,"esn":1865,"eso":719,"est":9497,"esu":218,"enč":254,"esr":69,"ess":341,"ev ":4515,"emš":2022,"eto":5019,"etr":1803,"ets":629,"ett":335,"etu":861,"etv":352,"ew ":247,"eve":3581,"evd":110,"evc":189,"eva":3659,"evo":978,"evn":851,"evl":113,"evk":344,"evj":120,"enš":165,"evi":3431,"euv":65,"eut":92,"eur":130,"eus":174,"ex ":78,"evu":106,"evr":568,"evs":223,"evt":159,"ey ":565,"evz":91,"epe":218,"epi":485,"eph":184,"er ":9909,"epa":2146,"eos":79,"eor":822,"eom":284,"eol":485,"eop":91,"eon":196,"es ":3592,"ept":897,"epu":2717,"epl":115,"epn":163,"elé":65,"epp":110,"epo":984,"epr":1096,"erk":1130,"erl":288,"ejš":1389,"eri":6828,"erj":1569,"erg":1075,"erh":74,"ere":2880,"erf":64,"erc":387,"erd":237,"era":3623,"erb":290,"et ":2922,"esj":60,"esk":362,"esl":322,"esm":246,"esi":510,"esc":198,"ese":3032,"eu ":71,"esa":1428,"erz":1265,"ery":65,"erv":377,"eru":570,"emč":403,"err":420,"ert":841,"ers":1249,"ern":2752,"erm":750,"erp":166,"ero":2923,"eki":619,"ekl":439,"ekm":687,"eko":1561,"ekr":138,"eks":912,"ekt":2647,"eku":579,"ekv":164,"en ":7706,"elb":111,"ela":2552,"eld":165,"elc":327,"elf":63,"ele":5343,"eli":7355,"elj":12080,"elg":274,"ehé":68,"elm":113,"eln":478,"elk":390,"ell":946,"elo":6099,"elu":1481,"els":386,"elt":135,"eo ":194,"emb":2938,"ema":2409,"edž":154,"eme":2514,"emd":94,"eml":1047,"emn":341,"emo":1461,"emi":2775,"emu":847,"emp":655,"ems":675,"ep ":100,"ene":4626,"enh":70,"eng":267,"enb":171,"ena":6583,"end":853,"enc":1426,"eno":7193,"enn":350,"enk":486,"enl":165,"eni":11655,"enj":3527,"enu":1052,"ens":9125,"ent":4611,"enr":131,"enz":343,"eog":377,"eod":241,"eob":101,"egl":515,"ego":1324,"egn":116,"ege":392,"egi":3464,"ej ":1349,"eha":369,"egr":207,"egu":231,"egy":59,"ehn":551,"ehr":149,"eho":984,"ehi":163,"ek ":3893,"eic":68,"eis":179,"eir":92,"eim":143,"eil":148,"ein":591,"eid":153,"eja":1145,"el ":3464,"eiz":90,"eit":89,"ejs":725,"ejo":1467,"ejn":247,"ebš":60,"eji":700,"eje":1829,"ekd":397,"eke":552,"ekc":78,"eka":3433,"em ":19835,"eju":371,"gl ":122,"git":143,"gis":130,"gir":72,"gim":692,"gij":4610,"gik":62,"gip":136,"gin":441,"gio":182,"gie":59,"gib":460,"gih":484,"gia":72,"ght":197,"gha":74,"ggi":66,"gač":142,"gi ":1057,"gen":1655,"geo":621,"get":148,"ger":535,"ges":132,"gh ":98,"geb":124,"geg":139,"gem":133,"gel":572,"gej":96,"gda":62,"ge ":1547,"gac":68,"gad":460,"gah":82,"gas":134,"gar":537,"gat":408,"gaj":272,"gam":198,"gal":701,"gan":2184,"ga ":19235,"fur":60,"fte":66,"fun":414,"ft ":152,"ačb":149,"ača":451,"fra":3096,"fre":206,"ače":1435,"ačj":77,"ačk":163,"fri":439,"ači":1402,"fsk":383,"fro":120,"ačn":463,"ačr":174,"aču":1108,"fov":120,"for":1149,"fos":82,"fot":167,"fon":272,"fol":119,"ač ":265,"fič":180,"fla":71,"fic":219,"fie":63,"fig":93,"fij":889,"fil":1101,"fik":288,"fin":542,"fit":105,"fiz":1064,"fja":62,"db ":97,"da ":14922,"dbe":281,"dba":322,"dbi":164,"dbo":232,"de ":3505,"dac":99,"dal":2088,"daj":1290,"dag":370,"dah":122,"dae":198,"dat":2652,"dar":1727,"dan":3799,"dam":251,"dav":343,"dda":258,"dde":307,"dce":69,"cul":97,"cto":99,"cti":246," Îl":184,"cy ":79,"cve":165,"cus":130,"cur":63,"cks":59,"cko":94,"cla":60,"cle":108,"co ":1155,"con":195,"col":193,"com":102,"cor":143,"cos":2856,"cot":60,"cou":95,"cs ":326,"cqu":61,"cro":134,"cu ":453,"cci":147,"cca":61,"cea":385,"ch ":526,"cev":1776,"cer":935,"ces":1318,"cet":77,"cen":988,"cep":196,"cej":81,"cem":898,"cel":1340,"ceg":119,"ced":151,"ci ":2670,"cha":428,"chw":61,"chu":146,"cia":974,"ck ":555,"cie":148,"cid":94,"che":837,"chl":72,"chi":339,"cho":135,"chm":179,"chn":116,"cht":110,"civ":109,"cij":6609,"cik":850,"cil":290,"cim":128,"cif":150,"cih":145,"cir":298,"cis":476,"cit":587,"cin":475,"cio":727,"cip":225,"cm ":87,"cke":249,"cka":102,"ed ":7632,"eba":410,"ebe":1030,"ebi":1286,"ebl":102,"ebn":705,"ebo":328,"ebr":1109,"ebu":659,"ec ":3986,"eac":70,"eag":60,"eae":122,"ead":77,"eak":245,"ean":473,"eal":308,"ear":308,"eas":76,"eap":68,"eat":181,"eau":166,"eb ":1452,"ea ":232,"efi":249,"efo":206,"efa":145,"efe":483,"ei ":95,"ega":14282,"een":162,"eh ":1490,"eer":68,"eev":58,"edk":372,"edl":222,"edm":691,"edn":4723,"edh":90,"edi":2962,"edj":165,"ede":4374,"ône":77,"eda":2590,"edb":168,"eg ":627,"edt":128,"eds":1765,"edv":775,"edu":552,"edp":144,"edo":1120,"edr":537,"eck":137,"ech":121,"eci":430,"ece":981,"eca":75,"ee ":129,"ef ":166,"ecu":64,"ect":136,"eco":75,"dož":69,"dvs":488,"dwa":102,"dy ":102,"dvi":1792,"dve":1124,"dvo":628,"dur":65,"dus":252,"dva":885,"duš":167,"drž":2000,"dzo":143,"dzi":74,"dze":62,"dor":425,"dop":136,"don":666,"dom":1025,"dol":2617,"dok":396,"doz":167,"dow":104,"dov":2766,"dot":187,"dos":834,"dr ":66,"dpi":182,"dpr":535,"dpo":228,"ds ":150,"diš":1126,"dmi":400,"dmo":356,"dna":1989,"dne":2475,"dni":3893,"dež":1743,"dnj":2661,"dno":3481,"dič":320,"dob":2688,"doc":83,"dod":289,"dog":505,"dst":1636,"dso":71,"dte":147,"dun":61,"duj":151,"dul":104,"duk":196,"duh":1475,"duc":137,"dri":615,"dra":2046,"dt ":61,"dre":1648,"du ":2258,"dro":1558,"drs":225,"dru":5537,"dsk":1257,"dse":412,"dge":82,"dgo":243,"dic":712,"did":62,"dia":709,"dho":97,"ôte":98,"der":1069,"des":1368,"det":180,"dev":559,"dez":147,"deb":135,"dea":152,"ded":131,"dec":783,"def":191,"dej":655,"del":8200,"dek":748,"den":2287,"dem":894,"dep":1917,"deo":172,"di ":7874,"dle":116,"dla":418,"dko":292,"dkr":290,"dki":137,"dme":496,"dma":184,"do ":2879,"dlo":208,"dlj":134,"dli":196,"dja":348,"dje":967,"div":552,"diu":58,"diz":86,"dim":344,"din":3211,"dio":320,"dip":467,"dir":3392,"dis":608,"dit":557,"die":123,"dif":117,"dig":180,"dih":219,"dij":1635,"dik":285,"dil":1003,"dka":143,"dke":226,"dju":78,"deč":365,"rgy":70,"rgu":403,"rhe":114,"rha":142,"rhi":372,"rhu":89,"rhn":68,"rho":225,"iža":226,"rga":1747,"ri ":6205,"rgl":58,"iži":369,"rgi":606,"ižj":188,"iže":597,"rge":583,"rgo":351,"ižn":1012,"rgn":87,"ret":1927,"res":1802,"rev":1974,"reu":328,"rez":1267,"rh ":216,"rfi":77,"rfo":61,"rač":1077,"rdu":102,"rds":107,"rg ":550,"iž ":81,"reb":2051,"rea":620,"ree":132,"ref":492,"rec":915,"red":9699,"rei":333,"rej":1975,"reg":4478,"reh":767,"rem":2494,"ren":2516,"rek":2213,"rel":1062,"rer":139,"reo":180,"rep":1325,"rda":399,"rcu":159,"rdo":364,"rdn":359,"rdi":2193,"rde":564,"re ":2956,"rbu":279,"rbs":360,"rci":266,"rch":173,"rce":392,"rca":244,"raz":7036,"rd ":765,"rap":609,"rar":714,"ras":1404,"rat":4465,"rau":89,"rav":10605,"rbi":646,"rbo":438,"rba":318,"rbe":206,"rc ":65,"raj":3231,"rai":122,"rah":639,"rag":448,"ran":10813,"ram":1883,"ral":3846,"rak":1045,"rab":4754,"raf":1035,"rae":188,"rad":7153,"rac":1106,"rpu":173,"rpo":96,"rs ":406,"rpe":109,"rpa":103,"ror":143,"ros":2112,"rot":1454,"rom":2391,"ron":2361,"roo":117,"rop":1736,"roz":633,"rou":216,"rov":3453,"row":90,"rob":744,"roa":69,"rod":3371,"roc":719,"roj":1187,"roi":1061,"rol":591,"rok":1027,"rof":772,"roe":143,"rog":1831,"rno":2826,"jšč":126,"rič":1125,"rns":80,"rnu":76,"rna":2170,"rež":741,"rne":1804,"rnj":672,"rni":3001,"rmo":552,"rmu":1839,"ro ":1744,"rma":1564,"rme":357,"rmi":362,"reš":389,"rlo":204,"rlj":61,"rli":272,"rle":264,"rla":328,"rn ":268,"rkv":475,"rku":166,"rkt":89,"rks":59,"rkn":66,"nço":87,"rko":671,"rki":446,"rke":698,"rka":3906,"rm ":91,"reč":850,"rju":560,"rji":433,"rja":3706,"raž":658,"rje":3010,"riz":1024,"rl ":197,"rip":1323,"jšo":114,"rio":714,"rir":527,"rit":2886,"ris":2096,"riv":1041,"riu":103,"rih":1145,"rig":966,"rij":4080,"raš":557,"jši":1298,"rii":2351,"ril":2003,"rik":1886,"jšn":99,"rin":1694,"rim":3965,"jša":896,"ria":1305,"rib":1637,"ric":1600,"rid":1029,"rie":837,"jše":763,"rif":96,"rk ":603,"roš":477,"rož":1407,"ruj":117,"ruh":77,"rug":3066,"rud":146,"ruc":91,"rup":276,"run":235,"rum":444,"rul":77,"ruk":405,"ruz":173,"rus":1264,"rut":93,"rva":5491,"rvi":1217,"rve":3036,"rvo":519,"rvn":190,"ry ":643,"rsk":7463,"rsi":153,"rso":356,"rsa":151,"rse":525,"rta":677,"rst":3047,"rtm":1893,"rtn":868,"rto":742,"rte":567,"rth":222,"rti":1649,"rub":82,"rua":643,"rts":92,"roč":1581,"rtu":402,"rtv":101,"riš":1946,"rt ":931,"rro":107,"mči":401,"rri":145,"rre":246,"riž":633,"rra":237,"ru ":1442,"rry":141,"sab":104,"sac":80,"sad":165,"saj":415,"sak":747,"sal":910,"sam":1606,"sba":85,"sbe":912,"sbi":124,"san":1213,"sat":1223,"sas":75,"sar":861,"sav":254,"sa ":1996,"ruž":2445,"ón ":126,"ruš":505,"rze":647,"rza":241,"ryj":60,"rzo":76,"rzi":1047,"sha":61,"sho":59,"shr":72,"she":68,"shi":263,"si ":1301,"sje":270,"siv":155,"seč":117,"sid":220,"sic":368,"sia":89,"sk ":194,"sit":181,"sir":202,"sis":1373,"sip":188,"sin":800,"kšn":168,"sio":244,"sil":1296,"sim":507,"sij":849,"sik":175,"sih":502,"saš":156,"sif":95,"sig":135,"sbo":112,"sbu":112,"se ":9988,"sca":143,"sce":180,"sci":213,"sch":525,"sco":197,"sev":1928,"ser":946,"ses":2057,"set":1089,"sez":2688,"sh ":159,"sfe":159,"sfo":66,"sei":64,"seh":402,"seg":907,"sed":3642,"sec":285,"seb":3164,"sep":883,"sen":803,"sem":2072,"sel":7746,"sek":379,"sej":258,"spu":64,"spo":2044,"spr":1492,"spe":1038,"spl":748,"spi":220,"spa":7101,"sot":293,"sou":74,"sov":1364,"sol":487,"som":341,"son":987,"sop":193,"sor":556,"sos":106,"sod":1527,"sof":102,"sok":589,"soj":102,"soc":318,"sob":183,"su ":1066,"nčn":750,"nči":273,"nče":232,"sre":2496,"srb":412,"nča":248,"st ":5603,"ss ":196,"sli":984,"slo":6036,"slu":603,"sla":2779,"sle":851,"ski":17344,"skl":1236,"sko":15385,"skr":668,"sku":2764,"skv":191,"ska":8402,"ske":14199,"sič":233,"sno":1962,"sna":435,"sni":1800,"snj":102,"sež":377,"sne":1079,"smo":133,"smr":229,"smu":290,"so ":8342,"sma":396,"smi":413,"sme":609,"sz ":97,"sza":136,"sze":92,"szt":71,"sse":338,"ssa":253,"sso":262,"ssi":329,"ste":4516,"sta":14712,"std":76,"stm":122,"stn":2769,"sto":9875,"sti":10401,"stj":760,"stk":173,"stl":589,"stv":6827,"stu":585,"soč":125,"str":7508,"sub":140,"suh":69,"sul":130,"sum":64,"suj":230,"sup":155,"sun":61,"sur":243,"sve":2955,"svi":91,"svo":1687,"tai":89,"taj":1653,"tak":1296,"tal":5739,"taf":62,"tag":120,"tah":112,"tab":357,"tac":360,"tad":115,"td ":92,"taz":72,"tav":4146,"tat":2093,"tas":324,"tar":2532,"tap":65,"tan":6147,"tam":415,"tch":88,"te ":3456,"tde":172,"ta ":16983,"ovš":201," št":2696," šv":175," ši":477,"pa ":6188," šk":1366," šo":471," šp":977," ša":246," še":1284," Šv":259," Šu":75," Št":405," Šp":321," Šo":105," Šm":149," Šk":346," Ši":182," Še":283," Ša":280,"ovč":87," šč":159,"pci":101,"pe ":794,"par":3565,"pat":325,"pas":565,"pav":120,"paz":284,"pac":108,"pad":8267,"pah":117,"pak":187,"pal":492,"paj":410,"pap":279,"pan":5531,"phe":97,"pha":91,"pho":59,"phi":118,"pi ":445,"ph ":153,"pev":467,"pač":83,"pea":111,"pec":334,"ped":485,"pen":956,"pep":58,"per":2309,"pet":1059,"lás":63,"pes":1184,"peh":707,"pel":589,"pek":319,"pla":1692,"plj":349,"pli":1265,"ple":1082,"plo":1730,"piz":105,"peč":83,"phy":92,"pia":104,"pid":74,"pic":81,"pih":119,"pij":931,"pik":108,"pil":764,"pin":2417,"pio":83,"pir":404,"pis":3588,"pit":455,"poz":877,"pr ":382,"por":6507,"pop":763,"pov":2801,"pou":108,"pot":2623,"pos":4743,"poi":280,"poj":1082,"pog":1928,"pom":2891,"pon":1163,"pok":980,"pol":5783,"pob":187,"poe":84,"pod":14532,"ps ":70,"plé":235,"ppo":61,"ppe":190,"lén":278,"peš":381,"po ":5444,"pič":147,"pno":567,"pnj":141,"pež":186,"pni":1125,"pne":206,"pna":93,"pse":98,"psi":273,"psk":942,"pso":79,"ptu":77,"pub":2962,"pte":795,"pti":568,"pto":218,"poč":106,"pra":8108,"pt ":65,"piš":190,"prv":4499,"prs":213,"prt":260,"pru":88,"pu ":357,"pri":11604,"pre":12368,"pro":5665,"poš":266,"pož":71,"pur":71,"pus":357,"put":68,"pun":78,"pul":238,"px ":59,"puš":308,"már":283,"iš ":113,"iše":281,"iša":220,"išl":273,"išn":372,"iši":543,"išk":6388,"išj":568,"išt":1077," Ži":199," Že":372," Ža":131," Žu":1147,"išć":99,"išč":2416," ži":1623," žl":73," ža":202," že":1263," žu":4184,"mén":60,"lčn":96,"qua":66,"que":223,"qui":88,"ra ":5234,"rb ":124,"ežn":508,"ngo":291,"ežj":186,"ngi":146,"eži":1395,"ngl":1754,"ežk":163,"ngu":231,"ngr":157,"ngt":104,"ngs":96,"ni ":21439,"eže":1628,"nge":731,"ngh":66,"nga":200,"eža":393,"nha":154,"nj ":974,"nhe":59,"neh":90,"neg":6715,"nej":1610,"nei":60,"nel":292,"nek":1786,"nen":595,"nem":5832,"nep":765,"neo":239,"ner":2095,"net":1642,"nes":1470,"nev":638,"neu":164,"ndv":192,"ež ":616,"ng ":946,"nea":167,"neb":386,"nec":499,"ned":247,"nfo":286,"nfr":73,"nač":1875,"ney":179,"nez":634,"nfa":314,"nfe":121,"nco":3080,"nci":1963,"nck":74,"nce":1597,"nch":251,"nca":769,"ne ":16673,"nbu":104,"ndu":365,"ndr":735,"nds":176,"ndo":673,"ndi":1187,"nde":738,"nda":1053,"ncu":165,"nak":2105,"nal":3824,"nam":2274,"nan":3844,"nap":1555,"nar":4271,"nac":538,"nad":2224,"nag":2320,"nah":1010,"nai":103,"naj":4748,"nc ":424,"nab":409,"nbe":101,"nd ":921,"nav":1486,"nau":169,"nat":1633,"nas":9591,"naz":549,"na ":45810,"muč":308,"mož":442,"nyi":95,"nz ":124,"nož":611,"ny ":285,"nve":127,"nuk":69,"num":110,"nun":197,"nuj":664,"nus":215,"nut":274,"nua":1914,"nud":60,"ntv":66,"nto":1165,"ntn":394,"ntu":151,"nts":282,"noč":122,"ntr":823,"nti":1732,"nth":129,"ntj":84,"nta":1740,"nte":2274,"nsp":149,"nso":136,"nst":4879,"nsf":59,"nse":185,"nsi":206,"nsk":18646,"nsc":84,"nsa":368,"nu ":1386,"iču":99,"ičn":8484,"ičk":636,"njš":744,"iči":660,"nri":146,"niž":206,"iče":649,"iča":1089,"nt ":1816,"niš":3134,"npr":251,"ns ":498,"noc":81,"nod":149,"noa":98,"nob":153,"nog":856,"nof":95,"nok":237,"nol":557,"noi":86,"noj":94,"noo":307,"nop":217,"nom":2492,"non":367,"not":1702,"nos":5345,"nor":656,"nov":7837,"noz":157,"ič ":1910,"nne":487,"než":185,"nna":175,"nić":78,"nno":127,"nni":311,"nič":1334,"nma":70,"neš":91,"ići":278,"nlj":152,"nn ":230,"no ":28820,"nke":357,"nki":201,"nm ":145,"nkc":434,"nka":820,"nku":97,"nko":712,"nkt":84,"nkr":119,"nji":3942,"njk":62,"nje":10740,"nja":5163,"ić ":428,"nju":1491,"neč":59,"njs":1007,"njo":572,"nij":12636,"naš":856,"nih":7675,"nig":117,"nif":78,"nie":143,"nid":118,"nic":4360,"nia":191,"nk ":305,"niz":1781,"niv":1064,"nis":1438,"nit":923,"nir":658,"nio":254,"nim":2568,"nin":1324,"nik":9988,"nil":489,"obč":4860,"ogr":2005,"ogu":149,"ogi":1571,"ogl":820,"ogo":3723,"ogn":253,"oga":915,"oge":466,"ohr":268,"ohl":58,"ohi":154,"oho":271,"ohn":289,"oha":244,"ohe":84,"oj ":853,"ois":217,"oir":158,"oit":129,"oin":114,"oim":560,"oid":870,"ok ":1437,"ojz":107,"ojv":145,"oju":183,"ojs":1259,"ojo":151,"ojn":3019,"ojm":105,"oji":1325,"oje":1842,"oja":2676,"ol ":641,"oiz":309,"oce":920,"och":145,"oci":1214,"ock":526,"oco":76,"obs":723,"obv":173,"obu":288,"oca":63,"odg":241,"ode":2090,"odk":490,"odl":499,"odi":2311,"odj":811,"odo":2908,"odp":861,"odm":304,"odn":5885,"ods":542,"odt":73,"odr":2425,"of ":1863,"odd":348,"odc":60,"odb":552,"oda":3554,"oel":114,"oen":93,"odz":124,"odv":669,"odu":1390,"og ":1603,"ofi":975,"ofj":119,"ofs":134,"oft":92,"ofo":143,"oh ":61,"oev":59,"off":75,"ofe":287,"ofa":151,"oa ":64,"ob ":1309,"oc ":81,"oam":62,"oak":62,"oba":1124,"od ":12681,"oar":69,"obo":1557,"obr":1689,"obl":2408,"obn":1165,"obm":522,"obh":168,"obj":732,"obi":1733,"obd":521,"obe":1617,"nza":121,"nze":101,"nzi":167,"nzo":136,"nzu":292,"oz ":588,"ows":139,"own":81,"ozv":174,"ozm":90,"ozn":2233,"ozl":77,"ouč":124,"ozo":660,"ozd":363,"oze":956,"ozj":60,"orš":73,"ozi":1844,"oza":922,"otu":189,"oud":99,"ouc":89,"ow ":91,"otl":190,"otj":79,"oti":1413,"oth":99,"ote":2905,"ott":253,"ots":334,"otr":1161,"oto":3788,"otn":1790,"ost":12934,"osu":137,"osv":805,"ota":1246,"ov ":9875,"osi":707,"osk":3606,"ose":3687,"osf":145,"osp":608,"oss":155,"onč":622,"osr":908,"osm":266,"osl":2901,"oso":665,"osn":920,"ovz":1051,"owe":104,"ovj":805,"ovi":6438,"ovn":6797,"ovl":1128,"ovk":184,"ovr":972,"ovp":60,"ovo":2629,"ovs":1169,"ova":8912,"ovc":416,"ove":14862,"olž":454,"oug":85,"oui":145,"oul":129,"oun":202,"ous":295,"our":376,"out":124,"opn":423,"opo":1059,"opi":1707,"opk":100,"opl":563,"ope":1736,"oph":167,"opa":1127,"os ":1104,"opu":601,"opr":1200,"opt":284,"ops":761,"ook":176,"ood":98,"or ":2915,"oot":78,"oos":261,"oor":234,"ork":374,"orl":98,"orm":2841,"orn":2246,"oro":2344,"orp":318,"orr":124,"orc":198,"ord":1013,"ore":2187,"orf":214,"org":1762,"ori":3690,"orj":1749,"ou ":161,"osa":1004,"osc":65,"ort":1525,"ors":2919,"orv":191,"oru":646,"orz":678,"ory":80,"m² ":116,"ot ":4531,"orb":248,"ora":6836,"olč":72,"ola":1198,"old":256,"olc":287,"on ":4034,"olj":3299,"oli":8521,"oll":233,"olk":1067,"olf":200,"ole":2539,"olh":61,"olg":662,"ols":682,"olt":165,"olm":216,"oln":1077,"olo":4662,"olp":199,"olz":68,"olu":478,"okc":353,"oka":3564,"om ":4672,"oki":527,"oke":1295,"okr":2091,"oks":347,"oko":2939,"okl":420,"okv":386,"okt":717,"oku":681,"ona":3944,"ond":566,"onc":719,"onf":152,"one":1109,"ong":354,"onj":581,"oni":3533,"onk":153,"onn":242,"ono":2372,"ons":2332,"ont":1027,"onu":380,"onv":124,"ony":108,"onz":388,"oma":3776,"ome":4659,"omb":385,"omi":1226,"omm":146,"oml":116,"omp":471,"omn":379,"omo":1779,"omt":60,"omu":612,"omr":152,"oms":494,"op ":353,"la ":14406,"kuž":64,"ína":99,"ín ":66,"ílo":74,"kuš":168,"le ":7709,"lce":1290,"lca":262,"lci":518,"lcs":234,"lf ":143,"őr ":86,"lde":127,"lda":104,"ldo":98,"ldi":83,"lab":207,"lac":514,"lad":2741,"lah":1475,"lag":668,"laj":371,"lai":176,"lal":158,"lak":556,"lan":4164,"lam":493,"lap":158,"lao":145,"lar":855,"lat":1921,"las":3314,"lau":130,"lav":3720,"lay":77,"laz":215,"lba":139,"ld ":368,"lbe":231,"lbi":66,"lbo":79,"lbu":240,"kvi":678,"kve":490,"kva":1108,"kus":268,"kur":144,"kup":2763,"kun":201,"kum":211,"kul":2114,"kuj":269,"koš":266,"ky ":76,"kta":268,"kte":244,"ksp":155,"kst":183,"ksi":550,"kso":225,"ksn":135,"kuh":70,"ktr":1174,"koč":387,"ktu":785,"kti":841,"ktn":114,"kto":1394,"krš":290,"íja":164,"kož":132,"lpo":59,"lps":155,"lpe":443,"lpi":97,"lph":69,"ls ":116,"lol":70,"lok":331,"lon":766,"lom":1330,"lop":499,"lor":376,"lod":293,"loc":74,"loh":68,"log":2821,"loj":149,"lpa":140,"los":423,"lot":1148,"lou":85,"lov":16172,"loz":578,"lno":1801,"lić":59,"lnj":113,"lni":3993,"lež":843,"lne":1558,"lob":711,"lič":1905,"lmo":111,"lmi":113,"leš":1366,"lme":146,"lma":647,"lp ":83,"lna":1726,"lmu":66,"hér":83,"lms":222,"lti":179,"lto":145,"ltr":80,"loč":1559,"lts":67,"ltu":477,"luc":178,"lub":512,"lug":80,"lue":65,"lsk":2568,"lso":81,"lst":393,"lta":305,"lte":1274,"ljš":529,"liž":879,"lu ":1284,"liš":2924,"ía ":66,"lt ":201,"lhe":70,"lj ":3087,"lha":78,"lgo":251,"lge":200,"lgi":319,"li ":11443,"lga":376,"lfr":59,"lač":361,"hât":62,"lfo":59,"lfi":89,"lfa":90,"ház":65,"lez":1147,"ley":245,"lex":102,"lev":543,"les":1759,"let":8204,"ler":672,"leo":160,"lep":918,"lem":1328,"len":1784,"lek":2164,"lel":63,"lei":115,"lej":216,"leh":60,"leg":676,"lef":95,"led":2297,"lec":1220,"leb":105,"lea":97,"lg ":68,"lls":71,"llu":110,"lly":120,"lo ":8977,"lla":550,"lle":786,"lli":672,"llo":334,"lko":692,"lku":60,"ln ":62,"lka":768,"lke":292,"lki":170,"ljs":1060,"leč":258,"lju":2873,"ljo":339,"ljn":358,"lm ":297,"lje":13663,"ll ":501,"lja":8525,"ljk":59,"laž":224,"lji":2324,"lit":3130,"lis":1861,"lir":252,"lip":265,"lio":237,"lin":3453,"lim":1141,"liz":841,"liv":1015,"liu":90,"lic":2658,"lid":143,"lia":493,"lib":162,"lk ":580,"lik":9667,"dšk":353,"lil":332,"laš":191,"lij":4137,"lig":667,"lih":765,"lie":274,"lif":220,"ma ":6156,"luž":388,"mb ":135,"mac":507,"mah":62,"maj":3291,"mak":294,"mad":706,"mag":926,"mar":1529,"mas":537,"mal":1048,"mam":116,"man":2972,"maz":61,"mat":4492,"mba":322,"mbi":346,"mbe":1994,"mbr":581,"mbo":391,"mbn":601,"me ":3191,"mbu":131,"mde":94,"med":6987,"meg":105,"mec":75,"met":4065,"mev":70,"mes":5031,"mer":4601,"mem":950,"mel":2712,"meo":80,"men":7879,"meh":365,"mek":1496,"mej":987,"mez":436,"mač":311,"mfo":74,"luz":65,"lva":240,"lve":110,"lvi":73,"luk":109,"luj":862,"lun":128,"lum":243,"lut":187,"lus":353,"ly ":206,"loš":1311,"ltä":132,"lož":762,"lza":60,"luč":58,"luš":63,"mpi":770,"mpe":599,"mpo":176,"mpl":480,"mpu":59,"mpt":60,"ms ":130,"mog":546,"mob":319,"mod":647,"mon":864,"mok":221,"moj":62,"mom":240,"mol":590,"mov":1124,"mor":2946,"mos":831,"mot":853,"mou":135,"mpa":312,"moz":59,"mre":315,"mrl":143,"mrt":287,"mu ":1595,"miš":516,"moč":1268,"mso":95,"msk":4107,"moš":595,"my ":71,"mur":404,"mus":157,"mut":85,"mul":1968,"mun":583,"muz":183,"dža":1295,"mi ":4700,"dži":218,"meč":117,"maž":60,"min":1835,"ešn":268,"mio":71,"mil":655,"mim":87,"mir":615,"mis":564,"mit":679,"ešt":114,"miz":89,"mic":185,"eša":172,"eše":255,"mie":124,"mid":113,"ešk":2738,"mik":628,"mij":927,"maš":150,"eši":154,"mih":245,"mo ":2844,"mlj":1176,"mle":124,"mla":591,"mki":710,"mka":116,"mm ":88,"ešč":404,"mič":519,"mni":612,"mnm":116,"mno":883,"mna":379,"mne":300,"meš":231,"mma":103,"mme":132,"Če ":73,"Čep":77,"Češ":144,"Črn":256,"rža":2068,"rže":110,"rži":130,"ča ":1709,"čal":131,"čam":203,"čan":1056,"včn":97,"čar":720,"čas":2119,"čaj":758,"čak":128,"vče":97,"vča":256,"zre":618,"uče":431,"uča":350,"zra":1527,"če ":2812,"uču":301,"zro":341,"učn":253,"uči":543,"čat":86,"čav":96,"čba":88,"čbe":68,"víl":96,"ziš":265,"zte":155,"čeg":102,"čen":2815,"čem":362,"čel":601,"ček":421,"čev":1119,"čet":926,"čes":137,"čer":105,"zto":106,"čep":104,"zse":225,"zu ":354,"zst":173,"zva":406,"zvi":2202,"zve":1702,"či ":940,"zvr":346,"zvo":918,"zuj":323,"čez":81,"zur":194,"zul":378,"zum":402,"zun":254,"zus":115,"čij":767,"čih":292,"čic":410,"čk ":142,"čit":716,"čis":78,"čin":8235,"čil":961,"čim":249,"čko":555,"čkr":195,"čka":504,"zzo":59,"čke":298,"čki":315,"zza":68,"čjo":263,"čju":736,"čja":509,"čje":920,"čji":637,"češ":144,"člo":587,"čo ":156,"čle":236,"čla":635,"čob":73,"čič":263,"čić":71,"čni":3672,"čno":2056,"čna":1890,"čne":3797,"čiš":160,"zgl":160,"zi ":788,"zač":773,"zha":357,"zgu":93,"zgr":400,"zgo":1653,"zej":178,"zdr":1230,"zdj":83,"zdo":198,"zdn":338,"zet":178,"zen":780,"ván":80,"zem":1646,"zel":858,"vár":138,"zer":530,"ze ":1270,"zbo":448,"zbi":532,"zbu":82,"zbr":206,"zda":703,"zdi":107,"zde":1030,"zab":392,"zad":779,"zac":850,"zaz":93,"zd ":136,"zbe":87,"zai":81,"zaj":329,"zag":420,"zah":1609,"zam":289,"zan":1549,"zak":553,"zal":882,"zar":791,"zap":901,"zav":812,"zas":719,"zat":657,"zod":127,"zob":347,"zor":519,"zom":118,"zon":2846,"zol":213,"zof":467,"zpe":152,"zpa":113,"zoz":300,"zov":527,"zpr":114,"zpo":448,"ال":104,"zo ":291,"zma":791,"zmn":81,"zmo":266,"zme":1501,"zmi":301,"zna":6251,"zmu":231,"zno":574,"zič":152,"ršč":1404,"zne":577,"zni":1693,"zka":85,"zko":152,"zkl":76,"zki":60,"zku":97,"zla":344,"zli":1716,"zle":63,"zlo":375,"zho":1743,"rša":147,"zia":58,"rše":205,"zid":236,"zic":70,"zij":1942,"ršj":95,"zaš":153,"rši":594,"ršn":88,"zin":229,"zim":197,"zil":483,"zik":2477,"ršk":1367,"zio":176,"zir":1419,"zis":483,"zit":356,"ziv":530,"zja":105,"zje":158,"yst":102,"ysi":60,"yro":69,"yon":68,"za ":8558,"ye ":58,"yer":80,"ya ":130,"yar":104,"yku":71,"yle":59,"yi ":114,"yje":66,"yja":58,"ن ":69,"ožu":71,"ože":1171,"oža":441,"ožb":309,"ožn":777,"oži":853,"ožj":690,"ožg":76,"ož ":115,"té ":62,"tät":153,"ći ":280,"xan":70,"ošč":370,"wn ":129,"ws ":103,"rče":97,"rči":287,"wor":59,"wer":110,"wel":68,"nže":273,"oš ":92,"wis":86,"ošt":692,"oši":152,"oše":119,"wic":65,"ošo":62,"ošn":419,"win":68,"ošk":1384,"oša":203,"vzo":115,"vzn":60,"vzr":280,"vzp":183,"vzg":93,"vze":217,"vzd":233,"vrš":1631,"vzh":1577,"vza":88,"wal":60,"war":181,"viš":902,"vrt":231,"vrs":1856,"vrn":62,"vro":1339,"vri":65,"vrh":387,"vre":731,"vra":482,"vso":118,"vst":1541,"vse":2779,"vsk":1809,"vsi":97,"vu ":881,"vsa":763,"vto":922,"vtr":73,"voč":112,"vts":62,"vul":228,"via":94,"vk ":203,"vio":100,"vir":2583,"vik":86,"vil":3700,"vim":485,"vin":3336,"vig":158,"vih":947,"vaš":4759,"vij":2768,"vic":1147,"vid":829,"vie":118,"nše":75,"vja":192,"viz":807,"nšt":314,"vit":1128,"vis":1138,"več":3002,"vje":763,"vka":371,"vju":170,"vko":123,"vke":182,"vkl":325,"vla":601,"vle":130,"vlo":204,"vlj":4644,"vo ":5275,"vme":74,"rén":67,"veš":647,"vež":91,"vne":3166,"vna":1676,"vno":7416,"vić":274,"vnj":103,"vni":6241,"nšč":326,"vič":1157,"vob":458,"vod":2329,"vog":94,"voj":6252,"vol":768,"vok":302,"von":637,"vom":445,"vor":1714,"vot":255,"vos":442,"vov":212,"voz":481,"vpi":58,"vpl":277,"vpr":143,"vgu":581,"vi ":4563,"vač":184,"vey":59,"vez":2827,"ver":4490,"ves":828,"vet":5958,"vdo":109,"vej":290,"veh":446,"veg":583,"rán":91,"ven":15616,"vem":1214,"vel":2593,"vek":749,"ved":1600,"vec":1132,"vcu":59,"vca":96,"ve ":3712,"vci":431,"vce":194,"val":4949,"vak":400,"van":6929,"vam":248,"var":2538,"vat":726,"vas":1162,"vaz":61,"vac":503,"vad":923,"vai":77,"vaj":1562,"vah":328,"va ":7766,"uzi":197,"urš":301,"uze":286,"uza":111,"urč":177,"ux ":175,"uva":93,"uve":379,"uvr":1131,"usl":98,"usm":167,"usk":1090,"usi":676,"use":332,"usa":242,"usu":60,"ust":3507,"uss":205,"usp":414,"uso":223,"usn":197,"utl":65,"utn":316,"uth":139,"uti":197,"ute":579,"uta":264,"utt":69,"uts":102,"uto":194,"utr":115,"us ":1853,"ut ":342,"urb":124,"ura":3309,"urd":58,"ure":1237,"urg":652,"urj":220,"uri":925,"url":67,"urk":122,"urm":63,"urn":892,"uro":433,"urs":478,"urt":136,"uru":97,"ury":61,"upa":4858,"ur ":618,"upi":1896,"upe":339,"upo":4232,"upr":4636,"upl":66,"upn":1389,"umr":152,"umu":107,"umi":296,"umo":158,"uma":367,"umb":237,"ume":1232,"unt":159,"uns":232,"unk":535,"unj":73,"uni":1649,"uno":147,"unc":267,"und":490,"una":1305,"ung":160,"une":190,"up ":120,"uks":65,"ukr":140,"uku":79,"ukt":476,"uko":214,"ukn":60,"ukl":92,"uki":118,"ukc":123,"uke":60,"um ":819,"uka":277,"ulu":100,"ult":2100,"uls":66,"ulo":296,"ull":127,"ulk":70,"ulj":355,"uli":1131,"ule":1791,"ulf":70,"uld":69,"ula":1090,"un ":304,"ukv":294,"uig":66,"mšk":1972,"uil":118,"uin":78,"uir":59,"uis":202,"uk ":155,"uje":4627,"uji":154,"ujo":137,"ujs":75,"uit":156,"ul ":297,"uja":181,"ugh":94,"ugi":1041,"lži":298,"uge":696,"lžn":64,"ugo":2841,"ugl":86,"uga":776,"uhi":80,"uho":1525,"ugu":295,"uha":183,"uj ":60,"uda":313,"ude":487,"udj":82,"udi":5813,"udn":106,"ubo":133,"ubn":112,"ubs":149,"ubr":361,"uca":72,"ue ":195,"uce":114,"uci":418,"uch":129,"uck":88,"uer":142,"ues":152,"uh ":100,"uds":601,"udo":411,"ug ":215,"ued":59,"uen":108,"uel":148,"ub ":374,"uar":2656,"ual":170,"uan":113,"ubi":368,"ubl":4817,"ube":341,"uba":207,"ud ":197,"trž":74,"ty ":183,"tvu":608,"tvo":3047,"tve":2705,"tvi":733,"tva":3299,"tur":2565,"tus":332,"tut":264,"tuj":422,"tul":174,"tun":135,"tum":104,"tub":74,"tua":118,"tud":5466,"tuc":67,"tug":184,"tz ":159,"toš":66,"ts ":250,"tiš":235,"tmá":241,"trd":395,"tre":2501,"oče":1653,"tt ":133,"oča":1047,"tra":4316,"trj":88,"očj":1644,"očk":616,"očl":103,"će ":102,"trm":72,"trg":328,"tri":4216,"oči":1373,"trs":733,"oču":60,"tru":1087,"trt":467,"tro":4048,"trn":84,"očn":740,"tu ":1700,"try":92,"tsc":117,"tsk":2341,"tta":143,"tte":299,"tti":218,"tto":129,"ttp":71,"tts":81,"toč":930,"tma":1947,"to ":6420,"tmo":86,"tmi":151,"teš":130,"tež":380,"tni":5182,"tne":1620,"ća ":63,"tp ":71,"tna":1556,"tič":5076,"tno":2333,"tod":350,"toc":762,"toj":799,"toi":353,"toh":82,"tog":270,"tob":807,"tou":124,"tov":5531,"tos":1124,"tot":329,"toz":100,"tom":1530,"ton":1758,"tok":2514,"tol":3650,"tor":3549,"top":2051,"oč ":359,"tij":686,"til":753,"tik":2804,"tif":115,"tie":119,"tih":1408,"tig":120,"tir":1113,"tit":785,"tis":2436,"tin":2891,"tim":668,"tip":613,"tio":1015,"thu":192,"tia":170,"tib":79,"tic":1448,"tid":147,"tji":207,"tju":277,"teč":443,"tjo":443,"tiz":729,"tiv":1588,"tje":1033,"tja":867,"tki":1874,"tko":496,"tku":163,"tka":483,"tke":192,"tlj":122,"tli":831,"tlo":345,"tla":447,"tle":327,"tem":4827,"ten":1364,"teo":775,"tep":103,"tei":263,"tej":504,"tek":2989,"tel":4105,"tef":109,"teg":1181,"teh":652,"tea":89,"teb":91,"tec":139,"ted":342,"th ":436,"tez":323,"tev":3243,"tet":1626,"tes":590,"ter":10610,"ti ":9411,"tho":148,"the":481,"thi":96,"tha":151,"zšl":321,"zši":325,"zše":149,"Živ":99,"yőr":92,"Žel":286,"ža ":604,"Žup":1073,"žko":65,"žle":58,"žlj":64,"žju":249,"žke":66,"žin":1764,"žim":160,"žil":222,"žir":92,"živ":1723,"žit":230,"žis":155,"žja":222,"žje":479,"žji":178,"žic":387,"žig":82,"žij":171,"žič":188,"žnj":265,"žni":1372,"žno":1191,"žna":269,"žne":657,"žo ":93,"žeš":277,"že ":817,"žbi":268,"žbe":388,"žbo":86,"žav":2001,"žba":234,"žaj":196,"žal":97,"žan":339,"žar":1500,"žga":114,"ži ":1033,"žev":1038,"žej":69,"žek":75,"žel":1057,"žem":871,"žen":2078,"žef":104,"ždi":82,"žuž":106,"užb":674,"uže":844,"užu":116,"uži":1380,"užn":1159,"žuj":195,"žup":4080,"žiš":141,"žu ":73,"všč":108,"všk":96,"vše":78,"vši":66,"yír":60,"ušč":304,"ušt":314,"ušn":118,"ušk":172,"uši":260,"uše":213,"uša":205},"n_words":[5788075,6773679,5606921],"name":"sl"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/som b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/som new file mode 100644 index 000000000..9d0c19cf6 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/som @@ -0,0 +1 @@ +{"freq":{"YO ":13,"jec":34,"jee":32,"D":313,"E":183,"F":66,"G":214,"A":673,"B":249,"C":240,"L":152,"M":367,"N":163,"O":122,"H":180,"I":236,"J":129,"K":173,"U":82,"T":107,"W":226,"V":11,"Q":76,"P":22,"S":486,"R":114,"Y":96,"X":120,"Z":10,"f":458,"g":2154,"d":5233,"e":4497,"b":2102,"c":900,"a":24510,"n":3878,"o":5982,"l":3786,"m":2460,"j":397,"k":2897,"h":3132,"i":6615,"w":2306,"v":27,"u":3829,"t":1545,"s":2871,"r":2895,"q":718,"p":77,"z":23,"y":3607,"x":1698,"jaa":13,"jab":16,"jar":10,"jam":12,"Xam":11,"joo":14,"Xas":10,"jis":14,"jir":95,"jii":13,"jid":17,"jo ":15,"Far":12,"isk":69,"ism":12,"isl":25,"iso":22,"isu":42,"ist":67,"ita":17,"is ":71,"ion":20,"ir ":84,"irs":56,"irt":28,"iro":22,"irk":32,"iri":56,"isi":32,"ish":96,"ise":18,"isb":17,"Wux":23,"isa":134,"ire":16,"ira":131,"iyi":10,"iyo":394,"iya":423,"iye":65,"ixi":16," l":598," m":880,"kii":161," n":189," o":537," h":365," i":795," j":267," k":1328," d":1214," e":328," f":95," g":401," a":1317," b":593," c":361," y":296," x":283," u":599," t":376," w":1834," q":291," p":20," s":807," r":112,"km ":14," J":125," K":142," H":119," I":161," N":93," O":34," L":81," M":322," B":217,"khd":24," C":229,"kha":11," A":275," F":59," G":169," D":236," E":41," Z":10," Y":40," X":90," S":438," R":66," Q":69," P":18," W":211," U":33," T":83,"kee":20,"key":11,"kh ":38,"Web":10,"Waa":56,"ku ":434,"kor":15,"Wax":40,"koo":94,"War":17,"XEE":11,"مد":16,"Gal":22,"و":25,"ي":76,"ف":13,"ق":12,"ل":77,"م":62,"ن":31,"ه":13,"د":46,"ح":26,"ب":37,"ة":21,"ا":98,"أ":11,"ع":29,"ش":21,"س":23,"ر":49,"kar":49,"kas":30,"kan":49,"kal":143,"kam":32,"kad":48,"kac":14,"kab":10,"kaa":81,"ka ":1268,"A ":83," Ga":53," Ge":18,"Da":59,"DU":11,"Cu":18,"Co":13,"DE":11," Fi":17,"Ce":13,"DH":15,"Ci":23," Ha":35,"Du":13,"EY":13," Go":61," Gu":12,"EG":11,"De":45,"EE":45,"EL":14,"Di":29,"Dh":36,"H ":16,"GA":19,"Fa":23," IY":15,"Er":12," Ho":29,"ha ":334," Hi":37,"Ge":18," Ji":25,"Ga":53,"حم":18,"HA":35,"I ":13," Ja":63," KA":16," Is":32," It":29,"GM":12," In":35,"Fi":17,"ham":43,"han":102," Ka":28,"hal":48,"haw":17,"hax":44,"haq":58," Ki":19,"har":45,"has":76," Kh":10," Ju":19,"hah":12,"hab":77,"haa":189,"had":144,"hac":36,"AS":15,"AR":23," MA":17,"AX":27," La":22,"AY":15,"BA":11," Li":11,"C ":10,"AD":43,"AA":51,"AB":14,"AG":11," Ko":23,"AH":23,"hay":333,"AL":37," Ku":26,"AM":13,"AN":35," Ma":180,"Ax":18,"Ar":12,"D ":22,"بن":10," Mi":27,"Ba":101,"CA":15,"Af":65,"بد":10,"he ":25,"Aa":22,"Ab":33,"Ad":10,"Am":17," Lu":25,"Al":38," Ne":14,"Bu":30," Na":32,"Ca":127,"DA":43,"E ":30,"Bi":19,"Be":25,"hda":27,"Bo":30,"Hin":18," Mu":78,"hel":22,"Ku":26,"hee":112,"Ko":23,"hey":26,"hex":72,"Li":11,"N ":26,"her":11,"MA":41,"La":22,"Lu":25,"hi ":27,"Mi":27,"NK":10,"ال":51,"O ":34,"NA":12,"Ma":180,"Mu":79,"Ne":14,"Na":32," Am":16," Al":38,"Nu":16," Af":65,"No":12,"OO":18," Ad":10," Aa":22," Ab":33," Ba":101," CA":12," Ax":18," Ar":12,"hig":23," Be":25,"hid":12," Bi":19,"hin":40,"Go":61,"him":17,"Gu":12," Bo":30,"hii":170," Bu":30,"his":24,"hir":31,"Ha":35," Ca":127,"Hi":37," Ce":13," DE":10," Ci":23,"IN":12,"Ho":29," DH":13,"IS":10," Co":12," Cu":18,"IY":20," Da":59," Di":29," Dh":36,"In":36," De":45,"Is":32,"It":30,"Ja":63,"KA":33," Du":13,"Ji":25," Er":12,"Ju":19,"LA":35,"Ka":28,"Kh":10,"ho ":53,"Har":14,"Ki":19,"LE":16," Fa":23,"gma":64,"go ":32," Xi":13," Xa":51,"UU":11,"yuu":26," Wu":23,"To":11,"Th":10," Wi":15," We":12,"Ta":37," Wa":133,"St":13,"Su":23,"Wu":23,"gob":97,"Wi":16,"Wa":133,"XA":19,"We":12,"XE":12,"Y ":18,"yst":29," Yu":14,"yso":15," Ya":10,"WA":26,"gmo":41,"ysa":93,"Qa":26,"Qo":17," م":12,"RA":10,"S ":18," ع":21," ا":48,"goo":52,"R ":20," ب":13,"gsa":14,"gu ":229,"Si":17,"Sh":86,"gsi":12,"So":180,"Ru":12,"U ":11,"Sa":70,"TA":13,"Re":13,"SH":11,"Ro":11,"yoo":24,"Qu":16,"SA":16,"Ra":20,"gud":22," Nu":16," No":12,"gta":43," Ra":20," Qu":16,"b ":130," Ro":11," Re":13,"guu":20,"gun":12,"a ":5909," Qo":17," Qa":26,"شي":10," Su":23," St":13," Ta":37,"Ya":10," Th":10,"Yu":14," To":11," Ru":12," Sa":70,"Xa":51,"YO":15," Sh":86," Si":17,"Xi":13," So":180," WA":20,"ري":12,"Gob":48," ja":60,"i ":853,"ye ":36,"ian":11," iy":365," ji":127,"ge":93," je":47,"ga":1135,"fk":16,"Ing":16," im":15," in":148," il":54," ii":23,"ic ":14,"fi":49,"fr":45,"fu":47,"ft":29,"fo":18," is":155," ka":688," kh":13,"hd":44,"he":286," ki":46," ke":11,"ha":1580,"gn":11,"gm":108," jo":14,"gl":15,"gi":72,"id ":171,"gu":305,"iba":32,"gt":52,"gs":27,"gr":15," ju":17,"go":196,"du":188,"dw":36,"dy":13,"g ":83," ha":190,"ea":16,"eb":72,"yee":61,"ec":51," he":28,"ed":360,"de":252,"dd":113,"di":494,"dh":632,"dk":189,"dl":33," go":117,"do":234,"dn":22," gu":55,"ia ":36,"ex":102,"ey":554,"fa":110,"h ":441," id":15,"fe":17,"eh":54,"ib ":32,"eg":202," hi":20,"ee":1263,"el":242,"ek":35," ho":120,"ei":12,"yey":26,"en":172,"em":31,"et":26,"es":93,"er":287,"ya ":266,"ca":427," ni":37,"e ":881," ne":15,"bs":21," na":54,"br":36,"bu":104,"bt":55,"bn":18,"bo":234,"bk":30,"bl":13," mu":48,"ig ":10,"bi":355,"bb":15,"bd":41,"be":201,"db":11,"da":2087," og":18,"f ":98,"cy":18," of":16,"cu":41,"ct":11,"cs":27,"co":62,"cm":24,"cn":13,"cl":19,"ci":73," nu":10,"ch":33," no":73,"ce":64,"cd":20,"yad":111,"yag":10," le":91,"c ":51,"yaa":287," la":334,"icm":22," ku":465,"ici":14," km":14,"ica":25," ko":88," me":49,"az":10,"ay":1458,"idu":13," mi":187,"ba":817,"d ":893,"at":134,"as":580,"yd ":29,"ido":43,"ar":1307,"aq":237," ma":590,"ax":1066,"aw":157,"idk":12,"yay":52," lu":25,"ak":76,"al":1647,"idi":35,"yaw":11,"idh":19,"ai":29,"aj":59,"yar":45,"am":590,"an":1951,"yaq":50,"yan":13,"ac":260,"ida":140,"ad":2243,"aa":4171," lo":138,"ab":630,"ag":664,"ah":1152,"yah":134,"af":128,"iib":15,"nu":38,"iic":11,"nt":263," af":45,"ns":59," ah":473," aa":208,"iig":13," ab":31,"iid":50,"no":160,"nn":18," ad":49,"q ":34," am":103," an":18,"iik":48,"iin":164,"ny":57,"yka":17,"iil":93," al":21,"iim":26,"iis":199,"iir":65,"of":78,"iiq":14,"oc":29," ax":10,"od":156," ar":26,"ob":291," aq":21," as":29,"om":340,"on":186," ba":344,"ok":16,"ol":273," ay":246,"og":129,"il ":80,"ot":41,"os":90," bi":107,"op":10,"oo":1738," be":63,"or":236,"oq":49,"yn ":105," bo":34,"r ":475,"ox":10,"ow":125,"oy":128," bu":35,"pa":14," ca":238,"im ":21,"ika":50,"lo":386,"ige":10,"lm":39,"ll":110,"ls":27,"iga":247,"ii ":339,"lw":14,"lu":48,"igi":31,"yo ":488,"ly":56,"igu":13,"igt":12,"o ":2012,"ma":1465,"mb":52,"mh":21,"me":199,"mk":39,"mi":333,"mp":19,"mo":102,"yna":98,"mu":85,"ihi":82,"yni":14,"na":851,"nb":30,"yne":30,"nc":10,"nd":137,"ne":107,"nf":30,"ng":58,"ynt":29,"ni":213,"nk":312,"nl":21,"imo":20,"ju":17,"jo":31," ee":295,"imi":21,"ki":203,"kh":95,"ke":48,"ind":29,"ina":80," fa":48,"yga":15,"ka":1778,"yi ":19,"m ":103," fu":10,"ino":13,"kt":20," fo":12,"ku":558,"int":102,"ins":10,"ko":130,"ine":14,"ing":16," fi":17,"ini":10,"km":16,"ink":82," ge":36,"li":577,"lk":332,"le":352," ga":186,"ld":23,"lg":22,"inu":15,"la":1306,"lb":52,"iny":13,"n ":1478," co":22,"ht":11,"hu":92,"ikh":54," ce":15,"hi":387,"hn":16,"ho":217," ci":36,"ila":160,"id":471,"ic":103,"yin":59,"ib":108,"ia":61,"ih":88,"in ":262,"ig":350," da":424,"if":21,"yih":49,"yig":21," cu":34,"hy":12,"k ":24,"iq":21," do":45,"ilo":13,"ir":438,"is":630,"it":49,"ill":18,"ilk":32,"ix":28,"ilm":12,"ii":1062,"ij":21,"ik":134," de":120,"ili":51,"il":385,"im":170,"in":663,"io":30," di":70,"yir":13," dh":511,"ima":76,"je":69,"ji":178,"iy":896," du":39,"l ":398,"ja":82,"xi":123,"xo":56,"xm":34,"xw":27,"xu":185,"xb":18,"xa":850,"xe":161,"xd":67,"wg":11,"wi":81,"how":15,"wl":60,"wo":26,"wu":102,"hog":13,"y ":1137,"wa":1722,"wd":13,"hoo":55,"we":185,"hor":60," yi":55," yu":13,"uy":12,"ux":164,"uw":34,"uu":720," ye":13,"ve":10," ya":211,"x ":140," xo":33,"uj":15,"uk":28,"ul":200,"uf":20," xi":90,"ug":210,"uh":16,"uq":90,"ur":259,"hna":12," xu":39,"us":114,"ut":54,"um":90,"un":214,"tu":47,"ub":104,"ua":11,"ud":145,"uc":17," xe":16,"w ":59," xa":103,"to":175,"hul":37,"tr":25,"te":120,"ti":246,"th":37,"ta":784,"su":111,"ss":19,"st":173,"sw":12,"sl":47,"sk":106,"sm":25,"so":371,"sr":10,"sc":17,"se":101,"sh":456,"ي ":20,"xme":19,"si":404,"xma":13,"u ":1296,"sa":722,"sb":21,"rr":20,"rs":115,"rt":160,"ru":77,"rw":11,"rx":11,"ry":27,"ro":144,"rn":40,"rm":32,"rl":22,"rk":200,"ri":397,"hu ":11,"rg":35,"re":258,"rd":49,"rc":12,"rb":25,"ra":754,"t ":51,"qu":35,"qs":10,"xoo":44,"qo":163,"IYO":15,"qi":33,"qe":23,"qa":334,"qd":61,"s ":240,"pu":15,"pr":14," ru":12," u ":194," sa":221," se":17," si":157," sh":112," so":259," qu":21,"xya":13," ra":48," re":33,"ن ":17," ro":11," qe":14," qa":168," qo":69," qi":18," oo":464," or":10,"huu":29," wa":1582," we":88," wo":12," wu":102," wi":39," uu":195,"xud":12,"xuu":133,"Hoo":12," tu":36," us":16," ur":10,"م ":11," um":12," un":11," ug":131,"yg":19," ta":231,"ye":133,"yd":48,"ya":998,"yb":27,"xwe":21,"xy":17," su":25,"yu":34,"ys":166," to":18," th":15," ti":62,"yo":522,"yn":280," te":11,"yk":19,"yi":189,"fee":11,"xey":58,"xee":54,"far":32,"fad":21,"faa":24,"Suu":12,"Axm":14,"xir":17,"xis":13,"xil":26,"xii":17,"xid":14,"xig":24,"Sta":10,"xa ":169,"eyb":17,"eya":63,"eys":74,"Tal":11,"eyn":163,"eyo":14,"eyk":10,"xda":51,"eyd":16,"eye":14,"exa":10,"exd":12,"exe":51,"xe ":46,"xar":38,"Ban":18,"Baa":14,"Bad":22,"xam":54,"xan":16,"Bar":23,"xay":166,"xba":16,"xaa":341,"xad":27,"xag":13,"wux":100,"Aas":11,"Shi":22,"She":12,"Sha":50,"ex ":21,"Af ":19,"ey ":159,"er ":103,"es ":21,"eri":33,"ere":30,"era":49,"Afr":32,"esh":28,"esa":10,"ers":11,"ern":14,"ekh":16,"en ":89,"ela":47,"ele":26,"eli":17,"ell":42,"elo":15,"emb":19,"ena":28,"wla":53,"eny":12,"egm":90,"ego":14,"egt":11,"Som":32,"Soo":136,"woq":10,"el ":65,"wda":13,"Buu":11,"Bur":11,"we ":12,"gir":17,"gii":26,"wey":124,"wee":27,"gey":15,"gee":44,"wi ":14,"wis":10,"wii":22,"Sal":11,"gab":12,"gac":45,"gad":26,"DA ":20,"gaa":436,"gar":35,"gay":21,"gal":70,"gan":69,"ga ":388,"San":27,"wa ":22,"Cab":27,"waq":26,"wan":30,"wal":39,"wax":715,"way":45,"Cal":18,"war":52,"was":18,"Car":40,"waa":581,"wad":168,"Bel":10,"fur":37,"Bis":12,"fri":39,"fii":15,"Boo":10,"fka":13,"da ":918,"de ":22,"dad":131,"daa":159,"dab":19,"dal":113,"WAX":16,"dag":65,"dah":101,"dar":51,"dan":291,"dam":39,"day":61,"dax":79,"daw":32,"Cum":10,"dda":74,"dde":11,"ddi":17,"cun":14,"EEY":13,"EEL":14,"EGM":11,"Deg":30,"cyo":15,"uxu":126,"Daa":22,"Dag":10,"Dal":10,"uxa":15,"uun":88,"uul":63,"uum":13,"uug":15,"uud":50,"uux":10,"ux ":12,"uus":29,"uur":74,"uuq":18,"uut":24,"uwa":28,"co ":26,"cma":23,"ush":13,"usi":11,"use":13,"uu ":316,"usu":26,"uso":11,"uti":16,"uta":19,"cod":10,"com":11,"uqa":33,"uqd":36,"ura":37,"ure":10,"uri":31,"urk":17,"urt":32,"uru":37,"ur ":39,"csi":14,"uma":56,"unt":32,"unk":27,"uni":11,"una":85,"cel":30,"uka":13,"cee":17,"uls":10,"ulo":20,"ull":14,"ulk":27,"uli":14,"ule":16,"ula":26,"un ":29,"che":12,"ul ":36,"ciy":12,"cii":28,"uga":40,"ugu":128,"ugs":11,"ed ":184,"ebi":20,"uf ":13,"uda":33,"udi":12,"eb ":12,"udu":37,"ug ":18,"ega":53,"ub ":32,"eek":25,"een":99,"eel":138,"eem":18,"eeb":23,"eeg":65,"eed":229,"eey":113,"eh ":42,"ees":56,"eer":157,"edk":18,"edi":12,"ede":22,"eda":72,"uba":39,"ubb":11,"edu":15,"ud ":36,"edo":11,"ecl":12,"ece":25,"ee ":319,"dwe":25,"dwa":11,"duu":57,"tuu":22,"doo":96,"dow":37,"tri":10,"The":10,"dna":12,"to ":75,"Dhe":14,"Dhu":12,"dun":12,"dul":20,"dug":23,"too":69,"du ":45,"tii":59,"tig":10,"tir":66,"dha":335,"tio":16,"tic":26,"dhu":33,"dib":25,"dhi":112,"dhe":122,"dho":21,"der":19,"dex":18,"dey":16,"dee":48,"deg":96,"den":15,"di ":38,"dle":11,"dla":17,"tee":36,"dku":14,"dki":33,"do ":77,"ter":36,"diy":39,"din":26,"ti ":29,"dir":60,"dis":51,"dig":42,"dii":165,"dil":12,"dka":134,"the":16,"rga":14,"ri ":48,"rge":14,"rey":42,"ree":110,"rda":15,"rdh":16,"re ":77,"rco":10,"rax":25,"ray":99,"rar":15,"ras":44,"rat":10,"rba":11,"rah":41,"ran":54,"ram":17,"rak":12,"rab":82,"raa":165,"rad":87,"rs ":11,"roo":48,"rna":16,"rne":11,"rni":10,"ro ":63,"rma":23,"Nab":15,"rla":13,"rku":10,"rko":10,"rki":41,"rke":18,"rka":117,"riy":58,"ris":28,"rig":31,"rii":110,"rik":46,"rin":21,"ric":16,"rya":13,"rur":10,"run":18,"ruu":10,"ry ":11,"rsi":16,"rsa":63,"rsh":15,"rta":110,"rto":18,"rte":11,"rti":11,"rub":12,"saa":120,"sab":11,"sad":52,"sag":23,"sah":11,"sal":49,"sam":47,"sbi":14,"san":191,"sas":14,"sar":33,"say":43,"sa ":99,"sha":242,"sho":46,"she":41,"shi":83,"si ":68,"siy":42,"sid":91,"shu":10,"sil":13,"sim":38,"sii":82,"sig":32,"se ":61,"sh ":17,"see":14,"sow":16,"som":59,"soo":214,"soc":14,"su ":25,"sla":30,"sku":37,"ska":59,"so ":55,"sma":15,"حمد":15,"ste":15,"sta":66,"sto":28,"sti":41,"sub":11,"suf":12,"sug":13,"sul":11,"suu":22,"tal":42,"tag":10,"tah":87,"taa":194,"tad":13,"tay":60,"tar":33,"tan":31,"tam":13,"te ":13,"ta ":272,"bka":23,"biy":71,"bis":28,"bir":12,"bil":48,"bin":31,"big":38,"bii":37,"bo ":47,"bol":129,"bna":15,"boo":24,"bba":12,"be ":19,"ban":61,"bal":43,"bah":27,"bad":232,"baa":96,"bab":12,"bay":35,"bax":34,"bas":10,"bar":156,"bdi":25,"bdu":11,"bi ":69,"bee":145,"ber":11,"bey":12,"ca ":55,"car":35,"cas":13,"can":24,"cay":13,"cab":20,"cad":53,"caa":145,"cal":33,"cag":16,"bri":13,"bra":15,"bsa":11,"bta":33,"bti":13,"bur":20,"bul":12,"buu":52,"aka":19,"am ":40,"aki":23,"aji":27,"ajo":16,"qa ":12,"al ":136,"ahi":41,"qar":20,"qay":16,"aho":10,"qad":44,"qab":47,"qaa":149,"ahd":20,"qan":14,"qal":17,"ahe":26,"aha":697,"agm":13,"agt":24,"agu":76,"ago":29,"aq ":22,"qdi":38,"qda":17,"any":23,"ano":51,"ann":10,"ant":70,"ans":32,"ane":21,"ang":10," ال":46,"ani":87,"ank":185,"ana":385,"anb":26,"and":92,"amu":23,"amo":10,"amk":32,"amh":19,"ami":82,"ame":93,"amb":16,"ama":257,"aly":20,"qey":14,"alo":160,"alm":17,"all":22,"alk":165,"alg":17,"ali":424,"ald":14,"ale":110,"ala":480,"alb":42,"an ":924,"aba":194,"abd":37,"abe":56,"abi":146,"abk":18,"abo":40,"abt":38,"abu":36,"aca":130,"aab":114,"aac":13,"aaa":15,"aaf":38,"aag":64,"aad":398,"aaj":28,"aak":21,"aah":75,"aan":742,"aal":743,"aam":113,"aas":211,"aar":259,"aaq":41,"aaw":32,"aat":37,"aay":89,"aax":19,"ad ":334,"qiy":15,"ac ":19,"aa ":1110,"qii":10,"ab ":33,"afr":11,"aft":15,"afi":18,"aga":458,"age":12,"ah ":325,"afa":38,"ado":85,"adl":23,"adk":153,"adn":12,"adh":26,"adi":223,"add":96,"ade":66,"ag ":29,"adw":22,"adu":44,"aci":16,"ace":10,"Qar":12,"acd":15,"ada":1138,"af ":19,"acy":15,"acs":19,"qor":48,"qoo":60,"qof":24,"axi":13,"axm":15,"axo":15,"axu":15,"axa":702,"axb":16,"axd":50,"axe":90,"ayi":11,"ayo":52,"ayn":115,"ays":84,"ayu":13,"axy":16,"axw":26,"ayb":10,"aya":151,"ayg":11,"ayd":32,"aye":26,"ba ":84,"qur":24,"at ":11,"arg":25,"are":96,"ard":30,"arb":14,"ara":357,"aro":72,"arn":19,"arm":17,"arl":10,"ark":135,"ari":153,"aru":20,"ars":39,"art":72,"asa":99,"ary":14,"asi":106,"ash":156,"ase":12,"aso":31,"ask":17,"ar ":198,"as ":80,"aqa":111,"aqi":13,"aqo":51,"ax ":98,"awe":20,"ay ":932,"awa":46,"awl":31,"awi":33,"ata":37,"asu":12,"ast":33,"ato":18,"ate":17,"ra ":58,"ati":34,"ngi":20,"ni ":47,"Isl":11,"neh":11,"ng ":11,"nee":16,"nfu":25,"ney":14,"ne ":43,"ndh":18,"ndi":22,"nan":17,"nac":45,"nad":83,"nah":41,"nab":18,"naa":131,"Ito":28,"nbe":15,"nd ":69,"AXE":10,"AY ":10,"nba":11,"AXA":12,"nay":47,"nax":11,"na ":412,"Jab":13,"Jan":13,"Jam":22,"KA ":11,"KAL":10,"nya":38,"AAL":13,"ADA":25,"nuu":21,"nto":13,"nti":37,"nta":176,"nte":24,"nsi":15,"nsa":22,"AHA":14,"noo":67,"noq":18,"nna":11,"ALA":17,"nle":12,"no ":59,"nki":22,"nka":271,"AN ":16,"nii":13,"nih":11,"nig":39,"niy":10,"nis":15,"nim":17,"nin":39,"ogu":24,"oga":60,"Jub":11,"ol ":60,"oco":11,"odi":15,"of ":38,"oda":43,"ofe":10,"LA ":12,"د ":29,"oba":86,"od ":60,"obo":134,"obi":38,"ة ":21,"oyi":94,"oya":10,"owl":29,"ow ":45,"ost":14,"ota":10,"ose":28,"os ":15,"oon":114,"ool":98,"oom":198,"oof":13,"oog":60,"ood":123,"oob":124,"or ":39,"ooy":111,"oow":16,"oot":14,"oos":65,"oor":31,"Koo":13,"ore":44,"ori":14,"osa":11,"ort":21,"oqo":37,"oqd":11,"ora":61,"ola":52,"on ":52,"olk":99,"ole":20,"olo":14,"oly":10,"ona":28,"onf":25,"oni":16,"onk":11,"ons":12,"ont":14,"oma":298,"oo ":749,"omp":12,"la ":241,"le ":159,"laa":281,"lab":61,"lac":11,"lad":232,"laf":10,"lah":96,"lag":116,"lal":23,"lan":88,"lam":27,"las":21,"lay":70,"lba":15,"lbe":31,"kuw":22,"kuu":18,"kun":22,"kul":14,"kto":17,"MAD":13,"lom":11,"loo":176,"lmo":12,"lmi":13,"lma":10,"lsh":13,"Luu":11,"li ":92,"lga":16,"ley":29,"leh":35,"lee":98,"lo ":165,"lla":49,"lle":32,"lka":311,"lki":14,"lis":19,"lin":48,"lim":15,"liy":204,"lid":28,"lia":24,"lib":24,"lil":40,"lii":17,"lig":30,"ma ":133,"maa":361,"mac":36,"mah":24,"mad":229,"mag":226,"mar":193,"mas":14,"mal":133,"man":32,"may":23,"max":25,"mba":26,"mbe":10,"me ":19,"med":68,"mee":72,"mey":24,"luq":12,"luu":17,"مد ":15,"lya":33,"lyo":10,"Mar":22,"Mas":10,"Mag":51,"Mad":20,"Maa":17,"Max":25,"moo":35,"muq":17,"muu":16,"mul":10,"Mux":13,"mhu":20,"Muq":24,"Mud":14,"mi ":19,"min":17,"mil":14,"mis":11,"miy":27,"mig":18,"mid":170,"mij":10,"mii":25,"mo ":60,"mka":33},"n_words":[94077,109135,83288],"name":"so"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/spa b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/spa new file mode 100644 index 000000000..cdc195676 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/spa @@ -0,0 +1 @@ +{"freq":{"D":116547,"E":296654,"F":128129,"G":121338,"A":269964,"B":167407,"C":324676,"L":239740,"M":232523,"N":101570,"O":64162,"H":81475,"I":139475,"J":79180,"K":34991,"U":62793,"T":132122,"W":35590,"V":93781,"Q":9803,"P":223906,"S":275410,"R":140692,"Y":15953,"X":27052,"Z":15636,"f":602083,"g":868874,"d":3877179,"e":8874725,"b":812441,"c":2912236,"a":7916083,"n":5177793,"o":5444424,"l":3848407,"m":1698678,"j":201978,"k":118503,"h":478078,"i":4816050,"w":47097,"v":521828,"u":2624688,"t":3108332,"s":4177405,"r":4307485,"q":288923,"p":1539196,"z":257162,"y":639511,"x":118459,"²":9268,"Á":8848,"í":298098,"é":232623,"è":9587,"á":241717,"ú":87005,"ó":542725,"ñ":141698," l":925296," m":342591," n":169035," o":224265," h":153575," i":177440," j":57642," k":20882," d":2112466," e":1686012," f":346033," g":128207," a":615947," b":110799," c":841620," y":413167," z":8894," u":509709," t":263819," v":109427," q":191724," p":764411," s":537300," r":229895," J":77814," K":33034," H":77965," I":96403," N":91185," O":55452," L":232579," M":222195," B":158843," C":308303," A":248654," F":121663," G":115612," D":105557," E":280970," Z":14852," Y":15119," X":18791," S":256762," R":131715," Q":9140," P":211939," W":33301," V":79914," U":57665," T":122063," á":26258," é":11575," ú":11089," Á":8823,"A ":15731,"Da":13474,"Cu":13670,"Cl":11053,"Co":80802,"Cr":14045,"Ce":15444,"Ch":44811,"Ci":15164,"Ed":7168,"Du":7509,"Do":14187,"De":29603,"Di":25181,"Fe":19702,"Fa":9899,"Eu":12005,"Es":99956,"En":28786,"El":96353,"Ge":16269,"Ga":21659,"I ":25126,"Fu":23434,"Fr":30636,"Fo":10911,"Fi":10813,"C ":12178,"Au":18315,"Ar":39333,"At":7482,"As":13866,"D ":7805,"Ba":43405,"Ac":8941,"Am":14049,"An":29222,"Ai":9057,"Al":51515,"Bu":16123,"Br":22960,"Ca":88236,"E ":7609,"Bi":10052,"Be":24042,"Bo":25983,"Le":25199,"Li":24708,"La":111930,"Lu":14073,"Lo":44117,"Me":30598,"Mi":26023,"Ma":85855,"Mu":18246,"Mo":36242,"Ni":10392,"Ne":11654,"Na":26109,"Nu":10474,"No":24130,"Gi":8606,"Gr":21868,"Go":14614,"Gu":21771,"Ha":19115,"He":16228,"II":18780,"Hi":11870,"Ho":13033,"Hu":9391,"In":34662,"Is":11404,"Ja":18733,"Je":8830,"Jo":22070,"Ju":22045,"Ka":8249,"Un":40236,"VI":7056,"Tu":7329,"Tr":17446,"To":19269,"Th":18313,"Ti":12341,"Te":21087,"Ta":17232,"V ":8314,"St":15377,"Su":36610,"Wi":9415,"Wa":8415,"Vi":28361,"X ":8775,"Va":20820,"Ve":16615,"Mé":10810,"Pu":11178,"Pr":36130,"S ":9671,"Pe":30523,"Pa":58336,"Pl":10964,"Po":27786,"Pi":20810,"Or":15403,"Se":51296,"Sc":7275,"Si":21213,"So":22342,"Ru":9143,"Sa":70712,"Re":46909,"Ri":14206,"Ro":31238,"Qu":8096,"Ra":15098,"b ":16974,"a ":2807777,"i ":67723,"cá":7737,"ge":97443,"ga":124206,"fl":18249,"fi":107495,"fr":77696,"fu":123473,"fo":79998,"có":10267,"he":77025,"ha":138548,"gn":24260,"cé":16005,"gl":50338,"gi":128766,"gh":9410,"gu":117756,"gr":97493,"cí":12742,"go":114696,"du":66523,"g ":31294,"ea":126973,"eb":49402,"ec":261065,"ed":147913,"de":2140534,"di":323631,"dm":7851,"do":556174,"dr":51266,"ex":62245,"eu":25398,"añ":100385,"ev":65967,"ey":26516,"ez":45865,"fa":71295,"h ":31038,"fe":72710,"eg":169863,"ef":34480,"ee":18956,"el":821140,"ej":32037,"ei":38528,"ep":114508,"eo":63152,"en":1446857,"em":183658,"et":133793,"es":1262459,"er":848036,"eq":18834,"aí":17948,"ca":518269,"e ":2816707,"bs":7367,"br":179247,"bu":47229,"bo":65362,"bl":117456,"bi":135239,"be":67612,"da":466302,"f ":15176,"cu":158454,"ct":134054,"cr":79888,"co":691321,"ck":21843,"cl":46854,"ci":780154,"ch":115875,"ce":230782,"cc":44533,"c ":23067,"az":30061,"ay":59587,"ba":136047,"d ":184141,"at":211115,"as":567489,"ar":691307,"aq":9531,"av":48388,"au":72787,"ak":11907,"al":659633,"ai":51423,"aj":50703,"ao":8102,"ap":77232,"am":297433,"an":805183,"ac":374463,"ad":631439,"ab":144055,"ag":85149,"ah":13118,"ae":43681,"af":21278,"nu":35537,"nt":779819,"ns":140899,"nq":11336,"no":368063,"nn":24107,"nz":31492,"ny":8769,"nv":18820,"oe":24400,"of":39013,"oc":180019,"od":93463,"oa":18159,"ob":123195,"om":334368,"on":689571,"ol":230551,"oi":24324,"oj":12159,"og":57063,"oh":10801,"m²":9191,"ot":93533,"os":699509,"ov":85328,"ou":52929,"op":77349,"oo":15677,"or":691238,"r ":505089,"ox":9374,"ow":10366,"oz":11222,"oy":19941,"lá":14567,"pe":253260,"pa":326975,"pl":67808,"lé":20848,"po":370364,"ph":12436,"pi":101456,"lo":395718,"lm":47465,"ll":193235,"ls":13390,"lp":10103,"lv":15446,"lu":77232,"lt":59369,"ly":9017,"o ":1816298,"ma":323604,"mb":142619,"me":329898,"mi":236057,"mm":8572,"ié":32355,"mp":132049,"mo":207044,"mu":126184,"ió":324878,"p ":13048,"na":683565,"nc":291584,"nd":277346,"ne":311456,"nf":32397,"ng":105777,"ni":309689,"nj":11352,"nk":8262,"nm":8232,"ju":57258,"fí":9213,"jo":44644,"ki":14501,"ke":14800,"ka":12118,"m ":52750,"gó":7060,"gí":14289,"gé":21878,"km":14607,"li":353994,"le":344098,"ld":22533,"lg":19778,"lf":10189,"la":1037960,"lc":15579,"lb":23157,"gú":7200,"n ":1645057,"hr":7436,"dí":25020,"ht":8163,"hu":24887,"hi":87814,"ho":64406,"dé":12258,"id":350652,"ic":527484,"ib":58759,"ia":458387,"ig":130847,"if":53944,"ie":349344,"k ":32633,"ir":119098,"is":363824,"it":317793,"iu":42028,"eñ":26834,"iv":114899,"eó":10608,"ij":12968,"ik":8874,"il":242265,"im":150543,"in":518205,"io":362002,"ip":90246,"je":41244,"iz":77284,"l ":1070460,"ja":41449,"xi":40771,"té":18357,"xp":12413,"tí":29392,"tó":61297,"xt":20556,"só":7077,"z ":55163,"tá":43968,"sé":9023,"sí":13754,"ró":22130,"y ":494983,"wa":13090,"ré":8377,"vi":184322,"rí":60498,"vo":65147,"uz":11349,"uy":29308,"ux":7768,"uv":14743,"rá":28876,"ve":131509,"va":112048,"x ":22885,"ui":101034,"uj":10219,"ul":130016,"ue":529325,"ug":37794,"ur":196055,"us":135539,"ut":75455,"um":62826,"un":688515,"uo":9672,"up":46545,"tu":178275,"tt":18266,"pó":8915,"ub":69875,"ua":157161,"ud":82055,"uc":86063,"w ":7730,"pú":12838,"to":492464,"tl":11756,"ts":11628,"tr":358077,"te":662982,"ti":404422,"th":33828,"tb":14576,"ta":636505,"su":163099,"ss":27514,"st":570360,"sl":23077,"sk":8256,"sm":35452,"sp":146933,"so":177522,"sd":21641,"sc":98040,"se":328771,"sh":16915,"si":316726,"rz":18465,"u ":97650,"nú":7450,"sa":193871,"rr":132506,"rs":76964,"rt":263306,"ru":82530,"rv":23971,"nó":12071,"ry":14114,"ní":12258,"rq":18301,"rp":16192,"ro":473902,"rn":71986,"né":9922,"rm":118903,"rl":28428,"rk":11610,"ri":592813,"rg":83834,"rf":13796,"ná":7351,"re":689451,"rd":86475,"rc":86488,"rb":27212,"ra":734384,"t ":94930,"mú":13777,"mó":11660,"qu":286748,"mí":7526,"mé":17124,"má":63634,"s ":1974557,"pt":30720,"pu":78951,"ló":19506,"lí":47975,"pr":228655,"ps":9053,"zó":8970,"zi":7657,"za":111482,"zu":8538,"zo":36191,"ye":23683,"ya":28514,"uí":10738,"yo":35768,"ué":9949,"² ":9260,"án":62336,"ál":20287,"áf":8040,"ác":15525,"ár":16431,"át":16282,"ás":49088,"á ":27321,"óg":11484,"ód":8472,"ór":13833,"ón":382883,"óm":11589,"ól":14360,"ó ":71778,"ña":56328,"ño":76416,"ín":33019,"ím":10418,"ío":16786,"ít":28434,"ís":34065,"íf":8702,"íc":18334,"íd":7650,"ía":105050,"í ":14487,"él":11392,"én":55163,"és":52145,"ét":12035,"ér":34634,"éx":11216,"éc":11450,"é ":16494,"ún":21741,"úl":7364,"út":8499,"ús":12464,"úb":12720,"ú ":7505,"一":7134," Ga":21582," Ge":16178," Fo":10836," Fu":23266," Fr":30592," Fi":10737," Ha":19064," He":16181," Go":14559," Gr":21740," Gu":21689," Gi":8540," Hu":9382," Ho":12969," Hi":11833," Je":8808," Ja":18701," Is":11343," In":34554," Ka":8187," Jo":22025," Ju":22012," La":111649," Le":25083," Li":24432," Ma":85482," Mi":25830," Me":30504," Lo":44008," Lu":14044," Ne":11540," Na":26019," Ni":10343," Mo":36161," Mu":18130," Am":14012," An":29155," Al":51409," Ai":9020," Ac":8911," Ba":43282," Au":18286," At":7457," As":13733," Ar":39211," Be":23973," Bi":9959," Bo":25824," Br":22869," Bu":16073," Ca":87586," Ce":15402," Ci":15105," Ch":44683," Cl":10942," Cr":13930," Co":80501," Cu":13492," Da":13336," Di":25027," De":29418," Do":13935," Du":7489," Ed":7143," El":96116," Es":98653," En":28605," Eu":11992," Fe":19655," Fa":9820," Wi":9336," Wa":8349," a ":151113," Or":15358," Po":27637," Pl":10897," Pi":20772," Pe":30452," Pa":58153," Nu":10454," No":24018," Ra":15024," Qu":7915," Ro":30970," Re":46794," Ri":14181," Pr":36030," Pu":11158," Mé":10807," Su":36537," St":14732," Ta":17163," Th":18237," Ti":12302," Te":20935," Tr":17351," To":19041," Ru":9128," Sa":70550," Si":21147," Sc":7137," Se":51093," So":22241," Va":20787," Ve":16562," Vi":28257," Tu":7181," Un":40136," ja":7912," im":16980," in":113728," is":9470," it":12073," ju":44169," ha":71347," he":17319," gr":47141," go":9321," gu":12156," id":8758," hi":30296," ho":20186," hu":9280," ni":9094," ne":10791," na":40693," mu":56375," mo":34821," oc":24698," of":15543," ob":20507," nu":10795," no":85354," le":29852," li":28752," la":626496," gé":18729," km":14107," me":61144," mi":48266," o ":71023," ma":85649," lu":16286," ll":24228," lo":186366," ag":19771," ab":21502," ac":45971," ad":18011," am":14490," an":45970," ap":24125," al":116261," au":26320," ar":40593," at":8359," as":24315," ba":52391," bi":11562," bo":13161," br":12518," ca":157850," e ":10258," er":14855," eq":8506," es":539820," en":614552," em":20859," ej":8137," el":384203," fe":21573," fa":54639," añ":28328," ex":38515," fu":116273," fr":61229," fo":35270," fl":10710," fi":33918," ge":20831," ga":13109," cl":15585," co":462664," cr":30029," ce":31950," ch":12983," ci":56484," da":13407," cu":60477," do":35749," de":1878742," di":146031," ed":14319," du":20922," té":10997," tí":7323," ru":8901," sa":21596," se":189308," si":104740," so":62800," qu":191524," mú":9473," ra":15504," re":170810," ro":18871," pu":38713," pr":177892," lí":9079," má":36795," ot":17424," or":52385," pe":108853," pa":137566," pl":26836," po":242173," pi":19178," y ":406137," va":23514," ve":32789," vo":9768," vi":36979," ub":13189," tu":8296," us":12351," ut":9609," un":466456," ta":42321," su":139495," tr":62181," to":30228," th":7488," ti":31564," te":60962," ár":9835," ál":11624,"Fer":7120,"Es ":20079,"Est":40499,"Esp":30688,"Eur":9266,"El ":89488,"En ":18934,"Gar":7699,"Fue":18788,"Fra":22586,"II ":12947,"Gue":7438,"Gra":11989,"Int":10608,"Ind":7667,"Arg":10516,"Bar":13123,"Ale":9873,"Alt":8713,"And":7070,"Ant":10595,"Cal":12289,"Cam":10802,"Cas":14393,"Car":17937,"Can":11389,"Ber":7187,"Chi":15815,"Cen":8021,"Cha":15858,"Cor":11229,"Com":17537,"Col":10868,"Con":24853,"Nac":11329,"Nue":8768,"Nor":14767,"Pla":8680,"Per":15205,"Par":20522,"Pro":17204,"Pri":7235,"Pre":7665,"Méx":8860,"Jos":9116,"Las":10322,"La ":78398,"Los":18518,"Med":8474,"Man":10902,"Mar":33709,"Mad":9566,"Mon":15534,"Mun":7799,"Su ":13104,"Sai":11675,"Sal":8578,"Se ":18407,"San":32494,"Rep":8544,"Val":13044,"Vil":8238,"Uni":27767,"The":12538,"bit":22599,"bio":8582,"bil":7159,"bo ":7079,"blo":8255,"ble":28350,"bli":27042,"bla":52392,"bol":20729,"bié":25416,"bor":11023,"be ":11171,"ban":26993,"bal":10177,"baj":17768,"bas":16282,"bar":17411,"ber":30080,"bia":11473,"bic":15037,"bie":16653,"ca ":145181,"car":45351,"cas":41067,"cat":14539,"can":94395,"cap":14546,"cac":16670,"cab":10529,"cad":51771,"cam":20670,"cal":48767,"ce ":35472,"bri":27454,"bro":15368,"bra":26651,"bre":105758,"bur":7145,"bum":12078,"am ":8792,"ajo":16624,"al ":274116,"aja":11561,"aje":17588,"ain":19507,"ais":7210,"agu":12491,"ago":28675,"anu":10190,"anz":18126,"ano":79509,"ann":7583,"ant":195066,"ans":17426,"ane":17755,"ang":19562,"ani":47254,"ana":70957,"anc":101262,"and":90623,"amo":12426,"amp":25988,"ami":57872,"ame":88516,"amb":41071,"ama":44395,"alu":9523,"alt":15595,"alo":13492,"alm":37560,"all":38280,"alg":10767,"ali":96797,"alc":7683,"ald":9255,"ale":82063,"ala":31798,"an ":104955,"aba":35637,"abe":14437,"abi":26160,"abl":18696,"abo":13547,"abr":22582,"ae ":28175,"aca":16009,"ad ":111062,"aga":11365,"ado":272062,"adr":17031,"adi":20049,"ade":31132,"adu":7585,"aco":10755,"aci":224093,"ach":10349,"ace":30766,"acc":10027,"ada":154737,"act":41870,"aza":10801,"ayo":25160,"aya":7832,"ba ":19878,"aqu":8935,"at ":7824,"arg":22636,"are":34407,"ard":31172,"arc":32672,"ara":95441,"aro":19229,"arn":7316,"arm":9270,"arl":13962,"ari":83070,"arq":11629,"arr":48459,"ars":9729,"art":119072,"asa":20743,"arz":11183,"asi":22274,"asc":10580,"ase":16265,"aso":13076,"ar ":100623,"apa":19232,"ape":7495,"api":11786,"apo":11441,"apr":7236,"as ":405615,"ava":9975,"aut":18769,"arí":13656,"avi":12074,"ave":14502,"ay ":13782,"ata":37974,"ast":48943,"atr":18116,"ato":31490,"ate":31650,"ati":40488,"atu":16694,"aun":7152,"aur":9494,"aus":7903,"jer":7889,"je ":13092,"jo ":28253,"ito":98982,"itu":57305,"eña":13429,"iud":31065,"ism":26830,"isl":10534,"iso":8290,"isp":12009,"ist":177840,"ita":90631,"ite":23119,"iti":14600,"ivo":27807,"eño":12432,"iva":29645,"ivi":28311,"ive":26878,"ipo":17187,"ipi":23278,"is ":44742,"ion":119701,"ior":15897,"ios":44527,"ipa":22022,"ir ":23370,"iri":18435,"isi":29089,"ise":10419,"isc":18799,"ire":21390,"ira":17066,"ja ":14889,"iza":56748,"km²":9037,"gía":13787,"gén":19973,"jul":9258,"jun":20993,"jue":11292,"ha ":23020,"ham":8200,"han":11281,"har":13249,"has":16766,"hab":28769,"hac":13453,"he ":23960,"her":16542,"hin":11792,"hil":16082,"his":17036,"ho ":17368,"go ":53446,"glo":15485,"gle":10695,"gla":7868,"gob":7093,"gni":7865,"gió":54574,"cés":10035,"glé":12339,"gon":9593,"gos":23034,"gru":17556,"gra":45297,"gri":10321,"gre":9359,"gui":14307,"gua":27766,"gue":27456,"gur":7400,"gun":20675,"iam":7087,"ial":56085,"ian":52472,"ias":29422,"iar":10235,"ic ":7674,"iac":10109,"iad":14476,"ibl":8505,"ibi":8164,"ibr":11003,"ibu":11957,"id ":12492,"ibe":11766,"ia ":260890,"iet":7563,"iel":8991,"iem":41853,"ien":137287,"ier":54165,"ies":19531,"ied":10903,"ieg":9534,"ifo":15425,"ife":9766,"ifi":21950,"ict":9719,"ico":124072,"ici":106469,"ich":18974,"ice":11245,"ie ":46477,"ica":217183,"ido":115195,"idi":11705,"ide":56950,"ida":143468,"il ":29082,"ige":12181,"iga":13218,"igl":16846,"igi":27180,"igu":25326,"igo":7750,"ign":13613,"imo":21293,"imp":19247,"ime":39882,"imi":27512,"inc":70215,"ind":21266,"ina":105516,"ino":52448,"int":60589,"ins":15850,"inf":13445,"ine":33717,"ing":45586,"ini":36645,"iod":9277,"inv":7546,"ila":17117,"in ":30692,"ilo":12791,"ill":61746,"ili":73439,"ile":24670,"ima":28669,"io ":149275,"día":18502,"hom":8228,"hos":7240,"hor":7815,"hum":8623,"fes":10458,"fer":25898,"fec":9155,"feb":8937,"fam":38352,"ext":18108,"ez ":27186,"exp":10760,"exi":15850,"eza":8196,"eta":35458,"ete":19089,"eti":13610,"esp":91539,"eso":20238,"est":182109,"aña":34948,"año":60064,"eto":13724,"etr":18301,"epú":7797,"eve":10842,"eva":20123,"evo":10163,"evi":21593,"erí":14511,"ey ":19031,"epe":9088,"er ":98611,"epa":47324,"eos":9539,"eor":7614,"eon":7647,"emá":15175,"es ":719197,"ept":16454,"epo":8010,"epr":9962,"elí":11498,"eri":85302,"erg":11010,"ere":38036,"erf":9607,"erc":31567,"erd":14302,"era":127455,"erb":7502,"et ":12616,"equ":18716,"aís":14636,"esi":46520,"esc":45995,"esd":20115,"ese":28957,"esa":79475,"erv":17764,"err":53481,"ert":62557,"ers":52410,"ern":44545,"erm":26731,"erp":8929,"ero":107826,"en ":609899,"ela":41071,"ele":43829,"eli":19783,"ell":40806,"elo":21079,"eo ":20655,"emb":41784,"ema":33787,"eme":18576,"emo":14924,"emi":17348,"emp":34242,"ene":94564,"eng":10179,"ena":41586,"end":51128,"enc":77537,"eno":37094,"eni":23612,"ens":46652,"ent":408861,"enz":9528,"ego":28111,"egi":66647,"egr":10013,"egu":24464,"ein":14332,"eja":7548,"el ":611266,"ejo":12599,"eje":7469,"gin":15815,"gio":12026,"gid":10945,"gic":10164,"gen":57105,"ger":8119,"ge ":11010,"gad":14992,"gas":7988,"gar":19699,"gal":9045,"gan":23906,"ga ":30329,"fue":90978,"fun":22112,"fra":50839,"fre":13616,"fri":7302,"for":59914,"flo":7804,"fic":57976,"fil":9492,"fin":19583,"da ":212873,"de ":1556339,"dad":141389,"dal":9998,"dae":14141,"das":36381,"dar":9501,"dan":12985,"dam":10048,"cul":40621,"cue":32934,"cua":33441,"ctu":33625,"ctr":9939,"cto":44819,"cti":20454,"cte":9828,"cta":10659,"cur":10605,"cuy":7974,"cla":14341,"clu":14576,"co ":135190,"ció":209489,"con":251381,"col":25189,"com":184452,"cor":25629,"cos":36158,"cre":24696,"cri":31616,"cro":8764,"cci":38750,"cea":16334,"ch ":11118,"cer":30048,"ces":71319,"cen":32729,"cep":7727,"cel":19017,"ced":7879,"cha":26138,"cia":152068,"ck ":13234,"cie":87706,"cid":70600,"che":19885,"chi":20475,"cho":21852,"cil":9620,"cim":9340,"cir":8507,"cis":9341,"cit":8942,"ciu":26750,"cin":17134,"cio":103441,"cip":45552,"ed ":10329,"ebr":19067,"eae":10702,"ead":15707,"eal":19761,"eas":12813,"eat":7412,"ea ":28070,"efi":9256,"efe":15631,"ega":22427,"edi":50600,"ede":34956,"eda":21258,"edo":13652,"edr":9154,"ech":18820,"eci":89707,"ece":32005,"ecc":12316,"eca":7852,"ecu":14868,"ect":45028,"eco":21596,"dur":19421,"dor":54124,"don":18997,"dou":11963,"dos":96466,"doc":7141,"duc":27199,"dri":13291,"dra":9547,"dre":11310,"dro":9953,"dic":47817,"did":11186,"dia":35235,"der":49978,"des":90830,"deb":8351,"dec":9801,"def":7698,"del":228490,"den":85908,"dem":11684,"dep":50829,"deo":9414,"do ":341916,"div":13995,"din":11969,"dio":35658,"dir":18800,"dis":80875,"dit":9088,"die":14888,"dif":14152,"rga":23318,"ri ":7113,"rge":24597,"rgo":16017,"ret":23611,"res":140547,"rev":10637,"rfi":8102,"rea":43224,"ref":13241,"rec":55408,"red":15261,"rei":7333,"reg":68764,"rem":14749,"ren":51706,"rel":19501,"rer":18242,"rep":14882,"rda":8172,"rdo":13679,"rdi":9872,"rde":29313,"re ":155218,"rci":19308,"rch":7367,"rce":15953,"rca":25800,"rd ":11954,"rar":15085,"ras":50104,"rat":31492,"rav":8075,"rag":12449,"ran":146320,"ram":21212,"ral":52901,"rab":19532,"raf":7329,"rad":60032,"rac":43442,"rs ":11514,"ros":47929,"rot":15483,"rom":15707,"ron":42744,"rop":32071,"rov":41024,"rod":21257,"roc":21679,"rol":20667,"rof":11386,"rog":9763,"rno":13811,"rna":28042,"rne":12661,"rni":8562,"ro ":146408,"rma":60914,"rme":24156,"rmi":20846,"rla":8699,"riz":10435,"rio":82353,"rit":87431,"ris":26175,"rig":32503,"ril":18939,"rin":44691,"rim":37251,"ria":74022,"rib":16779,"ric":53993,"rid":24912,"rie":40300,"rtí":7814,"ruc":9429,"rup":19339,"rus":10637,"rva":8468,"rvi":10259,"ry ":9879,"rsi":16295,"rso":23313,"rse":13455,"rta":69414,"rto":22364,"rte":83807,"rti":44079,"rtu":12987,"nía":7088,"rt ":11603,"rqu":18224,"rro":28597,"rri":26111,"rre":31796,"rra":36840,"sad":15576,"sal":12684,"san":10863,"sas":11791,"sar":21220,"sa ":86942,"rzo":11621,"sie":10373,"sid":35818,"sic":33044,"sia":21182,"sit":47886,"señ":8377,"sis":26321,"sin":18695,"sio":18884,"sil":10556,"sim":10529,"sig":27477,"scr":25119,"scu":15948,"sde":20004,"se ":142516,"sca":14799,"sco":24677,"ser":42063,"ses":15571,"seg":17308,"sec":10078,"sep":14018,"sen":28636,"sem":7053,"sel":10295,"spu":8777,"spo":14448,"spe":51710,"spa":61850,"sol":12812,"son":47400,"sor":10955,"sos":12831,"soc":12868,"sob":16402,"su ":57230,"st ":10396,"sla":17876,"smo":24196,"sió":31343,"so ":44831,"stá":22167,"ste":88396,"sta":179440,"sto":49757,"sti":69501,"stu":17380,"str":118933,"sub":9390,"sul":7853,"sup":14503,"sus":22170,"sur":23147,"tal":73680,"tag":7515,"tab":14559,"tac":23593,"tad":77862,"tat":7964,"tas":38619,"tar":41661,"tan":67218,"tam":79203,"te ":284941,"tbo":12533,"ta ":179252,"pa ":14872,"pe ":7492,"par":158326,"pas":11530,"pac":12615,"pal":23552,"pan":11657,"pañ":59522,"pec":57888,"pen":14739,"peo":7168,"per":107782,"paí":9997,"pes":10236,"pel":18436,"pla":29458,"pli":11132,"ple":15398,"plo":9048,"pic":11535,"pie":8675,"pin":12467,"pio":24607,"pit":12508,"por":173351,"pop":7479,"pos":33566,"pon":17239,"pol":27348,"pob":43702,"pod":7343,"lés":13215,"po ":39204,"pub":10168,"pti":14042,"lít":16259,"líc":10958,"lín":8248,"pri":52537,"pre":58569,"pro":108338,"put":7419,"pul":11629,"pue":30894,"mát":8971,"más":38263,"mán":10709,"mér":9468,"que":227040,"qui":47867,"quí":8097,"ra ":231606,"mús":8775,"ncé":9514,"ngo":7965,"ngl":22080,"ngu":15031,"ni ":7789,"nge":13697,"nga":8189,"nen":11810,"neo":11720,"ner":65372,"net":8127,"nes":80792,"ng ":18654,"nea":12399,"nec":28654,"nfo":10116,"nez":7381,"nco":17791,"nci":146898,"ncl":10729,"nce":61430,"nch":9730,"nca":12577,"ne ":57285,"ndu":7292,"ndr":12605,"ndo":65513,"ndi":38911,"nde":54981,"nda":66093,"ncu":16386,"nal":70953,"nam":8218,"nan":12157,"nar":27443,"nac":46410,"nad":35305,"naj":8529,"nd ":14500,"nat":21175,"nas":35377,"na ":398062,"ión":292845,"ntó":37020,"nve":10579,"nue":9759,"nto":136463,"ntu":7064,"ntr":93850,"nti":67583,"nta":102723,"nte":292971,"nso":9665,"nst":30664,"nse":26710,"nsi":26727,"nsa":11053,"nt ":24387,"nqu":11277,"ns ":13747,"noc":38585,"nom":49236,"nos":42446,"nor":29422,"nov":19327,"nne":10554,"no ":158177,"nif":10693,"nie":9958,"nid":51044,"nic":69869,"nia":31660,"niz":14512,"niv":15892,"nis":28903,"nit":8537,"nio":20490,"nim":13518,"ogr":18966,"ogo":8779,"ol ":38964,"oce":17267,"och":8312,"oci":56829,"ock":8945,"oco":9047,"oca":41229,"ode":14611,"odi":11580,"odo":26635,"ocu":9100,"oct":12604,"of ":7638,"oda":9018,"oes":12161,"odu":18410,"ofi":7512,"ofe":9434,"oba":8003,"obr":25648,"obl":50514,"obi":12794,"obe":8533,"nza":20160,"ote":14228,"otr":17397,"oto":14558,"ost":31662,"ota":19189,"osi":18739,"ose":15508,"oso":14720,"ovi":57483,"orí":9114,"ove":16922,"oun":14708,"our":10655,"opo":9237,"opi":14838,"ope":13312,"opa":10564,"os ":567590,"opu":9913,"olí":19344,"or ":251715,"orm":64912,"orn":13575,"oro":14041,"orr":19323,"ord":30127,"ore":48358,"org":21075,"ori":66357,"osa":21383,"ort":65622,"m² ":9185,"ora":46259,"ola":30987,"on ":190943,"oli":25682,"oll":17825,"ole":17479,"olo":38775,"olu":11781,"ogí":11606,"ona":104550,"ond":38242,"onc":23216,"onf":9258,"one":74442,"ong":11339,"onj":7098,"oni":32298,"ono":52521,"ons":50424,"ont":59611,"onv":7285,"oma":33534,"ome":21150,"omb":45255,"omi":25678,"omp":41070,"omo":82407,"omu":58045,"la ":610751,"gún":7107,"le ":58880,"lab":11220,"lac":64631,"lad":24486,"lag":7484,"lan":69592,"lam":24610,"lar":41436,"lat":24612,"las":124120,"lbu":12473,"lon":23409,"lom":10655,"lor":23128,"loc":26941,"log":23375,"los":171022,"lme":34946,"lti":12566,"lto":11513,"ltu":9464,"luc":12530,"lug":7366,"lta":15082,"lgu":7617,"lev":15617,"les":91476,"let":11653,"ler":15144,"lem":26257,"len":30658,"leg":14703,"lec":26734,"lea":8424,"lo ":93016,"lla":74669,"lle":47097,"lli":13816,"llo":31751,"ll ":10675,"lit":23261,"lis":29055,"lio":17662,"lin":23082,"lim":8340,"liz":32987,"lic":48449,"lid":38365,"lia":73957,"lib":11554,"lig":10555,"lie":8152,"ma ":72422,"mac":13622,"mad":34215,"mar":42452,"mas":23691,"mal":12192,"man":63359,"may":20759,"mat":18421,"mba":10176,"mbi":42599,"mbr":71287,"me ":12825,"med":24892,"met":16848,"mes":19527,"mer":60276,"men":167009,"mex":7078,"lva":8274,"lus":8634,"mpi":8494,"mpe":21376,"mpr":14573,"mpo":32948,"mpl":23586,"mpu":10144,"mod":10208,"mon":23296,"mor":11861,"mos":17488,"mpa":16447,"ió ":27428,"mus":8143,"mun":83842,"min":50965,"mil":54218,"mis":20947,"mit":22265,"mic":21219,"mie":39274,"mo ":116388,"ién":27517,"zad":34608,"zac":11303,"zan":7115,"zar":10021,"zon":9132,"zo ":17792,"yor":11730,"za ":34624,"ya ":16470,"yo ":17934,"ués":7665,"tín":7356,"tér":8916,"tón":43482,"tán":19529,"xim":7461,"xic":17547,"tá ":17299,"sí ":7618,"rís":7245,"río":10310,"ría":28707,"rón":9102,"via":12659,"vil":17697,"vin":37424,"vic":9152,"vid":23929,"vie":21693,"viv":7676,"vis":25393,"vo ":33305,"vol":10345,"vos":8624,"ver":42481,"ves":9401,"ven":28441,"vel":14981,"ve ":15016,"val":14785,"van":9128,"var":20642,"vas":9770,"vad":11386,"va ":31522,"uye":9933,"uy ":8325,"usi":15007,"use":7793,"usa":13025,"ust":26126,"uso":9699,"uti":16202,"uta":12332,"uto":18658,"us ":49172,"ura":67622,"ure":8908,"urg":11824,"uri":19845,"uro":19849,"ur ":25587,"upe":15682,"upo":17158,"uma":10015,"ume":13099,"unt":24294,"uni":64830,"uno":27366,"unc":10467,"und":48857,"una":267868,"une":8988,"um ":20862,"ult":21405,"ulo":17762,"uli":17880,"ula":47246,"un ":217532,"uid":13351,"uie":12890,"uil":7952,"uin":8672,"uip":8207,"uis":11000,"ueñ":8502,"uit":13101,"uga":15579,"ugu":12215,"uct":12213,"uda":37565,"udi":17314,"ubr":12417,"uca":7683,"ue ":294774,"uce":7415,"ucc":8218,"uci":25554,"uch":12624,"uev":15569,"uer":46622,"ues":36069,"ueg":19032,"ued":16010,"ueb":8677,"uen":38522,"uel":28446,"púb":11593,"ua ":14731,"uat":7912,"uar":13380,"ual":41530,"uan":21270,"ubi":18564,"ubl":12045,"ud ":8479,"uad":38503,"tur":45480,"tul":9339,"tub":10280,"tua":54339,"tud":17240,"tug":8561,"tre":58815,"tra":116327,"tri":81313,"tru":16821,"tro":72914,"to ":261732,"tod":17241,"tos":55424,"tom":10133,"ton":20463,"tor":94895,"til":28629,"tie":38174,"tig":17405,"tir":9162,"tit":18235,"tis":12154,"tin":45124,"tim":14112,"tip":10749,"tio":15498,"tia":11282,"tic":87300,"tid":24642,"tiv":46603,"tem":32370,"ten":66323,"tel":23707,"teg":9394,"tea":9283,"tec":13760,"th ":7178,"tes":66100,"ter":127000,"the":10645,"éti":7504,"éxi":11167,"éne":20764,"én ":28809,"éri":13573,"érm":8428,"és ":45633,"áti":14202,"án ":27367,"álb":11283,"áni":16413,"ás ":40719,"úsi":8717,"útb":7936,"úbl":12344,"ún ":11275,"óni":12420,"ólo":7805,"ón ":361830,"ógi":7057,"ño ":26522,"ños":18182,"ñol":28121,"ña ":43408,"íti":20855,"íst":9984,"íne":7430,"ín ":16078,"ío ":10995,"ís ":12371,"ícu":14416,"ías":8590,"ía ":90214},"n_words":[70286890,82926999,60413548],"name":"es"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/sqi b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/sqi new file mode 100644 index 000000000..fe3fc7a2f --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/sqi @@ -0,0 +1 @@ +{"freq":{"D":2951,"E":2593,"F":3211,"G":3160,"A":5867,"B":4180,"C":1638,"L":2905,"M":4987,"N":3399,"O":1229,"H":1921,"I":3066,"J":1447,"K":6663,"U":1057,"T":3497,"W":518,"V":1916,"Q":766,"P":4792,"S":7666,"R":2957,"Y":251,"X":569,"Z":898,"f":14736,"g":26110,"d":50009,"e":167179,"b":16462,"c":10479,"a":127255,"n":113931,"o":70925,"l":52723,"m":56721,"j":47732,"k":46937,"h":74009,"i":153617,"w":760,"v":25346,"u":51367,"t":143796,"s":94347,"r":123043,"q":14863,"p":40169,"z":11328,"y":8479,"x":1327,"Ë":504,"Ç":673,"Fil":198,"ë":138684,"ç":2147,"Fja":191,"Evr":427,"ο":279,"α":259," l":7602," m":19599," n":36778," o":2746," h":2298," i":13440," j":4180," k":16392," d":18386," e":22497," f":7928," g":6344," a":8088," b":5231," c":3040," z":2178," u":2660," t":29267," v":9770," q":6524," p":21985," s":22399," r":6234," J":1246," K":6396," H":1660," I":2018," N":2979," O":928," L":2729," M":4746," B":3697," C":1374," A":5029," F":3007," G":2987," D":2696," E":2074," Z":866," Y":222," X":455," S":7145," R":2508," Q":712," P":4598," W":483," V":1621," U":882," T":3065,"Gje":385," ç":814,"Gji":334," ë":7724,"Gju":218," Ç":648," Ë":309,"Gja":201,"Fra":312,"A ":555,"For":238,"Da":377,"Co":247,"Ch":193,"Du":229,"Do":262,"Dr":303,"De":624,"Di":445,"Dh":185,"Fe":366,"Fa":366,"Ev":475,"El":231,"Ga":322,"I ":544,"Fr":441,"Fo":342,"Fl":194,"Fj":196,"Fi":584,"BA":277,"C ":177,"Au":418,"Ar":625,"At":240,"Ba":1072,"Af":186,"Am":331,"An":632,"Ai":327,"Aj":203,"Al":611,"Bu":398,"Br":503,"Ca":335,"E ":302,"Bi":247,"Be":668,"Bo":499,"Ku":625,"Ky":228,"Kr":523,"Ko":2407,"Le":440,"Li":756,"La":432,"Lu":465,"Lo":267,"Me":757,"Mi":743,"Ma":1783,"Mu":398,"Mo":476,"Nj":248,"Ni":232,"Nd":207,"Ne":392,"Na":320,"No":435,"Gj":1228,"Gr":581,"Go":208,"Gu":206,"Ha":528,"He":303,"II":206,"Hi":261,"Ho":278,"In":443,"Is":481,"It":205,"Ja":385,"Je":182,"Jo":291,"Ju":322,"Ka":1334,"Kj":278,"Ki":240,"Un":312,"Tu":198,"Tr":315,"To":375,"Pë":415,"Th":341,"Ti":609,"Te":638,"Ta":357,"St":538,"Su":265,"Wi":200,"Vi":295,"Va":291,"Ve":412,"Qe":273,"Pu":185,"Pr":997,"Pe":613,"Pa":1058,"Po":615,"Pi":181,"Kë":300,"Se":537,"Si":523,"Sh":3256,"Sk":218,"Sp":262,"So":375,"Ru":267,"Rr":230,"Sa":579,"Re":810,"Ri":264,"Në":821,"Ro":386,"Ra":365,"Gre":313,"b ":407,"a ":28448,"Xh":218,"i ":33796,"ge":656,"ga":7640,"fj":347,"fl":382,"fi":3904,"fs":1052,"fr":816,"fu":1400,"ft":1033,"fo":1696,"bë":2042,"j ":4723,"hf":238,"he":19006,"ha":4203,"gl":638,"gj":7884,"gi":492,"gu":1606,"gr":2543,"cë":728,"go":1368,"du":2130,"dy":756,"g ":1263,"ea":970,"eb":315,"ec":617,"ed":3466,"de":5126,"di":8348,"dh":17111,"dj":1045,"dm":281,"do":4139,"ds":204,"dr":2528,"ew":200,"ex":233,"eu":592,"ev":3916,"ez":1764,"fa":1842,"h ":2770,"fe":1185,"eh":617,"eg":2448,"ef":474,"el":4768,"ek":4482,"ej":2627,"ei":482,"ep":1848,"eo":855,"en":13277,"em":3767,"et":19558,"es":10616,"er":15019,"eq":1060,"ca":1358,"e ":72317,"br":1628,"bu":1107,"bo":1748,"bj":242,"bl":1253,"bi":2183,"be":1978,"da":2581,"f ":429,"co":479,"ck":313,"ci":4788,"ch":654,"ce":1081,"c ":318,"az":1629,"ay":236,"ba":3411,"d ":2270,"at":11806,"as":8047,"ar":20865,"aq":1562,"av":2909,"au":845,"ak":4327,"al":8585,"ai":935,"aj":4288,"ap":2172,"am":3780,"an":16760,"ac":1088,"ad":3850,"ab":980,"ag":1063,"ah":884,"ae":194,"af":1439,"nu":1486,"nt":6015,"ns":1390,"jë":8682,"no":2581,"nn":299,"q ":809,"ny":268,"nx":351,"oe":253,"of":894,"oc":773,"od":2400,"oa":235,"ob":841,"om":4147,"on":11462,"ok":1665,"ol":4317,"oi":918,"oj":2100,"og":2207,"oh":3303,"ot":2941,"os":4887,"ov":2272,"ou":371,"op":2168,"oo":285,"kë":4598,"or":15900,"oq":456,"r ":22499,"oz":751,"pe":3763,"pa":6781,"pl":799,"lë":3066,"po":4293,"pi":2577,"pj":1679,"lo":4348,"hë":4530,"lm":750,"ll":8126,"ls":381,"lu":2680,"lt":1030,"ly":235,"o ":4990,"ma":6825,"mb":3911,"me":13242,"iç":252,"mi":11206,"mj":687,"mp":1128,"mo":2299,"mr":960,"mt":825,"ms":189,"mu":2606,"p ":820,"na":4803,"nc":1647,"nd":14065,"ne":6011,"nf":360,"ng":8085,"ni":9080,"nj":10024,"nk":623,"jy":374,"jv":200,"jt":2182,"ju":2055,"jr":203,"js":193,"jn":989,"fë":409,"jo":2391,"jm":201,"kj":232,"ki":2183,"ke":4651,"ka":7856,"m ":4929,"ky":261,"ks":1435,"kt":3378,"ku":6445,"ko":7127,"gë":1191,"kr":3597,"kl":551,"km":406,"kn":219,"li":13297,"lk":295,"lj":608,"le":5962,"ld":260,"lg":209,"la":6555,"lb":400,"n ":21363,"hr":608,"hs":268,"hp":932,"hq":3267,"hv":498,"ht":18411,"hu":3735,"hj":1397,"hk":4243,"hi":5167,"hn":261,"ho":1827,"dë":2976,"hm":1740,"id":1902,"ic":1580,"ib":803,"ia":5265,"ih":920,"ig":1500,"if":611,"ie":1546,"hy":320,"k ":3634,"iq":788,"ir":3308,"is":14282,"it":23622,"iu":865,"iv":2165,"ij":2183,"eç":454,"ik":8974,"il":7041,"im":10832,"in":18975,"io":3678,"ip":5685,"je":13383,"ji":4180,"iz":2757,"l ":3714,"ja":7433,"xh":647,"të":37539,"z ":666,"së":6850,"y ":1757,"wa":196,"vl":237,"vj":627,"vi":5977,"vr":700,"rë":7665,"vo":819,"uz":609,"uv":188,"ve":12217,"vd":565,"va":1908,"x ":256,"ui":282,"uj":950,"uk":1866,"ul":3717,"ue":2301,"uf":993,"ug":1106,"uh":1399,"uq":312,"ur":9836,"us":3067,"ut":2692,"um":2889,"un":3916,"që":4381,"up":1314,"ty":1124,"tu":7405,"tt":246,"ub":1079,"ua":6884,"ud":1227,"uc":369,"w ":197,"pë":9674,"to":7414,"tm":513,"ts":310,"tr":5518,"te":16922,"tj":1903,"ti":17731,"th":4122,"v ":372,"tb":272,"ta":11255,"su":1269,"sv":254,"ss":508,"st":7650,"sy":189,"sl":488,"sk":843,"sn":215,"sm":700,"sp":784,"so":3394,"sq":194,"sc":195,"se":5448,"sh":35309,"sj":384,"si":11685,"u ":4144,"sa":3279,"rr":4311,"rs":2938,"rt":4337,"ru":3266,"rv":415,"ry":2015,"rq":210,"rp":488,"ro":7859,"në":24491,"rn":818,"rm":3136,"rl":428,"rk":1734,"rj":983,"ri":20960,"rh":205,"rg":2062,"rf":941,"re":16088,"rd":2048,"rc":625,"rb":1536,"ra":14927,"t ":30601,"qy":921,"qu":769,"më":7228,"qj":229,"qi":4293,"qe":2941,"qa":297,"s ":14264,"pt":2183,"pu":2168,"pr":4557,"ps":322,"zë":930,"zg":391,"zh":1019,"zi":2576,"zb":204,"ze":1031,"za":1391,"zy":222,"zu":773,"zo":1184,"vë":1622,"zj":202,"zm":366,"ye":1323,"yt":1297,"ys":927,"yr":1681,"yp":187,"yn":208,"ym":190,"yl":202,"Art":179,"Aut":217,"Bas":348,"Ai ":287,"Ame":229,"Ber":210,"Bot":188,"Ës":295,"Çm":287,"アアア":185,"ër":16534,"çë":180,"ëp":625,"ëm":1771,"ën":7250,"ël":747,"ëz":648,"ëv":1509,"ës":19082,"ët":3696,"ëh":461,"ëj":261,"ëd":282,"ë ":85317,"çm":262,"çi":247,"çe":269,"ça":442,"ç ":230,"Nob":257,"Per":268,"Pas":194,"Par":336,"Pro":243,"Pri":459,"Pre":232,"Ish":253,"Ita":196,"ア":259,"Jug":202,"Ka ":178,"Kal":215,"Kar":206,"Kjo":277,"Kon":248,"Kom":428,"Kos":1014,"Kor":248,"Ky ":207,"Lig":189,"Mal":292,"Mar":396,"Maq":235,"Mad":210,"Min":180,"Ësh":295,"çmi":226,"ëhe":440,"ëm ":968,"ël ":264,"ëll":356,"ën ":3829,"ënt":362,"ëng":554,"ënd":1225,"ëna":195,"ëmi":309,"ëmb":216,"ëdh":247,"Sta":228,"Shk":524,"Shq":1268,"Sht":446,"Ser":197,"Rep":364,"Në ":708,"Uni":285,"The":241,"Tir":480,"Për":406,"çan":218,"bje":222,"bis":202,"bim":300,"bin":241,"ble":244,"bli":768,"bol":404,"bot":888,"be ":208,"ban":768,"baj":338,"baz":296,"bas":738,"bar":627,"bi ":668,"ber":314,"bel":434,"bet":408,"ca ":491,"cav":177,"cak":266,"ce ":197,"bri":501,"bra":276,"bre":593,"bur":304,"bul":254,"aka":205,"am ":292,"ake":288,"aki":184,"afë":206,"ajo":282,"ajt":819,"al ":1170,"aja":239,"ak ":563,"ahi":215,"aj ":1938,"agj":197,"ago":189,"ano":603,"ant":917,"ans":360,"ane":1253,"ang":643,"ani":2814,"anj":226,"ana":956,"anc":511,"and":1227,"amu":220,"amp":346,"ami":877,"ame":814,"amb":181,"ama":345,"alt":205,"alo":479,"all":1341,"ali":1967,"ale":1756,"ala":461,"an ":2721,"aks":181,"aku":485,"akt":1546,"ako":591,"aba":207,"abe":271,"aft":183,"afi":534,"ai ":361,"adm":223,"adh":1978,"adi":505,"ade":333,"aci":658,"ada":241,"azi":334,"aze":285,"azh":332,"atë":1708,"azë":204,"at ":2869,"arg":323,"are":2127,"ard":768,"ara":2483,"aro":307,"anë":3784,"arm":193,"arl":201,"ark":631,"arj":231,"ari":2009,"aru":212,"arr":782,"ars":590,"art":1488,"asa":351,"asi":536,"ash":2587,"ar ":6112,"apa":246,"alë":446,"apo":1058,"as ":2094,"aqe":844,"aqi":214,"aqj":186,"amë":284,"ava":276,"aut":366,"arë":1850,"avi":245,"ave":2116,"ata":707,"asu":211,"ast":1173,"atr":379,"ato":1090,"apë":205,"ate":982,"ati":2851,"atu":362,"aty":276,"アア":222,"jed":481,"jeo":227,"jer":1714,"jek":498,"jel":290,"jen":1698,"jes":2300,"jet":2586,"jev":418,"ji ":371,"jat":998,"jas":292,"jar":261,"jal":704,"jak":272,"jan":2402,"je ":2467,"joh":964,"jon":213,"fër":208,"jit":1409,"jis":586,"jim":228,"jin":428,"jik":319,"jih":193,"jo ":859,"ito":557,"ipë":1386,"itu":2464,"iud":180,"iso":211,"ist":3511,"iv ":257,"ita":1245,"ite":1604,"ith":1252,"iti":3696,"itj":291,"irë":662,"iut":194,"iva":248,"ivi":385,"ive":1169,"ilë":642,"ipt":1558,"ipi":226,"is ":537,"ion":2522,"ikë":1269,"ior":219,"ipa":1258,"ipe":572,"ir ":232,"inë":1756,"iro":194,"iri":583,"isi":327,"ish":5381,"ise":279,"isa":571,"iu ":213,"imë":180,"ire":227,"ira":796,"it ":11180,"ja ":2116,"itë":896,"isë":2854,"izu":355,"izo":367,"izm":294,"izi":684,"iza":492,"kim":794,"kin":237,"kip":221,"kis":422,"km ":346,"ken":688,"ket":291,"ke ":3158,"kra":414,"kre":377,"kt ":208,"kry":877,"ku ":990,"kro":261,"kru":297,"kri":1336,"kov":192,"gët":303,"kos":230,"kor":588,"kon":2239,"kom":1483,"gël":243,"kol":575,"koh":623,"kod":386,"gë ":240,"ko ":239,"kla":195,"jtë":442,"jut":199,"jtj":180,"jtu":499,"jua":282,"juh":823,"jug":449,"jta":181,"jti":303,"jnë":775,"jt ":307,"kat":718,"kar":404,"kas":189,"kan":1846,"kal":946,"kam":249,"kak":195,"ka ":2506,"jyr":194," Ga":321," Fo":338," Fr":441," Fi":583," Fl":194," Fj":187," Ha":528," He":302," Go":206," Gr":579," Gu":204," Gj":1228," Ho":278,"ha ":1068," Hi":261," Je":182," Ja":384," Is":478," It":205," In":442,"ham":267,"han":292,"hap":354," Ka":1328," Ki":237,"har":380," Kj":278,"has":365,"hat":909," Jo":291," Ju":322," La":426," Le":440," Li":748," Ko":2406," Kr":523," Ku":622," Ky":226," Ma":1780," Mi":739," Me":757,"he ":11876," Lo":267," Lu":464," Nd":206," Ne":390," Na":320," Nj":246," Ni":229," Mo":474," Mu":395,"hek":391,"hel":179,"hej":224,"het":2896,"hes":233,"her":715,"heq":210,"hen":1147,"hem":522,"hfa":178,"hi ":531," Am":329," An":631," Al":605," Ai":327," Aj":202," Af":185," Ba":1069," Au":417," At":239," Ar":624," Be":668," Bi":243,"hin":747,"him":565,"hil":181," Bo":497," Br":498," Bu":397,"his":436,"hit":1517,"hir":335," Ca":327,"hje":1227," Ch":191," Co":245,"hka":488," Da":377," Di":443,"hke":445," Dh":185," De":621,"hki":188," Dr":303,"hkr":988," Do":261,"hko":663,"hku":970," Du":229," El":231," Ev":475," Fe":366,"dë ":206," Fa":359,"cë ":308," Xh":218,"gli":277," Wi":198,"gjë":270,"gon":186,"cës":254,"gos":180,"gor":539," a ":180,"gru":420,"gra":1045,"gri":269,"gre":682," Kë":300," Po":615," Pi":181,"gul":267," Pe":612," Pa":1054," No":435," Ra":364," Në":821," Ro":384," Re":809," Ri":264," Pr":996,"gur":313,"gus":310," Pu":185," Qe":273," Su":263," St":520," Ta":356," Th":340," Ti":608," Te":634," Tr":311," To":373," Pë":415," Rr":230," Ru":266," Sa":578," Sh":3248," Si":519," Se":536," So":373," Sp":261," Sk":217," Va":291," Ve":411," Vi":293," Tu":194," Un":311," ja":2600,"ial":691,"ian":1176," je":756," in":1156," is":1788," it":245," ka":3973,"ibr":249," ki":698," ke":222," jo":218," ju":582," ha":507," he":538," gj":3833," gr":1301,"ia ":2790," gu":290," hi":627," dë":296," ho":209," hu":257," nj":8261," ni":252," ng":5742," nd":3078,"iel":198," ne":1135,"ien":214," na":398,"ier":413," mu":1092," mo":751," of":214,"ifi":230," nu":833," no":407," le":585," li":3581," la":1142," ku":2373,"ici":344,"ich":192," ky":232," km":370,"ie ":357," kl":275,"ica":291," kr":2025," ko":4104," me":6491," mi":1023," mj":371," ma":2979," mb":1927," lu":944,"idi":290,"idh":520,"ide":545," ll":324," lo":338," af":314," ad":323," am":508," an":1204," ap":925," ai":237," aj":220," ak":811," al":253," au":397," ar":1194," at":742," as":478," ba":1617,"il ":230,"ija":200," bi":487,"ije":259," be":279," bo":1013," bu":403,"iju":269," br":668," ca":214," e ":17735,"im ":2164,"eça":298,"ika":1647,"iga":202,"igj":563,"igu":244,"icë":252,"ij ":910,"ihe":650,"ik ":1689,"imo":407," et":343," es":291," en":262," em":840," el":514,"ime":1522," ek":723,"imi":5114,"ip ":230," fe":444,"ind":2986,"ina":1004," fa":908,"imt":634," fu":1154," fs":638,"ino":317,"ijë":223," fr":355,"int":466," fo":1164," bë":626,"ins":260,"inf":213,"ine":1441," fl":312,"ing":422," fj":334," fi":2335,"inj":211,"ini":1146,"iq ":474," ga":620,"inu":257," i ":9701,"iko":537,"iki":386,"ike":2366," ci":2530,"ila":1202," da":481,"in ":7905,"ikt":220,"iku":640," do":799,"ilo":291,"ill":1867," dr":678,"ilm":536," de":1917,"ilj":319,"ili":1491," di":2033," dh":10408,"ile":229,"ima":293," ed":1307,"io ":303," du":817," dy":651,"hpr":194," vë":300," zo":209,"hpe":278," zy":211," za":245,"dës":713," zb":179,"hkë":454," zh":535,"hoq":360,"hor":539,"dër":1831," zg":360," të":19747,"hme":1293,"hul":218,"hua":438,"hty":181,"htu":748,"htr":565,"htm":182,"hti":611,"htj":309,"hte":3639,"hta":810,"hsh":200,"hro":441,"ht ":2187,"hqi":3061," ru":213," rr":1833," u ":1417," sa":775," se":1591," si":4496," sh":10305," sk":290," sp":362," so":432," qu":416," qy":665," t ":287," ra":1563," re":1537," ri":358,"htë":9010," në":16417," ro":441," pu":708," pr":3527," qe":1420," më":4730," os":1270,"hum":1047," kë":1907," or":779,"hur":1522," pe":1738," pa":4231,"hvi":461," pl":373," lë":638," po":2196," pi":398," pj":1282," së":2396," va":567," ve":3244," vd":524," vo":419," rë":271," vi":3777," vj":545," vl":199," ty":371," tu":272," us":358," që":3732," uj":303," ta":476," st":879," su":385," tr":1582," to":411," pë":7156," th":1109," ti":1065," tj":633," te":3252,"fes":283,"fer":357,"faq":704,"fam":375,"fak":216,"ezë":244,"ez ":343,"etë":2083,"ezu":183,"eza":184,"ezo":208,"eze":303,"ezi":227,"eta":1185,"ete":1425,"etj":331,"eti":2581,"eth":892,"eso":355,"est":534,"esv":178,"eto":1111,"etr":567,"etu":501,"eve":3023,"erë":1553,"evi":375,"esë":1317,"epe":182,"er ":1621,"eor":217,"ekë":226,"eqi":478,"es ":2822,"epu":459,"elë":206,"epr":500,"eri":4116,"erg":266,"ere":548,"era":1561,"erb":418,"et ":8412,"emë":345,"esm":180,"esh":1754,"esi":1453,"ese":746,"eu ":239,"esa":635,"err":624,"ert":290,"ers":1252,"ern":432,"erm":871,"enë":512,"ero":390,"eki":248,"ekn":209,"eko":404,"egë":220,"eks":618,"ekt":1016,"eku":676,"en ":3312,"ela":426,"ele":1238,"eli":682,"ell":702,"elu":266,"emb":225,"ema":440,"eme":707,"emo":232,"emi":771,"emr":507,"ene":497,"ena":430,"end":3296,"enc":779,"eno":271,"eni":647,"enj":342,"ens":203,"ent":2477,"eog":217,"egj":763,"ego":445,"ej ":1063,"egu":355,"ek ":360,"eja":234,"el ":689,"ejt":732,"eka":189,"em ":322,"gju":704,"gjy":338,"gje":2061,"gji":3096,"gja":1196,"gim":207,"gaz":249,"gar":602,"gat":279,"gan":669,"ga ":5443,"ftë":453,"fus":270,"fut":207,"fun":698,"fra":187,"fri":223,"fsh":1041,"bër":688,"for":1268,"bët":491,"bëh":244,"fil":1245,"fik":505,"fin":217,"fis":186,"fit":614,"fiz":441,"fja":339,"da ":488," Çm":287,"de ":479,"dal":409,"dat":201,"dar":567,"dan":203," Ës":295,"ces":191,"ci ":188,"cia":487,"cil":2535,"cio":782,"ean":206,"eat":241,"ega":205,"edh":1894,"edi":471,"ede":284,"eda":183,"edo":295,"eci":308," çm":240,"dyt":203,"dy ":376,"dur":609," ës":7645,"dor":1271,"don":593,"dom":180,"dok":214,"dos":301,"dmi":238,"dod":448,"duk":778,"dua":191,"dri":384,"dra":292,"dre":608,"dry":602,"dro":361,"dha":308,"dhu":653,"dia":304,"dhj":875,"dhi":1463,"dhe":12079,"der":1468,"des":314,"det":819,"dh ":431,"deg":199,"del":210,"dek":243,"den":513,"dem":246,"di ":1814,"do ":585,"dhë":1093,"dje":856,"dim":1054,"din":518,"dio":362,"diq":424,"dis":945,"dit":1503,"dik":388,"rga":634,"ri ":4362,"rgj":700,"ret":2035,"res":1012,"rev":322,"rez":402,"rfa":431,"rbë":484,"rfs":234,"rg ":266,"rea":282,"rej":1398,"reg":1272,"reh":210,"rem":230,"ren":1060,"rek":369,"req":525,"rdo":695,"rdi":283,"rdh":548,"re ":5892,"rca":229,"rd ":234,"rap":224,"raq":331,"ras":547,"rat":1584,"rav":877,"rbi":290,"rba":177,"rbe":317,"raj":258,"rah":340,"ran":2020,"ram":546,"ral":554,"rak":530,"rab":220,"raf":580,"rad":1584,"rs ":444,"ror":1129,"ros":215,"nës":866,"nët":322,"rot":314,"rom":357,"ron":1148,"nën":960,"rop":794,"rov":207,"rod":677,"roc":243,"roj":419,"roi":191,"rol":305,"rok":233,"rof":239,"roh":382,"rog":307,"rne":248,"rmo":182,"rmu":349,"ro ":340,"në ":21951,"rmb":202,"rma":1098,"rme":349,"rmi":261,"rku":392,"rko":294,"rki":195,"rke":238,"rja":228,"rje":742,"riz":365,"rip":239,"rio":403,"rit":2857,"ris":2678,"riv":179,"riu":462,"rih":296,"rig":343,"rij":533,"ril":452,"rik":1578,"rin":1760,"rim":1881,"ria":1506,"rie":292,"rk ":231,"rtë":586,"rye":967,"rue":227,"rur":358,"rup":598,"rus":297,"rve":228,"rrë":463,"rsi":760,"rso":384,"rsa":288,"rsh":704,"rse":194,"rta":523,"rto":212,"rte":551,"rth":191,"rti":1091,"rua":870,"rtu":307,"rt ":743,"rmë":369,"rri":1024,"rrj":335,"rre":1446,"rra":326,"rru":264,"saj":699,"san":214,"sat":207,"sa ":1426,"rys":615,"sha":1190,"shm":1425,"sho":753,"shp":846,"shq":1997,"shr":422,"sht":17551,"she":1082,"shf":232,"shi":1551,"shk":3709,"si ":3797,"sje":269,"sid":277,"sia":412,"shu":1255,"sit":1207,"sir":214,"sis":1576,"sip":1484,"sin":587,"sio":712,"sim":613,"sik":262,"se ":3292,"ser":504,"set":189,"sh ":1239,"sen":315,"spo":232,"spe":251,"sot":202,"sov":1143,"son":618,"sor":814,"st ":714,"shë":1713,"sla":211,"ske":209,"sma":252,"sme":323,"stë":596,"sse":192,"ste":1041,"sta":1312,"sto":730,"sti":1254,"stu":543,"str":1367,"sua":229,"sue":178,"sur":369,"sve":238,"taj":547,"tal":816,"tav":260,"tat":899,"tas":209,"tar":4736,"tan":685,"te ":5516,"tbo":238,"ta ":2326,"pa ":427,"pe ":427,"par":1922,"pat":286,"pas":2622,"pak":267,"pan":389,"pi ":351,"per":1941,"pet":184,"pes":328,"pla":231,"plo":258,"pje":1425,"pju":181,"pia":517,"pik":379,"pin":244,"pio":290,"pit":346,"poz":244,"lër":206,"por":810,"pop":489,"lëv":248,"lët":262,"lës":678,"pos":377,"lën":745,"pon":243,"pol":674,"lë ":644,"po ":983,"pta":1447,"pub":598,"pti":317,"pto":261,"pra":544,"pri":797,"pre":1386,"pro":1746,"pun":526,"pul":588,"qar":179,"qe ":553,"qet":282,"qev":185,"qer":357,"qen":825,"qed":256,"qi ":290,"qit":232,"qip":2962,"qis":408,"më ":5423,"mës":389,"mër":628,"mën":311,"qua":358,"quh":192,"qyt":799,"ra ":3887,"ncë":386,"ngj":549,"ngl":339,"ngu":279,"ngr":213,"ni ":1941,"nge":207,"nga":5420,"ndë":2245,"nen":1014,"ner":340,"net":653,"nes":253,"nev":297,"ng ":438,"nez":219,"nci":280,"nce":340,"nca":359,"ne ":2694,"ndu":806,"ndr":1255,"ndo":1605,"ndj":868,"ndi":3173,"nde":1242,"nda":1141,"nal":768,"nar":589,"nd ":1287,"nav":195,"nat":905,"nas":219,"na ":1164,"ntë":218,"nxh":177,"nuk":387,"num":496,"nua":315,"nto":514,"ntr":261,"nti":1877,"nta":460,"nte":1912,"nst":368,"nsi":197,"nt ":562,"nom":633,"non":199,"jës":1000,"jër":345,"nor":452,"nov":244,"një":7204,"jë ":6765,"no ":251,"ngë":383,"nji":251,"nje":980,"nja":288,"njo":1016,"nie":218,"nic":209,"nia":391,"niz":506,"niv":445,"nis":1563,"nit":1162,"nim":624,"nin":724,"nik":917,"ogr":753,"ogj":624,"oi ":722,"ohu":860,"ohe":1613,"oj ":252,"ojn":599,"oje":249,"oja":193,"ol ":185,"oci":316,"odh":931,"ode":218,"odi":416,"of ":206,"odu":227,"ofe":213,"obe":363,"otë":804,"ovë":1008,"ozi":268,"otu":316,"oti":443,"ote":245,"oto":318,"opë":263,"ost":299,"ota":201,"osh":522,"ose":1363,"oso":1152,"ovi":292,"orë":1117,"ova":484,"ove":273,"oqë":260,"opo":219,"opi":438,"ope":206,"os ":591,"opu":565,"kën":763,"okë":307,"or ":3887,"kët":1025,"kës":1506,"kër":189,"orm":1202,"onë":412,"orr":382,"orc":230,"ord":255,"ore":3570,"org":551,"ori":2679,"ort":629,"oru":235,"ot ":268,"ora":318,"ola":251,"on ":2800,"oli":1087,"oll":1071,"ole":276,"olo":874,"ohë":394,"oka":403,"ogë":224,"oku":205,"ona":1138,"ond":187,"one":812,"onj":684,"oni":2539,"ojë":384,"ono":475,"ons":340,"ont":1418,"oma":638,"kë ":735,"ome":460,"omb":682,"omi":782,"omp":538,"omo":183,"omu":542,"la ":1588,"le ":1504,"lan":809,"lam":463,"lar":790,"lat":987,"las":448,"lav":342,"lba":191,"kut":329,"kus":201,"kur":1434,"kup":473,"kun":397,"kul":958,"ky ":230,"kth":196,"kte":440,"ksi":671,"kuf":336,"kua":615,"ktr":411,"ktu":532,"kti":608,"kto":809,"llë":931,"lon":395,"hën":1076,"hëm":639,"lor":960,"hër":431,"log":828,"loj":558,"loi":197,"hës":946,"lot":202,"lmi":262,"ltu":283,"lua":941,"luf":367,"lue":177,"lsi":217,"li ":2003,"lez":179,"lev":346,"les":310,"let":699,"ler":367,"lem":300,"len":674,"lek":623,"lls":213,"llu":548,"hë ":1014,"lla":1048,"lle":383,"lli":2212,"llo":1314,"lm ":208,"lje":416,"ll ":881,"lja":178,"lit":1752,"lis":1010,"lir":324,"lio":179,"lin":3413,"lim":1223,"liz":412,"lic":188,"lid":353,"lia":455,"lib":286,"lik":872,"lig":270,"ma ":556,"maj":406,"mak":224,"mad":655,"mar":852,"mas":295,"mal":684,"man":1367,"mat":1185,"mba":779,"mbl":257,"mbi":849,"mbe":401,"mbr":294,"me ":7511,"mbu":225,"med":203,"met":1333,"mev":393,"mes":776,"mer":1044,"mel":355,"men":1333,"mbë":676,"lum":373,"mpj":180,"mpi":353,"ëtë":434,"mpo":182,"mon":405,"mor":732,"mos":301,"mri":623,"mra":263,"mua":310,"mta":664,"mur":234,"mul":232,"mun":1237,"muz":308,"ës ":6600,"ëpi":229,"ër ":5836,"mi ":2352,"ëse":300,"ësa":205,"ërt":763,"ërs":761,"ërp":333,"ënë":345,"ëro":630,"ërr":212,"mje":546,"ërk":679,"ërm":698,"ërg":545,"ëri":1847,"min":2761,"ërf":795,"mil":488,"mim":764,"ërd":700,"mir":472,"ëra":457,"mis":535,"ërb":763,"ët ":1589,"mit":2427,"mik":541,"mij":213,"ëti":364,"ëto":188,"ëpë":198,"ëta":971,"ësh":8836,"ësi":2416,"ëso":446,"ësu":202,"ërë":456,"ëve":1277,"zua":506,"zyr":215,"zgj":372,"zi ":247,"zet":248,"ze ":310,"zan":199,"zak":278,"zat":320,"vës":631,"zon":428,"zoh":205,"vë ":592,"zmi":236,"zhv":458,"zim":386,"zik":591,"zis":248,"zit":331,"yrë":392,"yte":900,"ysh":673,"yrt":226,"yra":227,"yre":469,"za ":311,"ytë":280,"yes":421,"yer":268,"yeq":202,"të ":32538,"tëp":239,"tër":1782,"tët":229,"tës":1610,"tëv":188,"tën":440,"tëm":288,"xha":211,"xhi":228,"Çmi":287,"së ":5936,"sëm":198,"sën":372,"vro":528,"veç":250,"vil":586,"vin":191,"vic":177,"viz":481,"vit":3504,"vis":321,"vje":622,"rë ":3679,"vog":268,"rën":1295,"rët":460,"rës":1368,"rëv":444,"rëz":253,"vep":456,"ver":1289,"vet":682,"ven":1374,"vel":341,"vdi":416,"ve ":7283,"val":324,"var":488,"va ":428,"uzi":400,"urë":434,"ush":1610,"usi":271,"ust":434,"uti":207,"ute":336,"utb":206,"uto":619,"us ":390,"umë":772,"ut ":820,"ura":1239,"ure":247,"urg":207,"uri":1038,"uro":455,"unë":434,"urr":247,"urt":615,"qër":295,"qës":313,"ur ":4520,"upi":325,"upt":364,"umr":331,"umi":458,"uma":183,"umb":309,"ume":412,"që ":3460,"uni":521,"ujë":192,"und":1633,"una":206,"up ":226,"uku":221,"ukt":232,"uke":519,"ult":579,"uhë":641,"ull":1873,"uli":199,"ula":307,"un ":316,"uk ":422,"ujt":177,"ugo":283,"uft":506,"uhe":480,"uha":223,"udh":352,"udi":562,"ues":1871,"ufi":398,"ug ":248,"ua ":660,"uar":4550,"ual":287,"uan":427,"ubl":681,"uaj":694,"tyr":784,"tur":3146,"tul":217,"tua":1367,"tud":541,"tue":838,"tre":747,"tra":1541,"tri":1729,"tru":612,"tro":732,"tu ":717,"tme":342,"to ":593,"pë ":222,"toj":273,"toh":424,"pës":324,"tom":222,"ton":869,"tok":323,"tol":198,"për":8954,"tor":3712,"tij":916,"til":200,"tik":1967,"tit":3342,"tis":395,"tin":4094,"tim":1479,"tio":325,"thu":272,"tia":238,"tiv":962,"tje":1286,"tja":349,"thë":407,"tem":772,"ten":475,"tek":589,"tel":426,"th ":586,"tev":1136,"tet":4737,"tes":527,"ter":1775,"ti ":2991,"tho":197,"ths":192,"the":828,"thi":467,"tj ":257,"tha":760,"BA ":261,"zë ":417},"n_words":[1760559,2076420,1518161],"name":"sq"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/swa b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/swa new file mode 100644 index 000000000..e745ecba7 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/swa @@ -0,0 +1 @@ +{"freq":{"jer":348,"jen":305,"ji ":6234,"D":1805,"E":874,"F":1081,"G":1202,"A":4461,"B":2717,"C":2251,"L":1530,"M":12761,"N":2782,"O":860,"H":1677,"I":2605,"J":2641,"K":12188,"U":3120,"T":5185,"W":4730,"V":1116,"P":2090,"S":3343,"R":1632,"Y":517,"Z":395,"f":11048,"g":13829,"d":15034,"e":46694,"Feb":214,"b":19688,"c":9784,"a":289584,"n":90468,"o":57043,"l":42025,"m":53651,"j":21456,"k":76835,"h":32492,"i":164978,"w":60984,"v":3863,"u":57506,"t":40551,"s":35298,"r":27443,"p":13501,"z":18893,"y":38832,"x":501,"jar":185,"jan":137,"jaw":201,"é":167,"jim":1500,"jin":4267,"jil":163,"jij":492,"jia":221,"jib":3854,"ito":288,"itu":317,"itw":269,"isp":140,"ist":592,"ita":1061,"ite":213,"iti":334,"ivy":133,"iwa":2430,"ius":183,"ipo":224,"ipi":265,"is ":521,"ion":720,"iop":279,"ipa":165,"ipe":219,"iro":173,"iri":997,"isi":902,"ish":5756,"isa":694,"ire":164,"ira":314,"ja ":1529,"iyo":4644,"iye":227,"izo":242,"izi":413,"iza":568," l":8602,"kif":518," m":27935," n":19872," o":327,"kik":333," h":7652," i":9059,"kij":166,"kim":258," j":5212,"kil":389," k":27977," d":1010," e":802," f":914,"kia":390," g":257," a":6533," b":1252," c":2191,"kiw":279," y":17767," z":2257,"kin":442," u":4361,"kio":148," t":2402,"kip":379," w":34366," v":1482,"kis":520," p":2154,"kit":315," s":6097," r":837,"ki ":2193," J":2627," K":12017," H":1638," I":2128," N":2678," O":803," L":1487," M":12665," B":2646," C":2112," A":4277," F":1046," G":1172," D":1740," E":782," Z":375," Y":513,"и":142," S":3229," R":1588,"а":137," P":2015," W":4707," V":1031," U":3052," T":5117,"kea":156,"kem":150,"ke ":1988,"ku ":187,"kri":520,"kon":141,"koa":3734,"ko ":1214,"ل":165,"ا":240,"juu":155,"jul":257,"jum":177,"kaz":5045,"kaw":137,"kat":14149,"kar":374,"kas":316,"kan":2795,"kao":197,"kal":354,"kam":1048,"kad":160,"kab":375,"ka ":19783," Ga":196,"Da":365," Ge":229,"Co":364," Fr":177,"Ch":770," Ha":622," He":218," Go":142,"Do":469," Gr":177," Gu":142,"De":497,"Di":169,"Fe":311," Id":148,"Fa":160," Hu":173," Ho":177," II":154,"ha ":2668," Hi":392,"Ge":229," Ji":535,"Ga":198," Je":286,"I ":397," Ja":792,"Fr":177," Ir":284," Is":141," It":181," In":316," Ik":143," Il":224,"ham":522,"han":444,"hap":154," Ka":2225,"hai":238,"haj":163,"hak":611,"hal":314," Ke":708," Ki":3568,"har":1714,"has":255,"hat":148," Jo":255,"II ":207," Ju":691,"hag":267,"hab":181,"had":740," La":231," Le":207," Li":441," Ko":414," Ku":695," Kw":4009,"Au":181," Ma":4258," Mb":461,"Ar":475,"As":222," Mk":3388,"Ba":771," Mi":685," Mj":478," Me":615,"Af":445,"he ":544,"Ag":372," Lo":213,"Am":241,"An":463,"Ap":290," Lu":315,"Al":840," Ne":518,"Bu":429,"Br":278," Na":464,"Ca":592," Ni":435,"Bi":308," Mt":420,"Be":362," Mp":146," Mo":643,"Bo":282," Mu":471," Mw":545,"Ku":695,"Kw":4009,"Ko":415,"hez":299,"Le":210,"Li":441,"hes":336,"her":275,"hen":226,"hem":395,"La":231,"Lu":315,"Lo":213,"Me":621,"hi ":3880,"Mi":690,"Mj":478,"Mk":3388,"Ma":4263,"Mb":461,"Mw":546,"Mu":475,"Mt":420,"Mp":146,"Mo":643,"Ni":437,"Ne":518,"Na":466," Ap":290," Am":240," An":463," Al":833,"Ny":247," Ag":372," Af":443,"No":466," Ba":766,"Ok":277," Au":181," As":222," Ar":474," Be":362," Bi":308,"hio":2603,"Gr":177,"Go":143,"hin":1991,"him":244,"hil":432,"Gu":142," Bo":282,"hii":230," Br":278," Bu":429,"his":266,"hir":394,"Ha":622," Ca":582,"hiy":239,"He":219,"II":286,"Hi":393," Ch":768,"Ho":179,"Hu":173," Co":362,"K ":152,"Id":148," Da":365," Di":167,"In":317," De":495,"Ik":143,"Il":226,"Is":141,"It":181," Do":469,"Ir":284,"Ja":792,"Ji":536,"Je":286,"Jo":255,"Ju":691,"Ka":2234,"Has":225,"ho ":334," Fe":311,"Ki":3577," Fa":159,"Ke":708,"Us":172,"Ut":325,"Ur":181,"go ":920,"Un":355,"Uk":150,"Ul":189,"Ui":244,"Uj":249,"Uh":170,"Uf":251,"Uc":175,"Tu":237,"To":205,"Th":275,"Te":258," Wi":3377,"Ta":3841," We":188," Wa":1003,"St":260,"Su":178,"Wi":3380,"Wa":1003,"We":189," Zi":141," Za":152,"Vi":670," Yo":250,"Pr":150,"Pe":270,"goz":233,"Pa":858,"Po":195,"Pi":163,"gom":190,"gon":205,"gos":279,"gor":306,"Se":532,"gu ":424,"Si":424,"Sh":518,"So":239,"Ru":370,"Sa":668,"Re":188,"Ri":138,"Ro":385,"Ra":354," Po":195,"guj":253," Pi":163," Pe":270," Pa":857," Ny":247," No":466," Ok":277," Ra":354,"b ":211," Ro":385,"gwe":166," Re":188," Ri":138,"gwa":280,"guz":429," Pr":150,"a ":143240," Su":178," St":248," Ta":3838," Th":274,"Yo":250," Te":257," To":205," Ru":370," Sa":668," Sh":517," Si":421," Se":528," So":239," Vi":666," Tu":231,"Za":152,"Zi":141," Uc":175," Uf":251," Uh":170," Ui":243," Uj":249," Uk":150," Ul":189," Un":355," Ur":181," Us":172," Ut":325," ja":134,"iak":142,"i ":52347,"ian":874," ji":4522,"ias":364,"ge":1928,"iar":235," je":226,"ga":2900," im":145," in":3363," ik":274," il":4878,"fi":1075,"fr":504,"fu":1927,"fo":752,"ibl":142,"ibi":603," ka":16147,"gw":483," ki":3027,"he":2541,"ibu":4111,"ha":8898,"gl":145,"gi":1836,"gh":1233,"gu":1858,"iba":566," ju":300,"go":2336,"du":838,"dw":136,"g ":607," ha":1606,"ea":1091,"eb":539," he":144,"ec":251,"ed":686,"de":1841,"di":4816,"dh":617,"do":1639,"ia ":9119,"dr":203,"ew":912,"ex":163,"eu":261,"ev":332,"ey":739,"ez":1828,"fa":6104,"h ":704," id":219,"fe":174,"eh":737," hi":990,"eg":644,"ef":303,"ee":307,"el":2120,"ek":2577,"ej":155," ho":139,"ei":650,"ep":643,"eo":1165,"en":9965,"em":2423,"et":1296," hu":4749,"es":2258,"er":4147," nj":147,"ca":364," ni":9330,"e ":10467," ng":147," nd":690,"bw":843," nc":2455," na":6269,"br":408,"bu":5373,"bo":2905," mw":6857,"bl":321," mu":4335," mt":648," ms":331,"bi":2134," mp":280," mo":680," mn":1501,"be":1280," mm":157,"ifu":393,"da":3239,"f ":246,"ifo":606," of":164,"co":390," ny":523,"ck":301,"ci":283,"ch":7388,"ce":365,"ifa":585," le":184,"c ":192," li":859," la":7153," ku":5668,"ich":830," kw":2736," km":140,"ica":140," ko":150," me":184," mf":368,"az":6015,"ay":5308," mi":1257,"ba":6016," mj":5191," mk":1617,"d ":1205,"at":22079,"as":4908,"ar":9773," ma":3449," mb":469,"aw":1490," mc":155,"av":414,"au":1667," lu":341,"ak":14678,"al":8458,"idi":551,"ai":5267,"aj":1998,"ao":6210,"ap":5739,"ide":157,"am":9111,"an":29556,"ac":1224,"ad":3126,"ida":813,"aa":1773,"ab":2568,"ag":1596,"ah":1414,"ae":682,"af":1092,"nu":591,"nt":1270,"ns":4895,"no":1318,"nn":478," am":1335," an":488,"nz":5093," ai":153,"iin":242,"ny":7307," aj":134," ak":183," al":2589,"of":4380," au":941,"oc":308,"od":678,"oa":4118,"ob":631," at":195," as":220,"om":1846,"on":3853,"ok":2328," ba":679,"ol":1930,"oi":1488,"oj":1425,"og":855,"oh":360,"ija":140,"ot":1280," bi":222,"os":1066,"ov":580,"ou":534,"ije":137,"op":845,"oo":318,"or":2938,"iji":1232,"r ":1622,"ow":244,"oz":397,"oy":154,"pe":836,"pa":6921,"po":1264,"ph":151,"pi":2193,"ika":13864,"lo":1408,"lm":337,"Ida":135,"ll":791,"ls":182,"iga":224,"ii ":525,"lu":868,"lt":178,"igh":170,"igi":384,"ly":147,"o ":24303,"mc":173,"igo":169,"ma":8274,"mb":6660,"mh":261,"me":2630,"mf":564,"mk":1733,"ml":210,"mi":3477,"mj":5199,"mn":1546,"mm":321,"mp":578,"ihe":138,"mo":6079,"mr":140,"mt":753,"ms":447,"mu":6394,"mw":6988,"ihi":187,"p ":352,"na":23279,"nc":2788,"nd":5575,"ne":2353,"ng":6858,"ni":24361,"nj":567,"nk":135,"imo":196," es":141," en":369,"ju":713,"imf":161,"ime":354," el":223,"jo":133,"imi":180,"ki":6922,"kh":154,"ind":834,"ke":2748,"ina":8001," fa":353,"ka":45110,"imu":392,"m ":727," fu":177,"kw":3124,"ino":181,"ks":210,"kt":463,"ku":10532,"ins":133,"ko":5804,"ine":479,"ing":1959,"kr":669," fi":274,"ini":4598,"km":156,"li":17984,"le":2997,"ld":221,"lf":159,"la":14880,"lb":250,"iny":275,"n ":3144,"iko":612,"hw":492,"ht":198,"hu":6825,"iki":2488,"hi":11111," ch":2090,"hn":150,"ho":1180,"ila":4379,"id":1813,"ic":1403,"ib":5595,"ia":11251,"ih":490,"in ":378,"ig":1252," da":146,"if":1790,"ie":672,"iku":2496,"k ":628,"ilo":373,"ir":1982,"is":9376,"it":2904,"ill":288,"iu":466,"iv":385,"iw":2556,"ii":989,"ij":1580,"ik":19966," de":224,"ili":8251,"il":13887,"im":4832,"in":17333,"io":4395,"ile":321,"ip":1169,"ima":914,"je":934,"imb":2471,"io ":2960,"ji":17145,"iz":1362,"iy":4997," du":302,"l ":1018,"ja":2368,"z ":191,"wi":1773,"wo":202,"vy":671," za":1702,"y ":1239,"wa":56175," zi":456,"we":2203,"vi":1632,"vu":418,"vo":138,"uz":1451,"uw":2877,"uv":252,"uu":3068," ye":258,"ve":578," ya":17428,"va":328,"x ":213,"ui":563,"uj":4429,"uk":1643,"ul":2575,"ue":357,"uf":741,"ug":901,"uh":626,"ur":1919,"us":3274,"ut":2784,"um":5397,"un":5099,"uo":368,"up":1077,"ty":166,"tu":2287,"tt":391,"tw":473,"ub":1112,"ua":2111,"ud":534,"uc":476,"w ":435,"to":4407,"huk":345,"hul":146,"tl":220,"ts":343,"tr":455,"te":2280,"ti":12092,"th":999,"ta":14867,"su":644,"ss":500,"st":1842,"sw":308,"sl":142,"sk":865,"sm":139,"sp":289,"so":683,"sc":179,"se":5649,"sh":8151,"si":4764,"u ":13704,"sa":7736,"rr":220,"rs":467,"rt":620,"ru":2279,"ry":287,"ro":1786,"rn":619,"rm":257,"rl":223,"rk":320,"ri":8157,"rg":403,"re":3855,"rd":556,"rc":143,"rb":136,"ra":5018,"t ":1231,"s ":3025,"pt":348,"pu":357,"pw":193,"pr":381," sa":589," se":4480," si":369," sh":318," ra":432," ri":188,"hwa":473,"huo":175,"hum":2789,"hun":282,"hus":506,"hur":418,"huu":1333," pe":176," pa":632," pi":931," wa":33135," we":275," vy":396," wi":862," vi":1013," uc":144,"zi":8597,"ze":368,"za":8043," tu":189,"zw":257," us":165," ut":249," up":502," um":247,"zu":272," un":1571," uk":210,"zo":952," ul":573," uh":139," ta":1410,"ye":2395,"ya":24129,"yu":306," to":170," th":289,"yo":5888," te":201,"yi":4283,"Apr":266,"Asi":146,"Aru":195,"far":316,"fam":283,"fan":4203,"fal":292,"fa ":488,"eya":259,"Bah":237,"Bar":140,"eza":1136,"ezo":172,"ezi":237,"eta":229,"ete":154,"eti":253,"est":247,"ett":212,"ew ":355,"evi":165,"ewe":148,"ey ":361,"ewa":358,"er ":615,"epa":149,"es ":640,"ept":299,"eri":650,"ere":660,"era":456,"Afr":406,"esh":359,"ese":306,"esa":279,"eru":498,"Ago":254,"ert":152,"ers":339,"eku":184,"en ":297,"ela":204,"ele":786,"eli":360,"ell":177,"eo ":852,"emb":1055,"ema":157,"eme":314,"emi":276,"emu":365,"ene":704,"eng":671,"ena":283,"end":498,"eno":221,"eni":486,"ens":4087,"ent":441,"eny":1803,"Ali":478,"ege":351,"Ame":158,"ehe":647,"Ana":176,"el ":260,"eke":267,"eka":1754,"giz":193,"gir":232,"gin":349,"gid":165,"ght":136,"gha":925,"gi ":572,"gen":204,"ger":781,"ge ":611,"gaz":140,"gar":155,"gan":693,"ga ":1334,"Cal":307,"fup":194,"Bib":137,"fua":317,"fum":143,"fun":167,"fri":445,"fu ":810,"for":356,"fo ":342,"fil":269,"fik":168,"fiz":146,"da ":1525,"de ":752,"dad":386,"dae":220,"dar":151,"dan":305,"dam":173,"Des":272,"Dar":167,"Chi":216,"Chu":136,"Cha":300,"ch ":165,"cha":2430,"chu":596,"ck ":143,"che":571,"chi":3152,"cho":370,"ed ":154,"ebr":313,"ea ":663,"ei ":346,"efu":197,"edi":297,"ee ":156,"don":150,"dom":308,"dol":151,"dog":335,"dun":335,"dha":302,"dia":330,"dhi":240,"der":146,"deg":261,"del":152,"di ":2661,"do ":429,"Dod":240,"diy":201,"din":291,"dis":387,"dik":302,"ri ":2373,"rez":420,"rea":148,"ref":154,"reh":266,"ren":163,"rek":1672,"re ":305,"rd ":213,"ras":256,"rat":173,"Ni ":218,"New":381,"rai":160,"ran":867,"ram":226,"rab":297,"rad":150,"ron":135,"rog":253,"rne":169,"rni":283,"ro ":593,"riw":166,"ris":508,"ril":300,"rik":1688,"rin":373,"ria":769,"rib":1011,"ric":160,"rk ":191,"ruf":262,"rum":452,"ruk":315,"rus":423,"ry ":194,"rse":228,"Nya":144,"rua":234,"rt ":160,"ru ":273,"sab":458,"sac":139,"san":482,"sas":180,"sa ":5643,"Nov":242,"sha":1745,"sho":271,"she":240,"shi":5099,"si ":1365,"siw":355,"sia":608,"shw":458,"shu":187,"sis":157,"sin":881,"sil":283,"sim":158,"sik":319,"sey":212,"ser":175,"set":147,"Okt":259,"seh":319,"sen":4083,"sem":335,"spa":151,"son":242,"su ":198,"st ":167,"sko":136,"ska":599,"so ":134,"ssa":198,"ste":192,"sta":295,"sto":444,"sti":401,"str":197,"swa":181,"tai":280,"taj":233,"tak":462,"tal":339,"taa":220,"tab":242,"taw":344,"tat":292,"tar":668,"tao":3872,"tan":641,"tam":288,"te ":507,"ta ":6480,"pa ":765,"pat":4120,"pak":235,"pap":248,"pam":300,"pan":895,"pi ":233,"ped":156,"Pap":368,"pia":789,"pil":189,"pin":267,"pis":162,"pit":144,"po ":743,"pte":287,"pri":298,"pwa":189,"Rai":176,"ra ":1932,"ngo":958,"ngi":1065,"ngu":1084,"ngw":363,"ni ":18823,"Iri":209,"nge":937,"nga":1742,"Ita":147,"neo":505,"nes":161,"ng ":405,"nch":2504,"ne ":911,"ndu":263,"ndo":574,"ndi":1835,"nde":1085,"nda":1162,"nak":251,"nal":257,"nam":1855,"nan":221,"nao":1457,"nap":185,"nac":183,"nad":288,"naf":402,"nai":158,"naj":196,"nd ":409,"nat":353,"nas":439,"nay":454,"na ":15738,"Jan":271,"Jam":281,"nya":1379,"Jer":215,"nye":1338,"nyi":4239,"nus":133,"nua":282,"Jim":174,"Jin":277,"nti":403,"nta":151,"nte":177,"nsi":211,"nsa":4269,"nt ":232,"ns ":140,"nne":236,"no ":948,"nji":138,"nja":269,"Joh":134,"nia":4199,"nis":530,"ogo":593,"ois":1291,"oji":173,"oja":1149,"Jul":285,"Jun":259,"odo":288,"of ":150,"ofu":134,"ofa":3991,"oa ":3810,"oan":188,"oba":375,"nza":3817,"nzi":1111,"Kai":144,"Kag":175,"Kal":167,"Kan":354,"Kat":474,"Kas":372,"Kar":232,"Ken":632,"ozi":165,"Kis":329,"Kir":165,"Kit":204,"Kin":148,"Kib":138,"Kia":309,"ote":378,"Kik":287,"Kil":453,"Kim":202,"oto":331,"Kig":295,"Kii":249,"ost":309,"ota":195,"ove":320,"opo":325,"os ":178,"or ":161,"Kon":197,"orn":300,"oro":673,"ore":188,"ori":369,"ort":147,"ora":378,"ola":427,"on ":838,"oli":431,"ole":357,"olo":331,"oka":1580,"oke":163,"oko":236,"oku":141,"ona":230,"ond":383,"one":151,"ong":860,"oni":784,"oma":766,"omb":303,"omi":249,"omo":182,"op ":143,"la ":8089,"le ":1011,"Kwa":3975,"laa":157,"lai":293,"lak":564,"lan":660,"lam":497,"lat":186,"lay":3727,"Kus":393,"lba":165,"kuz":236,"kuw":2713,"kuu":1305,"kut":1795,"kus":492,"kur":190,"kup":186,"kun":409,"kum":210,"kul":297,"kuj":187,"kwe":591,"kwa":2512,"kub":762,"kuf":233,"kuh":134,"kua":620,"kto":308,"lom":136,"loj":136,"lme":241,"Lin":225,"lug":350,"lu ":155,"li ":2787,"lez":192,"lew":193,"lev":140,"les":155,"leo":178,"lem":198,"len":254,"lek":133,"lo ":347,"lla":138,"lle":153,"lli":198,"ll ":147,"lit":241,"lis":337,"lip":257,"lio":738,"lin":627,"lim":922,"liz":411,"liy":4415,"liw":979,"lic":340,"lia":1497,"lik":2742,"lil":529,"lih":179,"lif":397,"ma ":2611,"mb ":139,"maa":449,"maj":397,"mak":522,"mad":206,"mae":140,"mag":342,"mar":439,"mas":613,"mal":159,"mam":161,"man":1055,"mat":406,"mba":3047,"mbi":361,"mbe":389,"mbo":2343,"me ":516,"mbu":267,"mch":170,"met":211,"mer":252,"men":492,"mfa":152,"mez":387,"mfu":373,"Mei":250,"Man":216,"Mar":1940,"Mas":472,"Mag":282,"Mak":206,"Mac":287,"Mbe":273,"mpi":142,"mon":163,"moj":1127,"mpa":160,"Mor":279,"mu ":1602,"mtu":175,"mto":226,"Mic":182,"Mis":147,"msh":144,"mta":228,"mwe":383,"mwi":345,"Mko":3178,"mwa":6205,"Mku":138,"Mji":464,"muj":3839,"muz":374,"mhu":232,"Mtw":147,"mi ":359,"mji":5175,"min":192,"mil":749,"Mwa":460,"mit":295,"mia":630,"mik":321,"mo ":4413,"mku":1038,"mko":539,"mna":1501,"mmo":145,"Wik":149,"Wil":3077,"Wan":148,"zwa":252,"zi ":5785,"zai":249,"zaj":254,"zam":177,"zan":3194,"zal":783,"zar":173,"zo ":612,"zia":533,"zin":815,"zil":197,"zik":548,"zis":240,"一":303,"yof":3874,"yot":286,"za ":2981,"ye ":1320,"yen":237,"ya ":21762,"yar":252,"yan":567,"yao":167,"yam":250,"yak":657,"yo ":973,"yin":213,"yik":3954,"一一":144,"Tan":3407,"Tab":164,"Shi":315,"Sin":201,"Sep":283,"we ":401,"wez":265,"wen":1037,"wim":286,"wil":741,"Sal":197,"vyo":257,"wa ":33121,"wap":4111,"wan":3901,"wal":617,"wam":169,"wak":9923,"way":141,"wat":368,"war":238,"was":172,"wai":2667,"wah":176,"vu ":165,"vya":351,"vil":200,"vin":183,"vit":187,"vis":284,"Rom":180,"vem":244,"Vij":328,"uzi":743,"uza":470,"Uje":235,"uwa":2760,"uvu":174,"ush":417,"usi":1319,"use":183,"usa":176,"uu ":2892,"usu":216,"ust":207,"uso":141,"uti":211,"ute":137,"uta":560,"Uin":218,"utu":215,"uto":1436,"us ":536,"Ung":252,"ura":183,"ure":140,"uri":491,"uru":630,"unz":137,"Ula":150,"upa":554,"upi":311,"umu":162,"umi":484,"umo":2705,"uma":686,"umb":661,"ume":297,"uo ":238,"uni":940,"und":747,"una":1741,"ung":1193,"uku":302,"uko":457,"uki":429,"uka":247,"ulu":258,"uli":1405,"ule":192,"ula":478,"ukw":139,"uhu":267,"uji":4010,"uja":302,"Utu":261,"ugh":514,"ufu":352,"uhi":136,"ugu":137,"udi":174,"ubw":695,"uch":343,"ufa":176,"ufi":189,"ua ":369,"uat":317,"uar":494,"uan":690,"uba":185,"Uch":175,"ty ":146,"twa":450,"tur":369,"tun":270,"tum":424,"Ufa":219,"ts ":214,"tu ":896,"The":164,"tts":142,"to ":986,"tob":268,"tom":167,"ton":281,"tok":1553,"tol":482,"tor":246,"tik":8147,"tis":158,"tin":351,"tio":199,"thu":171,"tia":156,"tem":384,"ten":273,"tel":171,"th ":160,"ter":432,"ti ":2389,"the":225,"thi":213,"biw":209,"bis":191,"bil":315,"bin":256,"bo ":2326,"bli":173,"bor":262,"be ":229,"bam":230,"ban":516,"bal":619,"bah":147,"baa":227,"bab":179,"bay":333,"bar":432,"bao":277,"bi ":662,"ber":216,"bel":151,"bey":251,"bia":222,"ce ":176,"bu ":4649,"bru":221,"bur":149,"bun":177,"bwa":786,"aka":10583,"am ":337,"ake":1982,"aki":644,"aji":1355,"aju":170,"al ":304,"aja":293,"ain":393,"air":222,"ais":2933,"aif":267,"aid":437,"ahi":308,"aha":751,"agh":475,"agu":395,"aoi":1233,"anu":344,"anz":4756,"any":4453,"ano":638,"ann":141,"ant":323,"ans":490,"ane":261,"ang":1660,"ani":7747,"anj":260,"ana":4702,"anc":133,"and":2300,"amu":1047,"amo":1890,"amp":179,"amh":222,"ami":838,"ame":637,"amb":1658,"ama":1868,"ao ":4649,"alo":269,"alm":262,"all":133,"ali":5324,"ale":476,"ala":1026,"alb":152,"an ":1167,"akr":376,"aku":502,"ako":215,"aba":751,"abe":140,"abi":660,"abo":208,"abu":582,"ae ":291,"aad":302,"aan":389,"aal":140,"aam":185,"aar":236,"aa ":361,"afi":303,"ai ":477,"aga":223,"age":227,"afu":225,"aen":162,"ael":172,"afa":411,"ado":269,"adh":288,"adi":1538,"ach":840,"ada":637,"azo":205,"azi":5401,"aza":186,"ayo":638,"aya":4140,"aye":284,"ba ":2178,"are":1998,"ard":317,"ara":2057,"aro":249,"ari":3153,"aru":316,"art":243,"au ":993,"asa":1084,"asi":1169,"ash":895,"ask":665,"ar ":568,"apa":4869,"api":162,"apo":406,"as ":271,"aut":148,"awa":1126,"awi":190,"ata":10070,"ast":167,"ass":197,"ato":634,"ate":225,"ati":9962,"ath":135,"atu":749},"n_words":[1316698,1560317,1165243],"name":"sw"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/swe b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/swe new file mode 100644 index 000000000..a648588e8 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/swe @@ -0,0 +1 @@ +{"freq":{"D":81614,"E":57703,"F":65307,"G":58568,"A":101184,"B":88354,"C":71198,"L":68342,"M":88836,"N":55651,"O":30870,"H":85820,"I":53417,"J":41709,"K":67803,"U":32439,"T":73345,"W":29206,"V":48264,"P":64540,"S":183432,"R":54519,"Y":8819,"X":3563,"Z":5647,"f":573497,"g":796472,"d":1393951,"e":3122256,"b":426497,"c":439610,"a":2769748,"n":2605268,"o":1513455,"l":1576016,"m":1015154,"j":171593,"k":981769,"h":549646,"i":1975038,"w":38244,"v":702277,"u":641405,"t":2130744,"s":2008119,"r":2700083,"q":5367,"p":544314,"z":28076,"y":232177,"x":48501,"Å":5245,"Ö":9894,"é":11827,"å":315734,"ä":562602,"ü":3814,"ö":429328," l":92862," m":210837," n":78082," o":280066," h":123124," i":363557," j":42422," k":154387," d":271388," e":324754," f":359134," g":79790," a":307677," b":150256," c":22076," y":5622," u":95544," t":189989," v":181674," p":161981," s":494735," r":78305," J":40952," K":63008," H":83187," I":43524," N":52283," O":27251," L":64682," M":82331," B":82669," C":63320," A":84049," F":59275," G":56022," D":77148," E":54653," Z":5389," Y":8451,"и":3560,"о":3458," S":163518," R":51071," P":59385,"а":4143," W":28309," V":40400," U":30253," T":68207," å":25155," ä":214016," ö":25267," Å":5217," Ö":9837,"A ":15096,"F ":4011,"Da":13315,"Cl":3705,"Co":16319,"Ce":3786,"Ch":12336,"Ed":3462,"Do":5286,"De":40359,"Di":6082,"Fe":3321,"Fa":6453,"Eu":5433,"Er":5959,"En":12408,"El":5544,"Ge":7613,"Ga":6615,"I ":11291,"Fr":15828,"Fo":6429,"Fl":4338,"Fi":8854,"B ":3976,"C ":5688,"Au":4696,"Ar":9978,"As":4625,"D ":3210,"Ba":14125,"Ad":3948,"Am":3905,"An":15253,"Al":15279,"Bu":5535,"Br":13255,"Ca":15038,"Bi":5634,"Be":16801,"Bo":13961,"Bl":4691,"Ku":4607,"Gö":6526,"Kr":7039,"Ko":8264,"Le":10243,"Li":14030,"La":13793,"Lu":7481,"Lo":9958,"Me":11631,"Mi":11197,"Ma":32867,"Mu":4647,"Mo":11964,"Ni":7405,"Ne":10761,"Na":8237,"P ":3714,"Ny":3435,"No":15326,"Ol":4960,"Gr":10737,"Go":5035,"Gu":8716,"Ha":34281,"He":15981,"II":4483,"Hi":4225,"Ho":12929,"Hu":4943,"K ":4256,"In":13186,"Is":3759,"Ja":10130,"Je":5266,"Jo":15004,"Ju":4068,"Ka":19254,"Fö":6773,"M ":4536,"Ki":6491,"Ke":4271,"Up":4420,"Un":6136,"Ty":4282,"Tu":3610,"US":9839,"Tr":7442,"To":8743,"Th":13440,"Ti":6372,"Te":8278,"Ta":5863,"V ":6654,"Sy":4319,"St":38584,"Sv":20759,"TV":4696,"Su":6305,"Wo":3225,"Wi":9262,"Wa":7328,"We":4981,"Vi":10913,"Va":8115,"Ve":4995,"Pr":8839,"S ":6544,"Pe":11351,"Pa":14568,"Po":7593,"Pi":4124,"Or":4779,"Se":8850,"Sc":5830,"Si":8063,"Sh":4489,"Sk":9057,"Sp":7173,"So":11179,"Ru":3598,"Sa":15777,"Re":10230,"Ri":6924,"Ro":13031,"SA":10320,"Ra":8269,"b ":9647,"a ":475159,"Yo":5029,"Sö":3933,"Vä":9609,"bö":8648,"i ":355245,"fy":6327,"gd":12439,"ge":171880,"gf":3700,"ga":96208,"gb":3970,"fj":3473,"fl":21495,"ff":12688,"bå":4938,"fi":46296,"bä":6295,"fr":73976,"fu":7874,"ft":39725,"fo":44582,"j ":14814,"gy":3273,"he":67749,"ha":96551,"gn":17191,"gl":17131,"gj":3942,"gi":45303,"gh":13879,"gg":27749,"gu":21320,"gt":19887,"gs":51929,"gr":63119,"go":20646,"dt":3864,"du":15217,"dv":9506,"dy":5840,"g ":162227,"ea":25581,"eb":31218,"ec":33642,"ed":130488,"de":463243,"dd":77303,"dg":4171,"df":3528,"di":70271,"dh":3483,"dk":3943,"dj":7587,"dm":5988,"dl":16308,"do":35107,"dn":14977,"ds":66886,"dr":50264,"ew":8421,"ex":20287,"eu":8550,"ev":26002,"ey":12032,"fa":41395,"h ":210556,"fe":29350,"eh":9823,"eg":38958,"ef":28657,"ee":11526,"el":240548,"ek":41076,"ej":4317,"ei":17866,"ep":29857,"eo":14539,"en":790036,"em":80183,"et":324009,"es":162582,"er":632238,"ca":14258,"e ":392431,"by":19363,"br":42376,"bu":29326,"bo":47200,"bl":35898,"bi":33086,"bb":11237,"be":121628,"db":6093,"da":116179,"f ":20176,"cu":4292,"ct":5938,"co":13763,"ck":84782,"ci":26831,"ch":224513,"ce":44300,"c ":6962,"az":4871,"ay":9160,"ba":47465,"d ":342945,"at":219537,"as":105952,"ar":493878,"ax":4752,"aw":3514,"av":157525,"au":25162,"ak":38031,"al":200396,"ai":14768,"aj":13462,"ap":42925,"am":154793,"an":490452,"ac":25353,"ad":157516,"aa":3218,"ab":17368,"ag":71089,"ah":8954,"ae":7341,"af":19685,"nu":26246,"nt":115132,"ns":230163,"nr":8077,"no":73752,"nn":76927,"jö":13694,"ny":12036,"nv":25830,"oe":5372,"of":28837,"oc":231970,"od":38865,"oa":7955,"ob":24414,"om":258987,"on":206933,"ok":32662,"ol":124858,"oi":5452,"kå":10126,"oj":3321,"og":35630,"kä":17405,"oh":11968,"ot":63544,"os":44373,"ov":30611,"ou":23986,"op":33718,"oo":9810,"or":224835,"r ":824959,"ow":7736,"kö":11089,"pe":96760,"pg":3698,"pa":50445,"pl":23211,"pn":3697,"po":41753,"ph":7115,"lä":54929,"pi":19978,"lå":14272,"lo":57125,"ln":12525,"lm":43916,"ll":251645,"ls":70931,"lp":6851,"lv":21024,"lu":27907,"lt":40778,"hö":19038,"ly":18029,"o ":47987,"md":3318,"ma":128458,"mb":42798,"mg":3435,"mh":5236,"me":195253,"mf":8701,"mk":4460,"ml":20883,"mi":57579,"mn":28583,"mm":63704,"mp":23791,"mo":40002,"mr":10561,"mt":14449,"ms":22455,"mu":35770,"my":8276,"p ":30112,"na":190258,"nb":8963,"nc":14129,"nd":274187,"ne":121340,"nf":12519,"ng":233628,"jä":20365,"nh":9404,"ni":141019,"nj":5464,"nk":26276,"nl":21248,"nm":4189,"ju":37966,"jo":14819,"gå":19638,"ki":37850,"kh":15721,"ke":98699,"ka":235170,"m ":249455,"fö":204508,"ky":14497,"gö":7789,"ks":31609,"kt":90094,"ku":21062,"kv":10463,"ko":98732,"kr":52042,"kl":32687,"km":8676,"kn":24158,"li":194145,"hå":8698,"lh":8848,"hä":12770,"lk":26056,"lj":22122,"le":171301,"ld":48550,"lg":7505,"lf":10995,"la":251597,"lb":23488,"n ":932062,"hr":6279,"ht":5130,"hu":27638,"hj":3586,"dä":13148,"då":7895,"hi":28029,"hn":5105,"ho":40609,"hl":4048,"id":81847,"ic":45251,"ib":12524,"ia":49113,"ig":122539,"if":22472,"ie":80770,"dö":42849,"hy":3755,"k ":153527,"ir":29485,"is":203197,"it":107910,"iu":7188,"iv":58134,"ix":3284,"ii":3814,"ik":122112,"il":185111,"im":21187,"in":352330,"io":82024,"ip":11363,"je":24984,"få":5419,"fä":10915,"iz":3965,"l ":174554,"ja":31220,"tä":25279,"xi":4781,"tå":13823,"xt":11670,"sö":12206,"z ":7095,"xa":4078,"xe":8556,"sä":22008,"wi":3916,"så":23262,"rö":18726,"y ":50286,"wa":8836,"we":6979,"vl":8639,"rä":38698,"rå":61767,"vi":89468,"vt":4439,"vu":11778,"vr":3344,"vs":16546,"vn":4095,"vo":9064,"uv":14989,"ve":165060,"vd":3502,"va":154942,"x ":11441,"ui":6645,"uk":16033,"ul":41627,"ue":11748,"ug":17372,"ur":68778,"us":77613,"ut":71499,"um":42001,"un":129135,"up":38948,"ty":33055,"tu":36176,"tt":213949,"tv":19150,"ub":16763,"ua":23575,"ud":29487,"uc":9950,"w ":8904,"to":108377,"tn":19214,"tm":5831,"tl":17707,"ts":67257,"tr":105466,"tg":11122,"tf":8472,"te":298793,"tk":5397,"tj":8416,"ti":267169,"på":66737,"th":27907,"v ":145502,"tb":14691,"ta":250228,"su":13835,"sv":52306,"ss":78482,"st":354837,"sy":19796,"sl":47405,"sk":296865,"sn":10814,"sm":23482,"sp":69363,"so":182040,"sr":7516,"sd":11605,"sc":12968,"sf":11899,"se":125434,"sh":21233,"sg":4215,"sj":15800,"si":100666,"nö":3871,"u ":12792,"sa":104819,"sb":15311,"rr":35803,"rs":138379,"rt":88500,"ru":68780,"rv":15260,"ry":24021,"rp":8643,"ro":113836,"rn":86552,"rm":33875,"rl":42446,"rk":70077,"rj":9549,"ri":267243,"nå":6703,"nä":22292,"rh":9656,"rg":57899,"rf":20073,"re":276377,"rd":70096,"rc":6855,"rb":28710,"ra":275879,"t ":541739,"mö":6674,"qu":3576,"må":14078,"mä":17850,"s ":365755,"lö":8782,"pt":22670,"pu":12367,"pp":63825,"pr":69684,"ps":16974,"vä":52142,"zi":3697,"vå":20606,"za":3995,"yg":18262,"yf":3366,"yc":9359,"yd":14899,"ya":7829,"tö":15637,"yt":14189,"ys":34208,"yr":23125,"yp":6499,"yn":12472,"ym":10053,"yl":9018,"yk":5316,"å ":92466,"äc":6371,"Ös":5286,"ö ":8541,"én":3279,"åv":3406,"ån":81191,"åt":17902,"ås":6794,"år":43331,"åg":13520,"åe":3379,"ål":17121,"åk":8868,"åd":24022,"ät":25342,"äv":21618,"äx":8215,"äm":18322,"äl":34618,"än":82390,"äp":6744,"äs":34864,"är":272645,"äd":8120,"äg":24196,"äk":15670,"öv":17529,"öt":11908,"ör":194602,"ös":15048,"öp":9470,"ön":13721,"öl":7954,"öm":7511,"öj":4231,"ök":5353,"ög":10789,"öd":115283,"一":3570," Ga":6575," Ge":7551," I ":6565," Fo":6382," Fr":15807," Fi":8815," Fl":4322," Ha":34254," He":15951," Go":5001," Gr":10670," Gu":8675," Hu":4927," Ho":12906," Hi":4166," Je":5254," Ja":10108," Is":3740," In":13126," Fö":6755," Ka":19203," Ke":4195," Ki":6438," Jo":14976," Ju":4056," La":13680," Le":10167," Li":13966," Ko":8252," Kr":7023," Ku":4598," Gö":6518," Ma":32732," Mi":11127," Me":11596," Lo":9918," Lu":7453," Ne":10698," Na":8152," Ni":7391," Mo":11908," Mu":4615," Am":3890," An":15211," Al":15206," Ad":3934," Ba":14044," Au":4688," As":4526," Ar":9902," Be":16738," Bi":5612," Bl":4680," Bo":13888," Br":13201," Bu":5515," Ca":14547," Ce":3768," Ch":12294," Cl":3646," Co":16148," Da":13258," Di":6045," De":40274," Do":5127," Ed":3453," El":5523," Er":5935," En":12351," Eu":5425," Fe":3308," Fa":6390," Sö":3929," Wi":9211," We":4953," Wa":7296," Vä":9600," Yo":5022," Or":4762," Po":7530," Pi":4113," Pe":11321," Pa":14488," Ny":3423," No":15289," Ol":4952," Ra":8225," Ro":12950," Re":10191," Ri":6904," Pr":8806," Sy":4310," Sv":20662," TV":4398," Su":6295," St":38280," Ta":5840," Th":13403," Ti":6347," Te":8213," US":9725," Tr":7389," To":8642," Ru":3585," Sa":15732," Sh":4450," Si":8029," Sc":5776," Se":8798," So":11126," Sp":7111," Sk":9040," Va":8077," Ve":4954," Vi":10865," Tu":3571," Ty":4268," Un":6118," Up":4407," ja":13806," få":4608," fä":3840," in":71154," is":5201," ka":33444," fö":177054," gå":6683," ki":4333," ke":3269," jo":4366," ju":20755," ha":54753," he":14640," gi":5926," gr":27602," gu":3989," dö":38312," id":4924," dä":12563," då":6671," hi":6661," ho":7645," hu":13035," ne":4922," na":17184," my":5673," mu":11845," mo":16924," ok":9806," ol":7701," om":30114," kä":11926," oc":192923," of":14077," ny":4446," nu":5991," no":24830," le":9968," hä":8278," li":23241," la":18204," kv":5049," ku":9406," ky":7530," km":5693," kl":6892," kr":12841," ko":48113," me":100026," mi":15594," ma":40584," hö":10368," lo":3574," ad":5086," am":17761," an":46161," ap":9654," ak":3619," al":18398," av":131499," au":10184," ar":19850," at":35597," ba":19765," bi":15445," be":42377," bo":12025," bl":19693," by":8036," br":16393," e ":3326," et":57787," en":197679," el":30240," ef":10304," eg":6206," fe":13408," fa":16157," ex":7709," fu":4697," fr":64090," fo":25076," fl":15697," bå":3785," fi":26001," ge":16400," ga":6755," i ":270663," bö":6965," fy":5095," ce":5878," ci":5961," da":13590," do":7611," dr":6511," de":166176," di":13002," vä":22816," yt":3626," tä":6373," sö":6783," ru":4704," ry":5559," sa":28037," se":37040," sj":9848," si":31916," sm":3812," sl":17774," sk":41581," sp":27636," so":132908," mö":3254," ra":6370," re":30692," ri":11458," nå":5590," nä":11487," ro":9439," pu":3945," pr":32472," ps":3376," s ":6480," mä":6492," må":7724," or":14441," kö":4010," pe":10275," pa":12607," pl":6656," po":22401," lå":10106," lä":20032," rö":4188," så":14446," sä":12510," va":97104," ve":11661," rä":4287," vi":43226," ty":10671," tv":8751," tu":4474," ut":38370," ur":7073," up":19177," un":29257," ta":17457," sy":11768," st":66122," sv":36306," su":3592," tr":20781," to":9251," th":7205," på":64716," ti":85531," te":14430," Ös":5280," år":16994," åt":5457," än":4390," äl":3304," är":187240," äv":12511," ös":4997," öv":12751,"Fin":4121,"Eri":4081,"Eur":4760,"En ":5663,"Eng":3595,"Öst":5201,"Fra":6710,"Fre":3915,"Hel":4484,"Her":3363,"Han":20213,"Har":3270,"Gra":3275,"Ind":4121,"Hon":4948,"Alb":3593,"And":5658,"Car":7211,"Ber":6424,"De ":4186,"Det":11763,"Den":16516,"Dan":4412,"Cha":4718,"Cou":3952,"New":5646,"Nor":12355,"Per":3613,"Pet":3811,"Par":5960,"Pro":3506,"SA ":9788,"Joh":8659,"För":6368,"Kal":4090,"Kar":6529,"Göt":5300,"Lin":4919,"Man":3676,"Mal":3953,"Mar":11224,"Söd":3244,"Wil":4251,"Väs":5464,"Yor":3342,"Sve":19151,"Str":3346,"Sto":17434,"Sta":8398,"Ste":4189,"TV ":4653,"äga":3677,"äge":8468,"ägg":3687,"äck":6350,"änn":6181,"äns":11234,"ämn":7168,"äms":3895,"äng":10799,"änd":34964,"äpp":6344,"Sch":3849,"San":4701,"är ":211888,"älv":4078,"äll":14085,"äkt":7912,"äkn":3856,"äld":3913,"än ":11102,"äve":13254,"ävl":6172,"äxt":6157,"ärk":4071,"ärl":8853,"ärm":4235,"ära":8245,"ärd":6093,"äre":3225,"ärn":6279,"ärs":4830,"äst":24789,"ätt":18556,"åde":18255,"ågo":4233,"åna":9220,"ång":25948,"åll":6899,"ån ":40117,"åre":4622,"åt ":4155,"ård":7005,"år ":24938,"åte":4737,"ått":4014,"Upp":4062,"Tys":3259,"The":8834,"USA":9498,"bis":3915,"bil":16029,"bin":3462,"ble":7136,"bli":9670,"bla":13299,"bok":5630,"bol":12338,"bor":13470,"bbe":3314,"ban":15887,"bas":6749,"bar":10200,"beg":3230,"ber":59590,"ben":7083,"bel":10187,"bes":11143,"bet":17916,"ca ":4920,"ce ":7249,"bri":10671,"bro":7219,"bra":3701,"bre":3338,"bru":13260,"bur":4739,"bun":4581,"bum":12276,"by ":6960,"byg":8032,"aka":4483,"am ":15544,"ake":4072,"al ":27066,"ain":4963,"aj ":9347,"ags":6901,"agn":5084,"anv":11075,"anu":13080,"ano":4964,"ann":22378,"ant":22398,"ans":71523,"ane":7517,"anf":3613,"ang":11657,"ani":15707,"ank":9321,"anl":8379,"ap ":4055,"ana":13418,"anc":5238,"and":127973,"amt":9744,"amm":21193,"aml":16952,"amo":3480,"amn":18156,"amp":5088,"amh":4267,"ami":11713,"amf":3558,"ame":25638,"amb":4074,"ama":6369,"alv":3571,"alt":10698,"als":5130,"alo":3365,"alm":9277,"all":37991,"alk":5184,"ali":21293,"ald":6403,"ale":25866,"ala":19113,"alb":12779,"an ":132556,"akt":15324,"ad ":44388,"aft":3394,"aff":3221,"afi":4365,"aga":8161,"age":18047,"adm":3257,"adi":7918,"ade":78504,"ag ":17369,"ads":8986,"ack":8031,"ach":4677,"ace":4160,"ada":3703,"af ":3707,"at ":35834,"are":94208,"ard":11975,"arb":9854,"ara":27724,"aro":4452,"arn":18125,"arm":4137,"arl":13544,"ark":16487,"ari":37821,"arr":8387,"ars":21054,"art":35107,"asi":5423,"ase":5556,"ask":3632,"ar ":171511,"apa":8845,"ape":7645,"app":4146,"apr":9022,"as ":45411,"ava":3381,"avs":7927,"avi":4830,"ave":5436,"ay ":3818,"av ":125744,"ata":7543,"ast":21648,"ass":11560,"ato":8615,"ate":21603,"ati":48093,"att":63033,"ats":14038,"atu":6856,"aur":3255,"aug":8539,"jer":3396,"jen":6427,"fäl":3203,"fär":6347,"jan":14542,"je ":5239,"jor":7802,"itu":3337,"itt":20776,"ity":3491,"isk":74955,"ism":4171,"iss":12117,"ist":54624,"iv ":6421,"ita":12733,"ite":17827,"iti":20829,"ius":3596,"iva":11600,"ivi":7901,"ive":20061,"is ":19720,"ion":60198,"ir ":3453,"irk":5584,"isi":5287,"ish":4776,"ise":7902,"isa":8098,"ire":6030,"it ":10727,"ja ":4918,"kil":7942,"kiv":4415,"kin":6276,"gån":6463,"går":10145,"kis":6751,"kho":12716,"kel":5730,"ken":19496,"kes":3520,"ker":29895,"ket":13180,"key":3901,"ke ":13529,"kra":8741,"kre":6291,"kt ":28682,"ksa":5304,"ksd":4444,"kro":5638,"kri":26131,"kot":3776,"kor":12173,"kon":20182,"kom":35824,"kol":9820,"ks ":3388,"kna":9166,"kni":12636,"klu":5282,"kla":15409,"kli":6794,"jul":9684,"jun":10738,"jur":5620,"kat":7694,"kar":20696,"kas":4078,"kap":15909,"kan":45226,"kal":21132,"kam":3425,"kad":6591,"ka ":105354,"för":137814,"föd":63483,"ha ":4594,"ham":7622,"han":27562,"hal":5140,"hav":3856,"har":31426,"had":5793,"he ":12764,"hel":8034,"het":17433,"her":10299,"hen":4180,"hem":4216,"då ":5689,"där":12388,"hin":3839,"his":5950,"gli":6286,"gla":6605,"gni":3551,"gna":6982,"gs ":13333,"gon":4582,"gor":4044,"gsk":4034,"gru":20067,"gra":18317,"gt ":15114,"gre":14703,"gst":6826,"gsm":3229,"gus":10096,"grä":4757,"ial":7807,"ian":12040,"ic ":4032,"ibl":3325,"id ":28142,"ibe":3733,"ia ":17620,"iet":8507,"iel":7300,"ien":33298,"ier":11523,"ies":3414,"ig ":23812,"ift":11636,"ick":11163,"ici":4587,"ich":7049,"ice":6107,"ie ":9770,"ica":5181,"ids":4482,"idr":4877,"idn":3610,"idi":9977,"ide":12497,"ida":10207,"il ":15253,"ika":38088,"ige":28072,"iga":25749,"igh":9261,"igi":4197,"igg":9635,"igt":12741,"ik ":16104,"ime":3935,"ind":16350,"ina":18896,"inn":24862,"ino":16003,"int":17796,"ins":22420,"inf":4654,"ine":12860,"ing":135978,"ini":12277,"inl":6319,"ink":4368,"inv":10239,"ike":30688,"ila":3896,"in ":36372,"ikt":12966,"iks":9950,"ilo":5583,"ill":91188,"ilk":6078,"ilm":10451,"ilj":12364,"ili":8683,"ild":15424,"ile":4047,"io ":6788,"ils":3516,"hol":17007,"hon":3609,"hri":3262,"hum":3706,"hus":7589,"huv":8614,"död":37434,"fes":6198,"fer":3302,"feb":8379,"fat":13524,"far":5867,"fam":7188,"fal":3610,"ext":4721,"exe":4418,"eta":15891,"ete":27600,"eti":4494,"esp":9596,"est":29943,"ess":19229,"ev ":6530,"etr":3912,"ets":17582,"ett":72343,"ety":4212,"ew ":5717,"eve":6119,"eva":3607,"evi":3537,"ey ":7588,"elä":5847,"er ":284777,"eor":5154,"es ":68641,"ept":9611,"epp":4218,"epr":4795,"erk":19481,"erl":7951,"eri":65274,"erg":20456,"erh":4470,"enä":3549,"ere":6711,"erf":4436,"era":63522,"erb":6250,"et ":167149,"esk":4221,"esi":7482,"ese":7369,"erv":5509,"err":9816,"ert":13225,"ers":49047,"ern":40094,"erm":7787,"ero":5248,"eki":3784,"eko":7026,"ekt":14604,"en ":561421,"ela":36480,"ele":19021,"eli":7809,"eln":6244,"ell":67565,"els":32415,"elt":6933,"emb":26969,"ema":5588,"eme":8121,"emm":3946,"emo":6706,"emi":7410,"emp":5979,"ene":8729,"enh":4318,"eng":9041,"enb":3805,"ena":11883,"end":16477,"eno":10317,"enn":10256,"eni":7932,"ens":78815,"ent":44100,"enr":3651,"ege":11795,"egi":9515,"egr":5273,"eis":3601,"ein":4280,"el ":33296,"em ":8949,"öte":5512,"gjo":3575,"öst":10660,"git":4157,"gis":8031,"giv":6533,"gin":4809,"gio":4718,"gic":3318,"gif":3672,"örs":34131,"öra":7478,"örb":6194,"örd":7646,"ghe":6517,"öre":25188,"örf":10182,"örj":5505,"örk":3758,"ggn":3889,"gge":11686,"gga":4221,"gi ":4509,"öpi":3748,"ör ":72432,"gen":70552,"get":15734,"ger":32986,"ges":7614,"gel":15568,"gde":4040,"ge ":21010,"ön ":5859,"öm ":3264,"gas":5062,"gar":34878,"gat":4458,"gan":12485,"ga ":26894,"ögs":4071,"ödr":4070,"bör":6225,"frå":39311,"frä":4616,"fte":17736,"fta":8409,"fun":3567,"ft ":9311,"fra":14521,"fri":9705,"for":23834,"fot":7918,"fol":8477,"fle":7024,"flo":3656,"fly":6056,"fic":5656,"fil":11844,"fik":3556,"fin":14513,"fis":3388,"öve":12758,"da ":24533,"dd ":64224,"de ":113906,"dad":11525,"dal":5199,"dag":13716,"dat":8203,"das":4305,"dar":13228,"dan":22463,"dam":6624,"dda":3257,"dde":6028,"cks":6976,"ckh":12838,"ckn":5609,"ckl":6273,"öd ":37381,"öde":6673,"ödd":63162,"ch ":194706,"cer":9280,"cen":9841,"cem":8851,"cha":5427,"cia":6069,"ck ":16616,"cie":3837,"che":9375,"chi":3577,"cir":4840,"cke":18899,"cka":6286,"ed ":60806,"ebo":7090,"ebr":11024,"ean":3203,"eat":4659,"ea ":3260,"efo":3657,"eft":11252,"edl":4748,"edi":6332,"edd":3460,"ede":13539,"eda":22012,"edr":4279,"eck":13530,"eci":3498,"ece":9407,"dvä":3688,"dor":6126,"don":6243,"dom":6715,"ds ":21182,"dmi":3679,"dni":12167,"dst":6539,"duc":4844,"dri":7974,"dra":24350,"dre":6617,"dro":7925,"dsk":11908,"dia":4497,"der":69482,"des":48453,"det":49713,"dec":9237,"del":42235,"den":110439,"dem":7457,"dle":5138,"dla":5392,"dli":4421,"din":7458,"dio":6335,"dis":13125,"dit":3226,"die":4951,"dig":14250,"dju":3500,"näm":4493,"när":11567,"näs":3945,"rga":9150,"ri ":24498,"rgi":4148,"rge":9457,"rgs":6893,"ret":18000,"res":20396,"rev":5759,"rfa":11243,"rds":5163,"rg ":18322,"rea":6436,"red":13615,"reg":14934,"rem":4053,"ren":33831,"rek":11220,"rel":8037,"rer":8988,"rep":9910,"rda":6312,"rdn":3815,"rdi":6203,"rde":19138,"re ":105451,"rbu":4396,"rd ":16211,"rar":16692,"ras":12995,"rat":27144,"rav":4107,"rbe":10058,"rag":4677,"ran":40758,"ram":18971,"ral":14704,"rak":6953,"rab":3374,"raf":9108,"rad":32041,"rs ":30266,"rr ":4068,"rlä":3700,"ror":5868,"ros":5853,"rot":10704,"rom":7155,"ron":11508,"rop":10007,"rov":7683,"rod":8744,"roc":6434,"rol":8031,"rof":6006,"rog":7715,"rna":45582,"rne":7715,"rni":4580,"ro ":5673,"rma":11324,"rme":6990,"rli":7045,"rld":8530,"rle":4342,"rla":6287,"rn ":13803,"rks":6561,"rko":6401,"rki":4271,"rke":8992,"rka":21148,"rm ":4966,"rja":6006,"rl ":5718,"rio":4391,"rit":18193,"ris":26661,"riv":11699,"rig":24904,"någ":4585,"ril":11007,"rik":49805,"rin":29008,"rim":3215,"ria":11330,"ric":6800,"rid":7589,"rie":22621,"rif":3813,"rk ":11840,"rup":12524,"run":19578,"rum":7564,"ruk":6602,"rus":3564,"rva":5265,"rvi":3304,"ry ":6473,"rsk":18149,"rsi":7847,"rso":8438,"rsp":7925,"rsa":13567,"rse":4696,"rta":8444,"rst":26007,"rss":3568,"rte":14318,"rth":3501,"rti":15874,"rua":8438,"rts":3730,"rt ":25088,"rri":6493,"rre":7456,"rra":8312,"sak":4471,"sal":8723,"sam":44053,"san":6209,"sat":10892,"sar":8127,"sa ":10458,"rys":4892,"sho":4590,"shi":4912,"sju":4204,"sie":4171,"sid":6241,"sk ":90513,"sit":12645,"sis":10405,"sin":20425,"sio":10464,"sik":13865,"sig":10296,"sda":5839,"sde":3304,"se ":11017,"sch":5874,"ser":32108,"ses":3294,"set":6663,"sed":10233,"sep":9935,"sen":30980,"sel":3990,"spo":4913,"spr":13840,"slä":13781,"spe":39400,"spa":4154,"som":124363,"son":32242,"sor":7813,"skå":7923,"soc":6710,"st ":46043,"ss ":9668,"sli":3748,"slo":3319,"slu":6612,"sky":3403,"sla":13504,"sle":3801,"ski":13633,"skl":5724,"sko":16207,"skr":17282,"sku":3455,"skt":14119,"sfö":5604,"ska":106537,"ske":8526,"sjö":6673,"sni":4681,"sjä":3770,"sma":7643,"sme":3479,"stå":11548,"stä":10967,"syd":3945,"stö":8124,"sys":5192,"svä":4118,"sse":11502,"ssa":10371,"sso":16553,"ssl":3516,"ssi":9151,"sst":3551,"ssp":3681,"ste":53976,"sta":88293,"stn":5297,"sto":24174,"sti":35352,"stu":7051,"str":43893,"sty":3941,"sva":8262,"sve":36524,"tal":35934,"tag":10048,"tad":34944,"tav":3738,"tat":22284,"tas":6110,"tar":38387,"tan":25694,"tam":3270,"te ":29236,"tbo":6832,"ta ":57380,"pa ":4951,"par":19834,"pas":4154,"pan":9819,"läg":9136,"lär":4866,"läp":5670,"län":20491,"läk":8254,"pen":15225,"per":22100,"pet":5946,"pel":41073,"pla":14119,"pin":6560,"lån":4645,"pis":3811,"låt":5580,"por":8039,"pop":3841,"pos":4574,"pol":17194,"pps":6631,"ppt":7044,"ppl":4401,"ppa":4036,"ppe":13206,"pp ":11986,"pub":4680,"pte":14474,"pru":4841,"psa":5456,"pri":16288,"pre":11182,"pro":27839,"prå":5570,"män":8000,"mäs":4442,"mål":5318,"mån":4648,"ra ":70040,"ngl":9266,"ngr":3616,"ngt":3834,"ngs":25507,"ni ":11042,"nge":55986,"nga":25508,"ngd":5985,"jäl":6437,"jär":7781,"nhe":3391,"neh":3788,"nel":8830,"nen":21817,"ner":30394,"net":14471,"nes":10240,"ng ":83505,"neb":3747,"ned":3616,"nce":6161,"ne ":14860,"ndr":19487,"nds":29703,"ndo":7016,"ndl":5881,"ndi":11752,"nde":95443,"nda":25018,"nal":16599,"nam":15523,"nan":10186,"nar":23024,"nad":14500,"nd ":63041,"nat":21915,"nas":10608,"na ":68634,"ny ":3572,"num":3857,"nus":4249,"nua":9868,"nty":4644,"nto":5785,"ntr":13553,"nti":10623,"nta":12228,"nte":31914,"nsp":4485,"nst":23393,"nss":4316,"nse":13545,"nsi":5055,"nsl":4609,"nsk":92387,"nsa":6209,"nri":3216,"nt ":21290,"ns ":54594,"nom":26142,"nor":19884,"nov":9987,"nne":21868,"nna":22185,"nno":3272,"nni":10650,"nns":9117,"nli":10002,"nn ":5037,"nla":5932,"no ":3529,"nke":3380,"ngå":3281,"nkt":4581,"nkr":3354,"nfö":4263,"nie":10939,"nia":3660,"niv":6000,"nis":23117,"nit":5715,"nio":3817,"nin":62497,"nik":4407,"ogr":10374,"ogi":6891,"ohn":3565,"kän":11729,"oha":5651,"kåd":7525,"ok ":3568,"ol ":3524,"och":189597,"oci":4767,"ock":32660,"ode":11255,"of ":8033,"odu":7243,"og ":7992,"oft":6611,"off":4118,"ofe":5148,"od ":6498,"obe":13311,"nvä":12582,"nvå":8371,"jör":3329,"köp":4602,"ote":5241,"ott":18376,"ots":4197,"oto":5671,"ost":8837,"ota":4879,"otb":6812,"osi":3701,"ose":3675,"oss":3221,"ovi":7790,"ove":12742,"oun":6352,"our":5919,"opp":7590,"ope":5756,"opa":4338,"os ":9800,"or ":33039,"ork":5444,"orm":13532,"orn":10771,"orr":11303,"ord":31398,"ore":8252,"org":22560,"ori":16030,"osa":3703,"ort":28485,"ors":16477,"ot ":11261,"ora":9653,"ola":11528,"on ":79327,"oli":25700,"oll":18015,"olk":10298,"ole":5201,"ols":3442,"olm":16608,"olo":12711,"oly":3210,"oka":3360,"om ":168644,"oke":3223,"okr":4246,"okt":9964,"ona":12877,"ond":7866,"one":32789,"ong":8629,"oni":7172,"ono":6812,"ons":23539,"ont":10940,"oma":9422,"ome":9673,"omb":3421,"omi":4970,"omm":30299,"omk":3355,"omp":5523,"omr":7897,"oms":4749,"op ":3482,"la ":37263,"le ":15487,"lde":11008,"lda":11000,"lds":6297,"ldr":3289,"lac":3318,"lad":21513,"lag":21635,"lan":79933,"lam":3972,"lar":35655,"lat":17536,"las":17797,"lba":3463,"ld ":9319,"lbu":12650,"kvi":3264,"kva":4810,"kus":3478,"kun":6039,"kul":5875,"kså":3945,"kta":4658,"kte":14929,"kti":15289,"kto":12389,"kyr":9176,"gör":5454,"ls ":8684,"lom":6295,"lor":5534,"lod":5577,"log":11812,"los":3900,"lot":3451,"lni":4907,"lme":6188,"lma":4184,"lms":5047,"lti":5165,"lub":5423,"lsk":12154,"lss":5166,"lst":11990,"lta":4364,"lte":4556,"lse":12155,"lsa":4733,"lt ":15274,"häl":3201,"här":4070,"li ":11521,"lev":10258,"les":8492,"let":19531,"ler":49986,"lem":6956,"len":25248,"lek":6522,"led":11323,"lls":18041,"llt":8125,"llv":5128,"lhö":4242,"lla":46043,"lle":53525,"llh":4880,"lli":11251,"lln":3548,"lkr":4019,"ln ":4441,"lke":7097,"lm ":18320,"lje":9323,"ll ":78820,"lja":3349,"lit":24473,"lis":16271,"lin":35763,"liv":5593,"lic":4558,"lia":6013,"lik":14533,"hål":7111,"lig":48482,"lie":9952,"ma ":10795,"maj":9292,"mar":31731,"mas":5427,"mal":5574,"man":40392,"mat":14610,"mbe":28393,"me ":3701,"med":67946,"met":18659,"mes":8746,"mer":42686,"mel":15875,"men":33082,"lva":3742,"lve":7060,"lun":3206,"lut":8771,"lyg":4277,"hög":7787,"hör":6448,"mpi":3263,"mpe":6539,"mpo":3301,"ms ":6348,"mod":5091,"mon":5448,"mok":4020,"mor":4951,"mot":12947,"mt ":8137,"mst":8336,"mrå":8280,"mus":13621,"mun":18113,"mfö":3853,"min":18579,"mil":15426,"mis":6696,"mit":4808,"mli":14006,"mla":4634,"mn ":9157,"mni":3641,"mne":9027,"mmu":16790,"mma":26822,"mme":13993,"vå ":7032,"väg":7022,"vän":13490,"vär":10896,"väs":8080,"väx":7295,"vån":8847,"ytt":4640,"yta":3770,"yst":7068,"ysk":15364,"yrk":11273,"yra":3515,"yde":3835,"yck":8174,"ya ":3709,"ygg":9192,"xte":5064,"tör":12969,"täl":6340,"xem":4510,"tår":5717,"tär":4618,"täv":5108,"söd":5258,"så ":8428,"sån":9241,"sät":7762,"röm":5410,"rör":3335,"vs ":5015,"vud":9343,"rät":6983,"råk":6071,"vik":5560,"vil":12065,"rån":39221,"vin":14334,"råd":11141,"vid":23789,"vit":5788,"vis":16981,"vli":3664,"rän":8989,"räk":4195,"räm":4496,"räd":4698,"ver":61891,"vet":10570,"ven":64039,"vem":8723,"vec":5468,"ve ":6856,"val":12123,"van":15891,"var":99905,"vat":6662,"va ":9694,"uvu":9284,"usi":13675,"use":6334,"ust":23739,"utg":8418,"uti":3815,"ute":6086,"uta":8659,"utt":3405,"uts":5227,"utv":5038,"us ":21399,"ut ":10089,"ura":3453,"ure":6299,"urg":5379,"uri":5728,"urn":5209,"uro":7154,"urs":7342,"ur ":12946,"upp":32257,"umb":4012,"ume":9374,"unt":7357,"unk":5142,"uni":16744,"unn":5336,"und":51074,"ung":19464,"une":3661,"ukt":5611,"um ":17518,"ult":6645,"ull":6732,"uli":10267,"un ":12274,"ugu":9934,"ude":4661,"udi":4906,"uce":4932,"uds":4702,"udo":3784,"uar":18907,"ubl":5383,"ubb":6201,"två":7001,"typ":3540,"tyr":3920,"tys":8073,"ty ":8321,"trö":5020,"tve":6253,"trä":9790,"tur":14907,"tun":3943,"tud":5778,"tyd":4220,"ts ":26900,"tre":12611,"tt ":116227,"tra":36819,"tri":14508,"tru":8774,"tro":12216,"try":3989,"tse":5043,"tsk":5040,"tst":3437,"tta":33856,"tte":27085,"tti":9635,"ttn":5259,"tts":5893,"ttr":3221,"to ":4895,"tni":11444,"tjä":4558,"tna":3229,"tod":3739,"toc":13127,"tog":4722,"tob":9412,"tom":4310,"ton":13637,"tol":5901,"tor":39112,"til":75428,"tik":17763,"tif":5408,"tie":6576,"tig":8660,"tit":6965,"tis":30207,"tin":14073,"tio":41843,"thu":4634,"tia":4024,"tic":3207,"tid":19952,"tiv":14860,"tli":6668,"tla":6760,"tem":18447,"ten":56126,"tek":5853,"tel":9950,"teb":4880,"tec":5494,"th ":6931,"tex":3539,"tet":22695,"tes":9480,"ter":115723,"tgi":4603,"på ":62169,"ti ":13119,"the":7679},"n_words":[31862602,36956776,26222440],"name":"sv"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tam b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tam new file mode 100644 index 000000000..facb43d2d --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tam @@ -0,0 +1 @@ +{"freq":{"D":612,"E":464,"F":392,"G":381,"A":1033,"B":541,"C":1226,"L":485,"M":882,"N":489,"O":332,"H":425,"I":870,"K":359,"T":782,"W":287,"V":311,"P":878,"S":1046,"R":508,"f":1073,"g":1998,"d":2759,"e":8290,"b":1281,"c":2926,"a":10092,"n":6488,"o":5986,"l":4436,"m":3185,"k":952,"h":3181,"i":7588,"w":661,"v":857,"u":3410,"t":6374,"s":4316,"r":6588,"p":2229,"y":1574,"x":422,"ித ":544,"ில ":698,"ிய ":7880," m":283," o":562," d":292," a":454," c":438," t":733," p":559," s":429," r":341," K":344," H":326," I":509," N":361," L":347," M":788," B":464," C":741," A":832," F":341," G":361," D":414," E":381," S":843," R":426," P":727," T":657,"ாங்":593,"ாசி":571,"ாகி":1226,"ாகு":5727,"ாகா":403,"ாக்":2294,"ாகக":726,"ாகப":554,"ாகம":1267,"ாகவ":971,"ாகங":337,"ாகத":594,"ானி":1010,"ாந்":804,"ாநி":2007,"ானத":779,"ாப்":821,"ான்":1998,"ாடு":3023,"ாட்":5816,"ாடல":810,"ாடி":363,"ாடக":761,"ாத்":727,"ாண்":1485,"ாதம":306,"ாது":396,"ாதா":507,"ாதி":637,"ாணப":442,"ாணத":365,"ாஸ்":323,"ிங்":711,"ிச்":643,"ிசை":617,"ிடி":332,"ிடப":478,"ிடம":356,"ிடத":463,"ய":68757,"ம":127919,"ன":81690,"ந":46905,"ப":128120,"த":166688,"ண":25132,"ாரா":410,"ாரி":765,"ா":101548,"ி":184542,"ஸ":4761,"ஹ":1196,"ார்":5370,"ழ":21652,"வ":79830,"ஷ":1166,"ர":109358,"ற":58813,"ல":91486,"ள":62504,"ஏ":2039,"எ":16082,"ஊ":889,"உ":10751,"ஈ":845,"இ":32538,"ஆ":19361,"அ":23958,"ஃ":562,"ாறு":598,"ஞ":2219,"ட":101059,"ாலத":613,"ஜ":3516,"ச":50507,"ங":15929,"ாலம":447,"ாற்":1321,"க":197565,"ஒ":11957,"ஓ":1288,"ஐ":1009,"ாயக":290,"ாமல":357,"ாமி":434,"b ":301,"ாம்":1576,"ோ":14983,"ொ":17674,"ை":61878,"்":437238,"ௌ":348,"ூ":11561,"ாயி":304,"ு":185888,"ீ":8590,"ே":20308,"ெ":21142,"ாரண":513,"a ":854,"ாரத":304,"ாய்":1383,"ாரம":364,"ிகா":518,"ாவட":2380,"ாவத":750,"ாவர":299,"ிகை":370,"ிக்":6769,"ாழ்":1243,"ிகோ":462,"ாவி":3762,"ாவா":383,"ாலு":670,"ாலி":445,"ாளர":1347,"ால்":3272,"ாலை":675,"ாளா":324,"ாளி":348,"ிகள":3325,"ிகழ":507,"ாள்":696,"ிகப":373,"i ":647,"ினை":666,"ge":282,"ினி":620,"ga":286,"ினா":801,"ினர":628,"ினம":287,"ிந்":854,"he":687,"ha":472,"g ":377,"ea":314,"ec":300,"ed":390,"de":481,"di":495,"ிப்":4537,"h ":377,"el":404,"en":840,"em":293,"et":386,"es":700,"er":1464,"ின்":17928,"ca":348,"e ":1989,"da":327,"f ":407,"ct":322,"co":377,"ch":435,"ce":352,"ியே":373,"ியூ":340,"ிரத":942,"ியு":993,"ிரம":574,"ியோ":394,"ியை":838,"ிரப":448,"ியவ":789,"ியல":3188,"ியர":810,"ியி":4273,"ியா":6620,"ியத":1203,"ிமு":497,"d ":748,"at":1135,"as":419,"ியம":1215,"ar":1055,"ியன":1057,"ிமை":522,"ியப":743,"ியக":532,"al":1246,"ai":378,"ap":295,"am":828,"an":1637,"ac":346,"ad":343,"ிமா":411,"nt":654,"ns":302,"of":412,"om":409,"on":1256,"ol":463,"ிடை":404,"ou":276,"or":868,"ிட்":1455,"ிடு":635,"r ":1101,"pa":374,"lo":330,"ll":406,"o ":326,"ma":480,"mb":415,"me":406,"mi":333,"na":737,"nd":662,"ne":446,"ng":642,"ni":455,"ித்":3054,"m ":787,"ிணை":304,"ிண்":482,"li":572,"le":592,"ிதி":409,"la":866,"n ":1450,"ht":310,"hu":372,"hi":390,"ic":779,"ia":502,"ig":354,"is":617,"it":600,"il":395,"in":1071,"io":687,"l ":875,"ிஸ்":689,"y ":837,"ve":327,"x ":278,"ur":632,"us":340,"um":519,"un":283,"tt":320,"to":401,"tr":385,"te":756,"ti":1167,"th":985,"ta":522,"st":661,"se":294,"si":396,"rt":301,"ro":534,"ri":933,"re":684,"ra":1084,"t ":1022,"ீடு":326,"ீட்":724,"s ":1609,"ிரி":3610,"ிரா":1282,"ிர்":1294,"ிறப":627,"ிரை":1621,"ிரே":484,"ிறந":629,"ிறத":2122,"ிரு":4047,"ிறா":398,"ிறி":463,"ிறு":1338,"ிலங":466,"ிலம":1354,"ிற்":1776,"ிலத":1747,"ிலா":649,"ிலு":1997,"ிலி":1089,"ில்":23900,"ிலை":1645,"ிலே":416," த":26595,"ிழக":839," ய":1289," ம":33424," ப":40065," ந":18582,"ிழம":471,"ிழர":540," வ":24461," ல":1016," ர":1685,"ிளை":610," ஸ":454," ஹ":795," ஈ":841," உ":10726," ஊ":885," எ":15892," ஏ":2016," அ":23901,"ிழி":439," ஆ":19313," இ":32484," ச":22093,"ிவந":792," ஜ":2159," ட":1284," ஐ":986," ஓ":1277," ஒ":11946," க":32960,"ிவர":337,"ிழ்":3205,"ிவம":324,"ிவி":1334,"ிவா":521,"ிவு":1106,"ீதி":457,"ீர்":719,"ீன்":337,"ுச்":849,"ுங்":895,"ீவு":404,"ீழ்":360,"ுக்":10659,"ுகழ":319,"ுகி":3737,"ுகா":398,"ுகள":4206,"ுட்":1213,"ுடை":558,"ுடி":1579,"ுடு":653,"ுடன":1030,"ுநா":474,"ுனி":297,"ுபட":358,"ுந்":3187,"ுன்":993,"ுனை":280,"ுப்":4254,"ுது":799,"ுதி":3266,"ுண்":554,"ுதல":2039,"ுதப":476,"ுதன":363,"ுத்":6198,"ுரி":516,"ுரு":740,"ுரை":511,"ுறி":2453,"ுறு":308,"ுறை":2894,"ுற்":571,"ுளா":391,"ுளி":404,"ுள்":6921,"ுமை":377,"ுமு":342,"ுமா":937,"ும்":36442,"ுரம":392,"ுவை":304,"ுவி":1320,"ுவா":2204,"ுவர":1344,"ுவம":286,"ுவன":802,"ுவத":1697,"ுழு":744,"ூடி":578,"ூட்":652,"ூன்":565,"ூரா":577,"ூரி":517,"ூர்":1687,"ூறு":472,"ூலம":428,"ூற்":526,"ூல்":531,"ூலி":289,"அக்":419,"அதி":733,"அதன":471,"அணி":287,"அணு":326,"அடி":812,"அப்":365,"அன்":299,"அனை":343,"ஆகி":979,"ஆகு":4632,"ஆக்":285,"அழை":700,"அவர":558,"ென்":1743,"அல்":2972,"அளவ":598,"ெப்":657,"அரு":474,"அறி":1258,"அமெ":613,"அமை":3884,"அரச":1350,"அம்":318,"ெண்":620,"ஆங்":1422,"ெட்":778,"ெடு":671,"ஆசி":448,"ஆண்":2706,"ஆட்":480,"ஆம்":1544,"ைய ":1236,"ஆய்":339,"ஆரம":608,"ஆறு":307,"ஆற்":386,"இக்":380,"ஆவத":1054,"ஆவா":643,"ேயே":307,"ேட்":292,"இங்":400,"இசை":860,"ேண்":284,"இடத":337,"ேதி":335,"இடம":403,"இடை":433,"இத்":877,"இது":3256,"ேசி":564,"ேசு":307,"ேசப":275,"இணை":776,"இதன":761,"இந்":4776,"ெயர":1260,"ெயற":334,"ெயல":776,"இப்":496,"இன்":581,"ெர்":351,"ெறு":383,"ெய்":2021,"ெரி":1478,"ெரு":1277,"இயற":542,"இயல":277,"ெல்":969,"இம்":396,"இரண":675,"ெளி":2069,"இயக":775,"ெற்":1979,"இயங":307,"இலக":714,"இலங":1277,"இரு":3631,"இரா":2331,"இவ்":582,"இவை":339,"இவர":1304,"ைப்":5756,"இல்":712,"ையை":1039,"ையே":430,"ையத":341,"ையா":3283,"ையி":4758,"ையு":2157,"ையம":618,"ைமை":414,"ைத்":2427,"ைந்":3238,"ைநக":408,"ைச்":1529,"ேளம":371,"ேளக":469,"ேற்":1275,"ேலி":402,"ேலு":410,"ேர்":1922,"ேறு":768,"ேரூ":552,"ேரி":362,"ைக்":5944,"ேவை":525,"ைகள":3265,"்க ":1447,"ைவு":308,"ைவி":438,"ைவர":377,"ொன்":519,"்ப ":344,"ோக்":753,"ொள்":838,"ொழு":386,"ொழி":2875,"ொல்":850,"ொலை":513,"ொற்":349,"்ள ":4240,"ொரு":2529,"்ற ":3387,"்ட ":3672,"ொகு":770,"ொண்":2337,"ொது":899,"்த ":5466,"ொடு":300,"ொடங":359,"ொடர":1238,"ோப்":332,"ோன்":1334,"ோயி":659,"ோர்":868,"ோரி":632,"ோரா":279,"ோவி":367,"ோட்":1097,"ோடு":420,"ோது":603,"்கை":2757,"்கோ":938,"்கொ":643,"்க்":1264,"்கூ":637,"்கு":14044,"்கெ":383,"்கே":554,"்கா":4646,"்கி":8271,"்கள":15575,"்கல":1350,"்கர":1200,"்கவ":322,"்கப":3910,"்கம":1458,"்கத":1249,"்கண":471,"்கட":610,"்கங":350,"்சா":888,"்சி":4832,"்சு":884,"்சை":360,"எல்":437,"எழு":1211,"எடு":356,"எண்":595,"எதி":426,"எனப":826,"என்":8881,"்தா":3028,"்து":12325,"்தி":19739,"்த்":1974,"்தோ":339,"்தொ":367,"்தை":2288,"்தத":1008,"்ணி":349,"்தம":644,"்தப":1133,"்தன":629,"்தவ":959,"்தர":950,"்தல":971,"்பை":508,"்பே":287,"்பெ":966,"்போ":717,"்பொ":819,"்பி":4248,"்பா":4739,"்பூ":376,"்பு":5441,"்ப்":1248,"்பந":489,"்னை":343,"்பன":396,"்னி":1023,"்னா":524,"்பட":14770,"்னு":1025,"்பத":6302,"்பவ":714,"்பம":709,"்பர":1317,"்நி":304,"்நா":1754,"்பக":746,"்னர":478,"்ந்":2122,"்டத":3858,"்டன":373,"்டப":375,"்டம":1689,"்டர":578,"்டங":415,"்ச்":1088,"்தக":679,"்ட்":1036,"்டோ":535,"்டை":1115,"்டு":8476,"்டி":5785,"்டா":1951,"்டவ":480,"்வை":282,"்வத":502,"்வர":423,"்வி":886,"்வா":1151,"்வு":876,"்வே":640,"்ஸ்":867,"்மா":564,"்மன":338,"்யு":285,"்மை":1050,"்மு":410,"்யப":368,"்ளத":1941,"்லு":367,"்லூ":277,"்லி":796,"்லா":1037,"்றை":756,"்ளா":277,"்ளி":589,"்ளன":998,"்லை":579,"்றா":2083,"்றி":2742,"்று":6173,"்லத":2780,"்றழ":440,"்றவ":489,"்றம":405,"்றல":286,"்றத":1488,"்றன":1215,"ஐக்":380,"ஏற்":808,"ஊர்":281,"உரி":362,"உரு":1122,"உறு":409,"உலக":903,"உயி":570,"உயர":401,"உள்":3206,"உதவ":285,"உண்":440,"என ":651,"மக":2002,"மங":313,"மத":1505,"மண":816,"மட":614,"மன":2412,"யல":4462,"யற":1277,"யர":2780,"யவ":955,"ரக":668,"ரச":2387,"ரங":785,"ரட":422,"யா":11572,"யு":3982,"யூ":642,"ரண":1624,"யி":11562,"யீ":287,"ரத":2928,"ரப":1866,"யே":1284,"ரன":414,"யை":1942,"ரம":3652,"ய்":4254,"யோ":852,"மய":595,"மம":514,"மற":2418,"மர":1631,"மல":1338,"யக":1931,"யங":868,"மா":15034,"மி":8348,"மீ":1286,"மு":9054,"மூ":1942,"யத":2022,"மெ":1524,"மே":3645,"மை":8679,"யன":3058,"யப":1368,"மொ":2460,"மோ":314,"ம்":59753,"யம":2603,"பங":437,"னவ":812,"பக":2737,"னல":278,"னர":2255,"னம":1302,"ந்":20330,"நோ":770,"னப":1121,"பன":834,"னை":2914,"னே":371,"பந":774,"பத":7767,"பண":1265,"னு":2330,"னி":5915,"னா":2676,"பட":17323,"னக":412,"நவ":322,"நல":298,"நே":639,"நெ":1117,"நு":803,"நீ":1405,"னத":1823,"நூ":1307,"நி":7179,"னட":305,"நா":7474,"னங":575,"ப்":34661,"பொ":3990,"போ":3721,"பல":2780,"பள":417,"பழ":657,"பவ":1066,"னோ":401,"பம":782,"ன்":48370,"பய":2032,"பர":3306,"பற":996,"பூ":994,"பே":2341,"பெ":6101,"பை":873,"பி":11022,"பா":9941,"பு":9453,"பீ":476,"தை":3979,"தோ":1044,"தொ":4546,"தே":2805,"தெ":1540,"த்":34813,"தழ":321,"தவ":1763,"தூ":638,"தீ":1160,"து":39998,"தா":7230,"தி":33129,"தப":1845,"ணை":1673,"தன":4207,"தந":348,"தத":1637,"தள":614,"தல":4546,"தற":1613,"தர":2410,"தய":384,"ண்":13361,"தம":6359,"நட":1795,"நக":2290,"ட்":26642,"டோ":698,"டே":309,"டை":5277,"டெ":379,"டு":23773,"டி":13483,"தட":432,"ணா":409,"ணி":3340,"ணு":927,"தக":1336,"ணவ":477,"தங":477,"ணம":1051,"ணர":362,"ணத":619,"ணப":596,"ணக":587,"ணங":275,"ாக":19861,"ாங":594,"ாச":1598,"ாஜ":510,"ாட":11489,"ாத":4020,"ாண":3622,"ான":10191,"ாந":3098,"ாப":1499,"ார":8693,"ாற":2311,"ாம":3725,"ாய":2982,"ிக":14337,"ாழ":1765,"ாவ":8717,"ால":7588,"ாள":3674,"ாஸ":333,"ிங":712,"ிச":2403,"ிஞ":334,"ித":5697,"ிண":920,"ிட":5029,"ிம":2804,"ிந":1298,"ிப":5786,"ின":22037,"ிள":1636,"ிழ":6094,"ீக":398,"ிவ":5662,"ிய":32313,"ிர":16244,"ிற":8462,"ில":35051,"ீட":1354,"ிஸ":713,"ீச":331,"ீத":858,"ீன":904,"ுக":21093,"ீழ":591,"ீவ":685,"ீர":1646,"ுட":5430,"ுங":895,"ுச":1183,"ஸ்":4460,"ஹா":281,"வந":1310,"வன":1956,"ழை":1756,"வப":343,"வர":10633,"வம":1198,"ழ்":5992,"வள":1206,"வழ":1620,"வற":1169,"வல":1808,"வக":1767,"வச":597,"வங":465,"ழி":4553,"வட":4450,"ழா":328,"வத":5184,"வண":714,"ழு":3446,"வெ":3428,"வே":3105,"வை":3927,"வோ":475,"வ்":1486,"ங் ":289,"வா":8141,"வீ":991,"வி":15999,"வு":6267,"ஷ்":653,"ரோ":1002,"றப":1173,"ரை":4461,"றன":1468,"ர்":31916,"றம":626,"றத":3830,"ரூ":812,"ரு":27373,"ரீ":451,"ரே":1017,"றந":763,"ரெ":389,"றங":282,"ரா":8822,"ரி":12841,"ரல":936,"ரள":279,"ரர":859,"றக":313,"ரவ":1332,"லப":708,"லய":334,"லம":3186,"ற்":17148,"லர":750,"று":11549,"லத":5640,"றை":4508,"றா":2833,"றி":8018,"றல":363,"றழ":451,"லக":2902,"றவ":909,"லங":2178,"ளர":1895,"ல்":45274,"ளம":1268,"லோ":710,"ளப":432,"ளன":1049,"லை":8052,"லே":726,"ளத":2348,"லூ":633,"லு":4434,"லா":5224,"லி":6034,"ளங":419,"ளக":843,"லவ":809,"ழர":599,"ழல":340,"ள்":22645,"ழம":740,"ளை":6098,"ளி":11162,"ளு":3887,"ளா":3042,"ழங":730,"ழக":1857,"ளவ":1419,"எழ":1223,"எல":532,"கமா":1059,"கம்":3148,"என":11165,"எட":532,"எண":597,"எத":529,"கரத":596,"கரம":753,"கரா":588,"கரு":1925,"கரி":702,"கரை":390,"கர்":1591,"ஊர":477,"கற்":356,"கலை":1083,"உய":994,"உர":1677,"உற":823,"உல":1062,"உள":3281,"கலா":280,"கழக":436,"கல்":1081,"களை":4493,"கள்":9772,"களி":6714,"களா":1687,"ஈழ":284,"களு":3253,"உட":908,"உத":494,"உண":848,"இம":448,"கழ்":778,"இந":4780,"இன":1053,"இப":504,"இவ":2571,"இய":2152,"இர":7002,"இற":478,"இல":3110,"கவி":404,"கவல":360,"இட":1530,"இண":833,"இத":5637,"இங":400,"இச":1168,"ஆய":571,"ஆம":1554,"ஆற":784,"ஆர":1083,"ஆவ":1949,"இக":392,"கவு":1099,"ஆன":368,"ஆப":334,"ஆட":604,"ஆண":2834,"ஆங":1423,"அவ":1452,"ஆச":513,"அர":2426,"அம":5128,"ஆக":6177,"அழ":1041,"அள":802,"அல":3618,"அற":1466,"அந":302,"அப":488,"அன":910,"அண":903,"அத":1978,"அட":1678,"அச":379,"அக":783,"ஃப":444,"காண":1037,"காத":305,"காட":1197,"காக":926,"கிப":294,"கிர":1793,"கிற":2778,"கிய":4454,"கிழ":1101,"கில":2584,"கிள":303,"டங":1551,"டக":2338,"ஞர":411,"ஞ்":1568,"கான":927,"டம":3786,"காப":476,"டப":1246,"டன":1702,"காம":341,"கார":1102,"கால":2029,"டத":5604,"கிக":280,"காவ":696,"டா":3183,"கிட":434,"டவ":894,"டற":287,"டல":2022,"கின":3040,"டர":1996,"குள":472,"குர":499,"குற":3053,"ஜன":765,"கும":15556,"குழ":660,"குவ":564,"கூட":1198,"ஜெ":307,"ஜி":368,"ஜா":311,"குக":975,"கீழ":409,"ஜூ":479,"குட":1461,"குப":912,"குத":3019,"சட":699,"சந":447,"சன":838,"சத":750,"ங்":15912,"சம":2542,"சர":1035,"சப":743,"சல":387,"சீ":884,"சு":4739,"சா":3736,"சி":12172,"சை":2278,"செ":5006,"சே":2116,"கூற":724,"சூ":935,"ச்":6667,"சோ":703,"சொ":1085,"கெட":300,"சக":830,"சங":473,"க்":40970,"கைப":322,"கோ":3746,"கொ":4347,"கே":1313,"கை":5279,"கைய":1982,"கெ":595,"கைக":801,"கூ":2267,"கு":33794,"கீ":677,"கி":19030,"கா":10953,"கவ":2505,"கொல":275,"கொள":837,"கொண":2252,"கொட":399,"கம":4718,"கர":7242,"கற":456,"கல":3250,"கள":26914,"கழ":1431,"கன":1126,"கப":5340,"கட":3472,"கத":3423,"கண":2578,"கக":1180,"கச":448,"கங":1149,"ஒன":2135,"க்க":31923,"ஒர":8154,"கோர":492,"கோய":755,"கோவ":374,"ஓர":763,"கோட":700,"ஒல":300,"ஒள":283,"கோண":286,"ஏற":1035,"ஐக":383,"க்ட":361,"சக்":631,"்ட":31792,"்த":54197,"்ண":1523,"am ":356,"்ந":4822,"்ப":46615,"்ன":4757,"்க":63255,"்ச":10386,"al ":518,"ோம":420,"ோய":1038,"ோர":2106,"ோற":374,"ோல":725,"ோவ":577,"ோட":1840,"ோப":835,"ோன":1596,"ோத":1196,"ோண":311,"ொர":2700,"ொற":791,"ோச":380,"ொழ":3265,"ோக":1274,"ொல":1580,"ொள":880,"ொட":2489,"ொன":573,"ொண":2347,"ொத":1247,"ொக":1140,"and":321,"an ":334,"்வ":6141,"்ஸ":1010,"்ல":6654,"்ற":20507,"்ள":9314,"்ம":4103,"்ர":1658,"்ய":1630,"சு ":1200,"ூன":663,"ூத":353,"ூர":3051,"ூற":1305,"ூல":1999,"ூழ":431,"ுந":4175,"ுண":1116,"ுத":14095,"ுய":369,"ுர":3253,"ும":39489,"ுன":1831,"ுப":5592,"ுவ":9858,"ூக":634,"ுழ":1268,"ுள":8293,"ுல":1485,"ுற":6692,"ூட":1699,"ைவ":1932,"ைந":3816,"ைப":6286,"ைய":15390,"ைம":945,"ேல":1655,"ேற":2141,"ேர":3972,"ேய":740,"ேவ":930,"ைக":9533,"ேள":1091,"ேன":443,"ேம":327,"ைத":2725,"ைச":1726,"ெள":2310,"ெல":1418,"ேக":639,"ெய":4586,"ெற":2754,"ெர":3220,"ெப":689,"ென":2012,"ேண":375,"ேத":757,"ேட":601,"சி ":2531,"ேச":2248,"ெக":289,"ெண":621,"ெட":1667,"சை ":644,"ச் ":3259,"ati":457,"ஒளி":281,"ஒலி":275,"ஒரு":7842,"ஒன்":2133,"கே ":463,"கை ":1667,"கா ":505,"ச ":506,"க ":8647,"கு ":5427,"கி ":1073,"கச்":348,"ா ":4799,"ி ":16257,"கங்":1149,"ீ ":453,"ு ":58822,"கக்":1119,"ே ":3658,"ை ":18418,"ோ ":1470,"் ":167861,"கன்":508,"கப்":5197,"கணி":938,"கண்":880,"கத்":2578,"கதை":393,"கணக":371,"கடல":480,"கட்":1973,"ட ":4634,"ண ":792,"த ":6809,"ஓர்":624,"ன ":8248,"ப ":465,"க் ":7275,"ர ":1232,"ய ":9777,"ம ":541,"ழ ":296,"ள ":4773,"ல ":2350,"ற ":3775,"வ ":559,"ஜன்":468,"ion":604,"டி ":2152,"டா ":281,"டு ":6809,"ஜூல":309,"டை ":967,"ட் ":1325,"சங்":473,"he ":350,"சத்":482,"சட்":614,"சமய":437,"ங்க":15531,"சம்":940,"சமூ":398,"சன்":386,"சப்":396,"சந்":419,"சர்":489,"சிவ":528,"சில":849,"சிற":1550,"சிர":415,"சிய":2735,"சிப":459,"சின":560,"சித":585,"சிங":311,"சிக":977,"சால":592,"சார":993,"சாத":575," of":373,"சென":474,"சேவ":338,"சைக":291,"சேர":1297,"செல":774,"செய":2741,"சும":401,"சுற":312,"சுர":362,"சுவ":666,"சீன":355,"ing":312,"சுக":389,"சுத":324,"சூழ":384,"ச்ச":3340,"சைய":843,"சொல":606,"சொற":288,"டக ":523," th":509,"ட்ப":853,"ட்ட":19814,"ட்ச":2725,"ட்க":1235,"டைய":2172,"டைப":576,"டைக":531,"ணி ":660,"er ":398,"es ":343,"ண் ":586,"து ":27911,"தை ":1771,"தே ":341,"தி ":2552,"தா ":680,"டங்":1549,"டக்":1238,"ஞர்":315,"ஞ்ச":1519,"டமா":725,"டமை":297,"டம்":2072,"டர்":1679,"டன்":1240,"டப்":1121,"டத்":4115,"டது":1165,"டிய":2991,"டிப":984,"டின":1240,"டித":607,"டிவ":1222,"டில":1216,"டிர":537,"டாண":290,"டிட":382,"டிச":401,"டிக":1256,"டாவ":366,"டார":303,"டுப":1408,"டும":4650,"டுத":2954,"டுவ":1115,"டுள":785,"டுக":5293,"டாக":695,"டல்":1207,"தாக":1315,"தான":1137,"தாள":370,"தால":691,"தாவ":511,"திக":2302,"திச":403,"தாய":342,"தார":1089,"தின":3651,"திப":796,"திட":432,"திவ":299,"திம":291,"தில":7958,"திற":783,"திர":5993,"திய":6938,"துக":2030,"தீவ":583,"துண":389,"துட":443,"துப":404,"துள":2935,"துற":954,"துர":579,"தும":1383,"துவ":2062,"தூர":370,"தேச":1067,"தெற":289,"தென":697,"தைக":641,"தேவ":512,"தைச":349,"தேர":391,"தைய":745,"தொட":1925,"தொக":1037,"தொழ":704,"தொல":527,"தப்":1587,"ண்ம":630,"ண்ப":578,"தமி":4632,"தமா":339,"ண்க":445,"ண்ண":1196,"ண்ட":9721,"தம்":1071,"தயா":275,"தற்":1515,"தலா":427,"தலி":372,"தல்":1648,"தலை":1494,"தர்":937,"தவர":662,"தவி":419,"த்த":29791,"ணங்":275,"ணத்":603,"த் ":4416,"ணக்":539,"ணுக":317,"ணிக":735,"ணிய":592,"ணின":373,"ணித":474,"ணைய":630,"தந்":298,"தனி":760,"தன்":2053,"தனை":537,"ணைக":298,"தது":557,"தத்":779,"ணம்":660,"ணப்":571,"தங்":477,"தகவ":361,"தக்":543,"ணர்":292,"ந்ந":363,"ந்த":19873,"ng ":303,"னம்":921,"னர்":1811,"பகு":1877,"னது":1015,"னத்":650,"நேர":433,"நெட":597,"னப்":1023,"நோக":445,"நிக":520,"நாள":908,"நாய":319,"நான":310,"நாத":286,"நாட":4702,"நிய":299,"நிர":619,"நிற":1236,"நில":3876,"நீர":548,"நீத":282,"நுட":372,"நூற":484,"நூல":812,"னக்":283,"னங்":574,"பற்":788,"பலர":285,"பர்":1261,"பரி":581,"பரப":390,"பயன":1636,"பம்":365,"of ":362,"பவர":561,"பல்":1018,"பன்":334,"னைத":388,"பந்":594,"னைய":458,"னைவ":278,"னைக":358,"ன்ம":1125,"ன்ற":10571,"ன்ப":7799,"ன்ன":4301,"பமா":350,"ன்ட":278,"ன்க":958,"ன்ச":382,"னும":1622,"னார":414,"படம":801,"னிக":390,"னால":860,"படத":483,"படை":1050,"னின":559,"பட்":5520,"னிய":1758,"னில":287,"படி":920,"படு":7705,"னித":927,"பத்":1191,"பது":4499,"பதா":323,"பதி":845,"பண்":714,"பதற":308,"பணி":371,"பங்":436,"பக்":415,"னவர":288,"on ":583,"பல ":913,"ன் ":22050,"னை ":1086,"பட ":307,"னா ":289,"னி ":918,"ப் ":6813,"பை ":319,"நடி":497,"பு ":2795,"நடை":406,"பி ":577,"நகர":2167,"மணி":297,"ரே ":289,"மது":349,"மதி":359,"மத்":609,"ரு ":7941,"மட்":449,"ர் ":16957,"ரை ":1204,"றன ":856,"மன்":1232,"மனி":790,"மல்":385,"மலை":666,"யக்":1396,"மம்":421,"மரப":361,"மரு":359,"லக ":292,"மற்":2141,"றி ":716,"மாந":2194,"மான":2448,"மாத":610,"மாக":4202,"மிய":352,"மின":800,"று ":3977,"மாவ":2559,"மிக":1315,"மாற":977,"மார":743,"யங்":868,"யா ":1169,"ய் ":704,"யை ":1008,"யே ":849,"மகா":275,"ரா ":278,"ரி ":1486,"மங்":313,"மக்":1291,"மி ":296,"மே ":505,"மை ":1120,"ம் ":53178,"பின":1559,"பிய":742,"பிர":3751,"பிற":1054,"பில":819,"பிக":486,"பிட":1127,"பாத":646,"பான":683,"பாய":372,"பால":940,"பாள":428,"பார":981,"பாக":1005,"பாட":3059,"பாண":798,"பூர":411,"புத":1109,"புவ":296,"புல":660,"புற":357,"புர":1163,"பீட":289,"புக":1683,"பேர":1352,"பெண":307,"பெய":1296,"பெர":1861,"பெற":2100,"பேச":556,"போட":316,"பொற":395,"பொர":2127,"பொத":938,"போல":281,"போர":737,"போன":1011,"போத":864,"ப்ட":297,"ப்ப":26657,"ப்ர":488,"ளகர":469,"ளக்":350,"லம்":2464,"லமா":457,"லர்":460,"லப்":639,"ழ் ":1697,"ற்க":4226,"ற்ச":313,"ற்ப":2340,"ற்ற":9892,"றைக":742,"றைய":1266,"வே ":437,"ளத்":348,"ளது":1904,"லைக":1350,"லேய":338,"வை ":1638,"லும":2793,"லுக":305,"லிர":748,"லிய":1493,"லில":989,"லூர":479,"லுள":616,"வி ":735,"லிக":541,"லாற":423,"லாள":499,"லாம":957,"லிப":277,"லின":516,"வு ":1989,"லாக":721,"லான":565,"லாந":354,"ளங்":417,"லகி":465,"றம்":427,"ர்ச":956,"ர்க":5162,"ர்வ":1496,"ர்ம":805,"ர்ப":1555,"ர்ந":1909,"ர்த":1839,"ர்ட":360,"றப்":1150,"ள் ":12275,"ரைய":957,"றந்":718,"ரைப":1450,"றனர":342,"ளை ":2755,"ரைக":424,"றது":3133,"றத்":625,"லத்":2727,"லது":2796,"றுவ":1225,"றும":3125,"றுப":986,"றுத":532,"றுக":1202,"றில":535,"றிவ":770,"றிய":1917,"றின":604,"றிப":1027,"ழு ":279,"றித":312,"றார":526,"றிக":1316,"றாண":394,"றாக":1080,"ழி ":982,"லங்":2176,"லக்":1207,"றழை":438,"ரபு":329,"ரப்":990,"ல் ":34411,"ய்க":394,"ய்த":601,"ய்ய":1010,"ய்வ":739,"ரம்":2579,"ரமா":606,"ரர்":568,"ரலா":483,"யுள":362,"ரண்":815,"ரதே":555,"ரத்":1609,"ரது":278,"ளன ":701,"லை ":2437,"ரன்":291,"ளி ":635,"ராவ":406,"ரிக":2239,"ரால":435,"ராய":388,"ராம":869,"ரிச":541,"ரித":580,"ரிம":685,"ரின":1028,"ரிப":456,"ராக":2778,"ராச":370,"ராஜ":438,"ராட":1211,"ரான":615,"ருங":473,"ருட":752,"ருக":4077,"ருப":877,"ரும":2991,"ருத":1851,"ருந":3294,"ரிய":3104,"ரில":735,"ரிவ":1163,"ருவ":2848,"ருள":1674,"ரூர":620,"umb":290,"ரல்":362,"றங்":282,"மொழ":2149,"யப்":1295,"மைந":2631,"மைய":1873,"மைப":1460,"யன்":2673,"யமை":293,"யம்":1435,"ம்ச":279,"ம்ம":840,"ம்ப":4940,"யமா":620,"மூல":729,"மூன":356,"முழ":336,"மூக":412,"மீட":317,"மிழ":4631,"முற":1812,"மும":549,"முன":1115,"முத":1979,"முட":981,"முக":1304,"மென":349,"மெர":642,"றை ":1441,"மேல":805,"மேற":920,"மைக":943,"மேள":882,"யத்":1278,"யது":423,"லி ":729,"லா ":378,"ரங்":785,"ரசி":802,"ரசு":618,"யும":2862,"யிர":1042,"யில":6388,"யார":713,"யாவ":2647,"யாள":533,"யாழ":607,"யிட":437,"யின":2554,"யிய":701,"யாக":2905,"யாட":446,"யான":1415,"tio":513,"thu":314,"யல்":3022,"யலா":554,"யலி":566,"யற்":1115,"யர்":1747,"ter":301,"the":291,"யவர":291,"யவற":284,"வும":1702,"வாக":2334,"வாத":306,"வாச":280,"விக":832,"வாழ":922,"வால":316,"வான":889,"வாய":566,"வார":1236,"வித":708,"விண":306,"வின":2946,"விச":326,"விட":1092,"வில":3171,"விள":1040,"விய":1955,"விர":904,"விற":467,"வுக":1344,"வீர":321,"ஸ் ":1708,"வ்வ":1164,"வேற":846,"வேத":466,"வெள":2232,"வைய":661,"வைத":379,"வைக":768,"வேல":442,"வற்":1078,"வரி":937,"வரு":1641,"வரா":523,"வரை":1143,"வர்":4658,"வலை":345,"வல்":686,"வளர":473,"வழங":567,"ழ்ந":1868,"ழ்த":442,"ழ்வ":520,"ழ்ப":759,"ழ்க":412,"வரத":404,"வரல":407,"வம்":690,"வழி":728,"வடக":309,"வடி":817,"ழிப":303,"ழிக":564,"ழுவ":343,"ழும":521,"வட்":2653,"ழிய":1078,"ழில":887,"ழுத":1586,"வதற":541,"வதா":350,"வது":3201,"வத்":327,"வப்":301,"ழைக":1109,"வந்":1239,"வனம":324,"ழைய":304,"வன்":676,"ள்ள":9236,"ள்க":555,"ழர்":543,"ழமை":586,"வகை":1129,"வங்":465,"ழங்":729,"ளாக":1168,"ளிப":395,"ளின":2302,"ளால":742,"ளிக":491,"ளில":4426,"ளிய":1106,"ளிவ":966,"ளுட":327,"ளுக":1636,"ளும":1077,"ளுள":663,"ளைக":897,"ளைப":388,"ளைய":1472,"லைவ":579,"லைய":1591,"லைம":331,"ளனர":279,"லைப":623,"லைந":485,"லைத":348,"ளப்":366,"ல்ல":5939,"ல்வ":1233,"ல்ப":618,"ல்ந":316,"ல்க":1857,"ளம்":661,"ளமா":505,"ளர்":1471,"ழகத":295,"ளவை":282,"ழக்":933,"ளவு":424,"ளவி":419," நட":1718," நக":1501," நா":4504," நி":4279," நெ":933," நே":568," நூ":1176," நீ":1214," நு":519," நவ":316," பட":1904," பண":1105," பத":1073," பன":342," நோ":691," பக":1834," பங":296," பு":2928," பா":4041," பி":5649," பூ":498," பெ":4588," பே":1964," பற":718," பர":1247," பய":1942," பழ":608," பல":2289," பொ":3056," போ":2704," மன":1180," மட":504," மண":418," மத":890,"ிக ":435," மக":1685," மை":493," மே":3012," மெ":772," மொ":2003," மு":6572," மீ":747," மி":1990," மா":7055," மூ":1353," மர":989," மற":2304," மல":556,"ால ":279," டி":434,"ார ":281," தட":289," தக":507," தர":734," தற":353," தல":1342," தம":4737," தய":281," தன":1258," து":1451," தீ":745," தூ":310," தி":4210," தா":1353," தெ":1340," தே":1470," தொ":4079," தோ":559,"�":1175," ஸ்":417,"ான ":5124,"ாண ":290,"ாத ":411," ரா":553," யா":744," வட":1713," வண":356," வத":741," வக":1085," வச":354," வர":2716," வல":690," வழ":1368," வள":796," வந":384," வி":5451," வீ":639," வா":2177," வை":533," வே":1627," வெ":2854," உண":846," உத":491," உட":908," ஈழ":284," உள":3279," உல":1058," உற":820," உர":1675," உய":988," இண":833," இத":5634," இட":1528," இங":400," இச":1164," ஆவ":1943," இக":391," ஆய":570," ஆம":1553," ஆற":781," ஆர":1069," ஆப":332," ஆன":365," இவ":2571," இல":3087," இற":478," இர":6995," இய":2150," இம":448," இப":504," இன":1051," இந":4772," எட":530," எத":528," எண":593," என":11142," ஊர":477,"ாக ":5165," அக":780," அச":377," அட":1678," அத":1971," அண":901," அந":301," அன":909," அப":485," அம":5119," அர":2421," அற":1466," அல":3607," அள":796," ஆக":6168," அழ":1038," அவ":1449," ஆங":1422," ஆச":512," ஆட":602," ஆண":2832," சர":400," சம":1684," சந":326," சட":638," சங":283," சக":625," ஜூ":466," ஜெ":287," ஜன":633," சோ":491," சொ":885," சா":1798," சி":3884," சீ":724," சு":1865," சூ":738," செ":4613," சே":1783," ஒர":8153," ஒன":2134," ஏற":1035," ஐக":383," எழ":1219," எல":516," கவ":401," கு":5595," கூ":1517," கா":3988," கி":3235," கீ":461," கொ":3490," கோ":2006," கை":284," கே":530," கண":2002," கத":414," கட":2692," கன":550," கழ":306," கள":362," கல":1562," கர":2268," ஒல":300," ஒள":281," ஓர":762,"ஸ்க":347,"ஸ்ட":597,"ஸ்த":763},"n_words":[2733895,2995227,2314467],"name":"ta"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tel b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tel new file mode 100644 index 000000000..2a2370453 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tel @@ -0,0 +1 @@ +{"freq":{"ొరి":395,"D":266,"E":177,"F":114,"G":196,"A":519,"B":275,"C":368,"L":194,"M":322,"N":270,"O":138,"H":192,"I":350,"J":111,"K":142,"U":147,"T":316,"V":136,"P":450,"S":521,"R":276,"f":670,"g":908,"d":1461,"e":4276,"b":801,"c":1375,"a":5389,"n":3366,"o":3005,"l":2162,"m":1421,"j":112,"k":391,"h":2159,"i":3899,"w":466,"v":490,"u":1533,"t":3619,"s":2456,"r":3191,"p":1106,"్వ ":163,"y":766,"x":252,"్ల ":671,"్ర ":1330,"ొని":112,"ొన్":374,"్య ":1153,"్మ ":263,"ొదల":145,"ొదట":235,"ొత్":201,"్ప ":113,"్న ":986,"్ద ":312,"ొట్":128,"్ధ ":159,"్త ":383,"్థ ":302,"్ణ ":129,"ొక్":438," l":107," m":164," o":442," h":116," i":265," e":97," f":148," a":447," b":182," c":254,"్క ":414," t":666," w":134," p":388," s":269," r":221," J":106," K":133," H":173," I":300," N":209," O":104," L":173," M":286," B":241," C":316," A":428," F":98," G":181," D":227," E":138," S":425," R":253," P":381," V":124," U":129," T":274,"ొంద":344,"ొండ":319,"ل":112,"ఉద్":166,"ا":171,"ఉన్":1055,"ఉత్":337,"ఉపయ":174,"్కా":196,"్కి":134,"్గం":289,"్కు":347,"్కృ":177,"్కర":105,"్కల":130,"్కడ":197,"Ma":108,"Na":100,"र":112,"ा":126,"In":167,"Th":137,"Ra":122,"b ":223,"a ":692,"i ":282,"ge":141,"ga":105,"he":507,"ha":394,"gh":206,"ోబర":105,"ోయి":127,"g ":144,"ea":167,"ec":109,"ed":292,"de":174,"di":203,"h ":262,"ోమీ":223,"el":221,"en":398,"em":129,"et":241,"es":437,"er":625,"ca":177,"e ":1121,"ౌ":562,"్":81970,"ై":3997,"ొ":4527,"ోర్":149,"ో":18200,"ె":10608,"ే":14569,"ీ":10360,"ు":57347,"ూ":6654,"be":157,"ృ":1348,"da":157,"f ":323,"ct":100,"co":201,"ci":133,"ch":165,"ce":190,"ఘ":447,"ఛ":149,"చ":15206,"c ":186,"జ":11057,"ట":14914,"ఞ":164,"ఐ":184,"ఓ":160,"ఒ":2543,"క":36325,"గ":19947,"ఖ":1770,"ఈ":2196,"ఉ":3268,"ఊ":158,"ఎ":1173,"ఏ":730,"ం":43411,"అ":7490,"ఆ":3748,"ఇ":3357,"హ":4682,"ోలు":99,"స":22838,"ay":103,"ి":69802,"ా":61461,"d ":570,"at":690,"ళ":2227,"as":298,"ల":47610,"ar":638,"ర":61617,"ష":5311,"శ":7224,"వ":26890,"ప":26129,"ఫ":1064,"al":617,"న":46878,"ai":134,"మ":31451,"య":19501,"ap":114,"బ":7288,"am":273,"భ":4603,"an":764,"ac":150,"ణ":4171,"ad":159,"ఠ":238,"డ":16340,"ab":131,"ద":24907,"ag":119,"ధ":5601,"త":28253,"థ":2033,"nt":373,"ns":115,"of":309,"ోత్":140,"om":163,"on":653,"ol":158,"ot":144,"os":117,"ou":169,"op":107,"or":408,"r ":477,"pe":126,"pa":178,"ph":109,"lo":168,"ోదా":327,"ll":190,"o ":201,"ma":274,"mb":260,"me":185,"mi":151,"p ":107,"na":453,"nc":108,"nd":442,"ne":251,"ng":261,"ni":232,"ోనే":164,"ోనూ":131,"ోని":1569,"ka":99,"m ":247,"li":262,"le":271,"la":311,"n ":759,"ht":245,"hu":238,"hi":188,"ho":127,"id":115,"ic":417,"ia":224,"ig":225,"ie":147,"ir":142,"is":387,"it":280,"iv":131,"il":208,"in":615,"io":345,"ోపా":108,"l ":472,"ోజక":467,"ోజు":1239,"y ":444,"vi":97,"ve":202,"va":103,"x ":181,"ul":111,"ur":199,"us":218,"um":308,"un":137,"tt":129,"w ":99,"to":206,"tr":177,"te":479,"ti":559,"th":697,"ta":313,"ss":111,"st":281,"se":152,"sh":199,"si":231,"u ":109,"sa":101,"rs":111,"rt":125,"ry":99,"ro":238,"rn":149,"ri":529,"re":343,"ra":524,"t ":648,"s ":985,"px":158," అ":7472," ఇ":3349," ఆ":3719," ఉ":3240," ఈ":2188," ఊ":158," ఏ":725," ఎ":1157," ఐ":178," ఒ":2539," ఓ":155,"ొలి":167," క":10463," ఖ":358," గ":5736," ఘ":134," చ":6063," జ":5157," ట":497,"ొల్":112,"ోకి":106,"ోక్":172,"ోగి":184,"ya":98,"అసె":136,"అల్":163,"అరబ":119," డ":594," త":4637,"అర్":220," ధ":398," ద":3929," న":6927," ఫ":510," ప":14617," భ":2487," బ":2399," య":1063," మ":10243," ర":6209," ల":4976," వ":10214," శ":2160," ష":216," స":10032," హ":1355,"అమె":140,"అయి":199,"అభి":134,"అప్":103,"ఆధా":126,"్స్":527,"్సు":127,"్సి":119,"్సవ":107,"్ష్":173,"్సర":1414,"ఇంట":99,"ఇండ":128,"ఇంద":101,"ఇంక":425,"అక్":257,"్మక":121,"్మం":100,"్రం":1049,"్మీ":100,"్మి":779,"్మా":335,"్యక":335,"్యం":700,"్రజ":278,"్యా":2178,"్యు":431,"్యల":131,"్యవ":431,"్రక":927,"్యప":108,"్యమ":477,"్యత":143,"్యన":109,"్ధి":325,"్ధా":136,"్నద":482,"్ని":1493,"్నూ":99,"్నా":798,"్పట":140,"్పడ":119,"్పా":169,"్పి":132,"్పు":480,"్వత":158,"్శక":248,"్వవ":145,"్వర":328,"్వన":132,"్వే":159,"్వి":140,"్వా":901,"్వహ":104,"్షణ":127,"్షి":442,"్యే":161,"్రధ":337,"్రప":534,"్రత":526,"్యూ":276,"్రద":990,"్రయ":138,"్రల":146,"్యో":108,"్రమ":1464,"్రభ":230,"్రస":657,"్రహ":283,"్రవ":528,"్రి":1462,"్లం":396,"్రీ":1126,"్రు":244,"్రా":3971,"్రే":209,"్రె":472,"్రో":201,"్లా":2320,"్లి":708,"్లీ":237,"్లు":538,"్లూ":142,"్లె":187,"్లో":427,"్వం":342,"్ళు":159,"అధి":174,"అనగ":184,"్జా":141,"అదే":167,"్టమ":140,"్టణ":417,"అన్":250,"్ఞా":122,"అనే":708,"అని":495,"అను":265,"్గొ":101,"్గా":358,"్గర":100,"్గమ":101,"్చు":270,"్చి":657,"్చే":115,"అతి":194,"అత్":202,"్తు":1013,"్తూ":214,"్తి":885,"్తా":732,"్థల":171,"్త్":578,"్ణా":297,"్థం":104,"్ణు":99,"్తర":228,"ఆంధ":768,"్దు":149,"్ది":135,"్నం":164,"్దా":110,"్ధం":145,"్థా":493,"్థి":196,"ఆంగ":412,"్టి":519,"్టా":168,"్టు":592,"్టీ":169,"్టె":145,"్టే":107,"్టో":130,"్ట్":1367,"్తం":168,"్తక":101,"్డు":210,"్డి":275,"్డా":104,"ఇస్":134,"ఇవి":157,"ఈయన":143,"ఉంద":273,"ఉండ":260,"ఉంట":317,"ఇక్":152,"ఆస్":106,"ఆయన":107,"ఆర్":219,"ఇది":937,"ఇతన":164,"ఇతడ":125,"ంగు":105,"ంగా":1620,"ంగీ":190,"ంగ్":842,"ుబ్":104,"ంచం":115,"ంచడ":196,"ంచబ":269,"ురం":244,"ుమా":305,"ంచి":2098,"ంచా":900,"ంచు":217,"ంచే":428,"ునర":115,"ును":308,"ుని":447,"ంకట":194,"ున్":877,"ంకా":441,"ంగం":127,"ంకు":100,"ంక్":110,"ుపు":220,"ంకే":111,"ుప్":149,"ంగల":110,"ంట్":162,"ుతా":153,"ుతు":406,"ంటూ":289,"ంటు":309,"ంటి":346,"ంటా":630,"ంటే":263,"ండవ":146,"ండర":435,"ండల":1528,"ండా":227,"ుత్":335,"ుతో":165,"ండు":332,"ండి":934,"ుదల":235,"ండే":174,"ండ్":373,"ంతం":178,"ునక":539,"ుద్":398,"ుట్":223,"ుటు":199,"ుడి":231,"ుడై":99,"ుడు":1669,"ూడా":424,"ెం ":180,"ుస్":362,"ువు":534,"ువా":295,"ులన":225,"ులక":309,"ుర్":295,"ురి":204,"ురు":297,"ురా":315,"ులో":1709,"ుల్":297,"ులు":2048,"ులల":295,"ీపు":398,"ీని":626,"ీన్":101,"ుంట":481,"ుంచ":300,"ీటి":186,"ీడా":155,"ుంద":899,"ుండ":917,"ుంబ":248,"ీటర":270,"ీసు":107,"ీస్":140,"ుగు":1331,"ుగా":707,"ుఖ్":339,"ీవి":185,"ీవు":115,"ుక్":186,"ుకొ":218,"ుకో":172,"ుకు":711,"ీలు":116,"ీరు":184,"ీర్":177,"ీరా":161,"ీరి":154,"ేక ":252,"ృతి":120,"అంద":240,"ృత్":158,"అంత":284,"అంట":498,"ృద్":113,"ేట ":153,"ృష్":430,"ూబ్":222,"ంవత":1405,"ూర్":913,"ూరు":920,"ూరి":178,"ూమి":99,"ంస్":461,"ూరం":247,"ూడి":137,"ూన్":122,"ంనగ":106,"ంధి":102,"ంద్":655,"ందు":615,"ందీ":121,"ందూ":127,"ంది":3900,"ందా":120,"ందర":242,"ంత్":325,"ంతో":223,"ంతి":125,"ంతా":223,"ంతు":154,"ంతమ":531,"ంతర":294,"ంప్":193,"ంబం":197,"ంధ్":823,"ంబ్":147,"ంబర":346,"ంబా":123,"ంలో":2499,"ెక్":232,"ెగొ":368,"ెట్":682,"ేంద":485,"ెద్":322,"ెను":111,"ెన్":295,"ెడ్":327,"ైన ":1371,"ెంక":174,"ెండ":749,"ెంట":159,"ెంద":1703,"ెంబ":376,"ేయబ":121,"ేర్":242,"ేరు":810,"ేశమ":156,"ేవా":233,"ేవి":124,"ేవు":99,"ేశం":473,"ేశ్":948,"ేషన":164,"ేశా":391,"ేసు":136,"ేసే":128,"ేస్":215,"ేసి":385,"ైదర":183,"ైనా":98,"ెప్":281,"ెర్":117,"ంత ":201,"ెరి":197,"ెరు":117,"ండ ":260,"ెళ్":227,"ెల్":334,"ెలి":127,"ెలు":1031,"ెస్":269,"ంచ ":118,"ేట్":100,"ేదా":763,"ేది":324,"ేత్":212,"ేపల":115,"ేని":152,"చక్":98,"జీ ":270,"జు ":869,"చడం":113,"చడా":97,"జ్ ":143,"చబడ":285,"చయి":169,"చర్":162,"చరి":182,"టం ":155,"చిమ":219,"చిన":1351,"చిత":839,"చాయ":132,"చార":671,"చాల":242,"చాడ":421,"చిం":529,"చుట":109,"చుక":184,"చెర":102,"చేత":111,"చేశ":113,"చేస":711,"చేయ":279,"చేర":138,"చెం":1703,"చెప":157,"టక ":161,"చ్చ":739,"జకవ":368,"జట్":132,"జయం":110,"జయన":97,"జనా":117,"జనవ":101,"జన్":546,"జరి":198,"జరు":168,"జర్":124,"జిల":1917,"జాత":476,"జాబ":132,"టు ":571,"డం ":328,"టీ ":163,"టి ":1355,"ట్ ":976,"జూన":102,"జుల":578,"టే ":302,"జీవ":381,"జ్య":270,"జ్ఞ":163,"కలవ":99,"కలద":130,"కల్":174,"కలు":183,"కలి":375,"కళా":130,"కవర":379,"కవి":191,"కమై":100,"కము":112,"కరణ":169,"కరి":149,"కరీ":108,"కర్":483,"కృష":374,"కృత":281,"కూర":117,"కేం":355,"కెట":368,"కేత":124,"కొల":164,"కొన":532,"కొత":121,"కొం":355,"కాక":237,"కాన":220,"కిం":115,"కాం":219,"కిల":278,"కుం":288,"కాల":753,"కావ":146,"కాశ":150,"కార":1413,"కువ":215,"కుల":554,"కుమ":181,"కూడ":482,"గంల":249,"కున":307,"కుడ":387,"కుట":214,"క్త":493,"క్ట":234,"క్ర":1156,"క్ష":1241,"క్య":503,"క్స":190,"కోట":132,"కోవ":118,"కోస":136,"క్క":1351,"గణి":99,"చు ":184,"గాం":158,"గిం":251,"చి ":1132,"గల్":120,"ఖ్య":557,"గరం":165,"గము":239,"గర్":467,"గోద":304,"జక ":102,"గ్గ":278,"గ్ల":521,"గ్ర":2803,"గొర":375,"గొం":139,"గుం":380,"గీత":230,"గిన":273,"గిర":115,"గిల":409,"గాన":344,"గాల":538,"గార":322,"గుర":382,"గుల":283,"చే ":527,"గుత":171,"చంద":164,"The":111,"ఒకట":320,"ఈ ":1802,"కడ ":129,"ఆ ":194,"ం ":8664,"జ ":124,"ట ":666,"చ ":142,"క ":4039,"ఖ ":417,"గ ":279,"కా ":636,"కి ":2878,"కీ ":159,"గం ":342,"కు ":3007,"కే ":115,"కల ":176,"ో ":9069,"ొ ":154,"్ ":12057,"ూ ":882,"ే ":3256,"ె ":384,"కంగ":154,"ై ":627,"కంప":118,"క్ ":597,"al ":302,"కటి":342,"ప ":310,"కడప":102,"గి ":200,"ర ":2230,"య ":2100,"and":212,"గు ":978,"మ ":914,"an ":162,"భ ":236,"త ":2433,"ణ ":915,"గ్ ":310,"కని":99,"డ ":765,"కన్":185,"న ":8370,"గే ":100,"ధ ":351,"ద ":698,"కత్":143,"థ ":364,"గల ":283,"ి ":25169,"ు ":28831,"ీ ":2596,"ా ":10070,"గర ":98,"ళ ":256,"ara":113,"గా ":3484,"as ":101,"ల ":3843,"ష ":236,"స ":172,"వ ":1710,"ate":158,"ati":274,"శ ":151,"ఎక్":197,"ఒక ":1730,"ఎన్":170,"ఏర్":182,"ఏప్":108,"కం ":201,"పతి":175,"పత్":270,"పని":184,"పదా":153,"బ్ ":398,"పద్":166,"పబడ":136,"పర్":323,"పరి":615,"పయో":173,"is ":130,"ion":314,"మం ":434,"బీ ":112,"పడి":153,"పట్":664,"పటి":143,"నుల":119,"నుమ":118,"నుం":937,"పండ":161,"పంచ":381,"నిష":106,"నిస":137,"నుక":147,"నేద":234,"నేక":128,"నెల":200,"ఫ్ ":137,"న్స":247,"న్న":4348,"న్య":363,"న్మ":479,"నర్":180,"నల్":184,"నవల":101,"నవర":120,"నవి":505,"నవా":119,"నాన":204,"నాల":394,"నిక":2247,"నామ":117,"నాయ":625,"నార":407,"నాగ":146,"నాట":222,"నాడ":330,"నిం":101,"నిమ":603,"నిప":174,"నిన":273,"నివ":153,"నిల":173,"నియ":723,"నిర":621,"నిజ":109,"నిచ":107," In":167,"పై ":288,"ధుల":101," Ma":108,"he ":336,"నటి":194,"నటు":148,"ధాన":583," Na":99,"ధిక":249,"ధాల":110,"ధార":372,"ధిం":266,"ధ్ర":813,"ధ్య":539,"ధ్వ":128,"నము":174,"నప్":98,"నది":1069,"ప్ ":131,"నకు":648,"ధర్":117,"ద్ద":912,"ద్ధ":740,"ద్య":705,"ద్ర":1024,"ద్వ":366," Ra":122,"పు ":1089," Th":135,"పి ":170,"నగర":694,"నగా":212,"దుర":131,"దుల":359," in":168,"ic ":167,"దుక":199,"నంల":98,"దీన":642,"నంద":215,"నంత":121,"దూర":349," of":288,"నంగ":97,"దిన":1883,"దాల":166,"దార":401,"దిగ":97,"దావ":310,"దిక":108,"దాన":215,"దాయ":205,"దిం":248," an":154,"igh":175,"ing":133," co":127,"in ":172,"దేశ":1819,"దేవ":424,"దరా":213,"దరి":108,"దరు":98,"దర్":467,"దలై":227,"దము":121,"ht ":153," ri":133," px":158,"hum":206," th":488,"యక్":252,"మల్":108,"యకు":188,"ళం ":125,"మహా":326,"మహబ":214,"మస్":105,"భ్య":159,"మర్":164,"మము":1248,"మరి":1583,"్య":7206,"్ర":17902,"్భ":147,"్మ":2496,"్ళ":500,"్ల":6272,"్ష":1432,"్స":2574,"్వ":3316,"్శ":403,"భూమ":101,"ొత":206,"ొన":623,"ొద":448,"er ":201,"ొడ":148,"ొట":141,"ొక":526,"ోత":253,"ోద":489,"ోధ":191,"ోన":2053,"ోప":279,"ోజ":1789,"es ":247,"ోట":326,"మన్":141,"ోడ":255,"ొల":420,"ోక":416,"ోగ":536,"ొప":97,"ొమ":110,"ొర":534,"మధ్":230,"ోహ":103,"ోస":258,"ోష":120,"ోవ":239,"ోళ":97,"ోల":348,"ర్ ":2488,"ోర":356,"ోయ":204,"ోమ":362,"ోబ":166,"్ప":1717,"్బ":390,"్థ":1504,"్ద":1267,"్ధ":1039,"్న":5055,"్డ":878,"్ణ":861,"్త":4966,"మద్":165,"్ఞ":163,"్ట":4282,"్చ":1364,"్జ":379,"్క":2197,"్గ":1283,"ౌర":127,"ెక":273,"ెగ":454,"ెట":731,"ేం":571,"ెడ":401,"ెన":560,"ెద":446,"ెబ":128,"ెప":323,"ెర":576,"ెయ":109,"ేక":542,"ెల":1742,"ెళ":238,"ెస":311,"ేజ":151,"ేడ":137,"ేట":442,"ేద":1312,"ేత":579,"ేమ":144,"ేన":288,"ేప":266,"ైక":118,"ేవ":789,"ేశ":2277,"ేయ":473,"ేర":1324,"రు ":4219,"ేల":302,"ైట":119,"ేస":935,"ేష":349,"ైద":293,"ైప":117,"ైన":1789,"ైల":172,"ent":124,"ైర":115,"రీ ":399,"లం ":787,"ొం":865,"ుప":753,"ుబ":195,"ుమ":706,"ుర":1675,"ుడ":2134,"ుత":1344,"ుణ":146,"ుద":870,"ున":2892,"ూచ":102,"ూట":134,"ూడ":838,"ుల":6256,"ుళ":166,"ూక":114,"ువ":1504,"భుత":182,"ుష":187,"ుస":535,"ూబ":239,"ూప":393,"ూర":2460,"ూమ":147,"ూత":151,"యంగ":158,"భివ":99,"ూన":263,"యంల":180,"ూల":418,"యంత":161,"భావ":218,"ృత":512,"ృద":127,"భాష":346,"ృష":487,"భాగ":404,"ెం":3543,"భార":1164,"ght":162,"రా ":340,"రి ":1816,"బ్ద":180,"బ్య":153,"బ్ర":421,"బ్బ":268,"బ్ల":214,"మంల":137,"మంత":183,"మంద":199,"మండ":1520,"మంచ":160,"బూబ":215,"యి ":1015,"యా ":446,"యు ":1545,"బహు":111,"రత ":484,"రణ ":257,"బాల":182,"బాద":326,"చం":331,"చక":136,"గూ":124,"గు":2649,"గీ":290,"గి":1482,"గా":5233,"గ్":4119,"గో":680,"గొ":668,"గే":237,"చూ":162,"చే":2135,"చె":2255,"చి":4513,"చా":1586,"చు":758,"జం":238,"చీ":143,"జక":593,"చ్":872,"చన":284,"చడ":226,"చల":202,"చబ":291,"చర":425,"చయ":212,"జీ":767,"జు":1617,"జూ":225,"జా":1179,"జి":2298,"బర్":394,"జె":108,"జే":138,"జ్":689,"జట":138,"జన":1034,"జల":247,"జర":556,"జయ":406,"జమ":127,"ఞా":122,"టణ":417,"టన":141,"టమ":207,"టర":627,"టల":211,"టా":1086,"టం":232,"టక":349,"బరు":119,"ఏర":193,"ఒక":2332,"కప":131,"కన":498,"కథ":162,"కళ":218,"కల":1454,"కర":1217,"కమ":420,"కత":246,"కడ":370,"ఖం":105,"కట":682,"కం":721,"గన":109,"గమ":341,"ఖ్":606,"గల":557,"గర":1021,"గవ":148,"గడ":113,"ఖా":134,"గణ":180,"గత":148,"కె":553,"కే":816,"కొ":1436,"కో":857,"క్":5977,"కవ":683,"మ్ ":245,"కా":4315,"కి":3602,"గం":786,"కీ":401,"కు":5487,"కూ":725,"కృ":665,"ఇవ":231,"ఉం":885,"ఇస":145,"ఈయ":144,"ఉత":340,"ఉద":238,"ఉన":1071,"ఉప":428,"ఊర":103,"యన ":254,"మే ":227,"బడు":128,"బడి":519,"బడ్":106,"మె ":112,"ఎం":154,"ఎక":206,"ఫిబ":101,"ఎన":226,"ఎల":121,"ఏప":110,"ంట":2314,"ండ":4890,"ంచ":4715,"ంజ":258,"ంఖ":105,"ంగ":3503,"ంఘ":151,"ంక":1284,"ము ":3877,"ంస":547,"ంహ":127,"ంశ":194,"ంవ":1428,"ంల":2578,"ంభ":203,"మీ ":169,"రం ":1690,"ంబ":1040,"ంప":925,"ంన":133,"ంధ":1232,"ంద":6277,"ంత":2617,"అం":1210,"మి ":320,"అక":311,"మా ":484,"అత":486,"ఆం":1221,"అడ":112,"ఆగ":134,"అవ":290,"అస":267,"ఇం":883,"అప":148,"అద":293,"అధ":264,"అన":2095,"అల":293,"ఆక":150,"అభ":173,"అమ":349,"అయ":276,"అర":448,"ఆస":172,"ఇద":1021,"ఇత":411,"ఆద":158,"ఆధ":194,"ఇక":159,"ఆల":169,"ఆర":366,"ఆమ":98,"ఆయ":142,"ed ":203,"హా":889,"హీ":131,"హి":1070,"హై":216,"హు":207,"హ్":323,"సి":2638,"సా":1884,"సహ":150,"సే":373,"హన":103,"సె":515,"హద":248,"సూ":343,"సు":1296,"సీ":269,"హర":312,"హమ":119,"స్":7213,"సో":169,"హబ":217,"సై":168,"ీన":965,"ీప":582,"ీమ":216,"ీయ":835,"ుం":2995,"ీడ":294,"ీత":443,"ీద":226,"ప్ట":148,"ుచ":224,"ీస":356,"ుజ":115,"ుట":570,"ీర":995,"ీల":543,"ుఖ":811,"ీవ":537,"ుక":1639,"ుగ":2452,"ిప":1339,"ిధ":481,"ప్ర":6213,"ిన":7334,"ిభ":310,"ిమ":1311,"ిబ":193,"ీం":175,"ప్ప":767,"ిడ":512,"ిట":428,"ిద":1195,"ిణ":298,"ప్త":145,"ిత":2784,"ిహ":142,"ిస":1526,"ిష":595,"ీట":504,"ిల":4318,"ిర":1588,"ియ":3643,"ిశ":675,"ివ":1160,"ీక":548,"ిళ":268,"ాప":991,"ాబ":791,"ాభ":232,"ాద":1312,"ాధ":720,"ాన":5606,"ాణ":587,"ాత":1866,"ాథ":104,"ాట":1172,"ిం":5711,"ాడ":1873,"ిజ":737,"ాష":1417,"ిగ":1743,"ాశ":424,"ిచ":498,"ాహ":545,"ాస":1648,"ాళ":307,"ాల":7697,"ావ":1502,"ిక":5536,"ాయ":2657,"ామ":3420,"ార":9423,"ాం":2393,"ాజ":1333,"ాచ":406,"ాగ":1102,"ాఖ":177,"ాక":1433,"ళ్":660,"ళా":226,"ళు":204,"వం":1022,"ళి":199,"లూ":372,"లె":853,"లే":1247,"లై":507,"లొ":182,"లో":10420,"ల్":5828,"లల":1531,"లవ":368,"పొం":272,"లస":257,"లి":3093,"లా":4226,"లు":7313,"లీ":875,"లన":1389,"లద":177,"లత":291,"లర":153,"లమ":664,"లయ":457,"లభ":102,"లప":338,"లగ":164,"లక":1319,"ళం":168,"రె":1156,"రే":571,"లం":1397,"రీ":1644,"రు":6712,"రూ":370,"ర్":10720,"రై":236,"రొ":149,"రో":1788,"రవ":803,"రర":106,"రల":270,"రి":8236,"రా":9645,"రహ":470,"రస":1070,"పోయ":117,"సల":125,"సర":1986,"సవ":160,"సన":295,"షే":125,"సమ":856,"ష్":2463,"సభ":337,"షు":200,"షి":679,"హం":127,"సత":144,"షా":261,"షల":199,"షన":300,"శే":116,"శో":101,"శ్":2342,"శా":1493,"శి":616,"శీ":111,"సం":3277,"శు":134,"షణ":177,"శర":141,"శమ":213,"వ్":1485,"శప":105,"వై":429,"వే":1068,"వె":798,"పెర":121,"వృ":262,"శత":192,"పెద":371,"వు":1823,"వి":5005,"వీ":727,"వా":3654,"పెట":114,"వహ":409,"వస":762,"వవ":165,"వల":675,"శక":362,"వమ":143,"వర":2599,"వయ":126,"వబ":126,"పేర":775,"వద":165,"వన":469,"శం":714,"వడ":233,"వత":1750,"వచ":500,"పేట":181,"వక":188,"వగ":122,"పర":1387,"పయ":194,"పబ":173,"పుడ":183,"పుట":123,"పశ":239,"పవ":130,"పల":696,"పీ":121,"బం":418,"పు":3004,"పున":212,"పా":2599,"పి":1196,"పుల":197,"పై":426,"పుర":635,"పె":871,"పే":1148,"పూ":679,"పో":542,"పొ":493,"ప్":7624,"ఫి":208,"బంధ":198,"బడ":901,"ఫా":98,"పుక":147,"నప":317,"నన":175,"ధ్":1531,"నమ":463,"నల":465,"నర":396,"నవ":1165,"నస":228,"నా":3446,"ని":11511,"నూ":449,"పం":874,"నీ":780,"ను":3710,"నె":404,"నే":1616,"నై":122,"నో":217,"న్":7783,"పక":194,"పట":848,"పడ":347,"పత":560,"పద":604,"పూర":466,"పన":354,"మస":145,"మహ":733,"యక":627,"మవ":108,"మల":476,"మర":2137,"మమ":1293,"భ్":184,"మయ":233,"మ్":1298,"యమ":802,"మో":201,"యబ":173,"మొ":695,"యప":181,"మై":1143,"యన":1189,"మే":512,"మె":642,"యత":237,"మూ":561,"యణ":150,"ము":8249,"యడ":124,"రం":3512,"మీ":939,"మి":2427,"మా":3556,"రజ":343,"యా":3425,"యస":173,"రచ":538,"రక":1588,"యవ":582,"రగ":211,"యర":125,"యల":345,"రభ":250,"రబ":182,"యో":1070,"రయ":209,"రమ":3193,"య్":536,"యే":292,"రన":144,"యొ":325,"రప":785,"రత":1738,"రధ":361,"రద":1093,"యి":2020,"రణ":774,"యూ":387,"యు":2564,"భజ":115,"బహ":139,"ఫ్":329,"బల":111,"బర":571,"బె":226,"పిల":285,"బో":143,"బి":436,"బా":1142,"బూ":263,"బు":283,"మం":2740,"బీ":198,"భవ":117,"పిం":315,"పాడ":180,"పాట":306,"బ్":1702,"పాక":97,"మక":263,"పార":352,"మధ":257,"మద":259,"పాల":798,"మన":607,"భా":2350,"యం":1483,"భి":337,"మణ":175,"పాత":213,"భూ":233,"భు":226,"పాద":161,"మత":260,"తం":1159,"డె":175,"డై":152,"డే":590,"డూ":98,"డు":4437,"డ్":1447,"తగ":160,"తక":320,"ణు":288,"ణి":460,"తడ":168,"థం":125,"ణా":811,"పశ్":219,"ణమ":366,"డక":111,"డం":469,"టీ":380,"టి":2635,"టూ":417,"టు":1542,"టె":412,"టే":482,"టో":219,"ట్":4408,"డల":1645,"డవ":326,"డి":3130,"ణం":589,"డీ":118,"డా":1416,"డన":117,"డప":181,"యం ":918,"డర":467,"డమ":180,"దూ":569,"ది":7459,"దా":2559,"దు":1821,"నం":1132,"దీ":937,"దశ":127,"దల":498,"దవ":129,"దమ":252,"దర":1036,"దన":184,"నద":1194,"నత":159,"ధు":301,"నడ":153,"ధి":1062,"ధా":1185,"నట":452,"నగ":969,"నక":819,"ధర":205,"ధమ":185,"ద్":4147,"దో":106,"దై":97,"పల్":507,"ధన":195,"దే":2544,"తి":3113,"తా":2188,"తు":2234,"తీ":1022,"దం":398,"తూ":504,"తవ":124,"ణ్":199,"తమ":1218,"తయ":143,"తర":1102,"తల":412,"తత":106,"తద":425,"తన":727,"తప":172,"ధం":257,"థి":222,"దట":256,"థా":607,"దగ":155,"త్":7311,"దక":372,"థల":206,"తె":1297,"తే":283,"తొ":248,"తో":1099,"తన ":222,"re ":103,"తమ ":119,"తర ":195,"rna":99,"డర్":430,"rig":147,"డలం":220,"డలా":772,"డలమ":349,"తి ":1458,"తా ":207,"తు ":133,"దం ":185,"తీ ":111,"డాక":183,"తూ ":177,"ణంగ":137,"డిస":137,"డియ":171,"డిప":137,"డిన":531,"డిగ":126,"డాన":284,"డిం":217,"డున":104,"డుత":225,"డుద":220,"తే ":137,"డుగ":154,"టుం":409,"టుడ":112,"టుక":107,"టుల":128,"టాన":112,"టిం":317,"టార":521,"టాయ":145,"టిక":258,"టిన":213,"టిల":128,"టెం":107,"టూర":324,"టెస":126,"ట్ట":1520,"ట్న":97,"ట్ల":382,"ట్ర":1237,"టోబ":103,"థం ":106,"ణి ":141,"ణా ":186,"డే ":362,"టణం":170,"టణమ":136,"ఞాన":102,"డ్ ":409,"టర్":527,"తం ":582,"px ":156,"డప ":101,"డవ ":125,"డల ":98,"డు ":3436,"ణం ":367,"డి ":1391,"డా ":647,"దక్":263,"ng ":118,"దగ్":111,"nal":119,"ని ":5553,"nd ":184,"నా ":456,"nat":122,"తొల":175,"త్స":1562,"త్వ":496,"త్ప":99,"త్య":731,"త్ర":2659,"త్మ":140,"త్త":1214,"న్ ":2086,"nte":106,"నీ ":393,"ను ":1891,"నూ ":221,"థాన":257,"థాప":165,"దటి":194,"నే ":783,"తలు":105,"తర్":233,"తరా":100,"తరు":178,"తయా":124,"of ":287,"తని":130,"తను":162,"తదే":370,"ద్ ":290,"ణ్య":125,"తము":568,"తరం":98,"తమి":191,"తమై":176,"తూర":292,"తీస":125,"తీర":136,"తీయ":499,"తుం":576,"తువ":193,"తుల":549,"తున":363,"తుడ":101,"తుత":113,"తెల":1095,"or ":106,"ధి ":298,"on ":261,"తిం":103,"తాన":260,"తాబ":131,"తాయ":183,"తార":646,"తాల":289,"తిక":313,"తిప":135,"తిన":244,"తిల":128,"తిర":258,"ona":120,"ణము":230,"ణాట":124,"ణాన":134,"ణాల":199,"దే ":212,"తడు":135,"నం ":570,"దీ ":144,"దు ":735,"దూ ":152,"దా ":781,"ది ":4694,"mb ":192,"డ్ర":225,"డ్డ":567,"డైన":112,"త్ ":276,"తో ":862,"తంత":146,"తంల":160,"తంగ":162,"ధం ":174,"హైద":184,"హ్మ":154,"హరి":153,"హిం":546,"హాస":146,"హిత":221,"హార":226,"ాం ":154,"ాల ":1055,"ార ":189,"ాయ ":112,"ామ ":130,"ాష ":111,"ిక ":816,"ాడ ":161,"ాన ":423,"ాణ ":106,"ాత ":349,"షిణ":213,"షియ":100,"సత్":128,"ష్ణ":466,"ష్ట":1410,"ష్మ":151,"ష్య":127,"శ్వ":481,"శ్ర":732,"శ్చ":253,"సూర":115,"సుమ":114,"సుప":118,"సుల":177,"సుక":241,"సిన":1016,"సెప":103,"హదా":155,"సెం":276,"సేవ":130,"స్వ":634,"స్స":166,"స్ట":634,"స్త":2396,"స్క":441,"స్య":121,"స్ల":199,"స్థ":1195,"స్ప":97,"హబూ":215,"సర్":165,"సరా":545,"సరి":163,"సరం":158,"సము":220,"సమా":187,"సరమ":805,"సిం":294,"సాగ":118,"సార":233,"సాయ":137,"సామ":225,"సాల":116,"సాధ":336,"సిద":483,"సాహ":220,"సాం":202,"ాషల":143,"ిగా":515,"ిగి":822,"ాశి":102,"ాష్":1035,"ాసన":172,"ాస్":763,"ాసి":162,"ాసు":140,"ాహ్":114,"ాహి":212,"ిచే":186,"ాల్":490,"ాలె":525,"ాలో":374,"ాలి":340,"ాలా":319,"ాలు":1799,"ికం":141,"ాళ్":125,"ికల":174,"ావర":347,"ిక్":462,"ికె":356,"ికి":2410,"ికా":407,"ాశం":101,"ికీ":129,"ావు":393,"ావి":174,"ావా":119,"ాయక":252,"ామా":422,"ామి":301,"ువ ":165,"ాయణ":146,"ాము":207,"ామీ":105,"ారం":644,"ాయన":97,"ామ్":178,"ాయల":128,"ాయా":112,"ాయి":1156,"ారణ":247,"ాయు":174,"ారత":1096,"ారమ":516,"ాలం":253,"ారు":2695,"ారా":731,"ారి":987,"ారె":142,"ార్":1699,"ాలక":349,"ాలన":602,"ాలల":704,"ాలయ":271,"ాపా":110,"ాపి":155,"ాపు":243,"ుల ":664,"ాప్":131,"ాబ్":203,"ామం":407,"ాబా":337,"ాబి":105,"ాభా":138,"ామమ":1222,"ాయం":147,"ాధి":274,"ాధా":195,"ాద్":200,"ాది":262,"ాదా":163,"ాదు":323,"ానం":337,"ాన్":1330,"ాని":2256,"ానా":239,"ాను":249,"ానీ":138,"ానమ":140,"ానవ":144,"ాణి":118,"ాణా":137,"ాతం":140,"ాత్":473,"ాతి":287,"ాతీ":294,"ాటి":344,"ాటక":227,"ింద":1127,"ింప":204,"ింహ":109,"ున ":292,"ాణం":105,"ాడు":1280,"ాటు":186,"ాట్":155,"ించ":3485,"ింగ":388,"ాచా":147,"ాజక":97,"ాజ్":274,"ాజు":235,"ాజీ":183,"ిస్":1152,"ిసె":112,"ిసి":108,"ిశ్":326,"ిష్":330,"ివర":212,"ీకా":119,"ివి":228,"ివా":253,"ివృ":121,"ిలు":223,"ిలి":585,"ిల్":2371,"ిలో":795,"ీకర":173,"ిరి":250,"ిరా":106,"ిర్":662,"ిరు":214,"ిమా":662,"ిమి":102,"ియన":542,"ియా":466,"ియు":1543,"ియో":582,"ిభజ":97,"ిబ్":136,"ిభా":151,"ిప్":171,"ిపో":97,"ిపా":281,"ిపి":237,"ిన్":485,"ినే":113,"ినా":300,"ినీ":170,"ిని":1388,"ినవ":476,"ిధ్":101,"ినద":304,"ిద్":918,"ిది":107,"ితో":97,"ిత్":1390,"ితు":127,"ితా":191,"ితి":106,"ితమ":107,"ితం":125,"ీంన":105,"ిడి":106,"ిడు":224,"ిట్":149,"ిజ్":98,"ిజయ":327,"ిమ ":204,"ిన ":3712,"ిధ ":97,"us ":116,"umb":214,"ిత ":340,"ిణ ":131,"ాగా":294,"ాగం":166,"ాకు":548,"ాకా":261,"ాక్":268,"ాగమ":122,"ీయ ":614,"ుఖ ":363,"ాంప":98,"ాంత":945,"ాంచ":129,"ాంక":177,"ాంగ":129,"ాండ":272,"ాంట":124,"tio":240,"thu":204,"tic":109,"ీద ":119,"ter":183,"ీత ":149,"the":294,"రెగ":378," టె":198,"రెడ":266,"రెం":338," డి":256," తర":402," తల":122," తయ":126," తమ":296," తన":208,"రుల":346,"రువ":337," తీ":259,"రూప":260," తు":102," తూ":204," తా":347," తి":295," దర":275,"రిస":226,"రీక":244,"లంక":104,"రిశ":167,"లంగ":98,"రియ":2151,"రిల":238," దా":338," ది":263," నం":121," దీ":636," దు":100," దూ":346,"రీడ":197," త్":129," దక":226,"రుగ":346," తే":107," తె":1239,"రుక":143,"లంల":221," తో":176,"రీల":108," తొ":234,"రీర":165,"రుప":202,"రుద":98," దగ":103,"రుత":145,"రుడ":402," ని":1694," నా":986," నే":224," నె":256," ను":1002," నీ":159," పం":410," ధ్":128," నవ":245," నల":140," నర":118," నట":342," నద":241," ద్":355," దే":830," నగ":454," ధర":125," పు":828," బం":140," పి":453," పా":1265,"ర్జ":254,"ర్చ":276," పూ":375,"ర్గ":822," పై":166," పే":871,"ర్క":210," పె":701," పర":985," పల":194," పశ":232,"ర్ల":676," పట":506,"ర్భ":97,"ర్మ":671,"ర్య":611,"ర్ర":164," పత":150,"ర్వ":752,"ర్శ":394," పద":483,"ర్ష":165," పన":214,"ర్స":153,"ర్డ":192,"ర్త":647,"ర్ణ":379," న్":102,"ర్ట":234,"ర్ప":512,"ర్ద":134,"ర్థ":298,"ర్న":217,"ర్ధ":247," బె":166," మం":1840," బు":104," బా":514," బి":196," బహ":138," ఫి":158,"రోజ":1261," పో":317," పొ":389," ప్":5580," మె":212," మే":243," మొ":630," మీ":304," రం":324," ము":950," మా":1189," మి":579," మూ":307," మహ":682," మర":1780," మల":118," మద":144," మధ":241," మన":339," భా":1788," భూ":198," మత":120," బ్":391," రక":185," రచ":380," యా":130," యు":226," యొ":307," రహ":158," రా":2479," రి":152," రూ":154," రే":110," రె":413," రో":1305," లక":229," లా":183," లి":124," లీ":414,"లక్":278," లే":936," లో":2471," వం":288,"లకు":713," వచ":271," వర":687," వల":223," వన":123," శత":174," వృ":111," వు":163," వీ":487," వి":2741," వా":1113," వహ":154," వస":211," శర":115," వ్":920," వే":517," వై":295," వె":707," శి":276," శా":559," సం":2964," శ్":619," సభ":227," సమ":725," సర":319," సత":113," సో":126," సై":131," స్":1289," సహ":136," సా":1231," సి":984," సూ":295," సీ":113," సు":551," సె":214," సే":170," హా":151," హి":411," హై":215,"శం ":350,"లదు":145,"లనా":127,"లను":769," అద":293," అన":2095," అధ":264," అప":148," అమ":347," అభ":171," అర":447," అయ":275," అల":292," ఆక":148," అవ":290," ఆగ":133," అస":267," ఇం":883," అక":309," అత":484," ఆం":1219," అడ":112,"లతో":261," అం":1209,"లము":453," ఉప":425," ఉత":340," ఉద":238," ఉన":1059," ఈయ":143," ఉం":878," ఇస":144," ఇవ":231," ఇత":411," ఇద":1021," ఆస":171," ఆల":168," ఇక":159," ఆమ":98," ఆయ":141," ఆర":349," ఆద":158," ఆధ":194," ఎన":222,"లపా":106," ఎక":205," ఎం":151," ఊర":103,"లయం":174,"లసి":100,"వి ":1063," ఒక":2330," ఎల":121," ఏప":110,"వు ":683," ఏర":193," కడ":121," కన":324," కథ":133," కళ":192," కల":950," కర":453," కమ":146," కవ":208," కూ":537," కు":935," కృ":305,"లలో":1368," కా":1477," కీ":118," కి":608," కొ":916," కో":463," కె":104," కే":473," క్":1409," కం":234,"లవు":100,"లున":100,"లుప":124,"లుగ":1377," చం":138,"లీప":400," చర":227,"లిస":141,"లియ":176," గల":204," గణ":98,"లూర":257," గొ":123," గ్":2511," గో":479," గు":835,"లుస":156,"లువ":181," గా":766,"లాం":234," జీ":342," జూ":200," జి":1930," జా":544,"లిప":160,"లిన":457,"లాల":533," చి":1236," చా":356," జం":150," చూ":133,"లిచ":103,"లిక":169," చే":1234," చె":2126,"లిగ":302,"లిం":322," జర":424,"లాన":792," జట":132,"లాక":349," జన":782,"మాన":550,"మిం":658,"మాణ":180,"మాత":176,"మాజ":244,"మిత":118,"మిన":106,"మాల":362,"మార":804,"మిగ":392,"మిక":194,"మూర":145,"మూల":144,"ముస":98,"మూడ":128,"మీద":160,"రంభ":126,"రంగ":724,"మిళ":192,"మీట":267,"ముం":165,"మున":805,"ముద":263,"ముల":1642,"ముగ":175,"ముఖ":794,"రంల":639,"లన ":189,"మెర":163,"మొద":382,"యబడ":162,"మైన":961,"యన్":580,"యమై":151,"యము":343,"మ్య":156,"మ్మ":696,"రకు":296,"రకా":757,"యలు":117,"లి ":884,"లా ":1657,"రక్":177,"యవా":98,"యవస":290,"యాం":168,"రజల":129,"రజా":121,"లు ":5068,"రచయ":170,"లీ ":280,"రచి":149,"యాత":175,"యిం":162,"యాన":300,"యాప":194,"యిత":265,"యిన":317,"యాల":977,"యాయ":147,"యార":226,"యాస":145,"లె ":114,"యున":120,"యుద":115,"యుడ":244,"రణం":198,"లై ":139,"యుల":185,"రతద":370,"రత్":271,"లొ ":129,"రతి":294,"రతీ":189,"లో ":7792,"రదా":133,"రదే":797,"యేక":110,"ల్ ":1097,"రధా":328,"రపం":261,"యొక":313,"యోగ":322,"రప్":212,"యోజ":484,"రబ్":122,"రభు":164," న ":334,"య్య":475,"రమా":132,"రము":2455,"రమై":178," వ ":948,"రలో":108,"రవే":152,"రవర":163,"రసి":474,"రసా":125,"రహద":155,"రహ్":108,"ళు ":149,"రస్":344,"వం ":351,"రాం":782,"రాష":1004,"రిగ":429,"రాశ":107,"రిచ":101,"రాస":176,"రాల":911,"రావ":479,"రిక":1063,"రాయ":398,"రామ":2348,"రార":157,"రిమ":109,"రిన":146,"రిప":316,"రిత":332,"రీం":118,"రాజ":925,"రాచ":155,"రాక":131,"రాబ":238,"రాన":501,"రాత":218,"రాణ":222,"రిం":589,"సి ":308," ఈ ":1799,"వవి":98,"శకు":169,"వల్":164,"వలన":113,"వర్":961,"వరి":638,"వరా":124,"వరం":218,"వరక":228,"వబడ":120,"వని":123,"�":414," ఆ ":193,"వేశ":97,"వెన":102,"వేత":144,"వేద":126,"వేర":137,"వెల":135,"వెళ":168,"స్ ":1102,"శతా":121,"వెం":227,"వుల":548,"వృద":108,"వృత":103,"విభ":250,"విశ":387,"విష":171,"విస":184,"విల":124,"వివ":223,"వీట":109,"వీర":311,"వుడ":102,"సే ":113,"వున":206,"వాట":147,"వాడ":389,"విం":186,"వాత":351,"వాద":217,"వాన":154,"వాయ":104,"వార":1074,"వామ":220,"విక":160,"వాల":287,"వాస":216,"విజ":433,"విడ":296,"విత":252,"విన":171,"విధ":335,"విద":344,"వస్":529,"వహి":267,"సు ":228,"శము":175,"వ్య":1048,"వ్ర":129,"వ్వ":183,"షన్":215,"సంక":132,"శివ":165,"సంగ":237,"సంఘ":104,"సంవ":1416,"సంస":438,"సంబ":140,"సంప":159,"శాఖ":118,"శాన":154,"శాల":347,"శార":99,"శాస":530,"ల్ప":168,"ల్ల":3746,"ల్గ":136,"లేద":781,"వ్ ":114,"లేక":128,"లెం":508,"లోమ":231,"లోన":1869,"లోక":284,"లైన":312,"వంత":146,"వంట":147,"వంశ":116,"సం ":188,"వగా":101,"శ్ ":738,"ళ్ళ":500,"ళ్ల":102,"శంల":250,"వత్":1433,"సభ ":189,"ష్ ":119,"షి ":144,"వచ్":413},"n_words":[958347,1064684,731588],"name":"te"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tgl b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tgl new file mode 100644 index 000000000..d68c2b3df --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tgl @@ -0,0 +1 @@ +{"freq":{"D":3787,"E":3422,"F":1488,"G":3274,"A":19564,"B":7360,"C":4965,"L":4772,"M":7066,"N":4375,"O":1801,"H":3508,"I":8185,"J":1743,"K":5752,"U":1449,"T":5401,"W":1008,"V":1273,"Q":420,"P":11919,"S":10977,"R":3177,"Y":471,"X":334,"Z":463,"f":2669,"g":178562,"d":29955,"e":64572,"b":36938,"c":9968,"a":433329,"n":268000,"o":112013,"l":93919,"m":59846,"j":824,"k":54159,"h":28813,"i":161924,"w":15439,"v":3263,"u":56864,"t":84874,"s":113569,"r":58943,"q":542,"p":56795,"z":2158,"y":61992,"x":703,"Fil":231,"í":225,"é":238,"á":213,"ü":252,"ā":268,"Est":484,"Eng":311,"Ene":272," l":8609," m":26008," n":63523," o":8411," h":4923," i":23816," k":20018," d":6208," e":1886," f":514," g":3652," a":41230," b":12249," c":1285," y":708," u":3275," t":9124," w":1107," v":245," p":25524," s":37805," r":2505," J":1713," K":5573," H":3377," I":7706," N":3834," O":1616," L":4623," M":6813," B":6692," C":4389," A":18851," F":1372," G":3134," D":3532," E":3171," Z":430," Y":427," X":260," S":10261," R":2927," Q":408," P":11641," W":933," V":1041," U":1379," T":5149,"ا":230,"A ":369,"Da":1003,"Co":1457,"Ce":320,"Ch":481,"Do":225,"De":356,"Di":1582,"Fe":231,"Eu":252,"Es":754,"En":687,"Em":287,"Ge":222,"Ga":499,"I ":336,"Fr":271,"Fi":327,"C ":400,"Au":300,"Ar":695,"As":627,"Ba":3221,"Ay":1525,"Ag":601,"BC":219,"Ab":447,"Ad":339,"Am":736,"BN":257,"An":10961,"Ap":381,"Ak":282,"Al":957,"Bu":508,"Br":412,"Ca":1287,"Bi":744,"Be":555,"Bo":628,"Hil":266,"Ku":269,"Kr":232,"Ko":739,"Le":701,"Li":502,"N ":411,"La":1279,"Lu":1605,"Lo":364,"Me":527,"Mi":786,"Ma":4128,"Mu":386,"Mo":519,"Ni":284,"Ne":669,"Na":1605,"No":859,"Ok":212,"Ol":246,"Gi":363,"Gr":1131,"Go":284,"Gu":257,"Ha":926,"He":607,"Hi":663,"Ho":302,"Hu":700,"Im":288,"In":3099,"Ik":390,"Il":402,"Is":900,"It":1478,"Ir":258,"Ja":583,"Jo":504,"Ju":288,"Ka":3627,"Hap":403,"Ki":336,"Un":1045,"Tu":257,"Tr":725,"Ts":305,"To":291,"Th":568,"Ti":1025,"Te":370,"Ta":1438,"St":601,"Su":844,"Wi":302,"Wa":226,"Vi":399,"Va":226,"Pu":319,"Pr":784,"S ":239,"Pe":753,"Pa":3232,"Po":515,"Pi":5199,"Ph":519,"Or":329,"Se":751,"Sc":225,"Si":3949,"Sh":296,"So":479,"Sa":2369,"Re":1018,"Ri":307,"Ro":908,"Qu":349,"Ra":347,"Gre":522,"Gri":303,"b ":919,"a ":94136,"Sü":216,"Za":253,"i ":12212,"gd":846,"ge":1642,"ga":29192,"gb":804,"Ing":2213,"fi":306,"fo":309,"gy":549,"he":2166,"ha":12797,"gn":612,"gm":735,"gl":3792,"gk":3515,"gi":5586,"gh":1271,"gg":2300,"gu":3141,"gt":1399,"gs":3014,"gr":1126,"gp":2172,"go":3120,"dt":243,"du":1243,"dy":626,"g ":113439,"ea":1899,"eb":1161,"ec":685,"ed":1334,"de":3129,"di":5171,"do":3993,"Ilo":317,"dr":607,"ew":354,"ex":243,"eu":223,"ev":449,"ey":804,"ez":509,"fa":228,"h ":1453,"Ind":341,"fe":234,"eh":1900,"eg":2092,"ee":503,"el":4423,"ek":1455,"ei":449,"ep":1032,"eo":1328,"Imp":228,"en":9846,"em":2892,"et":2497,"es":7771,"er":9807,"ca":1369,"Ika":371,"e ":10545,"by":545,"br":2325,"bu":3483,"bo":2508,"bl":1265,"bi":7420,"be":1655,"da":7330,"f ":892,"cu":348,"ct":832,"cr":267,"co":1527,"ck":419,"ci":1114,"ch":1408,"ce":1134,"cc":244,"c ":679,"az":285,"ay":33855,"ba":16262,"d ":6470,"at":29146,"as":20781,"ar":16773,"aw":10001,"av":702,"au":1712,"ak":11317,"al":29791,"ai":3152,"ao":3807,"ap":8378,"am":13495,"an":101085,"ac":1440,"ad":5449,"aa":5389,"ab":8765,"ag":22898,"ah":9461,"ae":824,"nu":2551,"nt":6347,"ns":5167,"no":9894,"nn":491,"ny":2397,"of":922,"oc":711,"od":3388,"oa":467,"ob":1692,"om":3049,"on":28949,"ok":1666,"ol":5417,"oi":423,"og":2491,"oh":829,"ot":1896,"os":4877,"ov":562,"ou":1121,"op":3555,"oo":5633,"or":6366,"r ":5313,"ow":489,"oy":1082,"pe":2826,"pa":25955,"pl":758,"po":5042,"ph":416,"pi":11096,"lo":7059,"lm":376,"ll":2040,"ls":232,"lp":216,"lu":4808,"lt":766,"ly":1884,"o ":35938,"ma":23630,"mb":3361,"mg":9391,"me":3130,"mi":5214,"mm":511,"mp":3371,"mo":2915,"mu":4995,"p ":2357,"na":50921,"nc":944,"nd":5861,"ne":3717,"ng":124226,"ni":11322,"nl":1083,"ki":5108,"kh":660,"ke":653,"kb":240,"ka":28062,"m ":2592,"ky":234,"ks":1102,"kt":1232,"ku":3832,"ko":5455,"kr":397,"kl":2445,"li":16771,"le":7298,"ld":536,"la":41710,"lb":521,"n ":41545,"hr":229,"hu":1485,"hi":7425,"hn":275,"ho":2024,"id":2936,"ic":2306,"ib":3763,"ia":4281,"ih":1209,"ig":7316,"if":239,"ie":1122,"hy":251,"k ":4018,"ir":2572,"is":21654,"it":15297,"iu":510,"iv":697,"iw":1139,"ii":644,"ik":10689,"il":18574,"im":4535,"in":32448,"io":2262,"ip":8303,"iz":356,"iy":6303,"l ":8749,"ja":305,"z ":468,"wi":4192,"wo":282,"ws":238,"y ":26266,"wa":7331,"we":663,"vi":929,"vo":293,"uz":222,"uy":540,"uw":938,"uu":278,"ve":1065,"va":717,"x ":270,"ui":867,"uk":2223,"ul":10829,"ue":1048,"ug":2281,"uh":1222,"ur":4663,"us":3997,"ut":2718,"um":4571,"un":11124,"uo":841,"up":1559,"ty":936,"tu":5349,"tt":423,"tw":245,"ub":2276,"ua":2314,"ud":744,"uc":353,"w ":2307,"to":12113,"tn":494,"tl":670,"ts":639,"tr":2947,"te":5598,"ti":12280,"th":1499,"ta":23206,"su":2916,"ss":697,"st":7061,"sy":6204,"sl":357,"sk":592,"sm":643,"sp":948,"so":5456,"sc":415,"se":6243,"sh":1082,"si":9719,"u ":1011,"sa":50153,"rr":466,"rs":1459,"rt":2397,"ru":1218,"ry":2421,"rp":226,"ro":6522,"rn":1128,"rm":690,"rl":534,"rk":708,"ri":11065,"rg":616,"re":7270,"rd":981,"rc":435,"rb":496,"ra":14328,"t ":17794,"qu":482,"s ":20143,"py":238,"pt":257,"pu":5533,"pp":386,"pr":1443,"Hul":231,"za":466,"zo":453,"ye":2458,"ya":16851,"yb":251,"yu":966,"yt":264,"ys":635,"yr":507,"yo":11759,"yn":980,"Ara":274,"Apr":218,"Asy":352,"Ayo":1506,"Bag":274,"Ban":328,"Bay":1488,"Bat":317,"Abr":300,"Adi":220,"Ago":307,"BN ":257,"Ale":251,"Alt":229,"Ame":579,"Ang":10467,"Car":262,"Bib":239,"Com":233,"Col":584,"Dis":592,"üd":216,"Nat":309,"New":234,"Nag":476,"Nor":372,"Nob":295,"Pin":243,"Pil":4628,"Phi":298,"Per":237,"Pas":236,"Par":288,"Pag":236,"Pan":1029,"Pam":480,"Pal":436,"Pro":250,"Pra":302,"Que":246,"Isa":506,"Ita":502,"Ito":837,"Jam":280,"Jos":222,"Kab":349,"Kag":252,"Kal":869,"Kan":214,"Kat":442,"Kas":598,"Kar":312,"Kon":276,"Leo":280,"Lat":224,"Lun":1069,"Man":377,"Mal":287,"Mar":952,"May":1105,"Mat":220,"Min":268,"Süd":214,"Zam":212,"一":621,"一一":311,"Sur":412,"Sta":256,"Tag":668,"Siy":420,"Sil":411,"Set":224,"Si ":2472,"Sam":277,"Sal":320,"San":795,"Sa ":539,"Rey":251,"Rep":257,"Rom":461,"Uni":749,"The":357,"Tim":465,"Tin":234,"Tre":501,"Tsi":277,"bis":856,"bit":236,"bil":2673,"bin":1170,"big":1028,"bo ":562,"bli":613,"bla":330,"bol":310,"bon":590,"ban":3506,"bak":379,"bal":915,"bag":1029,"bah":2518,"bae":247,"bab":1067,"bay":2496,"baw":340,"bat":1046,"bas":870,"bar":318,"bi ":266,"ber":655,"bel":279,"bib":346,"bid":220,"ca ":245,"can":254,"ce ":518,"bri":332,"bra":317,"bre":1519,"buo":641,"bul":259,"bun":360,"bum":222,"buh":438,"but":324,"bye":332,"aka":4840,"am ":867,"aki":2053,"akh":385,"al ":4667,"ail":347,"ain":942,"ais":377,"ak ":1818,"aig":364,"ahi":1712,"ahu":567,"aho":893,"aha":5905,"agk":1800,"agl":815,"agm":409,"agg":261,"agh":599,"agi":2389,"ags":1175,"agt":890,"agu":765,"ago":873,"agp":2086,"anu":622,"any":1534,"ano":2033,"ant":1925,"ans":2023,"ane":370,"ang":54220,"ani":2704,"anl":847,"ap ":1248,"ana":5631,"anc":342,"and":2377,"amu":411,"amo":399,"amp":1054,"ami":2241,"ame":660,"amb":1287,"ama":6244,"ao ":2560,"aly":681,"alu":885,"alo":1422,"alm":256,"all":403,"ali":4268,"ale":940,"ala":15201,"alb":295,"an ":25875,"aku":295,"akt":378,"ako":347,"akl":349,"aba":5223,"abe":285,"abi":1848,"abo":410,"abu":558,"ae ":378,"aca":217,"aaa":370,"aan":2340,"aal":228,"aas":476,"aar":1310,"ad ":1547,"aga":6180,"agb":737,"agd":421,"ado":1685,"adi":344,"ade":215,"ag ":2962,"ada":1065,"ayo":1284,"ayn":676,"ays":426,"ayr":437,"ayu":244,"ayb":228,"aya":7316,"ba ":1007,"at ":11450,"are":434,"ard":406,"arc":218,"ara":6094,"aro":928,"arl":281,"ark":258,"ari":2740,"ars":347,"art":1318,"asa":4127,"ary":1252,"asi":1053,"ase":1923,"aso":401,"aon":1107,"ar ":1507,"apa":4168,"api":926,"apo":968,"apu":525,"as ":8041,"avi":292,"ay ":22870,"awa":4711,"awi":3261,"ata":9859,"asu":540,"ast":1119,"asy":2814,"atl":420,"ato":908,"ate":772,"ati":3674,"ath":277,"aw ":1870,"atu":1238,"aun":478,"aug":319,"itn":327,"ito":5794,"itu":365,"ity":376,"üdt":214,"ism":492,"ist":2727,"isy":1436,"ita":2453,"ite":522,"iti":1834,"iwa":1084,"ius":321,"ive":465,"ipo":219,"ipp":279,"ipi":5953,"is ":1468,"ion":1384,"ipa":894,"iro":325,"iri":318,"isi":1179,"ish":487,"ise":486,"isa":12350,"ire":294,"ira":1126,"it ":3154,"iyo":1973,"iya":3692,"iye":538,"kik":335,"kil":1497,"kin":1435,"kip":244,"kit":510,"ki ":400,"kha":550,"koy":367,"kop":294,"kon":1105,"kom":504,"kol":972,"ko ":1504,"kla":2111,"kay":687,"kat":4082,"kau":481,"kar":1361,"kas":2326,"kap":1524,"kan":3294,"kal":2502,"kam":987,"kak":1114,"kah":780,"kai":697,"kag":306,"kad":618,"kab":2686,"kaa":306,"ka ":4085," Ga":496," Ge":219," Fr":268," Fi":324," Ha":926," He":600," Go":283," Gr":1130," Gu":254," Gi":361," Hu":696," Ho":300,"ha ":509," Hi":657," Ja":583," Ir":258," Is":900," It":1471," Im":284," In":3092," Ik":389," Il":402,"ham":439,"han":3970," Ka":3625,"hal":1546," Ki":335,"har":726,"has":418,"hat":613," Jo":502," Ju":282,"hah":296,"hag":932,"hab":327," La":1273," Le":698," Li":486," Ko":738," Kr":232,"hay":2401," Ku":269," Ma":4113," Mi":784," Me":525,"he ":726," Lo":362," Lu":1602," Ne":660," Na":1601," Ni":283," Mo":516," Mu":380,"her":391,"hen":301,"hi ":256," Ap":381," Am":732," An":10945," Ak":280," Al":957," Ag":601," Ad":338," Ab":444," Ba":3213," Ay":1524," Au":300," As":625," Ar":684,"hig":262," Be":553," Bi":731,"hip":233,"hin":2102,"him":317," Bo":624,"hil":1124," Br":411," Bu":508,"hit":252,"hiy":1822," Ca":1275," Ce":318," Ch":477," Co":1435," Da":1001," Di":1559," De":354," Do":218," Es":753," En":683," Em":287," Eu":251," Fe":229,"gma":404,"go ":1131," Sü":216,"gle":2258,"gli":561,"gla":763," Wi":299,"gko":362," Wa":224," Za":253,"gna":429,"gmu":288,"gpu":1231,"gpa":814,"gon":726,"gos":419,"gor":456,"gsa":661,"gsi":395,"gra":396,"gre":308," Or":329," Po":510,"gui":242," Pi":5194,"gum":355," Ph":516,"gul":619," Pe":751," Pa":3220,"gsu":217,"gso":1676," No":856," Ol":245," Ok":212,"gta":876," Ra":342," Qu":347," Ro":902," Re":1013," Ri":307," Pr":781,"gus":319," Pu":319,"gun":828," Su":840," St":567," Ta":1427,"gya":341," Th":565," Ti":1025," Te":369," Tr":725," Ts":304," To":289," Sa":2358," Sh":292," Si":3946," Sc":224," Se":748," So":478," Va":226," Vi":396," Tu":256," Un":1043,"ial":214,"ian":1841," ip":821," im":295," in":1205," ik":2724," il":559,"ic ":391," is":12317," it":4118,"ibl":298,"ibi":852," ka":12843,"ibo":539," ki":1772,"id ":624,"iba":1373,"ibe":241," ha":2342," he":266," gi":1221," gr":273,"ia ":1668," gu":642," ib":1270," hi":1628," hu":502," ni":3203," ng":29501," ne":259,"ien":313," na":26725," mu":2405,"ig ":1084," mo":343," of":748," no":3658," le":482,"ict":361," li":1169," la":4719," ku":1926,"ich":298," kl":1518,"ica":454," ko":1618," me":432," mg":9378," mi":835," o ":6532,"ido":754," ma":12562," lu":1621,"ide":429,"ida":693," lo":567," ag":287," aa":479," an":11487," ap":351," ak":588," al":688," aw":224," ar":1782," at":8491,"iit":294," as":396," ba":6398," ay":15608,"il ":1019," bi":3286," be":279," bo":263," bl":303," bu":1574," ca":215,"im ":631,"ika":5845,"igd":340,"ige":351,"iga":3450,"igm":226,"igi":608,"iha":656,"ihi":488,"ik ":530,"imo":757," es":477," em":253,"imp":821," el":218,"ime":284," ek":212,"imi":396,"ip ":377,"ind":1253,"ina":12544,"imu":413,"ino":1637,"int":735,"ins":494,"ine":925,"ing":7215,"ini":1991," ga":1201,"inu":1256,"iko":1955," co":595,"iki":665,"ila":8566,"in ":3710," da":2205,"iku":803,"iks":322,"ilo":675,"ill":466," de":1318,"ili":6551," di":1938,"ima":551,"imb":583,"io ":525,"ily":587," du":359,"hol":219,"hon":897," ye":394,"hul":550," sa":28976," se":2207," si":4160," so":365," t ":331," re":1237," ri":835," pu":1239," pr":891," s ":272,"hum":213," op":300," or":499," pe":850," pa":17344," pl":235," po":2264," pi":2508," wa":403," wi":495," tu":1581," ur":1186," up":417," um":236," un":787," ta":3807," su":1227," tr":542," th":440," ti":1513," te":623,"eyn":227,"eta":377,"eti":227,"esp":220,"eso":216,"est":873,"ess":243,"esy":238,"eto":217,"etr":240,"ety":252,"ey ":259,"er ":1701,"es ":4679,"epu":270,"eri":1261,"ere":336,"era":1743,"erb":250,"et ":365,"esi":397,"ery":584,"ert":284,"ers":877,"ern":685,"erm":213,"ero":994,"eks":315,"ekt":395,"en ":605,"ela":487,"ele":614,"eli":929,"ell":447,"eo ":676,"emb":1031,"ema":617,"eme":244,"emo":250,"emi":251,"emp":247,"ene":540,"eng":2031,"ena":338,"end":702,"enc":265,"ens":1983,"ent":2381,"ego":798,"ege":495,"ehi":1394,"el ":1262,"eka":275,"gka":2797,"git":1186,"gis":283,"gil":253,"gin":2170,"gha":696,"ggi":233,"gga":1607,"gi ":930,"gen":305,"gda":265,"gdi":448,"ge ":872,"gbi":301,"gba":311,"gag":358,"gah":212,"gas":721,"gar":389,"gat":1029,"gaw":951,"gay":1184,"gam":1160,"gal":2016,"gan":8911,"gap":698,"ga ":10893,"da ":1215,"de ":630,"dad":487,"daa":229,"dal":1278,"dai":337,"dag":294,"dah":789,"dat":526,"dar":615,"dan":716,"dam":364,"cti":321,"co ":247,"com":405,"ch ":248,"cha":297,"cia":252,"ck ":232,"che":214,"ed ":364,"ebr":372,"ean":218,"ear":435,"eap":318,"ea ":269,"ega":369,"edi":305,"dya":287,"dor":701,"don":511,"dos":801,"dti":217,"dul":227,"duk":249,"dia":320,"der":377,"des":307,"del":555,"dek":245,"den":404,"di ":862,"do ":1342,"diy":230,"din":1025,"dis":689,"dit":243,"dig":691,"rga":250,"ri ":1883,"res":909,"rea":358,"reg":609,"reh":760,"ren":823,"rel":229,"rer":338,"re ":1785,"raw":1292,"rd ":279,"rap":411,"ras":562,"rat":708,"rag":342,"ran":3019,"ram":928,"ral":1710,"rab":295,"raa":290,"rad":734,"rs ":234,"ros":487,"rot":255,"ron":875,"roo":656,"rop":486,"rod":249,"rol":389,"rna":412,"rne":221,"ro ":2000,"rma":307,"riy":449,"rit":895,"ris":641,"rig":228,"ril":614,"rik":932,"rin":2120,"ria":1493,"ric":296,"rie":322,"rk ":265,"rya":408,"rup":247,"rus":239,"ry ":568,"rsi":370,"rso":362,"rte":436,"rti":1012,"saa":543,"sab":432,"sag":340,"sah":246,"sak":534,"sal":1402,"sam":846,"sap":373,"san":13859,"sas":644,"sar":588,"say":842,"sa ":29066,"ryo":1185,"shi":267,"si ":909,"siy":1352,"sid":252,"sia":279,"sit":454,"sis":871,"sip":588,"sin":2020,"sil":886,"sim":530,"sik":667,"sig":229,"se ":703,"ser":748,"ses":480,"sh ":511,"sen":3264,"spe":263,"spa":238,"son":453,"sod":1704,"st ":395,"ss ":216,"sla":213,"smo":455,"so ":2182,"sye":492,"sya":1319,"syo":3972,"syu":310,"ste":723,"sta":2233,"sto":847,"sti":1338,"str":1197,"sub":226,"sul":377,"sum":409,"suk":222,"sun":606,"sus":423,"tak":378,"tal":1825,"tag":2356,"taa":516,"tab":313,"tad":729,"tay":910,"taw":1462,"tat":2169,"tas":1294,"tar":426,"tap":454,"tao":2928,"tan":3973,"tam":283,"te ":1421,"ta ":2620,"pa ":793,"par":2056,"pat":1511,"pas":473,"pay":244,"paa":836,"pab":282,"pag":5944,"pah":588,"pak":582,"pal":1553,"pap":964,"pam":2183,"pan":7375,"pi ":308,"per":1160,"pel":619,"pla":312,"pik":487,"pil":381,"pin":8127,"pis":517,"pit":481,"por":477,"pop":1613,"pos":639,"pon":910,"pol":471,"ppi":245,"po ":494,"pua":1158,"pub":334,"pri":362,"pre":283,"pro":666,"put":222,"pun":775,"pul":2278,"ra ":2777,"ngo":322,"ngi":702,"ngl":2579,"ngk":1509,"ngu":1141,"ngr":246,"ngs":1763,"ni ":1903,"nge":218,"ngg":1999,"ngh":357,"nga":5141,"nel":268,"ner":635,"net":328,"nes":773,"ng ":107416,"nce":344,"ne ":832,"ndu":336,"ndo":855,"ndi":1104,"nde":357,"nda":2122,"nak":3214,"nal":1987,"nam":1069,"nan":5284,"nao":281,"nap":1249,"nar":667,"nad":394,"nag":3410,"nah":1201,"nai":343,"nab":490,"nd ":696,"nau":287,"nat":2025,"nas":5521,"nay":628,"naw":416,"na ":22155,"nya":1473,"nul":380,"num":251,"nun":621,"nus":223,"nut":274,"nub":254,"nto":1170,"ntu":218,"ntr":369,"nti":1113,"nta":1619,"nte":1041,"nsy":292,"nso":1561,"nst":288,"nse":338,"nsi":398,"nsa":1639,"nt ":493,"ns ":315,"nod":444,"noo":3554,"nom":260,"non":1292,"nla":384,"no ":3206,"nlu":471,"nid":488,"nib":262,"nia":263,"niy":508,"niw":515,"niv":230,"nis":952,"nit":1670,"nim":327,"nin":947,"nik":402,"nil":1831,"ogr":242,"ohi":487,"ok ":961,"ol ":1113,"oby":351,"ode":251,"of ":743,"og ":1738,"ob ":490,"od ":2512,"obe":281,"nyo":656,"oto":243,"ost":571,"ota":234,"osi":296,"ose":518,"oso":256,"oy ":861,"oun":298,"opo":245,"opi":377,"ope":331,"os ":2497,"opu":1605,"oon":4273,"ook":406,"oob":454,"or ":1386,"ork":236,"orm":244,"oro":293,"ord":364,"ore":565,"org":297,"ori":875,"osa":225,"ort":603,"ory":303,"ot ":787,"ora":483,"ola":327,"on ":10511,"oli":798,"oll":560,"ole":828,"olo":1158,"ona":1108,"ond":258,"one":582,"ong":14203,"oni":381,"ono":505,"ons":429,"ont":363,"ony":253,"oma":662,"ome":348,"omi":484,"omm":343,"omp":399,"omo":218,"op ":492,"la ":7051,"le ":657,"laa":472,"lab":1035,"lad":618,"lah":600,"lag":1451,"lal":5124,"lak":2054,"lan":8966,"lam":1407,"lap":417,"lar":1484,"lat":1650,"las":3731,"law":4043,"lay":1014,"lba":235,"ld ":260,"kuy":222,"kun":1182,"kum":367,"kul":1301,"ksy":373,"ksi":218,"ktu":302,"kto":418,"lon":1346,"loo":506,"lor":222,"loh":474,"log":979,"los":411,"lto":257,"lug":603,"li ":620,"les":2603,"lem":360,"len":771,"leh":645,"leg":553,"lea":415,"lo ":1738,"lla":492,"lle":760,"ll ":320,"lit":1575,"lis":938,"lip":5499,"lin":1820,"lim":971,"liy":225,"lic":224,"lid":294,"lia":495,"lib":291,"lik":1738,"lil":346,"lii":293,"lig":604,"lih":227,"ma ":1406,"maa":656,"mab":485,"mah":1161,"mai":353,"mak":856,"mad":287,"mag":1774,"map":283,"mar":866,"mas":904,"mal":1856,"mam":1144,"man":4514,"may":4380,"mat":2454,"mba":1424,"mbr":990,"mbo":357,"me ":332,"med":215,"met":267,"mes":455,"mer":827,"men":704,"luk":293,"lup":252,"lun":1075,"lum":601,"lut":234,"lus":323,"lur":429,"lya":1073,"lyo":437,"mpi":405,"mpe":729,"mpo":376,"mpu":307,"mog":636,"mon":703,"mot":220,"mpa":1165,"mus":340,"mut":297,"mul":2510,"mun":975,"mga":9380,"min":1128,"mil":657,"mis":408,"mit":1305,"mik":544,"mo ":604,"mmu":273,"zon":372,"yun":445,"ysa":370,"yro":432,"yos":430,"yon":8581,"yea":322,"yeg":287,"yen":248,"yem":924,"ya ":5481,"yag":346,"yar":349,"yan":8889,"yal":500,"yo ":2106,"yna":235,"yni":658,"wit":490,"wig":2597,"wik":476,"wa ":1340,"wan":2646,"wal":851,"wak":321,"wat":242,"war":240,"wag":936,"ver":481,"ve ":253,"va ":222,"uya":331,"uwe":288,"uwa":445,"usi":309,"usa":537,"usy":243,"usu":363,"ust":456,"uti":335,"ute":297,"uta":417,"utu":829,"uto":373,"us ":1413,"ura":1051,"ure":277,"uri":1726,"uro":457,"uny":224,"uon":264,"upa":766,"ur ":441,"upo":374,"ump":364,"umu":925,"umi":469,"uma":1769,"umb":268,"uly":233,"uo ":439,"unt":520,"unu":378,"uni":882,"uno":1281,"und":796,"una":2530,"ung":3950,"uku":387,"uko":610,"um ":503,"uka":453,"ulu":1033,"ult":291,"ulo":1229,"uli":710,"ula":6857,"uin":299,"ugn":288,"uga":1124,"uha":936,"ubo":309,"ubr":217,"ubu":535,"ue ":245,"uez":255,"uan":1897,"ubi":307,"ubl":385,"uba":263,"tye":228,"ty ":596,"tur":814,"tut":349,"tul":834,"tuk":407,"tun":595,"tum":594,"tub":614,"tra":868,"tri":838,"tro":879,"to ":7587,"tna":387,"tom":241,"ton":2028,"tol":467,"tor":922,"til":777,"tik":1397,"tig":242,"tir":721,"tit":772,"tis":888,"tin":3062,"tim":775,"tip":230,"tio":1023,"tib":304,"tid":407,"tiy":331,"tlo":414,"tem":511,"ten":352,"tel":392,"th ":280,"tes":226,"ter":1925,"ti ":555,"the":612,"tha":237},"n_words":[2110634,2489828,1864789],"name":"tl"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tha b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tha new file mode 100644 index 000000000..2852f4340 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tha @@ -0,0 +1 @@ +{"freq":{"D":2767,"E":2382,"F":1744,"G":2229,"A":4566,"B":2837,"C":4944,"L":2537,"M":3661,"N":2375,"O":1879,"H":2029,"I":2684,"J":1202,"K":1239,"U":982,"T":3940,"W":1428,"V":1153,"P":3623,"S":5025,"R":2458,"f":4548,"g":7700,"d":10407,"e":36793,"b":4586,"c":13011,"a":35754,"n":27098,"o":27360,"l":17507,"m":9775,"k":3233,"h":11517,"i":30062,"w":2927,"v":3191,"u":11836,"t":23508,"s":19258,"r":25409,"p":8180,"z":1147,"y":6708,"x":1329,"ี่ก":1219,"ี่ค":798,"ี่จ":1624,"ี่แ":1639,"ี้ย":1300,"ี่เ":7102,"ี่ไ":1804,"ี่ใ":2548,"ี่ท":1342,"ี่น":1525,"ี่ต":2048,"ี่ม":5943,"ี่ย":5902,"ี่ป":3449,"ี่พ":1219,"ี้จ":758,"ี่ส":5079,"ี่ร":1809,"ี่ห":1170,"ี่อ":2340,"ู่ ":1041,"ี้เ":1017," l":799," m":1059,"ึกษ":2877," o":2241," h":734," i":844," d":1129," e":750," f":963," a":1997," b":936," c":1950," t":2090," p":1738," s":2098," J":1111," K":1075," H":1671," I":1700," N":1646," O":1116," L":1847," M":2970," B":2345," C":3940," A":3318," F":1429," G":1940," D":1996," E":1607," S":3963," R":1952," P":2925," W":1239," V":824," T":2982,"ีปร":905,"ีนา":987,"ีวิ":1802,"ิ่ง":2648,"ีลั":1263,"ีรถ":1177,"ิโล":1164,"ีย์":1013,"ียบ":1082,"ียน":6852,"ียร":1356,"ียม":1021,"ียว":3305,"ียก":3983,"ิเม":917,"ียง":6904,"ิเว":1991,"ีฬา":1237,"ิ่น":1155,"ิ่ม":2587,"ิ้น":1155,"Co":1009,"Ch":760,"ือ ":11318,"ิทย":5393,"ิทธ":1425,"ินส":994,"ินแ":951,"ินเ":2159,"ินท":2179,"ิธี":1094,"ุด ":981,"Ma":1030,"ำแห":1099,"ิยม":1454,"ิมพ":1364,"ำเภ":2344,"ำเน":1700,"ีขน":839,"ีกา":2681,"ิภา":937,"ำให":1486,"ิร์":1529,"ิริ":860," ศ ":10355,"ีคว":2479,"ิย์":865,"ิยา":1638,"ิลป":1713,"ิวเ":1224,"Th":1304,"ิศา":1224,"ิสต":1802,"ิษั":1436,"ีชื":1806,"ิหา":1129," พ ":6930,"a ":4409,"ีที":1523,"i ":1629,"ge":1151,"he":3360,"ha":1753,"g ":1914,"ea":1472,"ec":1050,"ำตั":743,"ed":1616,"de":1807,"di":1292," ค ":3588,"h ":1481,"ำดั":807,"el":1781,"en":3747,"em":1263,"et":1470,"es":2908,"er":5983,"ca":1761,"e ":9681,"be":757,"da":1163,"f ":1782,"ct":1070,"co":1453,"ci":974,"ch":1872,"ce":1660,"ำนั":1183,"ำนา":1182,"c ":1262,"ำนว":1889,"ำบล":1639,"d ":3285,"at":4029,"as":1743,"ar":4079,"al":3985,"ai":1077,"ap":790,"am":1525,"an":5743,"ac":1436,"ad":868,"ag":1036,"ae":972,"nt":2832,"ns":1221,"no":1065,"ิกส":1152,"of":1717,"oc":793,"od":802,"om":1831,"on":5797,"ol":1972,"ot":991,"os":1228,"ou":1259,"op":973,"or":3612,"r ":3528,"pe":1355,"pa":819,"po":838,"ph":815,"lo":1494,"ll":1602,"o ":1832,"ma":1651,"me":1665,"mi":1301,"p ":991,"na":2372,"nc":1198,"nd":2063,"ne":2324,"ng":2747,"ni":2058,"าใน":1710,"m ":1949,"li":2285,"le":2488,"la":2669,"n ":6518,"ht":776,"hi":1241,"าแล":1356,"ho":994,"id":1548,"ic":3537,"ia":2041,"ig":855,"ie":1170,"k ":958,"ir":922,"is":2584,"it":2279,"il":1527,"าเร":879,"in":5078,"าเล":858,"io":2597,"าเป":2477,"ิกา":4876,"l ":3592,"ิงเ":1081,"ำว่":911,"y ":3290,"ve":1463,"ul":919,"ur":1530,"us":1967,"ut":915,"um":918,"un":1108,"ty":767,"tu":815,"tt":965,"ิงห":822,"to":1767,"ำหร":2147,"tr":1441,"te":3369,"ำหน":2147,"ti":3875,"th":2569,"ta":2328,"ss":1290,"st":2642,"so":847,"se":1374,"si":1814,"่":261149,"้":168823,"๊":2314,"๋":1031,"์":89548,"เ":290692,"rs":890,"แ":101902,"rt":1263,"โ":60108,"ใ":72132,"ไ":49049,"ๆ":5416,"ry":1040,"็":73338,"ro":2585,"ู":59743,"ุ":70364,"ื":81927,"ri":3400,"ึ":35498,"ี":202861,"ิ":162696,"re":2827,"ำ":45160,"า":458974,"rd":813,"ั":226972,"ะ":131072,"ฮ":6759,"ra":3541,"ฯ":856,"t ":3621,"ฬ":1901,"ิชา":1303,"อ":306842,"ส":153652,"ห":123525,"ศ":53898,"ษ":33643,"ว":181464,"ฤ":7018,"ล":179449,"ย":192630,"ร":390285,"ภ":30986,"ม":229909,"ฝ":4270,"ผ":20687,"ฟ":16906,"พ":93163,"น":423152,"ธ":26604,"ป":143207,"บ":116540,"ต":148116,"ด":152617,"ท":165794,"ถ":31675,"ฑ":2084,"ฐ":9273,"ณ":25387,"ฒ":2670,"ญ":19027,"s ":7041,"ฎ":2682,"ฏ":3414,"จ":90844,"ฉ":5998,"ช":80847,"ซ":33709,"ค":113272,"ฆ":1276,"ง":265772,"ก":280773,"ข":76134,"ิดา":785,"ิดห":1109,"ิติ":1042,"ิตา":823,"ิตร":1253,"ิดเ":1452,"ิตย":978,"ิดต":796,"ิดจ":807,"ิดข":1153,"ิดก":963,"าพั":805,"ามก":1469,"ามค":978,"ำกั":1274,"ามป":1047,"ายค":1118,"ามร":1484,"ายก":2414,"ายข":1115,"ามห":1771,"ายช":1084,"ามส":2270,"ายท":1440,"ายถ":2265,"ามี":784,"ายต":803,"ามา":3948,"ายน":2971,"ารจ":1307,"ายว":810,"ามแ":1031,"ารค":1595,"ารก":1847,"ามเ":3279,"ารข":1167,"ายอ":907,"ายส":1187,"ายห":1214,"าบั":892,"าปร":879," ผ":2939," ฟ":1382," พ":16963," น":7737," ธ":1538," ป":9774," บ":5180," ต":11154," ด":4226," ท":12249," ถ":2578," ณ":758," จ":10643," ช":5003," ซ":8285," ค":16867," ก":16644," ข":5596,"าพร":989,"าพย":2192,"ิ์ ":838,"าที":3260,"านก":1639,"านข":1418,"านค":1839,"าทส":973,"านน":858,"านท":1970,"าธิ":1501,"านต":791,"าธา":1105,"านใ":891,"านเ":2380,"านแ":1122,"านห":886,"านอ":1049,"านส":931,"านี":3469,"านา":1107,"านั":986,"าณา":1725,"าดเ":977,"าตุ":736,"าติ":3417,"าตั":740,"าตร":1001,"าดใ":893,"ี้ ":1390,"ี่ ":11834,"าหล":992,"าหา":1172,"าอย":985,"าอา":792,"าอั":1363," ล":3504," ว":6837,"ั่ง":3130," ม":16388," ภ":4698," ร":8182," ย":2545," อ":16304,"าศา":1885," ฮ":1180," ศ":11904," ห":17474," ส":15924,"าศั":834,"าวเ":1521," ๆ":1601," ไ":6086," ใ":10228," โ":13479," แ":27651," เ":59355,"าวิ":2918,"าวอ":979,"าสา":971,"ั้น":6620,"าสน":1688,"ั้ม":1016,"ั่ว":2312,"าษา":8207,"าสต":5817,"ั่น":1240,"ั้ง":16337,"าร์":6532,"ารแ":3430,"ารใ":1567,"ารเ":5283,"ารี":821,"ำคั":1775,"ารา":3089,"ารอ":1573,"ารส":2796,"ารศ":1222,"ารว":1014,"ายใ":2848,"ารร":1717,"ายแ":1390,"ารย":1381,"ายเ":3128,"ารพ":1130,"ารป":2397,"ารน":1040,"ารบ":1445,"ารท":2651,"ารต":1493,"ารถ":2935,"ายา":887,"ารณ":2161,"ารด":1027,"าลี":979,"าลั":2863,"ากค":746,"ากก":2663,"ากน":1203,"ากท":1139,"ากฏ":908,"ากอ":816,"ากส":915,"ะเจ":2079,"ากล":1523,"ากร":2608,"ากม":872,"ะเก":848,"ับอ":925,"ับส":1520,"ับเ":2350,"ับแ":746,"ันด":1864,"ันต":2569,"ันท":6775,"ันน":1059,"ันธ":3528,"ับก":2418,"ับค":1139,"ันย":781,"ันว":1287,"ันส":772,"ันอ":2900,"ับท":1243,"ับป":1271,"ันใ":1276,"ับร":1129,"ันแ":786,"ันเ":2354,"ันไ":773,"ันก":1116,"ัตร":1718,"ัดเ":1458,"ัตถ":1084,"ัดอ":823,"ัดส":1175,"ัติ":3172,"ัตว":1677,"ัดก":1357,"ัณฑ":1093," ๆ ":1525,"ัฐอ":1242,"ัฒน":2389,"ึง ":1975,"ีย ":3548,"าชน":1229,"าชว":1452,"าชอ":929,"าชิ":1510,"าชา":1285,"าชก":821,"ัวเ":1510,"ัศน":1087,"าจั":1830,"าจา":3547,"างๆ":1330,"ัวอ":898,"างเ":3767,"างไ":829,"ัวล":1090,"างใ":893,"างแ":1340,"างอ":972,"างส":1811,"างห":1367,"างว":1756,"างม":850,"างร":1234,"างป":1308,"างต":1708,"างท":1838,"างด":961,"างช":741,"างจ":1536,"างค":2031,"างข":1895,"างก":3719,"ัลบ":846,"ะได":777,"าคา":932,"าคม":4556,"าขา":1162,"ะเล":1717,"ากเ":1543,"ะเภ":1470,"าขอ":2080,"ีน ":1380,"ะเท":8450,"ากั":1026,"ากา":3774,"ัมพ":821,"ะเป":3470,"ะทร":812,"ะทา":1011,"ะที":1426,"ะทำ":752," เก":2484," เข":1752," เค":1359," เจ":1771," เช":2450," เซ":916," เด":1861," เท":1287," เน":1184," เป":26794," เพ":2641,"ะบบ":2022,"ะนา":1109,"ะปร":1082,"ะบา":1151,"ิต ":1048,"ิด ":1226,"ิง ":1118,"ะดั":1976,"ะดู":960,"ีก ":1051,"ะวั":4431," อย":1707,"ังเ":1838," อำ":1631," อิ":974," อั":2991," อา":2413,"ะสา":867," ออ":1734,"ิม ":803," วั":2877," วิ":1583,"ะอง":1516,"ัญญ":1369,"ะหว":2921,"ัญช":920," สถ":1382," สม":1526," หน":1504," สุ":760," สำ":1162," สา":2037," สิ":1143," สั":1226," ส่":1561," หร":10471," หล":1146," หม":2524,"ักด":1151," รว":890,"ักษ":6831," ระ":1251," รั":1312,"ักร":4702," รา":1609,"ะพุ":1098,"ะพั":826,"ักจ":822,"ักก":1221,"ะมา":2026,"ะมี":2632,"ะยั":766,"ะยะ":834,"ิน ":3149,"ักเ":1448,"ะยา":744," ภา":4274,"ะรา":2815," มี":8842," มั":898," มา":1778," มิ":1110,"ัจจ":2448,"ังส":1789,"ังห":4456," มห":1285,"ังก":5613,"ังค":1611,"ังจ":853,"アアア":748," พร":4751," พฤ":1063," ผู":1667," ปล":779," ปร":4492," ปี":1463," ปั":1211," บร":1264," บา":1052," นิ":1151," นั":2273," นา":1380," ทร":1302," ที":5982," ทำ":956," ทั":838," ทา":1100," ต่":814,"าล ":975," ถน":741," ตา":1753," ตั":4204," ตำ":1120," ตร":740,"าร ":2963,"าว ":2585,"ิก ":1504,"ะจั":762,"ะจำ":1148," ชา":799," ชื":1329," ซึ":6040," จำ":738," จา":1386," จั":3956," จะ":808,"ะชา":1877," คื":4533," คำ":751,"ะกอ":2553," คว":1268," ขอ":3435," ก่":1078," คร":1482," คน":1274,"ะคร":1889," กิ":1156," กั":1618," กา":4296," กล":1472," กร":3165,"ะกู":837,"ะกา":2005,"เคร":3765,"เคย":899,"เข้":3046,"เคล":946,"เกี":2538,"เกา":1880,"เกิ":4857,"เขต":2529,"เกล":1212,"เกม":1559,"เกร":925,"เขี":2819,"เขา":2400,"เก็":770,"ใน ":1513,"เซี":1618,"เจ้":6297,"เฉี":1063,"เชื":1779,"เชิ":917,"เชี":2100,"เช่":2859,"เซล":810,"เงิ":900,"เฉพ":1150,"ู้เ":1092,"ู่ห":1111,"ู้จ":1153,"ู่ท":2435,"ู่บ":1069,"ู่ใ":3858,"ู่เ":814,"ู้ท":742,"ア":1141,"ุ่น":2796,"ุ่ม":4128,"ุ่ง":863,"ูมิ":1515,"ูปแ":1059,"ูนย":864,"ื่อ":28338,"ุษย":1008,"ื่น":2592,"ื้อ":3123,"ื้น":2966,"ุรี":1349,"ุริ":781,"ุทร":864,"ุทธ":2795,"ุบั":2386,"ือเ":2326,"ือท":952,"ือน":2586,"ือส":1106,"ืออ":845,"ือว":1045,"ุดท":873,"ุดใ":860,"ุตร":863,"ุงเ":1324,"ึ่ง":15334,"ึ้น":5621,"ือด":804,"ือง":6868,"ือข":1238,"ือก":2818,"ุคค":864,"้า ":2891,"็กซ":748,"็จพ":2426,"็นเ":5516,"็นแ":1460,"็นโ":1337,"็นก":3439,"็นช":1716,"็นค":1866,"็นจ":1055,"็นผ":1694,"็นบ":1033,"็นป":1559,"็นภ":2128,"็นม":771,"็นพ":2607,"็นต":2314,"็นน":1867,"็นท":2718,"็นอ":2614,"็นห":2383,"็นส":4810,"็นร":2205,"็นว":1944,"่ขอ":746,"่งช":1246,"่งข":3362,"่งก":1222,"่งป":1000,"่งท":1841,"่งต":1001,"่งแ":1232,"่งเ":5701,"่งใ":2695,"่จะ":1049,"่งส":1203,"่งห":867,"่งอ":1487,"่งม":1795,"่งร":800,"็อก":867,"่ตั":1043,"่ที":2658,"่ทา":851,"่นด":850,"่นเ":1175,"่น้":1389,"่ปร":1522,"่ปุ":1738,"ไทย":5121,"ไม้":1526,"ไม่":4922,"่น ":4848,"ไฟฟ":846,"一":1792,"ไว้":1146,"่อ ":2927,"้ง ":1525,"่า ":8977,"้น ":3595,"้ว ":1138,"โบร":910,"โปร":1570,"ใกล":918,"โดย":14241,"โทร":1350,"ใช้":8306,"โลเ":1118,"โลก":2916,"โรม":847,"โรง":1846,"็ก ":901,"็น ":2078,"ใต้":3035,"ในช":1757,"ในต":1018,"ในค":959,"ในก":4474,"ในส":3229,"ในห":971,"ในอ":1785,"ในว":1980,"ในป":5976,"ในบ":1100,"ในท":1717,"ในร":2523,"ในพ":1416,"ในภ":1762,"ในแ":1213,"ในเ":3488,"ให้":6947,"่ง ":3045,"ได้":12204,"ใหม":1526,"ใหญ":3818,"เป็":52874,"เบิ":951,"เบี":820,"เปิ":978,"เปล":1464,"เท่":1160,"เธอ":1279,"เนิ":1467,"เนื":3043,"เนี":1468,"เต็":792,"เทค":856,"เทอ":765,"เทศ":9046,"เที":1082,"เทพ":2509,"เดอ":1340,"เดี":3292,"เดิ":2706,"เดื":969,"เตอ":2325,"เด็":3070,"เอ็":1297,"เอเ":1135,"เอง":1028,"เห็":854,"เอก":1715,"เหล":3579,"เส้":1396,"เหม":1208,"เสี":3555,"เหต":864,"เหน":2585,"เสร":829,"เศษ":814,"เศส":1255,"เวี":1017,"เวล":1640,"เล็":2263,"เล่":1978,"เวณ":1738,"เลี":1467,"เลื":1233,"เร็":978,"ไป ":836,"เลข":1395,"เริ":2046,"เรี":7952,"เรื":4783,"เยอ":752,"แข่":1582,"เมร":2010,"แก่":1962,"แก้":737,"เมื":12490,"แกร":866,"เภอ":2333,"เมต":1938,"เภท":1385,"เพล":3180,"เพร":748,"เพี":982,"เพื":3833,"แพท":735,"แผ่":1298,"แนว":1987,"แบบ":4625,"แปล":1818,"แบ่":978,"แดน":987,"แตก":800,"แต่":6839,"แทน":1132,"แดง":995,"แอน":801,"แสด":2090,"แห่":6124,"แหล":799,"แหน":1000,"และ":28762,"แลน":1347,"แล้":2088,"แยก":1197,"แรก":3318,"โคร":1607,"แม่":2248,"แรง":831," แล":16653," แม":1055," โค":742," แอ":790," แห":1041," โด":7452," เว":860," เล":918," เร":2527," เม":4395," เอ":1986," เส":1106," แต":2750," ได":1910," ไม":1165," โร":1135," ใช":876," ใน":8170,"์ใน":1573,"์เน":739,"์เป":837,"์เร":776,"์แล":1851,"์ขอ":1461,"์กา":933,"้ใน":1845,"์ที":2950,"์ตู":1145,"์ปร":767,"้นม":919,"้นส":1040,"้นต":741,"้นท":2678,"้นก":769,"้ที":841,"้ปร":770,"้นไ":757,"้นใ":1235,"้นเ":2203,"่าเ":2240,"アア":942,"่าน":3867,"่าว":1950,"่าย":3313,"่าก":964,"่าง":12952,"่สุ":2074,"่สา":868,"่อก":1359,"่อข":925,"่อม":2720,"่อย":2839,"่อท":791,"่อต":2073,"่อป":1191,"่อน":4061,"่อง":9204,"่อเ":3452,"่อใ":1119,"่ออ":896,"่อว":3681,"่อส":1953,"่วน":5177,"้งอ":3416,"้งส":845,"้งห":1146,"่วง":2102,"้จะ":789,"้จั":1225,"่วม":1638,"้งเ":1096,"่วย":1812,"้งแ":3344,"่วไ":1216,"่ยว":2420,"่ยม":1269,"่รู":752,"้งข":959,"้งท":1116,"่ละ":738,"้กั":1036,"่มา":795,"่ยน":1164,"่มี":6169,"้เป":2320,"้แก":1074,"้เก":745,"้าอ":1154,"้าส":795,"้าห":1044,"้าแ":781,"้าเ":1817,"้าท":1477,"้าร":977,"้าย":2779,"้าม":1703,"้าว":1169,"้าน":6510,"้าง":6437,"้อน":1455,"้อย":2449,"้อม":2269,"้อง":6049,"้ว่":734,"้วย":5521,"่ให":733,"่ได":1564,"่ไม":926,"่ใช":1862,"่ใน":4343,"้รั":2515,"่เก":1904,"่เข":763,"่เร":861,"่เป":2235,"้มี":1570,"่เห":1028," Ma":1010," Ch":742," Co":992," Th":1261," of":1521," co":752," th":1128,"�":5212,"กา ":1384,"กร ":1188,"ก่ ":760,"一一":774,"ของ":31894,"ก่อ":3663,"ขัน":1726,"ขาย":803,"ขาว":1067,"กี่":1664,"กีย":867,"กิโ":1154,"ค์ ":769,"กีฬ":1239,"กิน":769,"กิด":3855,"กิจ":1573,"กำห":759,"กูล":885,"กุล":1306,"กุม":773,"ขนา":2496,"กใน":2081,"กแล":866,"กแบ":824,"กเร":871,"กเม":773,"กเป":1534,"กเฉ":1039,"กเข":1098,"ข่ง":1611,"ข่า":854,"ข้อ":2417,"ข้า":4839,"คณะ":1457,"ขีย":2776,"ขึ้":5628,"คคล":827,"กจะ":954,"กจา":1248,"กคร":1721,"กกา":2113,"กกั":1063,"กกว":874,"คน ":1108,"กขอ":2098,"กซ์":975,"คร ":1077,"คม ":4347,"กล้":2502,"กล่":1300,"กษร":1944,"กว้":773,"กว่":3702,"กษณ":3331,"กษั":896,"กษา":3668,"กรม":2005,"กรณ":1173,"กรา":2022,"กรี":1057,"กรุ":2471,"กระ":5410,"กรร":3527,"กรว":929,"กฤษ":3489,"กลุ":3431,"กลั":865,"กลา":3035,"กัด":1452,"กัน":7783,"กับ":9982,"กาศ":2249,"กาล":1237,"การ":39240,"กาย":2168,"กาะ":1419,"กษ์":1004,"กอง":1215,"กอบ":2433,"กอา":822,"กที":2316,"กต่":822,"กติ":1015,"The":934,"กตั":798,"กดิ":842,"กมา":1372,"กรก":1149,"กภา":827,"กปร":1145,"งค์":4532,"งงา":824,"งจั":1172,"งจา":3155,"งชา":2378,"งกร":1669,"งกฤ":3370,"งกล":1847,"งกา":5753,"งกั":3274,"งขึ":1653,"งขั":1578,"งขอ":4624,"งข้":745,"งคว":1083,"งคล":878,"งคร":2365,"งต่":740,"งตั":1510,"งตะ":916,"งนั":904,"งที":5394,"งทา":994,"งทั":1042,"งปร":4913,"งนี":1331,"งผู":776,"งปี":968,"งด้":1068,"งสม":789,"งศ์":3006,"จจุ":2329,"งวั":2363,"งอย":4387,"งออ":847,"งอั":937,"งอา":1391,"งหน":1700,"งสุ":772,"งสื":1073,"งสิ":892,"งหม":1633,"งสร":855,"งสั":912,"งสา":1650,"งหล":2008,"งหว":4124,"งหา":876,"งภา":1562,"งมี":2826,"งมา":1681,"งพร":2199,"งรา":1862,"งรั":1304,"งระ":937,"จพร":2446,"งาน":5529,"งิน":899,"คลอ":868,"คลื":949,"คล้":1302,"ควา":10480,"ครง":1144,"ครอ":2563,"ครั":3903,"ครา":1915,"คริ":2019,"ครี":810,"ครื":2934,"คุณ":1069,"คือ":7513,"คาร":1456,"คัญ":1773,"คิด":898,"คำว":930,"คอม":1178,"งๆ ":1126,"al ":2103,"ค่า":1374,"and":1056,"an ":1298,"คู่":872,"ค์เ":768,"ค์ก":947,"ati":1494,"ค้า":1139,"ชวง":936,"ชอา":798,"ชาว":3493,"ชาย":1746,"ชาต":3190,"ญ่ ":976,"ชาช":786,"ชัย":783,"ชาก":1050,"ชัน":900,"ชิง":1090,"ชิก":963,"ชั้":1496,"ชั่":737,"ชีย":1882,"ชีว":1797,"ชุด":1385,"ชุม":779,"ชื่":9015,"ช่ว":2205,"ช่อ":1132,"ช่น":2842,"ซอร":818,"ช้ใ":1180,"ช้เ":1405,"ซีย":1624,"ซึ่":8007,"งไม":762,"งไป":735,"งได":1184,"งให":1499,"งเห":1953,"งเส":869,"งแต":2125,"งเพ":1132,"งเป":5244,"งเศ":1374,"งเล":753,"งเร":2306,"งเม":1299,"งเท":2214,"งเด":1083,"งเก":2093,"งเข":1000,"งเค":853,"จริ":1485,"งใต":746,"งใน":4860,"งโด":1508,"งแร":2003,"งแล":1588,"จอม":844,"จัก":4523,"จะม":1426,"จัง":4135,"จึง":1351,"ซ์ ":949,"จีน":2020,"จุบ":2333,"จุด":1489,"จัน":795,"จาก":13356,"จะเ":1881,"จัด":3836,"จาร":1224,"จำน":1462,"จิต":1255,"ฉพา":1147,"ชกา":919,"จ้า":6405,"ชนิ":2672,"ชนะ":817,"ฉีย":1060,"is ":767,"ion":2025,"ญิง":1134,"ญี่":1736,"ญญา":1273,"he ":1580,"ฐอเ":1010,"ดย ":1795,"ic ":1027,"ia ":801,"ica":989,"ine":780,"ing":1208,"in ":877,"ต้ ":1080,"ติ ":2277,"er ":1893,"es ":1392,"ด้ ":1252,"ด์ ":1553,"ent":1216,"ฒนา":1571,"ตร ":2238,"ดา ":815,"ดี ":1229,"ฐาน":2388,"ณ์ ":911,"ดีต":1119,"ดำเ":759,"ดิม":1868,"ตถุ":806,"ดิ์":821,"ท์ ":857,"ดีย":3255,"ดูก":1062,"ดือ":962,"ดับ":3761,"ดัง":1352,"ดาร":853,"ดาว":2014,"ดิน":2900,"ดหน":1239,"ดยก":793,"ดยเ":1721,"ดยม":1638,"ดยส":889,"ดยอ":756,"ดยท":955,"ดนต":1392,"ดที":1456,"ดตั":945,"ed ":825,"ทศ ":1067,"ณาจ":1453,"ณะเ":897,"ทย ":2718,"ดจา":942,"ดขึ":1374,"ดขอ":1317,"ดกั":890,"ดกา":1277,"ต์ ":1632,"ุ ":1109,"นี ":1305,"นา ":1502,"ี ":16016,"ิ ":4510,"ำ ":2043,"re ":749,"า ":25017,"ต้น":2996,"ต้อ":1614,"ต่ง":1112,"ต่อ":4486,"ต่า":3505,"ต่ล":740,"ู ":1781,"นๆ ":762,"่ ":16723,"้ ":5526,"ต์ศ":958,"ๆ ":4266,"ry ":820,"ถาป":753,"ถาน":3944,"ทธศ":829,"ถือ":1350,"ทธิ":2039,"ถูก":2600,"ถึง":6398,"น์ ":1653,"ถิ่":814,"์ ":28985,"ดเม":981,"ดเล":1139,"ดเป":846,"ตรง":1229,"ตรก":784,"ดใน":1781,"ตรี":2898,"ตริ":1006,"ตรา":1575,"ตระ":1105,"ตร์":7354,"ดให":1327,"ตวร":760,"ด็จ":2802,"ตว์":1614,"ด้แ":1081,"ด้เ":1187,"ด้า":3056,"ด้ว":5447,"ด้ร":2493,"ตอร":2348,"ตอน":1918,"ตัว":7601,"ตะว":2896,"ติก":1508,"ติน":757,"ติด":1536,"ตั้":8579,"ตาล":1104,"ตาร":1322,"ตาม":4567,"ตำบ":1639,"ธ์ ":976,"ติเ":954,"ติแ":866,"ติศ":1101,"ตำแ":988,"ถนน":2048,"ตุล":748,"นะ ":754,"ตูน":1178,"นขอ":3384,"นข้":932,"นคว":826,"ธรร":2826,"นคร":3912,"นกร":1617,"นกล":2158,"นกา":7632,"นกั":1355,"นฐา":769,"นช่":1290,"ท้อ":1115,"นชื":1549,"นชา":864,"ท่า":2380,"ท้า":1066,"นจา":1033,"นจั":1141,"นจะ":747,"ข ":896,"นธร":779,"นธุ":1127,"นทร":2489,"นทั":791,"นทา":2750,"นที":13368,"นต้":1225,"นถึ":809,"นต์":1445,"ธิ์":953,"นด้":1065,"ก ":14487,"นตร":4843,"นติ":835,"นตั":2147,"นตา":888,"นด์":1948,"ธิก":846,"นตก":1337,"นดั":1314,"นดิ":1223,"ธาร":1184,"ง ":27727,"ค ":5823,"ธาน":978,"นภา":4234,"บกา":2494,"ช ":2112,"นพื":1006,"จ ":1697,"นพร":3282,"นผู":1561,"นปี":3086,"นปร":4565,"นปั":802,"นบุ":863,"นบร":1204,"ธุ์":901,"นนิ":1044,"นนี":1085,"นนา":1321,"นนั":1485,"ญ ":928,"นธ์":2163,"ทรง":2910,"ทยา":5565,"ทรท":914,"ทรา":963,"ณ ":3143,"ทร์":996,"ถไฟ":2170,"ทพม":811,"ต ":4123,"ด ":8336,"ท ":2444,"น ":40656,"ทสม":792,"ทหา":866,"ป ":2071,"ทอง":1146,"บ ":5246,"ทอร":781,"ทศอ":828,"ฟ ":941,"ทวี":828,"พ ":8598,"ทศไ":1737,"ทศเ":766,"ม ":15299,"ทิน":1259,"ทั่":2123,"ทั้":3993,"ย ":16564,"ร ":10052,"ทำใ":1466,"ทิศ":1076,"ล ":7227,"ว ":7449,"ทัศ":1092,"ทาง":10997,"ทะเ":1496,"ทัพ":825,"ทาน":903,"ศ ":12299,"ษ ":3178,"ส ":5552,"ปี ":4823,"ทุก":1239,"อ ":17206,"ที่":56152,"ะ ":8344,"ปฏิ":1862,"บอล":946,"ng ":1471,"บิน":950,"ne ":979,"บาล":1707,"บั้":776,"บาง":2680,"บัน":3828,"บาท":1409,"nd ":964,"บัต":1362,"บัญ":812,"บวน":840,"นไป":997,"นไม":765,"นให":1732,"นได":1498,"บรา":1706,"บริ":5195,"นใน":4356,"น้ำ":5368,"น้า":3676,"น้อ":1479,"น่า":1206,"น่ว":1000,"น่ง":989,"ปรา":2156,"ประ":25303,"ปริ":937,"nt ":807,"บุค":937,"บีย":817,"บุร":1542,"นหม":998,"นสั":1468,"นสา":1759,"นสำ":796,"นสี":845,"นหน":3532,"นสุ":1261,"นหล":1601,"นส่":1409,"นสถ":1319,"นสม":1639,"นอย":1426,"นอั":1719,"นอา":1493,"นออ":2019,"นอก":1327,"นอง":1083,"นอิ":1016,"of ":1513,"นับ":1179,"นาง":1305,"นาค":1491,"นาด":2642,"นัง":1602,"นัก":6595,"บคว":838,"นยา":1119,"นยุ":813,"นมา":2249,"นมี":1207,"บขอ":813,"นรู":1331,"นรา":1843,"นระ":2096,"นรั":1125,"นย์":888,"นวน":2013,"นวง":1415,"นว่":1138,"นวา":814,"นวิ":1095,"นวั":1960,"บปร":1255,"บบเ":871,"ปกค":1297,"นเค":1189,"นเก":1640,"นเข":1425,"นเจ":957,"นเด":1933,"นเป":2635,"นเพ":1597,"นเท":2022,"นเร":1822,"นเม":2536,"นเส":1392,"นเว":905,"นเอ":1413,"นเห":886,"นแบ":783,"นแร":793,"นแล":1965,"นแห":1112,"นโด":2101,"บรม":1009,"บรร":1513,"นโล":1115,"นั้":3921,"นาม":2497,"นาย":2144,"นาน":1674,"นิน":1076,"นิด":3216,"นิก":1334,"นิว":770,"บด้":1147,"นิย":2396,"นีย":1820,"นีร":1196,"on ":2708,"บที":1359,"นี้":6260,"นือ":2427,"นึ่":6892,"นื้":1785,"นื่":1254,"นุษ":996,"le ":881,"ป่า":900,"ป็น":52765,"ผ่น":1156,"ฝรั":1300,"ผู้":7889,"ปิด":1097,"ปาก":1194,"ปัจ":2459,"บ้า":2101,"ปลา":2984,"ปลี":1161,"บ่ง":1079,"ผลง":1088,"ผลิ":1382,"ปแบ":1026,"ปุ่":1831,"พรร":1714,"พยา":839,"พยน":2010,"พมห":762,"ยน ":4029,"มี ":1149,"มา ":896,"ฝ่า":781,"ยม ":948,"พลั":814,"พวก":739,"พลง":2750,"พระ":17707,"พรา":866,"ยง ":1443,"ผ่า":1411,"ฟฟ้":828,"รม ":1362,"พัฒ":1494,"ม่ ":849,"พัน":3666,"พาะ":1326,"ยว ":1115,"พื่":3826,"พูด":1126,"พื้":2671,"ยา ":1376,"พิธ":838,"พิม":1132,"พิว":738,"พีย":958,"พุท":2067,"มขอ":1433,"มกร":823,"มกั":1433,"มกา":1276,"ฟ้า":1943,"มชา":782,"ลก ":1247,"ภอเ":800,"ลง ":792,"ย์ ":2750,"ระ ":742,"รี ":2785,"รา ":766,"ยขอ":1509,"มมา":901,"มริ":2047,"มรา":849,"ยงเ":962,"ยงใ":1176,"ยชน":801,"มหม":966,"มอง":738,"มหา":5731,"มาช":1046,"มาจ":2680,"มัย":2145,"มาก":4211,"มัน":2325,"มัก":1644,"ภาค":3301,"ฤษ ":2433,"ภาพ":5887,"ภาย":1934,"ภาษ":8339,"มตร":1922,"ร์ ":8527,"มทั":835,"มที":1983,"มนต":905,"มนุ":1036,"ภูม":1417,"มปร":865,"มพิ":882,"มพร":946,"มพ์":1080,"ยกา":2466,"มภา":858,"ยกั":787,"ยกว":1726,"ยกร":1291,"ยาน":1202,"ยาล":2584,"ยาว":2212,"ยาม":807,"ยาย":2092,"รณร":750,"ยาศ":1408,"รณ์":2303,"ยัง":2948,"ยาก":955,"วง ":1110,"ยอด":1124,"ยอร":940,"ยอย":754,"ม่เ":922,"ม่อ":742,"ยสา":1028,"รจั":932,"ม่น":1356,"ม่ม":1196,"ยวก":2166,"รงเ":2099,"มใน":892,"รงก":1367,"รกเ":741,"มเห":813,"รขอ":1042,"ยมี":1590,"รกร":1251,"มเก":770,"มเด":3008,"มเป":1110,"ลี ":1049,"ยปร":756,"มู่":1176,"ลา ":1161,"มูล":1423,"มื่":6537,"ละ ":3400,"มุท":857,"มือ":8088,"ยนต":2593,"ยที":1815,"ยทั":824,"ยถึ":2220,"มีเ":1932,"มีอ":1345,"มีล":1533,"มีห":1060,"มีส":1890,"มีผ":1122,"มีพ":1283,"มีร":1326,"มีท":746,"มีน":1210,"มีป":899,"มีค":3125,"มีช":2478,"มีข":1119,"มีก":2644,"มาเ":1480,"มาร":4462,"มาย":5367,"มาต":1157,"มาณ":1914,"ราบ":751,"ราน":740,"ราณ":897,"ราว":1444,"รั่":1334,"รั้":3560,"ราม":1910,"ราย":2763,"ราะ":1374,"ริญ":758,"ริก":3434,"ริง":1138,"ริน":744,"ริษ":1438,"ริส":1925,"ริม":1124,"ริย":2233,"ริเ":2100,"รีส":866,"ริ่":2037,"รีย":9363,"ระก":4332,"ระจ":2540,"ระช":2359,"ระด":3552,"ระน":1422,"ระบ":4735,"ระท":2215,"ระธ":815,"ระย":1763,"ระม":3043,"ระร":2751,"ระพ":1841,"รัก":1669,"ระส":2582,"รัช":1049,"ระห":3447,"ระว":1743,"รัฐ":5336,"ระอ":2225,"รับ":6837,"ระโ":884,"ราค":879,"ระเ":13435,"ราก":1663,"รัส":1059,"ราช":9495,"ราจ":779,"ราง":1497,"ย่า":4021,"ย่อ":1669,"วย ":1162,"รอง":3048,"รอบ":1542,"รอน":750,"รวม":2782,"รวง":825,"รษท":797,"รศึ":1157,"้ใ":2847,"้ไ":1284,"้แ":2652,"้เ":7277,"ยแล":953,"รรค":1151,"้ำ":5903,"้า":37643,"รรด":1433,"้อ":17505,"รรณ":1404,"้ห":1048,"้ส":2215,"์จ":1166,"์ช":1393,"วน ":1214,"์ค":1626,"์ก":3825,"์ข":1876,"รมั":970,"์ว":1155,"์ล":906,"์ส":3129,"์ห":969,"์ศ":1201,"์พ":863,"์ร":1348,"์ม":2202,"์ท":4622,"์ต":2998,"์ด":2081,"์ป":1557,"์บ":1254,"์น":1942,"์ไ":1599,"รรษ":1352,"รย์":876,"รรม":6124,"์เ":8295,"์แ":4502,"์โ":1808,"์ใ":2084,"ยใน":2770,"์อ":1673,"รพร":845,"ยเป":1383,"แอ":2776,"แส":3385,"โซ":1292,"แห":8308,"แล":33169,"แว":982,"โจ":1094,"แย":1484,"แม":4364,"โค":3872,"แร":4857,"โพ":1125,"ยุโ":733,"ใก":924,"โม":2045,"รปก":742,"โบ":1679,"โป":2206,"โท":2397,"โน":2242,"โด":16368,"โต":2472,"โอ":4042,"ใช":8587,"ใจ":1545,"โล":5940,"โร":5880,"โย":1454,"ไข":762,"ไก":791,"ใน":43294,"ใบ":873,"ใต":3040,"ใด":738,"ให":12321,"ไซ":1010,"ไฟ":3494,"ไม":7091,"ไร":1255,"ได":12875,"ไต":1235,"ไท":6054,"ไป":6850,"ไอ":1157,"ไว":1681,"ไล":879,"ยู่":11314,"ไห":1089,"รปร":1489,"็ก":4152,"็ง":850,"็จ":3701,"็ต":1012,"็ด":1111,"็บ":1365,"รดิ":1521,"็น":54742,"่ง":35546,"่ค":1361,"็ม":1660,"่ข":1323,"่ก":2880,"่จ":2216,"่ช":990,"็อ":1898,"่ด":1050,"่ต":3007,"่ถ":906,"่ท":5172,"่น":17313,"รที":1499,"่ป":4265,"่บ":1847,"่ผ":743,"่พ":1708,"่ม":15356,"้ข":1096,"้ก":2888,"่ร":2826,"้ค":1674,"่ย":6368,"่ล":1168,"ยุค":1712,"้จ":2773,"่ว":14132,"้ง":18710,"่ส":6307,"่ห":2814,"รถไ":2194,"้ช":1217,"่อ":46408,"่า":42021,"้ด":1042,"รทำ":739,"้ท":1936,"้ต":1075,"รทั":1036,"้ป":1226,"้บ":1138,"้น":24081,"๊ก":920,"้พ":1364,"่ใ":7390,"้ร":3437,"่โ":798,"่แ":2495,"้ย":1840,"่เ":10182,"้ม":4709,"้ว":10098,"่ไ":2895,"้ล":760,"เอ":9583,"เฮ":1007,"ศส ":746,"เศ":2656,"เส":8693,"เห":10183,"เล":12934,"เว":8237,"แก":4707,"เภ":3987,"เม":21131,"แข":3088,"เย":2348,"เร":18471,"แค":2187,"แพ":2260,"โก":2046,"แบ":6575,"แน":2938,"แผ":2002,"แป":2594,"แถ":810,"แต":8070,"แท":1899,"แด":2231,"เช":8753,"เซ":6021,"เจ":10004,"เฉ":2866,"เง":1146,"เค":8385,"เข":11528,"เก":16975,"เฟ":1048,"เพ":11355,"เผ":802,"เป":58033,"เบ":4728,"เน":8994,"เธ":1416,"เท":18401,"เต":6088,"เด":13846,"ลที":1395,"ูเ":2044,"ู่":14654,"ู้":10588,"ูป":4480,"ูน":2921,"ูร":1466,"ุโ":1437,"ูม":1757,"ุเ":849,"ูล":3073,"ุ่":7901,"ุ้":931,"ุ์":914,"ูต":1281,"ร่า":1627,"ูด":1928,"ร่ว":1692,"ื้":6123,"ุส":1052,"ื่":31115,"ุษ":1254,"ูง":2041,"ุล":3040,"ุร":4653,"ูก":5828,"ุม":4112,"ุบ":2913,"ุป":1128,"ุธ":955,"ุน":3561,"ร้า":4429,"ุต":2413,"ุด":8113,"ุท":4856,"ุณ":1621,"ุญ":872,"ือ":41365,"ร้อ":2730,"ึ้":5783,"ึ่":15365,"ุค":2816,"ุง":2994,"ุก":3888,"ุข":1229,"ืน":1145,"ี่":66161,"ี้":8515,"ีเ":7027,"ีใ":1123,"ีแ":2432,"ีโ":1682,"ีอ":2953,"ิ์":1865,"ึง":8316,"ีล":2237,"ีว":3304,"ีส":4174,"ิ้":2507,"ิ่":6446,"ีฬ":1240,"ีห":1469,"ีพ":2697,"ึก":5012,"ิเ":7222,"ีม":1954,"ิแ":1214,"ีย":34404,"ิโ":3549,"ีร":4629,"ีต":2652,"ีท":2505,"ีน":5775,"ีบ":2030,"ีป":2156,"ีผ":1219,"ิส":6204,"ิห":1497,"ิศ":3177,"ิษ":2523,"ีช":3206,"ีจ":1149,"ิว":4515,"ร์ส":1173,"ำใ":1865,"ิล":5788,"ำไ":839,"ีด":1673,"ิอ":948,"ิป":1641,"ร์เ":3538,"ิบ":2835,"ิน":18424,"ิธ":2036,"ิท":9171,"ิต":10282,"ิด":13442,"ิร":3582,"ีค":3922,"ำแ":2282,"ิย":5047,"ีข":2272,"ำเ":6458,"ิม":7019,"ีก":7455,"ิภ":1128,"ิพ":1917,"ร์แ":1733,"ร์โ":778,"ำว":1118,"ิจ":3243,"ิช":2649,"ำส":738,"ิค":1757,"าโ":3139,"ำร":1745,"าใ":3181,"ำล":1253,"าไ":2775,"ิง":7259,"ำห":4498,"ิญ":1127,"ำท":973,"ำบ":1971,"ำน":4890,"ำด":1025,"ำต":1664,"ิก":12850,"าแ":4055,"าเ":12583,"ำม":1274,"ำป":747,"ำพ":760,"าล":10057,"าย":37411,"ำค":2190,"าร":63897,"าศ":5622,"าษ":8889,"ั่":6714,"าว":19634,"ำจ":874,"าอ":4975,"าส":13760,"ั้":24167,"าห":5552,"าะ":4602,"าต":8268,"าด":6631,"าณ":5371,"าน":35220,"าธ":2890,"าท":8396,"าถ":784,"าผ":775,"ร์ก":1498,"าป":2833,"าบ":4733,"าม":30146,"ำก":2269,"าภ":1081,"าฟ":1063,"าพ":8053,"ะเ":24505,"าข":3951,"ัม":2974,"ะแ":2571,"ัย":8749,"าค":10848,"ะโ":2150,"ะใ":1602,"ะไ":1960,"ัล":3755,"าง":41529,"ัว":11006,"าจ":10067,"ัศ":1321,"าช":13729,"ัส":4036,"าซ":1724,"ร์ด":1551,"าญ":933,"ร์ต":2154,"ร์ท":1160,"ัฒ":2408,"ัด":14375,"ัณ":1273,"ัต":9709,"ัท":2203,"ร์ม":749,"ับ":25368,"ัน":39721,"ัพ":2281,"าก":31704,"ฮั":845,"ฮิ":902,"ฮา":872,"ะช":3044,"ะจ":3682,"ะข":1220,"ะก":7907,"ะค":3630,"ะธ":897,"ะน":3483,"ะบ":5762,"ะป":1992,"ะพ":3693,"ะด":4349,"ะต":2884,"ะถ":831,"ะท":5514,"ัช":1701,"รเล":875,"ะห":5596,"ะส":5803,"ะอ":4641,"ัญ":5583,"ัฐ":5386,"ะม":6798,"ัก":25499,"ะภ":863,"ะร":4376,"ัค":775,"ะย":3056,"รเม":755,"ะล":1194,"รแข":1253,"ัจ":2657,"ะว":5659,"ัง":23502,"อป":2561,"รเป":876,"อน":18187,"อบ":7490,"อท":2655,"อธ":1085,"อต":3868,"อถ":749,"ฬา":1653,"อด":5925,"ห์":1891,"อห":2050,"อส":6091,"อว":5778,"อล":4526,"อร":15873,"อย":21178,"อม":9516,"อภ":865,"อฟ":1564,"อพ":1610,"อี":4000,"อื":1874,"อุ":3605,"อั":11299,"อา":13455,"อำ":3262,"อิ":6605,"ออ":10729,"อะ":2163,"ฮอ":754,"อ่":1463,"อ็":1408,"อโ":1451,"อแ":1805,"อไ":1254,"อใ":1838,"อเ":12919,"ษ์":1229,"สอ":3466,"หญ":5078,"us ":1226,"สห":2331,"ลงา":1081,"สั":9793,"สะ":1590,"สี":9218,"หต":869,"สิ":7137,"สำ":6109,"สา":15975,"สู":4642,"หน":20409,"สุ":8301,"สื":2761,"หม":12564,"สเ":3613,"สแ":834,"หย":1301,"หล":16331,"สโ":1107,"หร":18933,"ส่":6557,"ส้":1769,"หว":8188,"ส์":4529,"หอ":742,"หา":12502,"หั":3338,"หิ":1200,"อก":17318,"อข":2506,"อค":2179,"อง":70500,"อจ":1268,"ห็":854,"อช":1235,"ห่":6955,"ห้":8276,"ษฐ":1153,"ศอ":967,"ษฎ":870,"ว์":2314,"ว้":3043,"ศส":1760,"ศษ":814,"ว่":16781,"ษท":1007,"ศึ":3055,"ศิ":2300,"ศา":8110,"ษณ":3808,"ศั":2984,"สก":2168,"ศู":867,"ศไ":1794,"สง":2785,"ษร":2008,"ศเ":1312,"ษย":1193,"ศ์":3007,"สถ":6089,"สน":4818,"ษา":12813,"รใน":1139,"ษั":2349,"สต":9741,"สด":3309,"สภ":1290,"สม":10925,"สว":2702,"สร":6497,"สล":1065,"รใช":756,"วย":9723,"วม":5477,"วร":6029,"วล":3904,"วท":1967,"วบ":1401,"วน":11532,"วป":795,"รูป":4257,"วณ":1942,"วด":2173,"วต":1183,"วง":11814,"วจ":1546,"ล็":3380,"รุ่":859,"วช":1103,"ล่":6051,"ล้":7758,"ล์":1887,"ศร":2364,"วโ":1470,"วแ":1429,"วเ":5629,"ศว":1021,"วไ":2301,"วใ":947,"ศน":1526,"วั":23102,"วา":16144,"วะ":947,"วี":3571,"ศท":825,"ศต":1496,"วิ":15211,"วส":1841,"ศจ":1019,"วอ":3830,"วห":1387,"รื่":5863,"ลย":1821,"ลม":2014,"ลร":753,"ลบ":1840,"ลน":3276,"ลป":2282,"ลต":1315,"ลท":2213,"ลด":1361,"รือ":16002,"ร์":31431,"ร็":1969,"ฤษ":4446,"ร่":5273,"ร้":7400,"รใ":2364,"รไ":1004,"ลง":7031,"รุง":2477,"ลจ":865,"ลใ":839,"ลโ":860,"วค":1204,"ลแ":1254,"ลเ":4918,"วข":1721,"วก":5218,"ลู":2435,"ลุ":4907,"ลื":3984,"ลี":7428,"ลำ":2409,"ลิ":7229,"ลั":14699,"ลา":17258,"ละ":32443,"ลอ":5473,"ลห":915,"ลส":1856,"ลว":3836,"ลล":2565,"ยา":16472,"รณ":5716,"รด":4057,"ยิ":1263,"รต":2974,"รถ":6175,"ยี":1186,"รท":5128,"ยื":1006,"รน":2627,"ยุ":5509,"ยู":12722,"รบ":2528,"รป":3771,"รพ":2742,"ยเ":7850,"รม":12636,"รย":2421,"ยแ":3243,"รค":3841,"มโ":1965,"ยร":3391,"มแ":3080,"ยล":1160,"มไ":1232,"มใ":1839,"รจ":2340,"ยว":7799,"รง":8918,"ม่":10097,"รช":1118,"ยศ":1015,"ยห":1973,"ม้":2616,"ยส":4483,"ยอ":5464,"ยั":4025,"ยะ":1489,"รี":20028,"ริ":20674,"รู":7587,"รื":21925,"รุ":4970,"รแ":4843,"รโ":1568,"ลค":797,"ลก":4719,"รเ":8258,"ลข":2218,"รล":1190,"ยไ":1866,"ยใ":4743,"รร":16031,"ยโ":1499,"รส":5411,"ย่":5792,"รษ":2069,"รศ":2322,"รว":7099,"รอ":8553,"ย์":8004,"รห":1918,"รา":29845,"รั":23940,"ระ":59662,"มต":4461,"มถ":925,"มท":4160,"ภั":1399,"มณ":1076,"ภา":21089,"มด":2959,"มพ":4702,"ยก":11626,"มภ":1402,"มน":5654,"ภู":2200,"มบ":2018,"มป":2831,"มผ":871,"มจ":1684,"มง":1139,"มข":2191,"มก":5523,"มค":2300,"ภอ":2334,"มช":2595,"ฟ้":2049,"มื":14762,"ยน":14895,"มุ":2792,"มี":30856,"ยถ":2445,"ยท":4014,"ยด":1555,"ยต":2395,"มิ":5697,"มั":8313,"มา":29552,"ยภ":836,"รก":8900,"มเ":11478,"ยม":7097,"รข":1777,"ยพ":1762,"ยบ":2166,"มู":3200,"ยป":1662,"มศ":1140,"มว":3354,"ยจ":1218,"ยง":8717,"มล":1770,"ยค":2918,"รู้":1907,"มร":6136,"มย":1297,"ยข":2004,"มม":2832,"มะ":1294,"มอ":4804,"มห":8473,"มส":4913,"ยช":2472,"ลาย":5187,"ฝร":1302,"ผ่":2887,"ฝั":851,"ลาด":921,"พท":1912,"พน":931,"ลาน":856,"พบ":1789,"ปแ":1689,"ปเ":1359,"ผล":4309,"ป้":1280,"ป็":53080,"ป่":1217,"ลำด":791,"ลำต":811,"ผิ":1067,"ผู":7995,"ฟร":1492,"ฟล":850,"ฟฟ":1043,"พเ":1196,"ลิม":935,"ฟอ":994,"พ์":1176,"ฟิ":1569,"ภท":1390,"ลิต":1534,"ฟุ":809,"พฤ":1487,"พล":6364,"พย":3936,"พร":23104,"ลีย":1437,"พม":1303,"พอ":1240,"ฝ่":810,"พว":940,"พี":2676,"พิ":6438,"พา":3798,"พั":6166,"พู":1636,"พุ":2493,"พื":7226,"นย":4074,"ลี่":2431,"บข":1492,"นม":6695,"บค":3089,"นร":8383,"นล":2573,"นศ":1853,"บจ":1007,"นว":11694,"นบ":4831,"ธุ":1517,"นน":9487,"นผ":3027,"นป":10367,"นพ":7135,"นภ":4756,"บก":4476,"นฟ":756,"นั":15362,"นา":19798,"บด":2422,"นำ":2990,"บต":1487,"นิ":13549,"นี":13301,"นึ":7032,"บท":4278,"นื":5497,"บน":4184,"นุ":3598,"นส":15743,"นห":8286,"ธ์":2434,"นอ":14760,"นะ":2415,"ธร":3542,"นค":9380,"ลือ":2681,"ธย":895,"ทเ":1085,"นข":6066,"นก":17019,"นจ":5539,"นง":887,"ทุ":2331,"ธา":3053,"นด":8599,"ธั":762,"นท":23586,"นธ":5365,"นต":15763,"ธิ":5695,"นถ":1559,"ธี":1300,"ท้":2426,"นซ":2369,"ธศ":832,"นช":5687,"ท่":3112,"นฐ":772,"ท์":2028,"ธอ":1358,"บ้":2221,"ปส":1027,"บ่":1386,"บใ":1319,"ปร":33042,"บโ":1424,"บไ":1667,"ปล":7500,"ลื่":1081,"บแ":1614,"บเ":5338,"ลูก":1704,"ปุ":2101,"ผน":738,"ปิ":2900,"ปี":8407,"ปะ":1033,"ปั":4469,"ปา":3048,"ปอ":1507,"น่":3725,"น็":766,"นๆ":1075,"บว":2339,"นไ":5452,"บล":3184,"นใ":7373,"นโ":6749,"บร":11830,"นแ":9829,"นเ":26787,"บม":1153,"บภ":734,"ปก":3047,"บพ":1205,"ลุ่":3574,"บป":2025,"บบ":7643,"ปน":1077,"บุ":4548,"บู":1144,"ปท":1302,"บิ":3104,"ปต":759,"บี":2069,"บา":8404,"ปด":805,"บั":9157,"ปฏ":1873,"บอ":4696,"น์":3647,"บส":3398,"น้":10964,"บห":1553,"ด็":3505,"ตว":2762,"ตล":1318,"ดไ":896,"ตส":1012,"ด้":20496,"ด่":844,"ตะ":4134,"ตอ":5825,"ด์":2932,"ติ":15034,"ตำ":3584,"ตา":9651,"ตั":18129,"ดื":1116,"ดิ":9252,"ตต":1078,"ดี":8816,"ตถ":1332,"ดุ":891,"ตน":2338,"ตบ":1002,"ดู":2853,"ตร":23291,"ดโ":963,"ดใ":3358,"ดเ":6934,"ดแ":2124,"ตย":2013,"ดล":1605,"ดว":1797,"ดห":2122,"ดส":2822,"ดอ":4967,"ณ์":3582,"ดั":6569,"ดำ":2067,"ดา":6669,"ดด":953,"ณิ":917,"ดต":2322,"ณี":962,"ดท":2962,"ดน":4803,"ดป":1230,"ดพ":988,"ตก":3537,"ดม":1612,"ดย":15171,"ดร":2790,"ทอ":3103,"ทห":1219,"ทส":1351,"ทศ":9520,"ทว":1599,"ที":59203,"ทิ":4236,"ทำ":5708,"ทา":13110,"ทั":9949,"ทะ":1722,"ทพ":2598,"ทน":2186,"ถุ":1404,"ทบ":1025,"ถู":2630,"ถึ":6411,"ทธ":4848,"ถื":1366,"ถไ":2196,"ลอง":1534,"ธง":1259,"ทร":10558,"ทย":11986,"ต้":8814,"ต์":5183,"ต่":15088,"ต็":806,"ลอด":966,"ถา":5861,"ถิ":1257,"ตู":1933,"ตี":1997,"ตุ":3328,"ถน":2338,"ตแ":903,"ทค":1361,"ตเ":2007,"ฐา":2537,"ฐอ":1245,"ฐม":814,"ละค":2575,"ฏิ":1907,"ละก":1772,"ละน":936,"ณา":2378,"ณะ":4781,"ละท":1069,"ละต":1127,"ดช":1164,"ดจ":1760,"ดง":3356,"ดค":1484,"ณร":978,"ละส":1767,"ดข":3245,"ดก":3268,"ลัง":3957,"ละร":817,"ละม":1718,"ลัก":5507,"ละพ":787,"ละป":964,"ณฑ":1856,"ลับ":937,"ละอ":1448,"ละไ":841,"ลาง":2453,"ลาก":914,"ละเ":4488,"ละแ":849,"ฒน":2389,"ลัย":2733,"ซั":988,"ซา":2350,"ซอ":2165,"ซู":753,"ซี":4385,"ซึ":8304,"ซิ":3377,"ญช":978,"ญญ":1807,"ซ์":1764,"ญิ":1154,"ญา":2270,"ญี":1753,"ญ่":3821,"งิ":983,"งา":6266,"งอ":10609,"งห":11834,"งส":12858,"งศ":4623,"จจ":3207,"งว":4781,"งๆ":1493,"งใ":8125,"ลล์":930,"งไ":4482,"งแ":10959,"งโ":5091,"จร":2901,"จม":901,"งเ":26671,"จพ":2589,"ลวง":2170,"จน":3023,"จี":2856,"จิ":3604,"จึ":1361,"จั":14501,"จะ":8562,"จำ":4839,"จา":15882,"จอ":2342,"ฉล":792,"จเ":946,"ฉพ":1153,"ชก":1650,"จุ":5283,"ฉา":1061,"ชน":7089,"ฉี":1150,"จ้":6665,"ชย":735,"ชร":794,"ชว":2061,"ชบ":758,"ชม":820,"ชา":13533,"ชี":5071,"ชิ":4498,"ชื":9652,"ซน":1061,"ชุ":2369,"ชส":1160,"ชอ":1761,"ชั":4493,"ซล":1003,"ช่":6714,"ช้":8872,"คน":5647,"คต":1444,"คม":6449,"คร":21353,"คย":1040,"tio":1636,"ข่":2813,"ข้":7740,"คค":1249,"ลบั":843,"คณ":2195,"คู":1293,"คุ":2351,"คื":7785,"คี":1217,"ลนด":1156,"คิ":2002,"คโ":1144,"คเ":1342,"คว":12568,"คล":7051,"คา":4157,"คำ":3659,"คั":3422,"คอ":3384,"งข":9913,"งก":19903,"งค":13884,"ค่":1995,"ค้":2249,"ค์":5026,"งบ":3074,"งน":4757,"งท":10771,"งพ":4931,"งผ":1609,"งป":7671,"งย":2006,"งม":7023,"งภ":1825,"จก":1261,"งล":2323,"งร":6456,"งช":5175,"งง":1006,"งจ":7033,"งซ":1220,"งต":6752,"งถ":1603,"งด":3806,"กภ":1049,"กพ":1569,"กป":1954,"กน":2935,"กบ":1539,"กท":4244,"กต":4649,"กด":2721,"กฏ":948,"กฎ":1349,"กซ":2148,"กช":1615,"กจ":3262,"กง":1224,"กค":3642,"กข":3351,"ter":1286,"กก":5870,"กู":1343,"กเ":10000,"กั":20495,"กา":51462,"กำ":3149,"กิ":9995,"ขต":2558,"กี":4840,"ขน":4066,"กุ":3321,"กส":5176,"กษ":11940,"กห":1741,"กอ":8499,"กะ":1354,"กย":1271,"กม":4662,"กฤ":4112,"กร":27767,"กล":15020,"กศ":807,"กว":6893,"ขี":3132,"ขา":5865,"the":1233,"ขุ":925,"ขึ":5668,"ก์":773,"ขอ":32858,"ก๊":859,"ก้":1794,"ขั":2842,"กไ":1756,"กใ":2974,"กโ":1476,"กแ":3798,"ก่":6422,"ก็":3535,"ขว":1297,"วกั":2290,"วขอ":818,"ลเม":1412,"ษา ":1133,"ล่น":1147,"ล่า":2925,"ล้ว":2260,"ล้อ":942,"ล้า":3112,"วงก":746,"วงศ":3050,"ล็ก":2525,"วนใ":973,"วนห":850,"วนก":966,"วที":983,"วยเ":735,"วรร":3044,"วร์":805,"วยก":1046,"วมก":896,"วอร":1058,"วลา":1487,"วละ":990,"ส์ ":2631,"วีย":1077,"ศตว":752,"วิน":754,"วิต":1559,"วิท":5574,"วิช":1485,"วาม":10406,"วาง":1213,"วัล":909,"วัน":10402,"วัต":2453,"วัด":5975,"วัฒ":910,"วัง":868,"ศน์":1136,"วเต":851,"ศรี":1384,"วไป":1324,"อก ":1672,"ว่า":16578,"ว้น":750,"ว้า":1054,"อง ":7392,"ศัย":746,"ศัก":1311,"ษณะ":2477,"ศาส":7153,"ศึก":3054,"ษณ์":883,"ศิล":1821,"ษที":956,"ศูน":857,"ษย์":1021,"ศไท":1672,"สกุ":748,"อน ":3168,"สงค":1388,"อม ":778,"อย ":1240,"ษาก":925,"ษัต":893,"ษัท":1443,"สตร":5931,"ษาอ":1852,"ษาเ":921,"สดง":2076,"สนา":1982,"สต์":1797,"สถา":5432,"สมเ":2557,"สมุ":1016,"สมา":1528,"สมั":2283,"สภา":1234,"สัญ":1359,"สัง":2218,"สัต":1750,"สัน":1365,"สาข":1007,"สัม":975,"สำน":1154,"สิง":944,"สาธ":1138,"สาย":2246,"สำค":1783,"สาร":3032,"สาม":4593,"สาว":795,"สอง":2064,"หญิ":1133,"สหร":1602,"หญ่":3811,"สร้":3626,"หมา":5219,"หมื":980,"หมู":1311,"หม่":2082,"หรื":14127,"หรั":3559,"สเต":1342,"หมด":1024,"สุร":1490,"สูง":1909,"สือ":1352,"หนด":759,"สุด":3697,"หน่":2681,"หน้":3646,"หนั":1888,"สูต":893,"หนื":2453,"หนึ":6865,"สู่":776,"สำเ":741,"สิท":1099,"สิน":1011,"สำห":2054,"สิ่":1600,"สีย":3370,"หตุ":849,"สี่":1091,"สีเ":803,"สุข":808,"หิน":734,"หาว":2346,"หัว":2009,"หาร":3693,"หาน":1005,"หาก":917,"ส้น":1351,"ส่ว":5073,"ส่ง":1119,"หว่":2958,"หวั":4202,"หล่":1190,"หลั":4230,"หลื":1267,"หลา":3254,"หลี":1577,"หลว":2304,"องจ":2432,"องค":5587,"องข":1511,"องก":4220,"องน":1770,"องท":3322,"องด":1078,"องต":1671,"องช":1455,"องว":1091,"องร":2706,"องพ":2170,"องม":1890,"องภ":735,"องป":3285,"องบ":1250,"องส":4135,"องห":2070,"องอ":2544,"อกเ":2315,"อกแ":903,"อขอ":1542,"อกจ":1222,"อกอ":862,"อกั":828,"อกา":1632,"อตั":1635,"อดี":1193,"อนก":910,"อที":1522,"ห่ง":6109,"ัก ":1014,"องโ":2181,"องใ":1090,"องไ":1059,"องเ":6096,"องแ":2259,"ห็น":791,"ห้เ":1731,"ัง ":1312,"ัน ":5497,"อมา":1234,"อมพ":870,"ับ ":2373,"อมเ":1000,"อมู":1073,"อย่":3805,"อยู":11352,"อร์":11720,"อวั":2718,"อวิ":799,"าก ":2111,"อว่":1274,"อนด":815,"อธิ":902,"อนท":1025,"อนุ":1065,"อบด":1116,"อนไ":741,"อนเ":1384,"ัด ":1246,"อิส":796,"อิน":2322,"อำเ":2340,"อีก":2134,"อำน":838,"อาห":1406,"ัส ":1055,"อาศ":740,"อาร":1724,"อาจ":1975,"อัล":1451,"อาณ":1739,"าช ":1056,"อื่":1772,"ออก":6565,"ัย ":1671,"อสา":832,"อัง":3552,"อาก":1660,"อัน":2487,"ัว ":1389,"อัก":2043,"าง ":4454,"อ่า":789,"าม ":1873,"าย ":3426,"าณ ":1847,"อเม":2930,"อเป":1207,"าน ":3701,"อเส":824,"อเร":1957,"อเช":951},"n_words":[7308152,7320273,4252865],"name":"th"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tur b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tur new file mode 100644 index 000000000..ed84e9ba3 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/tur @@ -0,0 +1 @@ +{"freq":{"D":20468,"E":16965,"F":15212,"G":16978,"A":46399,"B":33447,"C":16597,"L":11614,"M":29609,"N":10463,"O":12233,"H":17902,"I":6437,"J":5964,"K":30894,"U":5006,"T":27864,"W":5022,"V":7330,"P":19836,"S":32251,"R":13212,"Y":12032,"Z":2430,"f":59766,"g":101779,"d":361700,"e":798707,"b":176889,"c":86462,"a":1029574,"n":718304,"o":261031,"l":623439,"m":275808,"j":10372,"k":334154,"h":85819,"i":785261,"w":7611,"v":106213,"u":275921,"t":334795,"s":315971,"r":646028,"q":1181,"p":80800,"z":105754,"y":255623,"x":3410,"²":1600,"Ç":4715,"Ü":2583,"Ö":3499,"î":1753,"é":1705,"ç":69086,"â":3605,"ü":157542,"ö":58180,"ğ":69432,"ı":399538,"İ":20804,"ş":111613,"Ş":5518," l":7220," m":26771," n":32386," o":55007," h":21337," i":59190," k":78855," d":82641," e":36355," f":17358," g":42591,"р":1499," a":67898,"с":1190," b":117978,"т":957," c":5691," y":76657," z":4398," u":11497," t":53835," v":55379," p":15531," s":57822," r":8817," J":5925," K":30750," H":17802," I":6388," N":10386," O":12150," L":11515," M":29458," B":33275," C":16419," A":46229," F":15133," G":16827," D":20328," E":16897,"л":1101," Z":2402,"к":1097," Y":11995,"и":2029,"о":2304,"н":1554," S":31973,"в":1191," R":13120," P":19696,"а":2550," W":4958," V":7287,"е":1678," U":4989," T":27682," ç":18143," ö":14326," ü":15280," Ç":4706," Ö":3487," Ü":2581," ı":6625," İ":20776," ş":10933," Ş":5509,"ي":1130,"ل":1185,"ن":965,"ا":2068,"A ":2665,"Da":3349,"Cu":2398,"Co":2920,"Ce":1839,"Ch":2248,"Do":2641,"De":6139,"Di":2765,"Fe":2199,"Fa":2297,"Ey":1528,"Er":2288,"Es":1409,"En":2354,"El":1347,"Ek":1512,"Ağ":1411,"Ge":3246,"Ga":2711,"Bü":1152,"I ":2251,"Bö":1239,"Fr":4109,"Fo":1223,"Fi":2407,"B ":1016,"C ":1464,"Av":3034,"Ar":5311,"At":1678,"As":1760,"D ":3341,"Ba":8245,"Ay":1472,"Af":1012,"Ab":1087,"Ad":2089,"Am":3467,"An":5110,"Ak":1709,"Al":8286,"Bu":5544,"Br":2172,"Ca":3556,"Bi":5816,"Be":4617,"Bo":2818,"Ku":5039,"Gö":1216,"Kr":1520,"Ko":3871,"Le":1961,"Li":3051,"Gü":3195,"La":2872,"Lo":1867,"Me":5154,"Mi":3881,"Ma":11016,"Mu":2388,"Mo":2807,"Ni":2456,"Ne":2578,"Na":1799,"P ":982,"No":1828,"Ok":1001,"Ol":1014,"Oc":1091,"Gi":1074,"Gr":2260,"Go":1145,"Ha":7669,"He":2472,"Hi":1980,"Ho":2868,"Dü":2155,"In":1300,"Ja":2318,"Jo":1650,"Ka":10073,"M ":1217,"Ki":1749,"Ke":1920,"Ul":1131,"Tu":1634,"Tr":1523,"To":2482,"Th":2500,"Ti":1452,"Te":4160,"Ta":4376,"V ":1033,"St":3068,"Su":2048,"Wi":1541,"Wa":1156,"Vi":2393,"Va":1979,"Ve":1434,"Pr":2222,"S ":1244,"Pe":2037,"Pa":5059,"Kü":1314,"Po":6260,"Pi":1406,"Os":2243,"Or":2331,"Kö":1204,"Se":4094,"Sc":1963,"Si":3179,"Sh":999,"Sp":940,"So":3019,"Ru":3002,"Sa":7772,"Re":2740,"Ri":1066,"Ro":3278,"Kı":2617,"Ra":1699,"Mü":1802,"b ":1498,"a ":176902,"Ye":1685,"Tü":7528,"Ya":4483,"Yo":1238,"Yu":2386,"bö":7750,"i ":134793,"ge":29308,"ağ":18792,"bü":7597,"ga":7799,"fl":1604,"ff":1053,"fi":9181,"fr":3323,"fu":6151,"ft":2020,"fo":3898,"he":11849,"ha":24248,"cü":3165,"gl":1385,"gi":16689,"gh":1246,"gu":5867,"gr":6009,"go":2702,"du":14570,"dy":2265,"g ":6921,"ea":4032,"eb":5387,"ec":6696,"ed":29273,"de":95875,"dd":2946,"di":58969,"dl":2907,"do":12268,"dr":3254,"ew":1275,"eu":1087,"ev":14605,"ey":30087,"ez":8326,"fa":8497,"h ":5851,"fe":6028,"eh":5944,"eg":3973,"ef":3639,"ee":1898,"el":56887,"ek":41993,"aç":5873,"ei":4450,"ep":3432,"eo":3151,"en":100462,"em":27716,"et":47279,"es":52024,"er":131153,"ca":18661,"e ":189222,"br":3182,"bu":23594,"bo":7205,"bl":1863,"bi":65897,"be":19027,"da":97587,"f ":5395,"cu":6717,"ct":1404,"cr":1803,"co":3001,"ck":3008,"ci":12969,"ch":6435,"ce":16707,"c ":1516,"az":19018,"ay":42685,"ba":34644,"d ":11781,"at":38962,"as":49850,"ar":157561,"av":10941,"au":2292,"ak":57066,"al":73836,"ai":6322,"aj":1917,"ap":20439,"am":37584,"an":184545,"ac":10260,"ad":37380,"aa":2080,"ab":13369,"ag":3250,"ah":16357,"ae":2002,"af":13702,"nu":18358,"nt":17557,"ns":13849,"nr":3598,"no":7521,"nn":3019,"nz":1833,"ny":12611,"hı":1036,"iğ":11558,"of":3409,"oc":3225,"od":4927,"ob":3075,"om":13542,"on":43168,"ok":10977,"kç":3190,"ol":59486,"oi":1195,"oj":3578,"og":3689,"oh":1112,"m²":1589,"ot":7864,"os":10639,"ov":4695,"ou":3530,"op":8235,"oo":1893,"or":32678,"r ":170339,"ow":1477,"oz":2422,"kö":4303,"oy":8048,"pe":6240,"kü":6018,"pa":15264,"pl":7151,"pm":1729,"po":6918,"ph":1672,"pi":5799,"lç":5891,"lo":10260,"lm":31640,"ll":28962,"ls":3083,"fı":9951,"lu":32826,"lt":9362,"ly":5619,"o ":14289,"mc":2028,"md":5246,"hü":1497,"ma":67090,"mb":3028,"eş":11455,"mh":2240,"me":45214,"iç":12229,"ml":15462,"mi":33126,"mm":2739,"mp":4822,"mo":6599,"ms":3576,"mu":11366,"gı":2023,"my":1356,"p ":11912,"na":47407,"nb":3039,"nc":18538,"nd":102802,"ne":51401,"nf":1257,"ng":12672,"ni":53546,"nk":5100,"nl":28972,"nm":10641,"dı":37931,"ki":41309,"eğ":6350,"ke":25138,"ka":45970,"m ":32916,"ky":1403,"gö":9935,"ks":8093,"kt":21304,"ku":22990,"ko":13147,"kr":3294,"kk":1610,"kl":25669,"km":5012,"kn":1431,"li":71923,"lk":10655,"le":122046,"ld":15695,"lg":12154,"lf":964,"la":144587,"gü":8845,"lc":1649,"lb":3731,"n ":243619,"hr":4105,"bı":1392,"ht":2266,"hu":4538,"hi":16646,"hn":1197,"ho":2852,"hl":3714,"hm":1584,"id":21397,"ic":9431,"ib":5859,"dü":13708,"ia":8374,"ih":7127,"ig":4782,"aş":24105,"if":4811,"ie":4567,"dö":3928,"k ":83031,"ir":107452,"is":40125,"it":22698,"iu":1112,"iv":5224,"cı":8286,"ii":1103,"ij":1085,"ik":40360,"eç":4865,"il":86504,"im":27783,"in":138518,"io":5300,"ip":8100,"je":1713,"ji":4659,"iz":21969,"iy":28989,"l ":42232,"ja":1035,"tç":1871,"ğlu":963,"rı":43249,"sö":2312,"z ":18621,"sü":4852,"oş":947,"wi":1830,"sç":1475,"pı":8243,"vv":1012,"vy":1154,"y ":15418,"wa":1412,"rü":8173,"ğla":2983,"vl":4067,"rç":3762,"vi":9343,"nş":1036,"vu":2607,"vr":5677,"vo":1424,"uz":10570,"uy":4807,"uv":2249,"ve":59460,"va":15490,"x ":1999,"ui":1273,"uk":6582,"ul":36937,"ue":3947,"oğ":10206,"ug":2004,"ğit":1160,"uh":1861,"ur":35478,"ğin":3622,"us":21592,"ut":7622,"um":12243,"un":39859,"up":6378,"ty":1262,"tu":11035,"tt":7164,"nı":44489,"ub":5081,"ua":1900,"ud":5831,"uc":4903,"w ":1459,"to":17485,"tm":6406,"tl":13327,"ts":2378,"tr":10162,"te":52587,"pç":1206,"tk":2785,"ti":53158,"th":4577,"v ":2143,"tb":2499,"ta":68248,"su":11906,"sv":930,"ss":3728,"st":34655,"sy":6610,"mı":21024,"sw":1258,"sl":8558,"sk":7111,"sn":1024,"sm":5546,"sp":5003,"so":11037,"sc":1810,"se":25089,"sh":2001,"si":63532,"rz":1185,"u ":42818,"sa":39618,"nü":10410,"rr":2777,"rs":8400,"rt":19992,"ru":21036,"rv":1617,"lı":53226,"ry":3722,"rp":1215,"ro":18824,"rn":5785,"rm":14124,"rl":25348,"rk":23839,"nç":1698,"rj":994,"ri":89903,"rh":1272,"rg":7962,"rf":1575,"re":45975,"rd":23811,"rc":3479,"rb":3537,"mü":12609,"ği ":7346,"ra":89176,"t ":36013,"kı":16796,"ğer":2592,"iş":22142,"lü":12025,"s ":31408,"pt":3720,"pu":1218,"pr":5018,"ps":1980,"ğun":2143,"ğus":1809,"ğum":954,"zı":6859,"zü":1410,"yı":27954,"yü":11063,"ğu ":5997,"zö":2165,"ğlı":7152,"ğre":1586,"uş":11784,"yâ":1423,"yö":4435,"ğiş":1548,"uğ":6358,"zg":2173,"rş":2653,"zi":13389,"zc":5363,"zd":2307,"ze":21253,"za":12673,"tı":26503,"zy":1958,"zu":2578,"zo":2918,"zm":3788,"zl":5972,"yg":2621,"ye":34397,"yd":5178,"tü":11302,"ya":90167,"yb":1899,"tö":1628,"sı":43368,"yv":967,"yu":8007,"ys":1270,"yr":3168,"yo":15057,"yn":5330,"ym":1117,"yl":13689,"yk":1018,"uç":1551,"yi":7908,"² ":1587,"ğı ":9316,"ğın":3141,"Çi":1350,"Ça":1454,"âl":1634,"Ün":1471,"Öz":1299,"çı":7148,"çü":4634,"î ":1515,"ço":5321,"çm":1158,"çl":3470,"çi":13394,"çe":14606,"ça":9969,"ç ":5469,"üş":3641,"üğ":1561,"üç":3404,"ün":27564,"üm":12601,"ül":12799,"üs":5069,"ür":27019,"üp":974,"üt":2907,"üz":15474,"üy":5418,"üc":2767,"üf":4960,"üd":3476,"öğ":1623,"ük":10837,"ü ":14372,"öy":3363,"öz":7289,"ör":11792,"ös":1882,"ön":12083,"öl":13407,"ök":2015,"ğ ":1364,"ğu":12250,"ğr":3621,"ğe":3325,"ğd":979,"ğa":3324,"ğl":11320,"ği":14714,"ğı":15723,"ğü":1540,"ığ":10531,"ış":19918,"ı ":102139,"İn":4248,"İm":1089,"İl":1863,"ın":99943,"ım":16215,"ıp":1333,"ıl":42504,"ık":17416,"ıf":1477,"ıb":1069,"ıd":8898,"ıc":3354,"İt":1484,"İr":962,"İs":7391,"ıy":7698,"ız":6701,"ıs":11942,"ıt":2777,"ır":43940,"şt":19651,"şu":2786,"şi":12692,"şl":8667,"şk":4781,"şm":7053,"şa":13302,"şe":7623,"Şu":1166,"Şa":2212,"Şe":1159,"ş ":18890,"şı":10920,"şü":1419," Ga":2694," Bü":1149," Ağ":1410," Ge":3227," Bö":1239," Fo":1207," Fr":4097," Fi":2393," Ha":7643," He":2466," Go":1137," Gr":2225," Gi":1067," Dü":2153," Ho":2861," Hi":1971," Ja":2310," In":1293," Ka":10047," Ke":1904," Ki":1728," Jo":1635," Gü":3188," La":2844," Le":1944," Li":3034," Ko":3863," Kr":1518," Ku":5027," Gö":1215," Ma":10963," Mi":3862," Me":5127," Lo":1852," Ne":2557," Na":1779," Ni":2442," Mo":2790," Mu":2369," Am":3459," An":5094," Ak":1699," Al":8247," Af":1009," Ad":2080," Ab":1075," Ba":8219," Ay":1468," Av":3029," At":1662," As":1754," Ar":5292," Be":4599," Bi":5804," Bo":2788," Br":2154," Bu":5532," Ca":3515," Ce":1828," Ch":2228," Co":2886," Cu":2385," Da":3328," Di":2745," De":6126," Do":2600," El":1340," Ek":1512," Es":1407," Er":2282," En":2338," Ey":1526," Fe":2195," Fa":2283," Wi":1521," Wa":1142," Yu":2383," Yo":1225," Tü":7497," Ya":4478," Ye":1681," a ":1377," Kö":1204," Os":2235," Or":2329," Po":6216," Pi":1404," Pe":2029," Pa":5030," Kü":1311," No":1821," Ol":1012," Ok":999," Oc":1088," Ra":1684," Mü":1801," Kı":2610," Ro":3268," Re":2723," Ri":1059," Pr":2202," Su":2042," St":2970," Ta":4359," Th":2488," Ti":1443," Te":4145," Tr":1513," To":2461," Ru":2999," Sa":7750," Sh":981," Si":3171," Sc":1940," Se":4078," So":2983," Va":1973," Ve":1421," Vi":2383," Tu":1612," Ul":1129," im":933," in":10201," ik":4076," il":20054," is":5383," ka":23639," ki":5592," ke":6355," eğ":1244," dı":1534," ha":11824," he":4045," gi":4830," gr":3277," dö":3823," dü":5597," id":1007," aş":930," hi":2120," ni":6427," nd":4080," ne":3117," na":1507," mu":1078," mo":2617," ok":1391," ol":35321," on":2426," of":1496," nu":1915," no":1087," le":1165," li":3624," gü":6331," la":1347," ku":18460," gö":9671," km":3282," ko":8297," me":8098," mi":3110," iç":9390," hü":1380," ma":6917," ad":10374," am":2886," an":8617," ai":1874," ak":2362," al":14807," ar":9911," at":1881," as":2441," d ":1776," ba":23010," ay":4744," bi":52706," be":11424," bo":2633," bu":15855," ca":1538," e ":1478," er":1285," et":4327," es":3101," en":6931," el":3328," ek":1681," aç":1971," fe":1277," fa":4483," ey":3388," ev":1229," fu":1090," fr":1901," fo":1846," fi":5962," ağ":1494," ge":16462," bü":4020," ga":1355," i ":957," bö":7468," ci":1625," da":23947," do":7108," de":26605," di":9385," ed":6003," du":2416," za":2588," yo":2330," sı":5340," ye":11522," tü":4969," ya":37365," sö":2004," sü":3398," yı":13517," yü":5685," yö":4365," nü":5050," sa":17392," se":8759," si":6463," sp":996," so":7754," kı":5201," ra":1785," mü":4235," re":3088," ro":2639," pr":3082," iş":3101," ot":2226," or":5403," oy":4366," kö":3581," pe":1612," kü":2525," pa":4625," pl":965," po":2333," pi":1501," va":2885," ve":49979," uz":2734," uy":2267," vi":955," nı":8640," tu":1641," un":2824," ul":1616," ta":27334," st":1812," su":2833," to":3720," th":1268," ti":1727," te":11491," İt":1484," İs":7380," İr":961," ın":4768," İn":4243," İl":1857," İm":1089," Çi":1348," Ça":1452," Öz":1296," Ün":1468," çe":4156," ça":3855," ço":4379," çi":1440," çı":3500," öl":1632," ön":4253," ör":1000," öz":4179," ür":2793," üs":1211," ün":2173," ül":2545," üz":3783," öğ":1347," üç":1563," şi":1684," şe":4952," şa":3567," Şa":2210," Şe":1156," Şu":1166,"İst":2249,"İta":1353,"İsp":2587,"İng":3329,"İmp":936,"ıca":1274,"ıda":1227,"ılı":15802,"ısa":1923,"ıra":2874,"ırl":2487,"ırm":2227,"ını":15301,"ımı":5151,"ıya":1118,"ırı":3492,"ız ":2539,"ıl ":1920,"ıdı":7570,"ık ":8525,"ıcı":2074,"ıla":12183,"ın ":32401,"ıld":3344,"ılm":5978,"ıll":2939,"ım ":3853,"ıka":2439,"ıkl":3108,"ıkt":1193,"ınl":2820,"ıp ":1063,"ınd":38554,"ına":8579,"ınm":927,"ıma":1331,"ımc":938,"ıml":3642,"ıs ":2159,"ır ":29899,"ıyı":1283,"ızı":1437,"ısı":6837,"ıyl":4411,"ızl":1239,"Çin":1025,"ığı":10132,"ış ":6594,"ışt":5588,"ışa":989,"ışm":2843,"ışı":2617,"Fil":1047,"Eyl":1137,"Eki":1120,"End":927,"Ağu":1069,"Gen":1382,"Gal":926,"Böl":1142,"Fra":3208,"II ":1197,"Haz":1331,"Her":938,"Hal":1040,"Har":940,"Dün":1753,"Hol":1623,"Ara":2840,"Avr":1832,"Bar":1214,"Bat":956,"BD ":2271,"Ada":1186,"Alm":3781,"Ame":2710,"Ana":1277,"Ant":1215,"Bu ":2451,"şıl":1169,"şık":1556,"şın":2204,"şı ":3074,"Bel":1045,"Bil":1105,"Baş":989,"Bir":3328,"Cum":2030,"Dev":1876,"Den":1321,"Cha":1022,"Doğ":1141,"Nis":1117,"Oca":1015,"Ort":943,"Osm":1787,"Par":1928,"Pro":985,"Por":4336,"Kan":1554,"Kas":1322,"Kar":2603,"Kon":1226,"Kra":1061,"Kur":1360,"Kuz":1311,"Gün":1851,"Mer":1131,"Man":1052,"Mar":3200,"May":1678,"Mil":1269,"çok":3674,"çeş":1324,"çla":1690,"çim":1273,"çin":7152,"Yun":1817,"Tür":7269,"Yar":1131,"Sta":1148,"Tem":1343,"Rus":2328,"Sch":1519,"Sav":1634,"San":1732,"Rom":1453,"Ulu":930,"The":1923,"ça ":3264,"çal":2740,"çe ":2241,"çes":2357,"çer":2328,"çev":1541,"çek":2799,"çi ":1341,"biy":1472,"bit":1248,"bir":44645,"bil":11436,"bin":1380,"baş":7621,"şa ":1752,"bol":2761,"şam":1786,"şan":2545,"şar":3761,"boy":1344,"ban":1510,"bak":1768,"bal":1557,"baz":1091,"bay":1165,"azı":4805,"bat":3330,"bas":2581,"bar":2153,"Şub":979,"bi ":3364,"ber":3678,"ben":1194,"bel":7483,"bes":1722,"bağ":8489,"şla":4267,"şle":3059,"şma":4426,"şme":1364,"ca ":7674,"car":1245,"can":1925,"cak":4366,"ce ":9532,"bra":943,"bu ":5377,"şek":1911,"şeh":2781,"şi ":1181,"bur":1706,"bul":11239,"bun":1530,"buc":1673,"şid":1048,"şit":1478,"şir":1286,"şin":976,"şim":2323,"şil":1127,"şik":1949,"şki":1113,"şke":1220,"şka":1851,"aka":3723,"am ":5523,"aki":6742,"adı":13553,"al ":11243,"ail":1471,"air":932,"ait":1247,"acı":3398,"ak ":21809,"abı":1039,"ahi":5926,"aha":4061,"anu":1353,"any":6219,"ano":1022,"ann":1052,"anm":4730,"ant":4742,"ans":6131,"ane":2508,"ang":2190,"ani":4880,"ank":1605,"anl":12840,"ap ":1282,"ana":13099,"anb":2176,"anc":4224,"and":10443,"aml":2039,"amp":1789,"ami":2705,"ame":1745,"ama":13353,"aly":2496,"afı":8781,"alt":4529,"alm":2361,"all":3746,"alk":2064,"ali":6616,"ald":2079,"ale":5493,"ala":14214,"alb":2602,"an ":84156,"aks":970,"akt":8868,"akk":924,"akl":5036,"aba":3739,"abe":1525,"abi":3498,"abu":1168,"ae ":1012,"aca":2693,"ad ":1275,"ştu":4101,"şti":6965,"afi":1276,"ştı":7023,"ah ":1276,"ado":1356,"adl":2298,"adi":1602,"add":1987,"ade":4140,"ady":944,"ada":8970,"azi":2552,"azl":1262,"atı":8461,"aze":1261,"arş":2391,"aza":4710,"az ":2571,"ayn":2937,"ayl":1883,"ayr":2190,"ası":27693,"arı":35962,"aya":12842,"ayd":1055,"aye":1092,"âle":1449,"ba ":1088,"ayı":12386,"akı":5066,"at ":6328,"are":4111,"ard":9709,"arc":1066,"ara":45240,"arm":1435,"arl":5899,"ark":6902,"ari":9836,"alı":12304,"ars":1642,"art":5112,"asa":4734,"ary":1104,"asi":2326,"ask":1950,"ar ":19629,"apa":2097,"apm":1588,"apl":1156,"apo":1295,"apt":1792,"as ":3211,"ava":5024,"avr":943,"arç":1233,"avi":1237,"ay ":3414,"avu":1433,"apı":7957,"ata":3117,"ast":3088,"asy":2788,"amı":5927,"atm":1041,"apç":991,"atl":2228,"atr":1379,"ato":2437,"ate":2841,"ati":5438,"att":1422,"anı":18491,"Üni":1310,"Şar":1029,"ji ":1449,"jis":950,"itl":1849,"öğr":1364,"ito":956,"cı ":3493,"ism":1455,"ist":11668,"ita":3780,"ite":3995,"iti":3699,"cıl":1667,"üfu":4682,"iva":1157,"ive":2871,"ilç":2129,"is ":3578,"ion":3161,"ir ":71671,"irm":3093,"irk":1523,"irl":6644,"iri":12312,"isi":13092,"ise":2824,"isa":3166,"ire":3266,"ira":2633,"ird":1851,"it ":3783,"ünl":1704,"üni":930,"ünc":1623,"ünd":2862,"üne":6398,"üml":1023,"üme":1310,"ült":1479,"ür ":5331,"üny":3730,"iyi":1021,"ül ":1714,"iyl":2890,"iyo":3774,"iya":6327,"iye":14035,"üdü":2475,"ük ":5512,"cıy":983,"iz ":6631,"üle":2031,"ülk":2638,"üll":944,"üks":1988,"ün ":4631,"izm":2299,"izl":1160,"izi":3733,"izc":3709,"ükl":1155,"iza":1126,"üm ":2100,"kim":2642,"kil":4381,"kiy":3334,"kiz":4406,"kin":3419,"kis":1066,"kit":1608,"km ":1709,"ki ":15464,"eğe":1107,"eği":4944,"kel":2350,"ken":7944,"kes":1806,"ker":2097,"ket":3347,"kez":3142,"ke ":1164,"kra":1708,"kiş":2390,"kse":2982,"klı":3118,"km²":1573,"kor":1133,"kon":4434,"kom":1557,"kol":1873,"kle":9482,"kla":8235,"kli":3448,"dız":949,"dıy":1257,"dır":19814,"dın":2440,"dı ":5738,"kaz":1358,"kay":2732,"kat":3255,"kar":8976,"kas":2234,"kap":1914,"kan":7174,"kal":4961,"kam":982,"kad":3577,"kab":1637,"dış":1185,"ka ":4513,"dığ":4219,"ha ":3071,"cü ":1507,"ham":1081,"han":2727,"hak":1219,"hal":3743,"hav":968,"har":3475,"has":1125,"hat":1036,"haz":1057,"hay":1743,"he ":3168,"her":2799,"hen":1336,"hem":1060,"hi ":1444,"hip":4144,"hin":2793,"hil":1264,"hir":2302,"hle":2209,"ağı":5375,"gru":2866,"gra":2358,"gul":1221,"gue":2075,"dül":2427,"ian":1361,"dün":2104,"dür":3900,"ibi":3243,"düz":2369,"id ":1061,"iba":969,"ia ":4696,"aş ":1969,"ig ":1399,"ici":2058,"ich":1442,"ice":1186,"ie ":1088,"ica":1674,"idi":13477,"ide":3373,"ida":1813,"if ":1449,"düş":1411,"il ":5350,"im ":8509,"ika":5895,"aşa":4663,"aşl":3782,"aşm":1272,"aşk":2892,"aşt":1881,"ihl":1333,"ihi":3044,"ik ":16892,"iml":3173,"imp":924,"ime":2281,"imd":1567,"imi":5215,"ip ":4274,"inc":5308,"ind":30574,"ina":3996,"aşı":5939,"ino":995,"int":1436,"ins":2898,"ine":16354,"ing":3240,"ini":20786,"inl":1777,"iko":990,"ikl":5637,"iki":4685,"eçi":1614,"eçe":1013,"ila":2643,"in ":47078,"ikt":2801,"ilo":1062,"ill":5588,"ilk":4218,"ilm":10420,"ilg":3153,"ili":20573,"ild":2510,"ile":24870,"ima":2176,"io ":955,"ily":1842,"hri":2688,"hur":2425,"dör":1115,"dön":2425,"fes":1014,"fer":1326,"far":1401,"eyâ":1363,"fa ":1026,"eyb":1488,"eya":8242,"eyl":966,"eyi":4871,"eyd":2007,"eye":3542,"ez ":1852,"ezo":1005,"ezi":2727,"eta":1696,"ete":2836,"eti":16248,"etm":3594,"etl":4019,"etk":1732,"est":3861,"ess":1296,"esw":1087,"ev ":1032,"etr":1981,"ett":2719,"eve":1133,"eva":954,"evl":3752,"erç":1693,"evi":3588,"evr":2587,"ey ":4964,"er ":28073,"es ":5122,"erk":5212,"erl":5910,"eri":48739,"erg":2108,"ere":9775,"erc":963,"erd":6317,"era":4204,"erb":1053,"et ":9016,"açı":2094,"esk":1828,"esl":1542,"esm":989,"esi":30715,"ese":2043,"esa":1128,"ert":1494,"ers":4580,"ern":2620,"erm":2340,"eki":11678,"ekl":5425,"açl":1635,"ekn":1222,"eko":1029,"eks":1790,"ekt":6067,"en ":46837,"ela":1161,"eld":2163,"ele":20479,"eli":10508,"elm":1130,"ell":5734,"els":966,"ema":2676,"eme":6814,"eml":3228,"emm":1228,"emi":6693,"ene":8543,"eng":1269,"ena":1544,"end":6506,"enc":1546,"enm":2094,"enk":1143,"enl":4600,"eni":13441,"ens":1925,"ent":5851,"enz":1180,"egu":1647,"ehr":2303,"ehi":2131,"ek ":9883,"aç ":1092,"ein":1910,"el ":11201,"eke":1777,"eka":935,"em ":2604,"öst":1805,"gis":1807,"gir":1360,"gil":5370,"önü":972,"geç":2375,"gin":1021,"gib":2269,"ört":1016,"öre":4482,"ölü":2891,"ölç":2720,"gi ":2386,"ör ":949,"gen":4928,"ger":3542,"ges":4599,"ağa":1186,"gel":7731,"ağl":9979,"önc":1623,"öne":7107,"ge ":2812,"ağ ":1140,"gaz":1147,"ölg":6551,"gar":1277,"büy":3008,"büm":2701,"gan":1892,"böl":7461,"fus":4728,"fut":963,"öyü":1007,"fre":2029,"for":2226,"öze":3441,"özl":926,"örü":2439,"fil":4052,"da ":52350,"de ":46250,"dak":5123,"dal":2767,"dah":2619,"das":1177,"dar":3775,"dan":21526,"dam":1680,"day":1218,"dde":1533,"cul":955,"cus":1172,"cre":977,"cu ":1846,"ch ":1055,"ces":998,"cek":1367,"cel":1540,"ci ":4802,"ck ":1696,"che":1266,"chl":1164,"cil":1965,"cis":1558,"cin":1363,"ed ":1577,"ebe":1387,"ebi":2611,"efe":1034,"edi":16774,"ede":8053,"eda":1066,"eci":1467,"ece":3057,"dyo":1078,"dur":5671,"duğ":3327,"don":972,"dol":1859,"dok":977,"diğ":3682,"doğ":5145,"dra":1187,"dlı":1288,"du ":2273,"dağ":1454,"der":6369,"des":1911,"dev":2820,"ded":1153,"del":2710,"dek":4272,"den":20219,"dem":1663,"di ":6071,"dla":1190,"do ":1033,"diz":1879,"diy":5465,"din":3013,"dir":24487,"dis":2432,"dik":1433,"dil":6616,"değ":2872,"rga":1818,"ri ":19287,"rgi":1489,"rge":959,"ret":5334,"res":4290,"rev":1391,"rdu":2054,"rg ":1524,"rec":1008,"red":1084,"reg":1836,"ren":6966,"rek":4543,"rel":1942,"rda":4941,"rdi":3615,"rde":5880,"re ":11153,"ray":2290,"müz":3407,"rd ":1472,"rap":1757,"rar":2927,"ras":9820,"rat":4222,"rbi":1042,"rba":1205,"mün":3661,"ran":10600,"ram":4044,"ral":5875,"rak":15812,"rab":1433,"raf":10463,"rad":2346,"rac":1216,"rs ":1268,"ros":1512,"rot":967,"rom":2121,"ron":1936,"rol":2443,"rkç":1463,"rog":1323,"rna":1248,"rne":1926,"ro ":1843,"rma":6313,"rme":4031,"rmi":1407,"rlu":1118,"rli":4427,"rle":9208,"rla":6927,"rki":3194,"rkl":1461,"rke":5713,"rka":1543,"rdı":3751,"riy":3959,"rit":1940,"ris":5765,"rih":5101,"müş":1050,"raş":1079,"ril":8019,"rik":4914,"rin":23896,"rim":3407,"ria":1426,"rdü":1150,"ric":1498,"rid":4314,"rk ":5291,"lıl":999,"lık":8208,"lın":9443,"lım":1113,"lır":2906,"rya":1228,"rup":3018,"run":1284,"rum":2945,"rul":5547,"ry ":1364,"rsi":2903,"rsa":1025,"rta":4786,"rte":4662,"rti":1858,"lı ":21277,"rub":2412,"rt ":3885,"rkı":3548,"ru ":1610,"rlı":1952,"sab":1070,"sad":1069,"nüf":4498,"sah":5074,"sal":4864,"nüm":1062,"san":6337,"nün":1717,"sat":1316,"sar":2328,"say":5210,"sav":1790,"sa ":4002,"nü ":1409,"lış":2586,"lığ":4204,"si ":18237,"sağ":1738,"siz":1136,"siy":3676,"sid":3408,"sia":1857,"sit":3495,"sis":2770,"sin":18799,"sil":2083,"sim":2963,"sik":1925,"se ":2953,"ser":3758,"ses":2131,"sen":2086,"sem":1040,"sel":4229,"sek":2392,"spo":1131,"spa":2896,"son":6601,"su ":5315,"st ":3445,"slu":1935,"sla":3121,"sle":1769,"ski":2726,"ske":1671,"sma":2231,"smi":1955,"mın":4103,"swi":1113,"stü":1161,"sya":2595,"syo":3350,"ste":9865,"sta":9233,"sto":2278,"sti":3825,"stl":934,"str":1911,"mı ":4565,"sun":2855,"tak":3619,"tal":5550,"tab":2400,"tad":4726,"tay":1623,"tat":1503,"tas":2835,"tar":17331,"tap":1242,"tan":13930,"tam":2113,"te ":6912,"tbo":1793,"ta ":6535,"mış":10404,"pa ":2055,"par":4696,"kül":1832,"küm":1078,"pan":3919,"per":2301,"küç":956,"pla":3634,"ple":961,"plu":1414,"lçe":2541,"piy":2262,"por":1907,"pon":1081,"pol":1613,"lçü":2547,"pti":1099,"pra":1013,"pro":2802,"ptı":1375,"lü ":3559,"lüm":2580,"lül":1275,"lük":1015,"iş ":5374,"işi":4832,"işk":1088,"işl":2771,"işt":5462,"kı ":2158,"kıl":1124,"kım":2874,"kıs":2851,"kın":2434,"kıy":1259,"ra ":9857,"mü ":1475,"ngi":4542,"ni ":12017,"nge":1612,"ncü":1344,"nel":4863,"nek":1315,"nen":2962,"nem":4576,"ner":2342,"net":4444,"nes":2204,"ng ":2974,"ned":1504,"ney":4102,"nci":4377,"nce":5236,"nca":4009,"ne ":19615,"nbu":2438,"ndu":1472,"ndr":1044,"ndo":1041,"ndi":6541,"nde":35967,"nda":48013,"ncu":1481,"nak":1647,"nal":3192,"nam":1052,"nan":13136,"nar":2141,"nad":2145,"nd ":2524,"nat":3318,"nas":1441,"nay":1104,"na ":14803,"muş":4297,"nya":10222,"nun":5903,"nus":1510,"nuc":968,"nto":981,"ntr":1143,"nti":4165,"nta":1967,"nte":3585,"nmı":2809,"nst":987,"nse":1596,"nsi":1251,"nsa":3394,"nu ":4463,"nlı":4882,"nra":2468,"nt ":2440,"niş":970,"ns ":1946,"nlü":1339,"nom":2114,"nne":1221,"nme":1944,"nma":4498,"nmi":973,"nli":2503,"nla":14247,"nle":4649,"nlu":1296,"nka":1369,"ndı":4155,"nic":987,"ndü":1181,"niy":1052,"niz":3806,"ncı":1170,"niv":2157,"nis":1976,"nir":2294,"nim":1125,"nin":20306,"nik":2175,"nil":944,"ogr":1717,"ok ":4093,"oji":2722,"ol ":4011,"ock":1051,"ode":1635,"of ":1645,"iği":9467,"iğe":1929,"obi":987,"nsı":2063,"köy":1994,"oyu":4442,"oyn":1402,"oto":3517,"osy":1120,"ost":1210,"osu":1204,"ovi":1205,"ova":1326,"opl":2685,"os ":3304,"çıl":1025,"çık":4300,"or ":3792,"ork":1035,"orl":1782,"orm":2268,"ord":2039,"ore":1088,"org":1822,"ori":2004,"ort":8149,"oru":2784,"m² ":1578,"ora":1605,"ola":24963,"old":3573,"olc":925,"on ":12904,"oli":2380,"oll":2123,"ole":1383,"ols":1253,"olm":3895,"olo":4194,"olu":8661,"om ":1843,"kçe":1715,"okt":974,"oku":2095,"ona":2977,"ond":1625,"one":1566,"oni":1789,"onl":1840,"ono":2239,"onr":2464,"ons":1619,"ont":1468,"onu":7635,"ony":1563,"oma":3785,"ome":1724,"omi":1625,"omo":1197,"la ":11386,"le ":19263,"lde":3058,"ldi":2187,"ldu":3454,"lab":1412,"lac":926,"lad":1565,"lah":1109,"lak":1159,"gün":5583,"lan":43556,"lam":9121,"lar":57894,"lat":2773,"las":2417,"lay":4711,"ld ":958,"kuz":3055,"kur":7540,"kul":7562,"kta":6976,"kte":6402,"ksi":2396,"ktr":1368,"kti":2217,"gös":1720,"gör":5828,"ktı":2504,"lon":1166,"liğ":4787,"loj":2682,"lmi":5563,"lme":4109,"leş":5292,"lma":11588,"lmu":3175,"lst":1073,"lmı":3998,"lta":1114,"lte":1773,"lu ":7438,"llı":1332,"liş":3210,"lt ":1120,"lge":7089,"lgi":3114,"li ":16772,"lbü":2715,"lga":999,"ley":2404,"lev":1310,"les":3725,"let":9791,"ler":45886,"lem":4975,"len":16099,"lek":2724,"led":5291,"lec":1154,"lo ":939,"lla":11633,"lle":6955,"lli":5594,"lke":3179,"lm ":1714,"ldı":4073,"ll ":1428,"lit":1562,"lis":4164,"lir":4755,"lin":9226,"lim":4866,"liz":3501,"liy":1446,"lid":1846,"lia":946,"lk ":5135,"lik":9172,"lil":1002,"laş":3620,"ma ":9869,"mac":2119,"mak":8947,"mad":3045,"mar":2763,"mas":9043,"mal":4481,"mam":1405,"man":15375,"may":3231,"mat":2471,"me ":6043,"mda":1303,"mde":1460,"mdi":1706,"med":2057,"eş ":1039,"met":4942,"mes":5862,"mer":6138,"mel":3135,"men":5922,"mek":5999,"maç":1261,"mey":2238,"çüm":2197,"çük":1139,"luk":1924,"lup":1601,"lun":8327,"lum":1008,"lus":2340,"fın":8889,"lya":3819,"luğ":2080,"ltı":2446,"luş":5045,"mpi":1862,"mod":1329,"mon":1220,"mpa":1588,"mu ":1170,"miş":7571,"mun":1116,"muz":1291,"mhu":2129,"eşm":1123,"eşt":1717,"mi ":6405,"eşi":5221,"min":6521,"mil":2577,"mir":1395,"mis":1028,"mcı":1046,"mit":1204,"mid":2070,"mik":1507,"mlu":936,"mli":2428,"mle":5174,"mla":5844,"içi":8066,"içe":2201,"mmu":1223,"uğu":5772,"tı ":4071,"zun":1539,"tıl":3307,"tın":2882,"tır":10360,"tıs":1266,"zyo":962,"tığ":1565,"zi ":3100,"zet":1053,"zey":4798,"zen":2488,"zel":3272,"zer":6678,"ze ":1245,"zce":3650,"zde":1081,"zam":2429,"zan":2260,"zak":1080,"zar":3022,"zon":1273,"zme":978,"rşı":2081,"zla":2044,"zgü":956,"zle":1804,"zin":1617,"zik":2532,"zir":1408,"zis":1290,"yum":1152,"yun":4454,"sı ":14744,"ynı":1581,"ylü":1204,"yol":2904,"yor":1353,"yon":7554,"yrı":1788,"sıd":1928,"sıl":1373,"sım":1355,"sır":2328,"sın":16353,"sız":2708,"sıy":986,"ye ":8402,"yda":1138,"yed":1753,"yes":4583,"yer":7744,"yen":3683,"yel":1262,"yet":5659,"ya ":30890,"rış":2333,"yba":1101,"yaz":5444,"yay":4498,"yat":3352,"yar":6010,"tür":5785,"yas":4408,"yap":11061,"tün":1161,"yan":10579,"yal":5013,"tüm":1022,"yak":2748,"ydı":961,"yla":6744,"yle":4770,"yo ":1109,"yna":2824,"yi ":2354,"ygu":1552,"yin":3381,"yaş":2680,"tör":1578,"rı ":14655,"rım":1734,"rın":16497,"rıl":3423,"rıs":1452,"sür":2901,"söz":1499,"sça":1363,"wig":1137,"rü ":1492,"rün":2219,"rül":1328,"vru":1839,"vri":1244,"vre":1449,"vra":964,"pıl":3787,"pım":2266,"vil":989,"vaş":2523,"viz":960,"vis":1122,"rça":1249,"rçe":1701,"vle":3463,"vi ":1409,"vey":5886,"ver":8628,"vet":1190,"ven":1213,"ve ":40015,"val":1203,"van":2336,"var":3116,"va ":2329,"uzu":1436,"uze":4115,"uyu":1005,"uza":1667,"uyg":1403,"uya":1017,"uz ":2525,"usç":954,"uva":1017,"usl":3168,"usa":1561,"usu":5699,"ust":2940,"utb":1431,"us ":4706,"ut ":1302,"ura":2627,"urd":1061,"urg":1888,"uri":2897,"urm":935,"uro":982,"urt":1354,"uru":9050,"upa":2517,"ur ":10047,"umu":1897,"umh":2127,"uml":1645,"uma":1385,"unu":6201,"unl":2635,"unm":1881,"unc":2040,"und":5507,"una":8329,"up ":2721,"ukl":1910,"um ":2957,"ulu":12477,"ult":959,"ulm":2979,"ull":6976,"ula":6334,"un ":10772,"uk ":2310,"ul ":3821,"uha":1114,"ucu":1955,"udi":996,"ubu":2444,"uca":2065,"oğu":5104,"oğr":1470,"ues":1785,"udu":3053,"oğa":1679,"oğl":957,"uba":1499,"tur":6494,"nır":2256,"nıl":5540,"nın":19519,"nım":1872,"nıf":1036,"tre":1553,"tra":2671,"tri":1839,"tro":3501,"tte":1278,"tti":2653,"nı ":11130,"tme":3621,"tma":1695,"to ":1507,"tiğ":1447,"tos":1656,"tom":1446,"ton":2840,"tol":991,"tor":3257,"top":3422,"til":2825,"tik":5330,"tif":1158,"taş":2105,"tir":10735,"tis":1905,"tin":8295,"tim":3897,"tio":1845,"tic":1549,"tid":1024,"tiy":1388,"tki":2141,"pça":1027,"tli":1970,"tla":3863,"tle":6323,"tem":6048,"ten":3191,"tei":1620,"tek":7857,"tel":3048,"ted":3509,"th ":1012,"tes":4105,"ter":10441,"ti ":6632,"the":1663,"üşü":1357,"üğü":1444,"zı ":1890,"zıl":2487,"üç ":948,"zöl":2079,"üçü":1824,"yı ":2418,"yım":2005,"yıl":14867,"yın":3653,"yıs":2728,"yük":5408,"yüz":3683,"yön":3982,"üzö":2079,"üyü":3989,"üzi":2596,"üze":7514,"üye":1004,"ütü":1249,"üsü":1036,"ürü":4447,"ürk":7688,"ürl":1211,"üre":5286,"ümü":6554,"ülü":2192,"üs ":1086,"üst":1769,"ünü":3990,"uş ":2901,"uşu":1743,"uşt":4122,"uşa":1668,"yâl":1370},"n_words":[9192208,10449574,7620193],"name":"tr"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ukr b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ukr new file mode 100644 index 000000000..e80f2034b --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/ukr @@ -0,0 +1 @@ +{"freq":{"D":2686,"E":45335,"F":1931,"G":2251,"A":4545,"B":2792,"C":4259,"L":2592,"M":3964,"N":23611,"O":1971,"H":1743,"I":29162,"T":3063,"V":2399,"P":3688,"S":26730,"R":2282,"X":2695,"f":3088,"g":5064,"d":7920,"e":26938,"b":4218,"c":9825,"a":26142,"n":18042,"o":19695,"l":12837,"m":7697,"k":2703,"h":7896,"i":22805,"w":2062,"v":2426,"u":10520,"t":16747,"s":15016,"r":19222,"p":6493,"y":4268,"x":1842,"́":45988,"ь":314859,"ю":121712,"я":259056,"ш":55425,"щ":34352,"ф":70318,"х":152145,"ц":190380,"ч":157844,"р":767814,"с":616542,"т":784384,"у":465611," t":1584,"є":83027,"ї":138148,"і":1047876," p":1613,"Є":3706,"І":14787,"Й":2127,"Л":22219,"К":34440,"Н":39528,"М":28217,"П":47409,"О":15488,"Б":23123,"А":35851,"Г":15610,"В":31676,"Е":8630,"Д":40073,"З":11772,"Ж":3520,"Ш":12613," I":24900,"Ю":2003,"Я":3891," L":1894," M":2910," B":2299,"Т":14847," C":3270,"У":18037,"Р":27850," A":3247,"С":43546," F":1599,"Ц":5942,"Ч":5807," G":1797,"Ф":32198," D":1850,"Х":6705,"л":484150,"к":541520,"й":174507," X":1787,"и":768429,"п":339521,"о":1248992,"н":1274404,"м":381536,"г":226618," S":3616," R":1762,"в":579991,"б":162019," P":2630,"а":1251055,"з":257293,"ж":95383,"е":806087," T":2138,"д":454853,"Ґ":1990,"ґ":4623," А":31736," Б":22701," В":30948," Г":15174," Д":39397," Е":7917," Ж":3460," З":11194," Й":2051," К":32754," Л":21825," М":27530," Н":36830," О":14175," П":46014," Є":3619," І":13525,"EE":21655,"I ":2684," б":36681," а":43891," г":34855," в":154625," е":34325," д":117491," з":113779," ж":8768," й":6819," л":26339," к":61923," н":123337," м":87814," п":148797," о":74913," Р":21137," С":39028," Т":13848," У":16956," Ф":31501," Х":6271," Ц":5651," Ч":5720," Ш":10618," Ю":1964," Я":3806," ї":5196," і":83499," є":13641," т":92032," у":89129," р":101219," с":120858," ц":13483," ч":24594," ф":40198," х":11362," ш":8917," щ":18497," ю":2119," я":36739," Ґ":1984,"E ":21977,"NS":21624,"II":2127,"IN":21640,"SE":21638,"a ":4767,"i ":1589,"he":1740,"el":1571,"en":2535,"es":2308,"er":4659,"e ":6591,"d ":1983,"at":2458,"ar":2758,"al":2232,"an":3512,"ac":1574,"nt":1885,"on":3299,"or":2694,"r ":2633,"o ":1648,"na":1574,"ni":1555,"li":1877,"le":1913,"la":1826,"n ":4271,"ic":2243,"ia":1621,"is":1891,"in":3535,"io":1638,"l ":1929,"y ":1830,"us":2293,"um":1631,"te":2376,"ti":2183,"th":1945,"ta":1627,"st":1645,"ro":2012,"ri":2866,"re":1930,"ra":2584,"t ":3059,"s ":6868,"́ ":2290,"́в":3741,"́д":2078,"́к":2065,"́й":3031,"́м":2120,"́л":4305,"́н":8997,"́р":4428,"́с":2026,"́т":2528,"А ":2905,"В ":2961,"ьє":2885,"юв":4387,"юд":3425,"юр":3284,"ют":14456,"юч":4396,"ює":2722,"яд":6152,"яг":3108,"яв":2990,"юю":1542,"ян":10771,"ям":9107,"ял":2194,"як":26414,"яз":4329,"ях":3443,"ят":9738,"яр":2263,"яч":4477,"яє":2354,"ші":2899,"щи":3380,"ще":5720,"ща":2636,"що":19501,"щі":1589,"ьк":115778,"і́":5805,"ьб":1841,"ьв":2256,"ьш":4727,"ьс":24456,"ьт":4512,"ьн":50183,"ьм":4831,"ьп":5070,"ьо":12701,"фі":13912,"хи":2735,"хн":7629,"хо":17158,"хр":2067,"ху":3902,"ха":7837,"ци":27077,"хі":11714,"цт":3698,"цу":23008,"це":16672,"чл":2502,"чн":59778,"чо":6493,"ці":93529,"чи":16012,"чк":3842,"чу":3146,"ць":14520,"че":19603,"ця":6177,"ча":25750,"цю":1804,"шо":7889,"шн":3282,"шк":3613,"шл":2107,"ши":11930,"шт":3498,"шу":1879,"чч":1777,"чі":4713,"ше":8200,"ша":4745,"ск":15952,"см":3119,"сл":40211,"со":21185,"сн":22933,"сп":20278,"св":10260,"се":44728,"си":21636,"рі":55323,"рш":6088,"рю":2898,"са":14767,"ря":9090,"рр":2512,"рс":15180,"рт":37524,"ру":28810,"рх":8486,"рц":1712,"тн":17002,"тл":3183,"тк":8278,"тс":3967,"тр":48477,"то":75584,"те":71719,"тв":21013,"ти":129473,"сі":43933,"сь":82109,"та":153881,"ся":27435,"сю":2514,"су":15433,"сс":3485,"ст":199868,"сх":2897,"сц":3318,"ур":24405,"уп":9084,"ут":35010,"ус":11964,"ум":8171,"ул":17666,"ун":34351,"ті":36808,"уз":30153,"ук":20646,"уд":13417,"уг":6510,"уж":3934,"тю":2714,"уа":9949,"тя":7369,"уб":6901,"ув":18706,"ть":44694,"тт":6769,"ту":74115,"фу":3164,"фт":2346,"фр":25365,"фо":9781,"фе":6303,"ує":8184,"фа":4406,"ую":4341,"уч":6062,"уш":1880,"ух":4146,"іш":7237,"іц":26077,"іч":43837,"іє":28690,"їв":4260,"ію":3757,"ія":30142,"ін":70416,"ім":15479,"іл":34864,"ік":38962,"ій":44252,"із":21994,"іж":6237,"іх":3168,"іф":1617,"іт":52153,"іс":42072,"ір":18028,"іп":25092,"іо":58208,"ів":71042,"іг":5632,"ід":79007,"іа":11156,"іб":26830,"її":1916,"ії":55045,"їн":18326,"їх":2476,"єю":25186,"єм":3400,"єн":2727,"єт":11907,"єр":2623,"єд":3075,"єк":1686,"єв":4497," IN":21609,"а ":272631,"Р ":3804,"У ":2439,"Єв":1986,"Ів":2523,"Ін":2522,"Іл":1807,"к ":38380,"й ":109949,"Ле":2968,"Ла":4470,"Ку":2193,"Ко":9293,"м ":60876,"Кр":3269,"Ки":4604,"Ка":8275,"л ":10034,"Йо":1971,"На":28658,"Не":1779,"Мі":3387,"Мо":5475,"о ":171358,"Ма":9118,"Ль":1829,"Ми":3400,"Лі":2822,"Ме":3642,"н ":48334,"Ло":1601,"Лу":5897,"Па":5129,"Пе":6590,"По":6892,"с ":17750,"р ":43282,"Ос":1646,"Ор":1949,"Ні":1710,"Ол":3009,"Но":2027,"п ":4596,"в ":98488,"Ам":1689,"Ан":4049,"Ак":1666,"Ал":7021,"Ав":2330,"Ба":3984,"Ар":5755,"б ":28913,"Во":3994,"д ":30432,"Ве":7201,"Ви":2444,"Бі":2125,"Га":3476,"Бо":3837,"г ":7123,"Бр":2821,"Бе":3301,"Ва":4390,"Бу":4720,"Дж":1933,"Де":3400,"До":4198,"ж ":10290,"Ві":6492,"Ге":2702,"Гр":3253,"Го":2499,"е ":51777,"Да":23258,"и ":147695,"За":6302,"з ":38125,"Ен":2243,"ь ":77560,"е́":6375,"Ша":6268,"Ше":1818,"и́":5895,"ю ":78537,"я ":164366,"Ст":3877,"Су":1648,"Та":2989,"Сі":1751,"Те":3497,"То":1720,"ф ":2068,"Тр":1849,"Ук":9250,"х ":93221,"РС":2535,"Пр":9085,"Пу":2178,"Ра":2736,"Ре":2944,"Пі":12505,"Ри":1682,"СР":4182,"т ":74217,"Ро":9385,"Ру":1597,"СШ":1868,"Са":5497,"Св":1748,"Си":1634,"Се":8345,"Со":4417,"у ":182563,"Це":4350,"ш ":3438,"а́":12498,"Че":2490,"ША":1865,"Фр":25493,"Фе":1857,"Ха":2266,"ч ":13144,"ль":97373,"лю":13039,"мб":2910,"ма":43992,"ля":27148,"ме":56645,"лі":100876,"ми":33489,"мл":2674,"мк":1772,"лл":4063,"ло":47531,"лу":11894,"ла":56466,"ле":64714,"лк":3429,"ли":41628,"кі":53446,"км":1768,"кн":2648,"кл":18117,"кр":33069,"кс":9526,"ко":160847,"кт":21418,"ку":30802,"кц":4113,"ка":63693,"ки":83769,"кв":7446,"ке":9654,"йн":15208,"йо":12518,"йк":1565,"йл":1986,"йм":3040,"йс":17098,"ия":1553,"ищ":6034,"иш":3403,"иї":2680,"у́":2267,"иє":2892,"йд":1750,"йб":2838,"ип":31662,"им":32760,"ин":52951,"ик":67385,"ил":14249,"ий":79035,"иц":14181,"ич":30391,"иф":2474,"их":75898,"ит":52472,"ир":15232,"ис":66975,"ри":69723,"рк":9097,"рл":2627,"рм":12337,"рн":24183,"ро":132547,"рп":3819,"ра":159212,"рб":3520,"рв":5932,"рг":12811,"рд":11789,"ре":97753,"рж":5968,"пі":30461,"пр":61701,"пт":2856,"пс":1790,"пу":8363,"ої":42339,"пи":15610,"пн":6007,"по":70389,"пл":11153,"ою":42263,"оя":1743,"па":69692,"оє":2366,"пе":54812,"ощ":2597,"ош":4991,"оч":9700,"оц":9082,"ос":101143,"ор":94904,"оп":23531,"оо":1738,"ох":8570,"оф":6129,"от":23405,"ок":38039,"ол":59373,"ом":93606,"он":134604,"ож":13014,"ні":182081,"оз":26801,"ой":3869,"ов":119233,"ог":97492,"од":63564,"ое":3185,"ню":3932,"ня":95444,"об":38077,"нь":43392,"нц":54211,"нш":5309,"нч":1583,"нт":57484,"нс":58539,"нф":2536,"ну":21092,"но":153491,"нн":89867,"нк":13365,"мі":70237,"ни":149376,"не":44107,"нг":6365,"нд":19006,"на":216248,"му":49313,"мс":3566,"мп":12768,"мо":32397,"мн":5261,"мм":1713,"ге":9243,"ві":92696,"ги":4209,"гн":2639,"го":97928,"гл":6748,"гр":20635,"гу":9031,"дв":4924,"дб":1844,"да":33332,"вд":7688,"ве":48786,"вж":2823,"бі":16889,"ви":75994,"вк":5403,"вл":11314,"вн":39402,"є ":23248,"во":52805,"вп":2102,"вр":5405,"вс":21071,"ву":11922,"вт":7129,"вч":4263,"вц":1693,"га":24943,"вя":2583,"би":5176,"аї":20255,"ає":15656,"бе":15560,"бр":8733,"бн":4172,"бо":24369,"бл":17974,"бк":1672,"бу":17942,"бс":1904,"ва":79944,"ад":39043,"аж":6697,"аз":20777,"аб":18055,"ав":68705,"аг":13743,"ам":54378,"ан":186015,"ап":12553,"ай":22198,"ак":29485,"ал":112843,"ах":20860,"аф":6570,"ач":13762,"ац":41300,"ас":69626,"ар":92013,"ау":6764,"ат":76559,"ба":13923,"аю":6775,"аш":6416,"зт":3423,"зр":3339,"зп":3833,"зу":8061,"зк":2540,"зи":11355,"жі":2914,"зо":12242,"зн":22505,"зм":7721,"ив":25953,"иг":5812,"иб":4671,"иж":2800,"зі":9568,"из":10688,"ид":11644,"зь":26870,"жо":4282,"жу":4654,"еї":6545,"жи":9686,"жн":10415,"за":70302,"зб":4513,"зв":12953,"зг":1786,"зд":4686,"зе":9240,"еф":2808,"ет":48754,"ес":21933,"ер":123318,"еп":28664,"ї ":106019,"ео":7564,"ен":200818,"ем":25862,"ел":52238,"ек":44785,"ей":12736,"ез":15415,"ді":60214,"еж":8691,"же":36749,"ея":2396,"жа":10671,"еч":5677,"еш":1971,"ех":4631,"ец":12416,"дс":7505,"др":11609,"ду":13511,"дн":33993,"дм":3635,"дп":3899,"і ":217878,"до":70187,"ди":35057,"дл":9508,"дк":6162,"де":83166,"дз":2175,"гі":41117,"о́":9048,"дж":30353,"еб":4669,"ев":15708,"ег":29992,"ед":62088,"дя":4582,"еа":4570," ар":4635," ба":6422," аб":10662," ав":3504," ад":2033," ал":3311," ак":3721," ан":4873," ам":2325," бу":8984," ва":2979," бе":6626," бр":1983," бо":3438," бл":2347," ву":2932," га":4235," бі":6025," ви":31633," ве":7581," во":6259," є ":4843," вс":3250," вл":2695," дв":2986," да":3768," гу":2423," го":6549," гр":11679," ге":4251," ві":52058," до":45102," і ":33511," др":3031," де":37135," гі":3754," ди":4078," дл":8069," ел":3252," ек":24873," ді":8202," зд":2257," зе":1996," за":56665," зв":4345," зб":3336," жо":2604," жи":2736," зм":2726," зо":3274," зн":5228," зі":1585," йо":3069," ка":7109," кв":3523," кр":6792," ко":25840," кн":1684," кл":3559," ку":3737," ла":4131," кі":5040," ли":5653," ле":3016," ме":10350," лі":7010," ми":2991," лю":4680," ма":12887," мо":13377," му":26214," ни":3719," мі":18386," не":11146," на":101285," но":3271," ок":3237," оз":1668," ні":2363," од":9316," об":14076," от":1642," ор":5923," ос":30485," оп":3801," по":44438," пл":4775," пи":3225," пе":16844," па":8207," Ре":2937," Пі":12498," Ра":2732," Ро":9378," Ри":1682," Пу":2177," Пр":9060," Пе":6585," Па":5105," По":6869," Ос":1642," Ор":1944," р ":1902," Те":3490," Сі":1746," То":1716," Тр":1847," Ст":3864," Су":1643," Та":2975," Св":1745," Си":1629," Се":8339," Со":4411," у ":67844," Ру":1597," СШ":1865," Са":5492," Фр":25493," Фе":1855," Ук":9235," Це":4345," Ха":2264," Ше":1818," Ша":6265," Че":2486," я ":1678," Ба":3980," Ар":5747," в ":34140," Ан":4045," Ам":1689," Ал":7017," Ак":1665," Ав":2326," Ва":4387," Бу":4716," Бо":3831," Бр":2819," Бе":3297," а ":3713," Дж":1930," Де":3390," До":4191," Ен":2238," з ":28463," Га":3472," Ве":7185," Ви":2437," Бі":2122," Во":3987," Да":23253," Ге":2696," Ві":6479," Го":2496," Гр":3249," Йо":1970," Ки":4602," Ка":8259," За":6236," й ":3420," Мо":5471," На":28633," Не":1775," Мі":3382," Но":2025," Ол":3009," Ні":1705," Ко":9278," м ":2294," Кр":3260," Ку":2189," Ла":4467," Ле":2966," Ло":1600," Лу":5896," Ль":1829," Ма":9106," Лі":2816," Ме":3636," Ми":3397," У ":1855," Єв":1986," Ів":2522," Іл":1806," Ін":2499," В ":2749,"Шам":2267,"Шар":2655,"INS":21596,"Кар":1691,"Кор":2456,"Киї":2310," єк":1604," єд":2480," їх":2188," іс":5151," із":3768," ім":4088," ін":33850," її":1897,"Луа":4691," ра":11678," ре":33133," пі":17870," ри":2122," ро":38150," пр":49254," св":7646," рі":9410," си":9133," се":11547," сл":3167," см":1572," ск":6896," сп":12079," со":4130," ру":3107," са":3132," сі":4244," ти":4115," тв":2718," те":13347," то":7539," тр":8770," сх":2630," ст":41843," су":7442," сю":1727," та":50935," ук":7367," ті":1840," ус":2008," ут":2182," ун":1655," фо":4647," фр":23569," фу":2570," фа":2336," уч":1717," хр":1639," хо":1776," ху":1552," фі":5255," ха":2328," ци":1770," це":7308," чо":1959," чл":2302," чи":4976," ці":2356," че":5747," ча":8926,"Льв":1624,"Мар":4041," шт":1850," що":17557," ян":1885," яз":3165," як":23816," ят":2201,"Мик":1636,"Мон":1603,"Нас":21926,"ад ":3964,"ав ":5473,"EE ":21630,"ам ":4361,"ан ":7774,"ак ":2945,"ал ":2859,"ай ":1706,"Оле":2078,"авч":1579,"авт":2891,"ага":5972,"аві":2505,"аго":2958,"ада":8317,"ади":3697,"аде":2606,"аду":2146,"адс":2241,"адо":2036,"адм":1600,"адя":2411,"аді":3733,"би ":2028,"ажа":1619,"або":10777,"абе":1768,"ава":4168,"авн":9017,"авл":3400,"авс":2814,"ає ":8442,"аво":4040,"аве":24071,"ави":3333,"бо ":10197,"ало":3744,"алу":3259,"ала":5763,"али":6052,"акі":1706,"але":7492,"амо":2377,"амп":2753,"ама":2782,"аль":45514,"ами":10086,"аме":25683,"алі":34159,"анн":20969,"ано":8600,"ану":2414,"анс":11789,"ант":9369,"анц":47104,"ань":4811,"ана":9630,"анд":6858,"анг":2311,"ани":9657,"амі":2404,"ане":2623,"анк":2826,"ані":36761,"азу":2305,"азо":3692,"ази":2579,"азв":4425,"аза":2057,"азі":1724,"айс":1694,"айо":6278,"айн":1941,"айб":2377,"акт":6740,"ако":7371,"ака":2878,"ах ":10031,"Пар":1681,"ас ":3290,"ар ":5874,"ат ":4127,"СР ":2617,"ба ":1557,"Пет":1744,"Пер":2277,"Пол":2322,"РСР":2369,"При":2113,"Про":3790,"Пуа":1541,"Пік":2365,"Пір":3646,"Рос":2415,"Роз":1581,"Рон":3384,"Пів":4853,"Аль":5551,"Сан":1563,"США":1862,"Сер":1775,"Сен":4479,"Ста":1577,"Ард":2815,"Тер":1748,"Вол":2219,"Вер":4116,"Вел":1833,"Укр":9121,"Бур":2431,"Фра":24714,"Дан":22031,"ША ":1853,"а́н":3396,"Цен":2677,"Чер":1615,"NSE":21595,"лам":1827,"лан":5122,"лас":12503,"лат":2370,"ма ":7369,"ля ":13589,"лав":3656,"лад":10782,"кці":3993,"ль ":10569,"кул":3808,"кур":1627,"кою":25572,"кої":15644,"кре":3214,"кра":21169,"кри":4236,"кро":1703,"лу ":3819,"кса":1966,"кте":2165,"кти":3833,"кто":5082,"ктр":2798,"кту":3015,"кла":11761,"ло ":6223,"клю":1692,"клі":1698,"ког":16518,"ков":13165,"ком":15826,"кон":32464,"коп":2254,"кор":9858,"кос":2132,"кож":4742,"кол":8207,"ким":4246,"кий":27960,"ких":8957,"кві":3598,"ле ":3371,"кі ":7394,"ли ":7619,"кер":1599,"ква":2483,"ках":2083,"кат":2360,"кар":5682,"кам":2944,"кан":6220,"кал":2575,"каз":1777,"кад":1810,"ла ":13040,"Іва":2158,"йсь":13547,"кт ":1727,"ку ":18769,"йна":1852,"йно":3774,"йни":5036,"йов":2120,"йог":2770,"йон":6057,"ко ":7248,"иїв":2473,"ки ":39616,"ке ":4049,"йбі":2012,"од ":2452,"нах":3061,"нац":23841,"нау":3625,"наф":1792,"нач":7238,"ог ":2185,"нан":4567,"нам":2788,"нал":31101,"нат":2955,"нас":4427,"нар":6454,"нап":3620,"над":4116,"нак":1904,"най":5486,"наз":4802,"нде":1705,"нда":2557,"ож ":4256,"нгл":1926,"неї":3826,"нен":4632,"нер":5081,"нес":1886,"нет":1977,"нец":1734,"нев":2650,"нез":1549,"нді":4444,"ні ":100559,"ндр":3680,"мії":2239,"ник":15713,"ний":35532,"ок ":8024,"мір":2620,"міс":12191,"мік":1956,"мін":9879,"міч":24763,"між":4232,"нь ":34487,"ня ":85321,"ню ":1561,"ов ":5346,"нав":26133,"об ":3066,"мпо":1641,"нт ":27692,"мпе":2663,"мпа":3905,"ну ":12904,"мпі":1622,"мсь":1988,"мун":23434,"муз":3552,"ліз":3946,"лій":2290,"лік":3856,"лід":25282,"лів":5148,"літ":32189,"ліс":3353,"лін":5016,"лії":2011,"мис":2927,"мир":2021,"но ":17011,"мно":2222,"мод":1683,"мог":2124,"мов":8204,"мож":2842,"мон":3152,"мол":2071,"мор":4169,"нс ":2855,"має":2263,"ляє":1872,"мац":1743,"мал":3075,"мад":2394,"ляд":1770,"мат":7712,"мас":1664,"ляр":1752,"мар":2087,"лян":1603,"ман":6730,"люч":1579,"маг":1762,"люд":2454,"лют":2538,"мет":6826,"мен":33354,"ни ":22900,"мер":6133,"меж":1784,"мі ":2838,"не ":13395,"льп":5070,"льн":50159,"льо":2192,"на ":73406,"льм":2015,"льк":3474,"льш":4684,"льт":4502,"льс":6409,"му ":17492,"лок":1590,"лог":8013,"лод":3460,"лор":1601,"лос":2987,"лот":1979,"лом":2920,"лон":2251,"лов":10255,"луж":1851,"ків":10057,"кій":3619,"кіл":3020,"кіп":21719,"кін":3986,"кіс":1867,"лив":4838,"лиз":2163,"лик":4841,"лі ":6988,"леж":2754,"ми ":23542,"лен":36965,"лем":3035,"лек":7457,"лиц":3452,"лиш":2141,"лис":4376,"лин":3727,"лип":2133,"пат":1536,"пад":4424,"пал":24506,"пан":5073,"пар":26316,"ре ":2016,"ра ":10978,"пис":6483,"пла":3785,"пле":2508,"пло":1933,"ро ":4356,"пед":22902,"ри ":9926,"пер":22098,"печ":1592,"ори":10852,"опі":2491,"орд":2209,"оре":6973,"орг":5783,"орс":3875,"оро":12661,"орм":6382,"орн":2519,"опу":1571,"ора":4398,"опе":4273,"опи":2385,"опо":5348,"опа":3672,"осі":28049,"оте":2368,"оти":4264,"ото":4402,"отр":2511,"ота":2076,"орі":12506,"оси":1994,"оск":2565,"осл":27847,"осн":4625,"осо":4627,"осп":1773,"ост":18846,"ору":3825,"орт":4236,"оря":2411,"оми":3494,"олі":11097,"оме":3420,"ома":8391,"оля":2505,"олю":1788,"оль":6830,"олу":1961,"по ":3091,"оло":19189,"оле":3051,"оли":6076,"окі":1858,"ола":2363,"окр":3962,"оку":9695,"око":4015,"оні":30331,"онс":3562,"онт":3739,"ону":5669,"они":2616,"омі":28058,"оно":28802,"онн":3725,"она":36879,"онд":1886,"оне":2765,"омо":4256,"омп":5253,"ому":14955,"оча":2902,"очи":1547,"оці":5589,"офе":1770,"оце":2765,"офі":2407,"охо":3822,"оба":1591,"нят":1850,"ням":4193,"ова":23572,"обу":2657,"обр":3128,"обо":4431,"обн":1797,"обл":9987,"оби":2069,"ою ":40879,"ньо":6069,"па ":1808,"оки":2050,"оке":1657,"ока":3381,"ожн":3109,"озв":2698,"нів":6803,"ніз":4328,"ози":2146,"оза":1905,"озт":3392,"ніт":1771,"ніс":9671,"ніц":22879,"ніш":2881,"ніч":5481,"нік":1930,"ній":8198,"озм":1625,"нім":3177,"озн":3472,"озр":1991,"озп":1689,"нії":3375,"нія":2921,"одн":11088,"оди":15822,"одж":2752,"огі":6272,"оду":4615,"одо":6110,"ої ":40186,"пи ":6419,"оді":8902,"оже":2141,"обі":3439,"ове":4729,"овл":2741,"ови":27036,"ово":14293,"овн":9596,"овт":2617,"ову":5401,"овс":3796,"ога":1966,"ові":15249,"ого":77853,"огр":5122,"ода":5921,"оде":2118,"ної":16682,"ною":5373,"нос":8914,"ноп":1707,"ном":33988,"нок":2048,"нні":5141,"ног":41554,"нов":14623,"ння":64956,"нно":4474,"ор ":9067,"нни":8535,"нна":3011,"SEE":21595,"нко":3013,"он ":7906,"нку":1909,"нка":2370,"ом ":22352,"ним":10232,"нин":2727,"нич":2031,"них":49028,"ниц":6236,"нши":2462,"нці":27792,"нцу":22511,"нув":2948,"нті":3002,"нсь":25045,"нта":5969,"нте":3274,"нти":4476,"нту":1658,"нто":2721,"ох ":2654,"нтр":7071,"нст":25118,"сам":2553,"рям":1886,"сан":2886,"ряд":3770,"сво":2566,"свя":1631,"сві":5195,"сі ":3512,"сел":26979,"ти ":13731,"сен":1784,"сер":9261,"рів":9362,"рід":3016,"ріа":3973,"рій":3132,"різ":4766,"ріо":2440,"ріш":1652,"річ":3119,"рія":3137,"сис":3972,"сит":2195,"рії":5126,"син":2791,"сил":2927,"ска":1987,"сли":1774,"сла":3451,"ско":3258,"скл":4964,"слі":25511,"сля":1724,"слу":2674,"сло":3957,"то ":6783,"сни":4268,"сня":2333,"соб":4324,"сов":3112,"сні":1707,"сок":1638,"сно":9584,"тр ":4211,"сну":2111,"спе":2794,"сор":1743,"сон":2424,"соц":1647,"ту ":33552,"спі":4109,"спу":1543,"спо":6481,"спр":2669,"су ":3870,"роц":5357,"рот":5051,"роф":2524,"роп":4979,"рос":8219,"ст ":6153,"рпн":1909,"рсь":7310,"рта":23604,"рст":1652,"рти":2701,"рси":2327,"рух":1575,"рту":2197,"рті":2581,"рук":2570,"руг":2655,"руд":3764,"руп":2957,"рус":1928,"рхі":2138,"рхн":4291,"рши":1950,"сь ":1944,"та ":53895,"ся ":24676,"рад":5772,"раж":1608,"раз":3483,"рав":11695,"рам":5248,"ран":55851,"рай":6264,"рак":4056,"рал":6105,"рах":2738,"раф":3312,"рац":4988,"рас":1585,"рат":9434,"раї":18701,"рі ":5250,"рде":3344,"ргі":2098,"реб":1606,"рев":3520,"рег":26086,"ред":9949,"реа":2012,"рет":3016,"рес":6263,"си ":1816,"рен":12198,"рем":5175,"рел":2059,"рек":2766,"рез":6938,"рді":3024,"реж":3159,"ржа":4954,"реч":1677,"рец":2506,"рвн":2312,"рга":5371,"ргу":2442,"рим":4841,"рин":4051,"рик":6384,"рил":1738,"рий":1712,"рич":3064,"рит":7476,"рир":1816,"рис":11068,"рка":1676,"пів":7244,"під":9422,"риб":1872,"риг":1977,"рив":2681,"риз":3342,"піл":3701,"піс":2425,"рмі":3148,"рни":5921,"рне":1575,"рна":4926,"рок":13067,"рол":3802,"ром":8841,"рон":6202,"роз":14973,"рні":3617,"ров":13779,"рог":3625,"род":18027,"роб":8445,"рно":5153,"рко":1653,"рма":4259,"пра":9765,"при":17085,"пре":5034,"про":26547,"ру ":4801,"поп":1576,"пор":8542,"пос":5211,"пот":2142,"пох":2319,"поч":2731,"пош":1607,"рт ":1813,"под":5278,"пов":10451,"пня":3871,"пон":3944,"пом":2310,"пол":10620,"пок":1979,"поз":3035,"пуб":2176,"пус":1543,"пря":1882,"са ":2954,"вар":4866,"ват":3699,"вач":1754,"ває":1673,"вав":2297,"ван":27620,"вал":6746,"важ":2723,"га ":2428,"бут":2028,"бул":3726,"бур":1929,"буд":3912,"був":3407,"́н ":1990,"вся":2929,"вто":3926,"втн":2139,"вст":3544,"всь":11822,"гу ":1846,"вро":2652,"вою":2829,"вої":4164,"вол":4005,"вні":6649,"вод":5394,"вог":4666,"вов":1600,"вня":4991,"вор":9030,"вос":3392,"вом":2439,"вон":1910,"вни":11918,"вне":1755,"вна":3546,"вно":8046,"влі":1867,"вля":2045,"вле":3353,"вла":2838,"го ":74789,"вка":1932,"вищ":4417,"вич":10270,"виз":2384,"вий":5063,"вил":1963,"вик":6641,"вин":5363,"вим":3289,"вип":2153,"вис":3214,"вир":3300,"вит":2461,"вих":6912,"вив":1786,"виг":1941,"вид":7090,"біл":7304,"вец":2207,"вер":12033,"ги ":1955,"вел":4069,"вед":23850,"ві ":8320,"вде":5262,"ва ":20184,"ают":4986,"баг":2186,"аці":38441,"ашо":3325,"аук":3811,"аті":2815,"афт":2014,"ахо":3481,"афі":2408,"ача":3308,"аче":5139,"ахі":3064,"апр":2675,"апа":1903,"апо":2274,"апи":1583,"арх":2803,"арс":2742,"арт":27902,"аре":1829,"ард":4062,"ара":11795,"арн":4172,"аро":9064,"ари":4536,"арк":3550,"аст":19420,"ата":3063,"аси":3444,"арі":4603,"асе":23473,"асл":1823,"асо":2485,"асн":7019,"ату":6561,"ать":1702,"ате":4441,"асі":1565,"ати":34490,"атк":2377,"атн":2400,"́ль":1996,"ато":8833,"атр":2250,"бол":1926,"бор":3014,"бни":2582,"бро":2133,"ву ":2725,"бра":3585,"блі":3564,"бла":6820,"бли":3503,"бле":1613,"во ":6738,"ви ":5236,"аєт":5513,"бер":8329,"без":3385,"аїн":17837,"ве ":2027,"дає":2865,"дач":1562,"дан":4800,"дар":3127,"дат":2935,"дал":2067,"дав":3568,"дем":2009,"ден":35742,"дер":7440,"деп":22255,"дже":27277,"ей ":5110,"дво":2066,"ез ":2842,"ді ":6167,"дсь":3872,"дст":2708,"дрі":2262,"дро":2499,"дру":2324,"дра":1728,"дпо":2072,"ет ":25079,"дко":1659,"ен ":10176,"ем ":4029,"див":2382,"гіч":3315,"дин":11940,"дит":3892,"гії":2091,"о́в":1799,"гіо":23749,"гір":2225,"гід":1618,"дня":2562,"доб":2151,"дні":5130,"дов":8472,"дос":25281,"дор":2173,"док":2841,"дон":2228,"дом":6507,"дна":4835,"дмі":2603,"дни":7067,"дне":1547,"дно":10257,"ер ":7534,"для":8246,"да ":6361,"газ":2730,"гал":4240,"гат":2475,"вят":1631,"ган":6922,"де ":6060,"вул":1831,"вує":1869,"вча":1606,"вче":1615,"гол":4270,"гос":1776,"гор":5348,"гов":2480,"год":1736,"гру":5182,"ду ":6755,"гро":3158,"гра":8609,"гре":2241,"гун":2442,"ген":3541,"ди ":6794,"гео":1703,"вів":2194,"вік":22506,"віл":2297,"вій":5760,"від":28365,"віт":10410,"вір":2465,"віс":2374,"він":3115,"гля":1806,"до ":11544,"жав":4567,"за ":31382,"жит":2833,"жив":2319,"жин":1953,"жі ":1618,"жен":31144,"зу ":2376,"жно":2243,"жни":2399,"жна":2353,"жні":1682,"жов":2516,"ежа":1636,"ежн":1674,"ежи":2240,"едс":1966,"еї ":5804,"еді":22755,"дія":9605,"діє":22354,"дії":2193,"діл":4733,"езн":2478,"езп":2124,"дів":4952,"дій":3323,"ева":2033,"еви":2106,"еат":1536,"дян":2535,"еда":2858,"еде":24252,"еди":1957,"егі":24559,"едо":1597,"едн":2110,"евн":1571,"же ":2405,"ево":2649,"еві":2180,"ент":38060,"енс":2476,"енц":1664,"енк":2033,"ени":9106,"ено":4866,"енн":55011,"ена":6246,"емі":4010,"ене":8942,"енд":1893,"еор":1718,"ені":27559,"ень":28255,"епа":22831,"ерш":4377,"ерх":5234,"ерп":2312,"ерс":4919,"ерт":3088,"ерм":2838,"ерн":8048,"еро":3883,"ери":8614,"ерк":2529,"ерд":2064,"ерг":2332,"ерж":5295,"ере":27737,"ера":11283,"ерв":4795,"ерб":1797,"ейс":2515,"еко":24801,"ект":7509,"екс":5740,"ели":5579,"ело":1860,"еле":29499,"ела":1663,"емл":1627,"емо":2244,"емн":1709,"еми":2190,"елі":3500,"ель":6771,"еме":2758,"ема":4374,"ехн":2533,"ець":7827,"еці":2099,"ері":9985,"есн":2797,"есп":2017,"есо":1640,"ест":4336,"ета":3510,"есі":2297,"ети":3023,"ете":1577,"етр":4098,"ето":3229,"ету":1803,"ива":5433,"иді":1970,"иго":1963,"ида":2853,"ивс":1559,"иво":3293,"ивн":5798,"иві":2780,"икл":3021,"ико":10700,"ики":26994,"ика":9412,"изь":1617,"изн":4148,"ині":5661,"имі":1780,"ини":11405,"инн":2229,"ино":4309,"инс":2389,"ину":2117,"ина":9917,"ими":8406,"илі":2149,"имо":2293,"има":1943,"иль":2368,"икі":3590,"или":2166,"ило":1638,"ила":2574,"исе":1748,"иса":1892,"ист":43720,"исо":2640,"исл":3795,"иск":1974,"ити":3061,"ите":2660,"ита":3840,"ися":2391,"ись":3153,"иту":23904,"итт":1716,"ито":5821,"ипа":23599,"ипн":2085,"ире":1798,"иро":6079,"ихо":1721,"ицт":1948,"иць":3344,"ить":5744,"ище":2694,"иці":4564,"ичи":1676,"ичн":15682,"иця":3075,"ича":2349,"ка ":31484,"ив ":2824,"зав":2331,"заб":1710,"заг":2313,"ид ":1647,"зви":3864,"зва":3561,"зац":3958,"зах":3661,"зас":5087,"зап":2437,"зан":2419,"зал":3333,"зак":3350,"ий ":76977,"зер":2249,"зем":2575,"зді":2313,"зі ":4174,"зик":1993,"ик ":11149,"ин ":8446,"им ":13202,"зич":2000,"зна":12042,"зни":3492,"змі":3801,"зно":1802,"зня":3181,"зов":3243,"зон":2606,"зпе":1731,"зпо":1609,"зро":1734,"зта":3312,"их ":71895,"ич ":8041,"зьк":25702,"ьме":1976,"ьна":3031,"ьни":9629,"ьно":31998,"ька":11941,"ьке":2474,"ьки":32360,"ько":60206,"ькі":5969,"ьту":1942,"ься":17960,"ьсь":5340,"ьог":3861,"ьов":1687,"ьні":3450,"ьпи":4442,"як ":5568,"ям ":4621,"ює ":1572,"юва":4241,"юр ":1687,"er ":1536,"яка":3149,"яки":6457,"яко":4501,"які":4711,"яч ":2564,"юто":2149,"ях ":2449,"ють":10792,"ючи":2094,"янс":3724,"ями":2547,"ять":2425,"яти":2263,"уча":3150,"уєт":3972,"фес":1886,"фер":1827,"уют":3197,"фун":1616,"фра":23347,"фор":6458,"фік":1922,"філ":3022,"фіз":1799,"це ":3714,"хан":1700,"хар":2307,"хні":3188,"хов":2787,"ход":8360,"хня":2286,"сто":20885,"стр":14612,"ств":9052,"сте":10268,"сти":58155,"ста":42984,"сті":17422,"стя":1612,"стю":2000,"сть":9349,"сту":4755,"сце":2414,"ть ":23970,"тю ":2076,"ськ":76644,"тя ":4033,"сьм":2215,"сюр":1594,"ув ":2334,"тав":4291,"так":7239,"тал":7016,"там":24076,"тан":13432,"тат":26660,"тах":1715,"тар":4879,"таш":3389,"тво":10485,"тва":6033,"тех":2451,"тец":1853,"тем":5996,"тел":3217,"тен":2843,"тер":16300,"теп":1791,"тет":24922,"тек":2381,"тей":1760,"ті ":19387,"січ":2428,"тив":7452,"сій":4342,"ук ":2255,"сів":2280,"сіб":22500,"тка":1831,"тич":9159,"сії":1716,"тий":2070,"тин":8122,"тик":26054,"тил":2041,"тир":1541,"тис":25636,"тип":1715,"тит":24505,"тку":2518,"тко":2210,"тла":1548,"ур ":1549,"тно":2899,"тні":2826,"тод":1678,"ток":3298,"тол":4612,"тов":10097,"тог":4926,"тня":4250,"тни":4639,"тре":1761,"тра":13299,"три":6247,"тор":19453,"тос":2194,"том":6059,"тон":3478,"топ":3418,"тою":1721,"тсь":3003,"тро":10751,"тру":4586,"трі":6027,"тув":1637,"туп":2434,"тур":8289,"ття":4038,"тут":22979,"тьс":17965,"ує ":4149,"ува":15273,"уго":1668,"уар":5114,"уат":1738,"убл":2373,"узь":23065,"узе":1844,"тій":2025,"узи":2433,"тіл":1694,"тів":6962,"уді":1635,"удо":3223,"удн":2817,"уме":1763,"уль":5593,"уля":1849,"ули":2646,"уло":1791,"ула":2199,"укт":2271,"укр":7476,"уко":2812,"упн":1546,"ура":2553,"ург":3415,"ури":2733,"упа":1808,"унк":2435,"уні":25084,"умо":1836,"унд":2657,"уту":22317,"уст":2645,"утв":1947,"урн":4525,"уро":1539,"що ":17655,"шов":4224,"ших":3225,"шир":2574,"ший":2090,"ще ":2338,"шен":2816,"ші ":1719,"шта":1833,"щин":2002,"щен":2787,"цен":4287,"чи ":3745,"цев":1886,"цес":2327,"цер":1781,"ці ":10080,"хід":5700,"цип":23018,"ць ":4743,"ця ":4768,"ча ":2185,"цуз":22494,"цтв":3628,"ців":2368,"ціа":3468,"ціо":25893,"цій":6921,"ція":7173,"чен":10697,"чер":4797,"чі ":2791,"чле":2375,"чка":1597,"чин":4805,"ціє":1783,"ції":31741,"чис":2289,"цьк":8704,"ша ":1587,"ше ":3944,"чає":2804,"час":12463,"чат":2049,"чай":1572,"ща ":1848,"чні":4741,"чна":4519,"чня":2280,"чни":34595,"чно":11306,"us ":1758,"ію ":3147,"їв ":1974,"іал":5781,"іан":1803,"ія ":24064,"іде":1874,"ідж":22706,"ідк":2690,"ідн":11513,"ії ":54256,"ідр":2425,"ідп":3775,"ідо":5503,"івд":5855,"іве":2535,"ібн":1843,"івс":5463,"івн":8627,"ійн":9751,"ійс":12117,"іжн":2207,"ізо":1615,"ізн":5205,"ізм":1906,"ізи":1715,"іза":4100,"інд":1760,"іне":2360,"іна":3489,"інн":4758,"іно":3712,"імі":1726,"інф":1596,"інц":2809,"інс":24263,"інт":1810,"іль":17941,"іме":3447,"іля":2402,"ілі":1831,"імп":2489,"іле":1779,"ікі":22043,"іло":3466,"іка":6429,"іки":2076,"іко":1702,"ісц":2429,"іст":27606,"ісл":1997,"існ":3890,"іре":3719,"ірн":2678,"іпе":22100,"іні":5468,"іод":1626,"інш":3831,"інь":1631,"іон":51386,"ітн":4596,"іто":2264,"їх ":2010,"ітт":1981,"іту":1943,"іта":3402,"іте":26865,"іти":4695,"ішн":1712,"іше":2070,"ічн":39482,"іці":2111,"іци":22860,"іб ":22595,"ів ":41252,"ід ":15090,"із ":3976,"іж ":3000,"ій ":20369,"ік ":2836,"ім ":3593,"ін ":5333,"ір ":2760,"іх ":2419,"єю ":25174,"єдн":2196,"єкт":1631,"єть":11566,"її ":1912,"ією":24943,"іяч":2557,"ївс":1781,"їнс":8303,"їни":6169},"n_words":[15331232,17151725,12469252],"name":"uk"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/urd b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/urd new file mode 100644 index 000000000..0c11cc7f6 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/urd @@ -0,0 +1 @@ +{"freq":{"ٹ":7565,"پ":19909,"ٰ":348,"و":91887,"ي":164757,"ً":561,"َ":343,"ُ":600,"ـ":316,"ف":15396,"ق":19382,"ك":314,"ل":61015,"م":85213,"ن":73500,"ه":210,"ّ":218,"ِ":1208,"خ":10520,"د":42999,"ج":29799,"ح":15399,"ت":63424,"ث":2772,"ب":46160,"ئ":12622,"ا":210246,"ؤ":741,"آ":6835,"ء":3457,"غ":3607,"ع":26594,"ظ":4173,"ط":9560,"ض":4853,"ص":11646,"ش":17043,"س":59068,"ز":13283,"ر":100269,"ذ":2393,"،":8584,"؛":310,"ہ":81948,"ۃ":194,"ۂ":442,"ے":72723,"ۓ":1226,"۔":21285,"گ":13942,"ک":96247,"ھ":18217,"ں":33709,"چ":6431,"ڈ":3486,"ڑ":2986,"ژ":212," ،":2410," ۔":1318," ہ":33487," ھ":395," گ":5518," ک":67994," ن":12353," ل":8072," م":43729," ق":5408," ك":206," ف":4429," ي":9396," و":11189," ص":3954," ش":8375," ط":3503," ض":1387," ر":7523," ذ":1057," س":22509," ز":3628," ع":9286," ظ":270," غ":946," ا":57235," ء":2548," آ":6281," ج":19940," ح":6228," خ":5235," د":11120," ب":20334," ت":17083," ث":374," چ":3475," ڈ":1133," ٹ":932," پ":14925,"کا ":9732,"کت ":188," ، ":2340," ء ":2420," و ":1367," بھ":3806," جن":2286," حا":1179," جل":205," بہ":901," جم":727," جي":597," جو":3440," جد":255," جس":2699," جز":358," جر":340," اے":201," اہ":629," جا":6670," جب":836," تي":855," اک":704," بڑ":974," اگ":491," خل":943," تہ":199," تھ":4319," خي":280," خو":966," دا":1316," خص":169," خر":184," خد":283," خط":402," حق":234," حي":633," تک":1112," حم":243," خا":1564," حر":509," حس":437," حد":214," حض":717," حص":647," بے":210," بن":2795," بل":1071," بغ":190," بع":1385," اُ":270," بر":1803," اي":8027," او":11360," بد":254," بح":524," اق":467," اف":961," ال":4248," با":2739," ان":6816," ام":1333," اط":314," اع":876," اد":879," ار":1330," از":241," اس":10716," اش":424," اص":842," اض":219," اب":1381," ات":313," اث":175," اج":297," اح":507," اخ":805," تو":1190," بچ":211," تن":378," تم":482," تق":681," تف":194," تع":1588," تش":261," تص":444," تر":1553," تخ":375," تج":367," تح":884," تا":1192," تب":411," اپ":1467," اٹ":312," بو":485," بي":1555," آپ":775," آل":254," آن":292," آي":279," آخ":168," آر":246," آت":368," آج":212," آئ":402," آب":1319," آف":180," آس":249," آز":331," عہ":219," سے":9513," شک":419," طو":1200," ظا":186," عظ":314," عر":1083," عد":298," عث":218," عا":1056," عب":533," شہ":1939," عي":293," عل":2998," عم":1153," عن":249," عو":213," غي":270," سع":194," سط":261," دھ":223," سف":224," سي":1366," سو":980," سم":787," دہ":248," شا":2109," سن":832," سل":1069," شر":734," شخ":260," شع":372," شي":299," شم":1497," صا":255," صر":324," رک":1032," صح":380," صد":878," صل":252," صف":254," صو":1376," رہ":1328," ضر":190," ضل":1004," طا":301," طب":638," سک":803," طر":1051," دس":404," در":2025," دي":2436," دو":2534," دن":789," دل":217," ذر":344," جگ":269," حک":746," ذي":205," جہ":593," را":903," جھ":293," رس":334," ري":940," زر":261," رق":405," رو":1485," زب":1015," زا":201," رن":190," زي":935," سر":1466," زم":612," سب":960," سا":2953," زن":311," ست":266,"گھر":200,"گہ ":210," ہے":16945,"گوں":240,"گيا":1207," ٹا":182," پڑ":329," پن":536," پو":662," پي":2142," پا":3033," پت":168," پر":5135," پش":170," پس":187," ٹي":317," لف":878,"ں، ":508," لغ":168," لح":265," لئ":237," لا":1034," مل":1468," مق":1520," مف":313," مغ":611," مع":1708," مط":921," مض":238," مص":513," مس":1572," مش":1902," مر":2119," مز":309," مد":642," مذ":261," مح":1355," مخ":914," لي":2681," مث":406," مج":498," لو":614," مت":1246," ما":1837," نف":215," نق":288," نم":568," نظ":923," نس":373," نش":178," مم":601," من":1456," نا":2714," نب":179," مو":1833," مي":17546," نج":183," وا":3957," لڑ":168," نو":730," ني":646," فض":168," فر":1011," فا":763," فت":168," قس":291," قص":318," فل":520," قا":1019," فن":193," فو":398," قب":691," في":493," قد":579," قر":855," فٹ":171," قل":240," قو":565," قي":355," وہ":1582," يہ":4254," لک":550," وج":661," لگ":411," وس":430," وز":353," ور":376," وغ":293," ول":235," وق":563," وف":272," مک":558," وي":428," لے":206," مگ":362," مہ":365," يا":2941," نک":275," نگ":248," يع":665," نہ":1220," يو":1100," نے":2696," گھ":362," ہو":7614," ہم":409," ہن":745," ہي":5912," ہز":243," ہر":384," ہا":430," ہج":240," کت":582," کر":5496," کس":1214," کش":187," کل":1235," کن":341," کم":719," کو":6421," کي":15836," کا":11009," کئ":348," کہ":5408," کھ":713," گا":490," گئ":863," کے":17634," کچ":321," گن":214," گل":202," گي":1388," گو":519," گر":807," ۔ ":1018," پہ":1353," پھ":659," چت":240," چا":498," چل":252," چي":492," چو":467," چن":303," ڈا":359," ڈي":297," چھ":653," چک":241,"کٹر":175,"کيے":174,"کي۔":282,"کلا":210,"کلو":610,"کلي":168,"کيا":2343,"کيو":230,"کيم":299,"کين":186,"کيل":348,"کمي":186,"کمل":193,"کنا":202,"کوئ":495,"کور":176,"کوم":779,"کرا":507,"کتے":245,"کسي":1209,"کست":1507,"کزي":242,"کري":262,"کرت":1247,"کرد":421,"کرن":1152,"کرک":265,"کار":1107,"کائ":219,"کئي":281,"کان":309,"کام":558,"کال":425,"کتي":199,"کثر":209,"کتا":937,"کم ":404,"کل ":646,"کن ":715,"کي ":12997,"کو ":5510,"کر ":2045,"کز ":207,"کس ":278,"گور":172,"گري":1479,"گرو":225,"گرد":220,"گرا":170,"گاہ":224,"گئے":444,"گار":222,"گئي":576,"گي ":628,"کہل":354,"کہت":572,"کہا":1480,"کھا":567,"کھت":425,"کھو":307,"کھن":402,"کھي":483,"گر ":1024,"گا ":209,"کے ":18223,"کچھ":310,"کھ ":350,"کہ ":4209,"ا، ":388,"ھا۔":1135,"ھائ":250,"ں۔ ":2401,"ھان":195,"ھار":432,"عہد":221,"ھتے":283,"پان":548,"پار":326,"پاس":169,"پائ":259,"ہ، ":321,"پي ":246,"ئي ":3847,"ات ":5026,"اح ":512,"اج ":434,"ئم ":385,"پرو":236,"پري":221,"ئل ":289,"اب ":1615,"اء ":706,"اؤ ":172,"پاک":1528,"پنج":401,"پنا":177,"ئع ":214,"پور":484,"پني":552,"ئش ":369,"ھي ":3674,"ئر ":279,"بت ":362,"فر ":258,"ان ":9264,"با ":254,"فظ ":915,"ہم ":759,"اً ":534,"ہو ":977,"پنے":725,"اف ":395,"پيش":361,"پيد":1076,"ام ":5824,"ال ":3321,"ہي ":1279,"اق ":313,"اظ ":454,"اع ":255,"ہائ":399,"ہات":210,"ہار":307,"ار ":4602,"اخ ":174,"فت ":347,"اد ":2459,"ہاں":875,"اص ":271,"از ":1002,"اس ":6443,"ہان":212,"ارے":550,"اطا":177,"ھوا":216,"اسک":1125,"ت، ":322,"بي ":1989,"اضي":270,"بو ":188,"اصط":318,"اصل":1371,"ارہ":558,"اسے":795,"اعت":501,"اعد":311,"اعر":317,"ھوٹ":341,"ھيل":511,"اطي":187,"ھنے":355,"اعظ":290,"ھوں":204,"اعل":259,"قع ":1257,"فار":420,"ھيں":343,"فات":329,"فاظ":273,"ادا":654,"اخل":199,"اتھ":922,"ھي۔":577,"احي":174,"اخت":714,"احم":281,"احت":209,"ئي۔":457,"ہا ":1654,"ارا":821,"ادي":1677,"ئيں":363,"ادل":266,"ادب":182,"ادت":200,"بق ":617,"ادر":214,"اتے":523,"ازي":292,"است":1978,"اري":1870,"ارن":318,"ارو":652,"ہت ":499,"ارف":181,"ارس":382,"بل ":520,"ارد":993,"ارت":911,"ارک":342,"اشي":236,"اسم":259,"ادہ":769,"اسل":804,"اشا":172,"اسي":947,"ارٹ":196,"بن ":873,"بع ":355,"ائد":205,"ائر":395,"ائش":451,"ائع":219,"ائن":582,"ائم":404,"ائل":355,"ائي":3099,"ئنس":292,"ابت":325,"ابر":254,"اؤں":202,"ہد ":227,"ابي":488,"ابل":415,"ابق":678,"ابو":358,"ابن":262,"اتح":175,"اتا":3152,"ہر ":2189,"اثر":224,"ؤں ":253,"اتي":1903,"قت ":631,"ائے":1094,"اجا":187,"بر ":849,"في ":604,"عظي":276,"عظم":356,"پڑھ":180,"عري":274,"عرو":255,"عرب":766,"عرا":186,"عدا":424,"عدد":310,"عثم":220,"ظيم":431,"عبد":345,"عات":242,"شہو":678,"شہر":1734,"عال":536,"عام":681,"عاش":251,"عار":177,"صے ":201,"پہن":208,"پہل":895,"غرب":546,"طہ ":206,"عيا":204,"عيس":213,"پھر":309,"پھي":228,"عمل":531,"عمو":341,"عمي":283,"عمر":256,"غان":180,"عني":881,"غاز":188,"علا":1570,"علق":602,"علي":1229,"علو":368,"عما":1154,"علم":738,"آتا":178,"آئي":238,"آبا":1188,"آخر":190,"آزا":306,"ھر ":618,"آن ":225,"ھا ":1233,"غير":796,"آيا":202,"عے ":290,"آپ ":665,"عہ ":760,"جسم":317,"جزي":258,"خت ":294,"جرا":223,"جري":262,"شعب":197,"جزا":198,"جرم":182,"بکہ":367,"ثيت":188,"ذہب":185,"شما":1408,"جبک":363,"اہم":638,"جائ":411,"اہل":181,"جات":4030,"اہو":304,"جاب":370,"جاس":338,"اہي":375,"جار":388,"جان":1341,"جام":298,"رے ":1358,"بہت":604,"رکز":477,"بہا":219,"صبہ":185,"جما":288,"رکا":241,"صحا":176,"رکي":303,"صدر":477,"حال":384,"جنو":753,"ہے۔":9056,"صدي":342,"حاد":180,"حاص":632,"حاظ":206,"جمع":225,"جمو":257,"شيا":452,"خط ":169,"بھي":3076,"بھا":585,"ضي ":277,"صطل":323,"جسے":332,"رکھ":862,"صرف":317,"جسک":274,"زہ ":268,"طب ":280,"تک ":956,"خي ":172,"حرک":215,"حضر":635,"حصي":251,"دت ":251,"حدہ":191,"سٹي":260,"حسا":181,"دا ":1143,"حسن":171,"سٹر":203,"حرا":239,"حري":437,"طح ":229,"تہ ":472,"تھ ":814,"صوص":325,"ہے،":923,"صول":176,"حدي":195,"صور":542,"صوب":1118,"رہي":215,"رہن":216,"جمہ":270,"رہا":394,"جنگ":528,"جيس":335,"رہت":193,"صلا":189,"جود":775,"ضرت":619,"ضرو":182,"خان":852,"خاص":306,"خار":176,"حمد":801,"حقي":267,"تے ":3295,"رہے":389,"صيل":310,"دس ":176,"در ":1119,"دد ":492,"حصہ":359,"دن ":286,"ٹا ":239,"دو ":1561,"ظر ":265,"خصو":323,"ر، ":449,"دي ":2904,"حير":216,"ضلع":1009,"حيا":329,"ختل":505,"حيث":191,"ختي":341,"سے ":11230,"طان":608,"طال":493,"طاب":536,"طبي":334,"دل ":339,"دم ":215,"خلي":574,"سکت":863,"تہا":216,"سکا":323,"سکي":300,"خلا":443,"سکو":402,"دان":840,"دال":423,"تھے":1383,"دائ":580,"دار":1737,"داز":181,"داد":564,"طرح":391,"طرز":173,"طرف":300,"خوا":291,"خود":282,"طري":194,"ظم ":393,"شہ ":199,"سکے":358,"خيا":180,"عت ":511,"تھي":1189,"عد ":1126,"تھا":1925,"رج ":392,"ٹي ":724,"رت ":2032,"رد ":384,"طلب":258,"طلا":420,"عض ":255,"رح ":408,"طور":1195,"ظام":601,"طنت":356,"شکل":258,"را ":761,"دست":238,"رب ":643,"ظاہ":223,"درس":185,"درج":475,"درا":374,"دري":711,"جہ ":949,"درم":359,"درو":190,"دون":230,"ظري":241,"صہ ":469,"دور":724,"دوس":950,"دني":624,"دوں":249,"رف ":993,"ديو":334,"ديم":368,"دين":825,"ديل":228,"ديا":819,"ديت":278,"ديد":212,"ٹر ":1167,"رس ":290,"عي ":320,"دما":182,"جے ":273,"اقو":437,"اقي":177,"اقت":219,"اقا":176,"افي":307,"اقع":1323,"الق":182,"الف":464,"الل":695,"الي":1802,"ان،":219,"امت":248,"اما":469,"الن":229,"الم":986,"الو":429,"امر":725,"الج":351,"الت":351,"الب":611,"الا":1303,"الس":179,"الر":180,"الد":643,"الح":530,"الع":407,"ري ":3579,"جگہ":221,"افر":440,"افت":417,"ٹري":255,"انے":1223,"ايم":221,"انہ":1162,"ايو":177,"ايس":1069,"انگ":1569,"ايش":229,"امہ":269,"ايا":902,"ايت":316,"انک":290,"اير":272,"، ":8315,"بحي":221,"اوہ":305,"رو ":291,"بحر":243,"اقے":283,"ديگ":275,"اني":2788,"انو":1426,"ديک":357,"رق ":406,"باً":193,"اقہ":415,"بان":1448,"بال":507,"اند":1077,"باد":1658,"باز":180,"بار":1042,"انس":905,"امن":202,"انا":720,"انب":309,"امو":288,"انت":736,"بات":454,"امي":1316,"انج":263,"امل":979,"بائ":435,"الے":826,"بتد":219,"اوي":243,"انڈ":193,"انچ":276,"الہ":394,"اون":198,"اول":497,"اوق":178,"اور":10590,"الک":535,"رم ":316,"ذري":244,"اوا":211,"تا ":6076,"حکو":764,"حکم":277,"رحد":298,"ردو":947,"ردي":295,"ردا":370,"رتے":586,"رتا":498,"ايک":5551,"بدا":306,"راچ":302,"ربع":318,"بدي":235,"برا":685,"ربي":855,"ذيل":186,"راہ":513,"برط":276,"برق":294,"بري":212,"رتي":676,"راک":232,"جہا":530,"تر ":480,"ران":1556,"ربا":206,"راع":230,"راف":173,"رام":330,"رال":643,"راب":283,"رائ":562,"راج":355,"رات":605,"راث":218,"رار":318,"راد":611,"راص":190,"راس":245,"ہيں":6226,"بعد":1053,"تح ":170,"ہو۔":237,"جھي":195,"بعض":255,"رآن":223,"بني":578,"بنا":831,"ہوگ":285,"ہوں":722,"بند":385,"ا ":36261,"بلن":294,"ہنچ":177,"بلو":291,"بلي":191,"ہلے":442,"سر ":306,"بلا":185,"ب ":6862,"ء ":3203,"ہوئ":1384,"ہور":1098,"ہوت":2264,"ہوا":926,"ہون":793,"ہلي":355,"ہند":711,"ہمي":171,"ؤ ":175,"زي ":1743,"رطا":394,"ح ":1752,"ھے ":736,"ہلا":565,"خ ":788,"رسٹ":177,"د ":10666,"بوں":222,"بيٹ":246,"ست ":854,"ذ ":232,"بين":440,"بيل":268,"سا ":510,"رست":341,"بيع":188,"ت ":16193,"بيا":321,"بير":253,"رسي":336,"سب ":865,"رجہ":199,"ث ":408,"بول":436,"ج ":1790,"بلک":176,"سم ":677,"دہ ":2099,"تي ":4132,"سل ":210,"اک ":371,"ريہ":436,"تو ":819,"ٹلي":171,"ريک":876,"دھ ":232,"روں":847,"رپ ":187,"ريع":323,"رين":690,"ريل":294,"ريف":299,"ريق":376,"رنے":958,"تم ":196,"ريا":1581,"ريب":696,"ريخ":486,"ريت":171,"ريز":1341,"ريش":173,"رنگ":273,"روف":378,"رون":314,"روم":315,"روع":324,"رور":309,"روز":221,"روس":205,"روا":481,"اپن":1352,"ہزا":285,"ہري":293,"زبا":959,"زار":465,"رند":247,"زاد":421,"ہرا":229,"رمي":582,"رمن":177,"رنا":383,"زائ":318,"رما":229,"اٹل":178,"ہتے":651,"ثر ":284,"؛ ":306,"سط ":176,"رقي":620,"رقب":303,"ہجر":225,"ئے ":2320,"تبد":215,"تان":2396,"تبا":381,"تار":774,"تاب":521,"اچي":318,"دے ":517,"سن ":294,"ہے ":7219,"اں ":1697,"سو ":217,"تحر":360,"شت ":170,"تحا":210,"تحص":253,"سي ":3401,"تدا":329,"اہ ":1042,"تري":474,"ترا":469,"جا ":352,"تصا":242,"جب ":430,"تصو":215,"ترک":411,"اڑي":213,"ستہ":193,"تظا":196,"سري":335,"تعا":188,"سرح":298,"سرا":421,"تعم":1291,"تعل":965,"تعد":362,"دگي":389,"جد ":384,"شن ":295,"زما":353,"سام":409,"سال":748,"سان":757,"زند":314,"جس ":1740,"سائ":617,"زمي":343,"سات":868,"ساب":328,"ستا":2494,"تقا":197,"سجد":245,"تقر":347,"تقس":240,"ستع":1050,"زيا":694,"ستي":192,"ستو":208,"زيد":178,"اے ":199,"زير":703,"تمل":297,"ا۔ ":2384,"صر ":373,"تلف":484,"تما":488,"اۓ ":304,"سلا":945,"تين":302,"سمج":250,"سلي":236,"سمب":188,"سلم":718,"سما":225,"تيس":201,"تيا":780,"سلط":553,"سلس":275,"توا":248,"شي ":269,"سطح":252,"تيں":193,"پر ":4411,"اکي":196,"اکا":303,"اکس":1424,"سرے":373,"توں":404,"صد ":229,"ٹے ":294,"اگر":397,"جن ":581,"بڑا":364,"رک ":436,"بہ ":1879,"اکھ":210,"رہ ":1976,"جي ":406,"شرق":569,"شرو":345,"شري":335,"صل ":1226,"جو ":2871,"بڑي":256,"حت ":262,"ئے۔":600,"بڑے":246,"حد ":400,"ھے۔":835,"سوي":178,"شتر":182,"سوا":232,"سور":248,"شاع":346,"شام":808,"سمن":228,"شائ":191,"سند":323,"شاخ":186,"سمي":191,"ثلا":193,"شخص":263,"ثما":224,"ذکر":233,"اہر":591,"اہد":216,"سين":345,"سيم":308,"شاہ":679,"شتم":303,"سيد":218,"بے ":441,"سيا":755,"ڑا ":500,"ٹھ":533,"پت":249,"پا":3394,"پس":366,"پش":179,"پر":5467,"ٹے":304,"گ ":1702,"ٹک":243,"پڑ":366,"پو":978,"پن":2069,"پي":2662,"پل":260,"ٹي":1294,"ٹو":369,"ٹن":221,"ٹل":297,"ٹر":1769,"ٹا":643,"ک ":9401,"لے":2164,"يں،":396,"مگ":395,"مک":804,"نڈ":840,"وي":2835,"ي،":686,"نچ":605,"وو":294,"يب":1474,"يا":18357,"مہ":1477,"يئ":237,"يع":1465,"يز":2169,"يس":3006,"نگ":3438,"يش":1424,"يص":226,"يخ":630,"يد":2958,"ير":4679,"يت":2515,"يث":342,"يج":682,"نک":1176,"يح":396,"ين":5944,"يو":3744,"وچ":363,"نھ":192,"يق":966,"يم":3458,"نہ":3293,"يل":3575,"يف":992,"وپ":411,"وٹ":898,"وڑ":349,"نے":8036,"وڈ":316,"يٹ":1722,"وک":763,"پ ":1225,"يٰ":198,"وگ":857,"وہ":2577,"يچ":216,"يڈ":589,"وں":7039,"يپ":229,"و۔":276,"يک":8185,"يگ":581,"يہ":6841,"يں":24637,"ي۔":1652,"يۓ":606,"يے":1374,"فع":234,"فض":206,"فظ":975,"فر":2018,"فس":304,"فت":956,"فا":1934,"يہا":454,"قع":1462,"قط":251,"قص":525,"قس":674,"قر":1456,"قد":958,"قت":918,"في":1664,"قب":1358,"فو":716,"قا":2876,"فن":259,"فل":626,"فق":170,"فٹ":222,"قي":2110,"ل،":228,"قل":641,"قو":1321,"لق":994,"لف":1951,"لط":721,"يں۔":3302,"لغ":238,"لع":1546,"لد":859,"لج":430,"لح":953,"لز":212,"لس":945,"لر":265,"لئ":340,"لا":9180,"لت":997,"لب":1083,"مع":2282,"مغ":639,"مص":529,"مض":257,"مط":1001,"مف":327,"مق":1607,"مل":3799,"مت":2835,"لو":3381,"مج":828,"لي":9899,"ن،":378,"مث":441,"لم":3135,"لل":728,"مب":937,"لن":899,"ما":9656,"مز":517,"مر":3546,"مش":2018,"مس":1772,"مخ":947,"مح":1397,"مذ":278,"مد":1699,"نظ":1248,"نع":313,"نل":169,"قہ":970,"نم":856,"نق":463,"نف":515,"ے، ":1325,"نج":1093,"مي":23019,"نت":1838,"مو":3519,"نب":733,"نا":7139,"من":2588,"فہ":638,"مم":631,"نص":409,"نش":418,"نس":2278,"نز":337,"نر":275,"ند":4576,"قے":375,"مپ":203,"وئ":2114,"وا":9079,"نن":295,"نو":3979,"ني":8247,"و،":187,"ٹ ":1461,"لڑ":176,"وغ":354,"نٹ":588,"وع":906,"وق":1147,"وف":901,"ون":4062,"ول":2928,"وم":3387,"لہ":2193,"وت":3089,"وب":2645,"ود":2057,"لک":2192,"وح":206,"وج":2206,"لگ":620,"وس":2774,"وز":895,"ور":18253,"وط":241,"وض":250,"وص":445,"وش":613,"يکھ":326,"ڑ ":321,"يکن":476,"يکي":320,"يگر":286,"چ ":481,"يکہ":301,"ڈ ":843,"خو":1180,"دت":297,"دا":6455,"دب":338,"خي":646,"خل":1333,"خم":176,"تہ":894,"تھ":5631,"خط":526,"خر":474,"خد":295,"خص":603,"دو":4578,"ر،":467,"دي":7480,"دف":241,"دل":705,"دم":634,"ذا":327,"دن":1041,"تے":3362,"دع":168,"دد":552,"در":3958,"دش":266,"دس":695,"جي":1296,"جو":4658,"حت":458,"جن":2503,"حا":2227,"حب":298,"جل":349,"بہ":2825,"جم":1355,"بھ":4084,"ا۔":3031,"اۓ":335,"اے":213,"جس":2866,"جز":533,"جر":1045,"جد":723,"بک":601,"خت":1742,"حي":1318,"تک":1171,"حم":1392,"خا":1967,"خب":324,"حو":294,"حق":534,"حل":497,"حض":792,"حص":974,"بے":458,"حر":1330,"حس":621,"حد":976,"تف":294,"تم":1316,"تل":864,"تق":1058,"تو":2257,"بچ":213,"ثا":431,"تن":759,"تج":398,"تح":1528,"تر":2642,"تخ":631,"تد":422,"اڑ":396,"تش":356,"تص":699,"تس":246,"تظ":210,"تع":3085,"اں":1731,"ثل":246,"جا":8260,"ثم":243,"اہ":3738,"جب":952,"ثي":412,"تي":6367,"اک":3503,"ثر":502,"اگ":766,"بڑ":994,"ئے":3028,"ؤں":259,"بغ":203,"بع":1847,"بن":3272,"بم":183,"بل":2052,"بق":773,"بد":925,"اً":548,"بج":198,"بح":566,"بت":774,"اي":9647,"او":12882,"بط":281,"بص":181,"بز":199,"بس":224,"اُ":281,"بر":3415,"اپ":1892,"اٹ":526,"تا":10999,"اچ":510,"تب":1015,"بو":1546,"ت،":328,"بي":4832,"ئد":211,"ئر":536,"ئش":454,"ا،":402,"اء":804,"اؤ":588,"ئل":407,"ائ":7576,"ئم":430,"ئع":221,"از":2184,"ار":13604,"اد":7175,"اض":766,"اص":2408,"اش":1157,"اس":13319,"ات":12391,"اب":5157,"ئن":668,"اخ":1510,"اح":1946,"اج":1405,"اث":517,"ئي":5602,"اف":2468,"اق":3776,"ام":10852,"با":7594,"ان":23472,"ال":15347,"اع":2513,"اغ":318,"اط":844,"اظ":619,"آپ":794,"آئ":413,"آب":1377,"آت":374,"آج":214,"آخ":195,"آر":259,"آس":262,"آز":333,"آف":182,"آل":275,"آم":177,"آن":518,"آي":281,"عے":301,"ٰ ":195,"عہ":1012,"طہ":234,"غي":910,"غل":246,"عي":1223,"غر":737,"صے":202,"عق":239,"عل":4649,"صہ":487,"عم":2601,"غا":645,"عن":1246,"عو":588,"عث":370,"ظي":492,"عت":818,"عد":2145,"عز":175,"عر":1942,"عظ":634,"عض":358,"عا":2408,"عب":841,"ظم":515,"شہ":2846,"ظا":851,"طن":541,"سہ":287,"طل":743,"سے":11317,"ظر":549,"شک":686,"طي":706,"طو":1493,"ضم":182,"زہ":344,"ضل":1190,"رے":1402,"طر":1375,"ضي":496,"سک":2597,"طح":262,"طا":2021,"طب":814,"ضو":288,"سپ":375,"صل":1848,"صف":401,"صط":357,"سٹ":824,"ضر":887,"صو":2504,"رہ":3575,"صن":434,"ضا":582,"صي":766,"دے":538,"شع":464,"رک":3328,"صح":404,"صد":1147,"صر":962,"رگ":411,"شم":1789,"ذہ":258,"صا":794,"شن":774,"صب":345,"شو":358,"شي":1319,"سع":252,"سط":727,"دگ":457,"سف":448,"دھ":774,"رپ":455,"رٹ":425,"رڈ":213,"سي":6156,"شت":955,"رچ":305,"سو":1823,"شا":3056,"سن":1275,"دہ":2389,"سم":1996,"سل":3485,"شر":1691,"شد":243,"شخ":304,"ذک":274,"سب":1244,"سا":5309,"زن":603,"ست":5770,"زو":460,"زم":950,"زل":234,"سر":2705,"سج":282,"زي":3808,"دک":188,"رس":1755,"رش":298,"رر":201,"رز":482,"جے":273,"رط":461,"رص":252,"رض":357,"رل":427,"رق":1634,"رف":1286,"رو":5304,"زب":1100,"رن":2342,"زا":1886,"رم":1656,"ري":12753,"زر":534,"ذر":554,"جگ":285,"رآ":320,"جھ":599,"جہ":1619,"رب":2493,"را":9267,"رت":4343,"رج":1190,"ذي":412,"رخ":287,"رح":1014,"حک":1119,"رد":2466,"ف ":3475,"ع ":4219,"ڑي ":543,"غ ":230,"ص ":761,"ض ":697,"ط ":839,"ظ ":1429,"ر ":38086,"ز ":2573,"س ":11232,"ش ":1550,"ِ ":847,"ً ":542,"ي ":57056,"ن ":18794,"و ":15262,"ق ":2735,"م ":14225,"ل ":13265,"ينہ":361,"ينے":248,"يوں":1103,"وہ ":2016,"يقي":265,"يلا":274,"يلي":664,"يما":422,"يلو":184,"ينا":221,"نہي":1033,"يمي":391,"نہو":438,"يٹ ":181,"يني":579,"يقہ":243,"وچس":192,"يور":512,"يوا":288,"يون":715,"ينڈ":257,"وں ":6861,"ہے":17450,"يٰ ":189,"وٹي":197,"يعے":209,"وگ ":226,"يرہ":738,"يشي":298,"يشن":306,"يسي":670,"نگي":216,"نگل":243,"يسو":203,"يسر":205,"ے،":1342,"نگر":1405,"يزي":1326,"نگا":269,"يسا":524,"يرو":314,"يري":407,"يعن":649,"يسے":586,"۔ا":238,"يثي":187,"يا۔":1172,"نکا":269,"ے۔":10861,"يتي":187,"ياں":353,"يرا":565,"نکہ":250,"يدا":1270,"نے ":7909,"يال":283,"يان":856,"يبا":352,"يام":192,"ياس":748,"يار":881,"ياد":1222,"ياض":232,"ياء":241,"يات":2312,"ياب":173,"يائ":508,"کچ":345,"کٹ":398,"کي":17718,"ي۔ ":1247,"کس":3186,"کش":375,"کر":6688,"کز":505,"کث":328,"کت":1905,"کو":8220,"کن":1311,"کم":1336,"کل":1933,"کئ":359,"کب":357,"کا":13105,"يۓ ":585,"يے ":1282,"گہ":320,"گھ":468,"گل":520,"گن":309,"گو":1092,"گي":2325,"گز":223,"گر":3536,"گئ":1042,"گا":1385,"کے":18417,"کھ":2829,"کہ":6908,"ں،":524,"گے":188,"يہ ":6011,"يڈي":227,"ھے":1744,"ہز":291,"ہر":3373,"ہج":298,"ہت":1501,"ہد":644,"ہا":4675,"ہب":255,"ہي":8193,"ہل":1738,"ہم":1207,"ہن":1510,"ہو":9694,"ں۔":3376,"ھم":206,"ھل":258,"ھي":5556,"ھو":1393,"ھن":692,"ہ،":328,"ھر":965,"يں ":20810,"ھا":3850,"ھت":572,"ں ":29650,"ڈر":227,"چي":975,"چن":411,"چو":627,"وہا":172,"ڈا":533,"چک":371,"چہ":230,"چھ":1116,"ڈو":318,"ڈي":856,"پھ":684,"پہ":1407,"چس":237,"چا":849,"چت":269,"چل":282,"ڑا":619,"ۃ ":184,"ۂ ":441,"ڑے ":367,"يٹر":982,"ڑي":670,"يک ":5968,"ھ ":2275,"چے":173,"ہ ":29676,"وگو":199,"ڑک":206,"ڑھ":467,"ڑے":384,"ے ":59880,"ۓ ":1150,"۔ ":15851,"و۔ ":200,"وز ":174,"ور ":14043,"ود ":1161,"ڈي ":274,"لگ ":206,"وس ":423,"چين":228,"نما":532,"وع ":503,"نيا":1482,"نوي":380,"نون":235,"نور":347,"نوب":664,"نوا":373,"نٹ ":234,"وف ":378,"نيہ":422,"نيو":458,"نوں":1111,"وم ":918,"لہ ":1961,"ون ":1017,"چند":174,"ول ":1088,"نڈ ":285,"وي ":1068,"ي، ":669,"نچ ":177,"مغر":519,"معل":267,"معن":336,"معر":258,"مشہ":684,"معا":596,"چست":201,"مقا":854,"مقد":219,"چان":177,"ملت":253,"ملا":357,"چتر":233,"قے ":368,"منا":208,"نائ":404,"مند":339,"نات":285,"منت":213,"نار":304,"مما":299,"ملي":227,"موا":174,"ملک":619,"موج":660,"مور":225,"موس":304,"موع":240,"نام":2044,"نان":513,"ناي":217,"نتق":217,"نتظ":204,"نتخ":209,"مون":289,"موم":337,"مول":250,"ميل":269,"ميد":233,"مير":641,"ميا":812,"ميت":203,"نتي":206,"نجا":562,"مين":762,"ميٹ":952,"موں":292,"ندا":677,"ميں":16302,"ندو":448,"ندر":713,"ندي":569,"چار":237,"نسا":448,"چي ":376,"وا ":736,"ندگ":273,"ندہ":249,"نسي":397,"نسل":289,"ندھ":311,"وب ":577,"وت ":377,"نظا":416,"نظر":493,"وج ":244,"نظي":172,"لک ":878,"ونا":319,"ومي":882,"ونس":207,"وما":454,"ولي":616,"ولو":168,"ومت":782,"يع ":214,"ولا":396,"وقت":472,"وفا":282,"يش ":423,"يس ":618,"نگ ":881,"ويں":364,"يق ":261,"يف ":611,"مکم":188,"ونے":813,"نڈي":216,"چہ ":203,"ونک":263,"چھ ":368,"وني":567,"وٹ ":170,"ونو":241,"وڈ ":203,"يو ":296,"نہ ":1535,"يم ":2131,"ين ":3424,"مگر":341,"يل ":1806,"لے ":2120,"وئے":873,"واں":205,"وتي":759,"وتا":1184,"وبہ":880,"وجي":169,"وجو":858,"وا۔":228,"وار":699,"واز":279,"واد":234,"واج":227,"وئي":1076,"واب":205,"وائ":356,"وبي":420,"واي":171,"واق":1340,"وال":2546,"وان":598,"وبا":263,"وام":369,"وري":875,"مہ ":911,"وست":275,"لگا":240,"وزي":317,"يا ":8493,"وسر":713,"وسط":295,"ورپ":286,"ودہ":176,"وسي":366,"يب ":717,"ورہ":195,"لکي":197,"وتے":500,"ودي":279,"ورا":750,"وجہ":615,"ورس":204,"ورت":506,"لکہ":196,"ورن":218,"لکھ":453,"وغي":292,"يد ":1164,"ير ":2092,"يز ":500,"يت ":1838,"يج ":176,"يح ":219,"يخ ":423,"لد ":289,"قصب":216,"لت ":358,"لا ":1251,"قسم":285,"لب ":395,"قسي":239,"�":423,"لق ":599,"لف ":570,"چھو":396,"قوں":260,"ما ":498,"لم ":1252,"لع ":962,"قيق":283,"قيا":359,"قوم":305,"قوا":311,"قل ":209,"فرا":633,"فرو":181,"فري":361,"قي ":950,"ل، ":225,"فيص":180,"قبہ":284,"قدر":190,"قدي":366,"قري":696,"قرآ":222,"قرا":218,"قال":197,"قائ":507,"قاب":316,"قات":245,"فلم":218,"فوج":255,"قبو":176,"قبل":223,"قان":205,"قبا":188,"قام":703,"فٹ ":202,"لما":635,"ماع":315,"لمي":331,"مات":656,"مار":1346,"ماد":258,"لند":373,"مائ":379,"لفظ":904,"لفا":303,"نس ":426,"لعہ":239,"ند ":917,"لطا":204,"مي ":1920,"لطن":355,"مطل":234,"ني ":4359,"و، ":185,"مطا":719,"مصن":197,"مصر":194,"مرک":583,"نو ":281,"مذہ":183,"مشر":609,"مسل":679,"مشت":387,"مست":254,"مسج":242,"مسا":197,"قہ ":928,"مري":646,"مجھ":254,"مرا":743,"مرب":331,"مرت":186,"مدي":169,"ليے":1014,"ليۓ":470,"مدد":185,"ليک":538,"ليہ":571,"مخت":598,"لوگ":423,"محم":603,"لوں":448,"لوچ":226,"لين":425,"مجم":256,"لنے":191,"ليت":222,"متي":175,"ليا":836,"ماہ":260,"ليم":656,"مثل":227,"لوي":317,"لوم":894,"للہ":672,"متح":211,"متع":399,"مال":2414,"مام":560,"مان":1742,"مبا":175,"ماي":231,"مبر":417,"مر ":315,"مد ":873,"لو ":198,"ے۔ ":8070,"مت ":1234,"لي ":3595,"ن، ":362,"لسل":386,"نب ":260,"نا ":1656,"من ":398,"فہ ":313,"نت ":572,"لدي":343,"لحک":303,"مل ":1925,"لتي":176,"لاک":279,"لئے":321,"لاہ":228,"لتا":182,"لحا":247,"لاح":555,"لاد":170,"لاز":192,"لائ":397,"لات":751,"لاق":1241,"لاف":367,"مع ":244,"لاو":376,"لام":1294,"لان":427,"لبا":312},"n_words":[1602570,1999510,1324903],"name":"ur"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/vie b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/vie new file mode 100644 index 000000000..10c3d892e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/vie @@ -0,0 +1 @@ +{"freq":{"D":18934,"E":10094,"F":9985,"G":23207,"A":42579,"B":48257,"C":72224,"L":45665,"M":47574,"N":70917,"O":10000,"H":57302,"I":15743,"J":5371,"K":22108,"U":5400,"T":104616,"W":8071,"V":30021,"Q":14744,"P":61692,"S":43824,"R":17604,"Y":3509,"X":6207,"Z":3364,"f":32992,"g":525146,"d":205922,"e":428748,"b":182777,"c":671453,"a":692878,"n":1382200,"o":437498,"l":442210,"m":420259,"j":4762,"k":100510,"h":937660,"i":759263,"w":22119,"v":178461,"u":410719,"t":952446,"s":286409,"r":444790,"q":33677,"p":174320,"z":16996,"y":192811,"x":29082,"²":689,"Î":330,"É":501,"Á":3556,"Â":2373,"Ý":1288,"ß":648,"Ú":1274,"Ô":1751,"í":49339,"ì":32480,"ê":66073,"é":38397,"è":3862,"ç":233,"ä":808,"ã":19808,"â":112923,"á":116051,"à":337783,"ü":3187,"ý":5197,"ú":10002,"ù":30808,"ö":2319,"ô":98885,"õ":1117,"ò":13544,"ó":78081,"ñ":390,"đ":198318,"Đ":41649,"ă":37793,"ā":557,"ĩ":9562,"ī":249,"ō":772,"ũ":5403,"ū":650,"ư":147894,"ơ":25607,"́":204,"ο":236,"ι":146,"λ":139,"α":217,"ς":203,"ρ":170," l":242575,"ь":159," m":173509," n":244497,"я":194," o":12009," h":134731," i":13655," j":644,"ы":142," k":76050," d":93354," e":7007," f":8319," g":49741,"ч":190,"р":638,"с":522," a":22488," b":142456,"т":441,"у":252," c":262807," y":1958," x":17955," z":365," u":1259," t":566783," w":4693," v":156401," q":28586," p":59115," s":94989," r":14869," J":5319," K":22031," H":57162," I":15633," N":70771," O":9935," L":45508," M":47408," B":48077," C":71972," A":42454,"С":156," F":9904," G":23091," D":18825," E":10050,"л":506,"к":551," Z":3238,"й":211," Y":3492,"и":885," X":6141,"о":889,"н":659,"м":235,"г":168," S":43565,"в":508," R":17493," Q":14713,"б":149,"а":1192," P":61533," W":8016," V":29925," U":5377,"е":792,"д":263," T":104253," á":1499," â":3662," í":541," ô":2220," ý":503," ă":627," Đ":41607," đ":198156," Â":2373," Á":3556," É":500," Î":330," Ô":1748," Ú":1274," Ý":1277," ư":1144,"ي":271,"ل":264,"م":187,"ن":142,"ا":398,"ر":178,"A ":2159,"F ":494,"Da":2569,"Cu":1591,"Cy":963,"Cl":1245,"Co":10944,"Cr":1746,"Ce":2576,"Ch":19039,"Ci":1005,"G ":637,"Ec":908,"Ed":361,"Ea":530,"Du":1267,"Dy":152,"Do":2470,"Dr":1247,"De":2217,"Di":2894,"Bà":792,"Bá":858,"Fe":902,"H ":455,"Fa":1831,"Eu":2126,"Ex":464,"Er":617,"Et":367,"Es":894,"En":771,"Em":460,"Ep":314,"Ei":335,"El":872,"Cá":2732,"Ge":2583,"Câ":290,"Cà":157,"Ga":3052,"I ":2174,"Fu":749,"Fr":2327,"Bí":387,"Bì":1773,"Fo":1217,"Bé":191,"Fl":1104,"Fi":1024,"B ":642," С":156,"C ":1227,"Av":428,"Au":2997,"Ar":5387,"Aq":1658,"At":1067,"As":1434,"D ":745,"Ba":13610,"Az":1190,"Ay":139,"Ae":265,"Af":962,"Ag":750,"Ah":192,"Ab":577,"Ac":1193,"Ad":611,"Am":2029,"An":10483,"Ap":626,"Ai":1117,"Ak":164,"Al":6955,"By":154,"Bu":3220,"Br":4012,"Ca":14082,"E ":3496,"Bh":176,"Bi":2488,"Be":3517,"Bo":4388,"Bl":876,"Gò":247,"Ku":658,"Gö":233,"Ky":391,"Kn":144,"Kl":231,"Kr":781,"Ko":952,"Hã":340,"Hà":3871,"Há":6912,"Le":5532,"Li":5716,"N ":1502,"La":11255,"Lu":1591,"Hó":455,"Hò":671,"Ly":614,"Bư":341,"Hé":321,"Lo":11096,"Hì":160,"Me":5622,"Mi":7578,"Cơ":380,"O ":859,"Ma":14564,"Cư":440,"My":979,"Mu":2726,"Mo":6001,"Nh":15252,"Ni":3602,"Ng":8870,"Ne":5246,"Na":14732,"P ":1136,"Dư":2196,"ưu ":1732,"Ny":327,"Nu":290,"No":7260,"Ok":174,"Ol":595,"Om":201,"On":483,"Oh":203,"Oi":748,"Oc":485,"Od":183,"Oe":270,"Oa":270,"Ob":773,"Gi":6635,"Gh":326,"Gl":496,"Gr":4171,"Go":1400,"Gu":2462,"Gy":286,"Cô":3480,"Có":402,"Cú":325,"J ":219,"Ha":7544,"Dâ":1283,"He":2483,"Hi":2709,"Ho":13976,"Hu":4398,"Hy":1927,"Dô":340,"K ":324,"Ib":265,"Id":176,"Ic":220,"Im":190,"In":3623,"Il":428,"Is":1691,"It":2092,"Ir":1003,"Ja":1797,"L ":642,"Ji":230,"Je":710,"Jo":1104,"Ju":1037,"Ka":2594,"M ":626,"Kh":4970,"ưng":2590,"Ki":2990,"Ke":1180,"Ut":638,"Ur":404,"Um":166,"Un":919,"Uk":408,"Ul":140,"Ug":456,"W ":203,"Ty":201,"Tw":155,"Tu":2972,"Tr":21381,"To":2690,"Th":42787,"Ti":3875,"Te":2952,"Ta":3822,"V ":758,"Sw":579,"Sy":613,"St":3687,"Su":1921,"Wo":921,"Wi":1647,"Wh":297,"Sé":358,"Sè":329,"Wa":2024,"Sâ":534,"Sá":354,"We":2017,"Sà":247,"Y ":322,"Lư":806,"Vo":1915,"Vu":318,"Vi":16219,"Ré":208,"X ":401,"Va":2214,"Ve":2267,"Uy":394,"Lă":215,"Mã":1030,"Má":214,"Lý":664,"Lü":151,"Mé":245,"Pt":637,"Pu":1475,"Pr":3920,"Ps":557,"S ":1842,"Py":3299,"Pe":2603,"Là":800,"Lã":279,"Pf":1720,"Lâ":833,"Pa":7810,"Lé":142,"Pl":1384,"Po":3931,"Lê":927,"Pi":2275,"Ph":31098,"Os":655,"Ot":301,"Ou":271,"Ov":238," ا":171,"Op":394,"Or":2938,"R ":429,"Kô":237,"Se":3444,"Sc":3122,"Si":2745,"Nă":720,"Sh":1345,"Sm":208,"Sl":522,"Sk":307,"Sr":367,"Sp":2000,"So":3317,"Ru":1170,"Nô":330,"Ry":155,"Nó":11015,"U ":337,"Hư":909,"Sa":11442,"Re":2085,"Ri":2194,"Rh":4441,"Ro":3835,"Qu":14208,"Mô":839,"T ":649,"Mù":252,"Ra":1904,"Mü":183,"Sơ":2030,"Sư":226,"Yê":502,"Xã":2079,"Wü":541,"Xô":549,"ưa ":1620,"Xí":179,"Vĩ":456,"b ":1444,"a ":226759,"Tư":1027,"Vũ":589,"Tù":160,"Tú":283,"Tô":962,"Xy":153,"Nư":140,"Ye":349,"Ya":435,"Yp":239,"Yo":874,"Sĩ":507,"Yv":187,"Yu":292,"Mư":225,"Só":240,"Sô":413,"Tâ":9624,"Tà":542,"Xe":229,"Tá":302,"Sü":308,"Xa":216,"Tê":676,"Xi":420,"Tò":164,"Xu":1093,"Tí":259,"Vù":202,"Vă":1172,"Za":1272,"Và":236,"Ze":739,"Zh":185,"Zi":458,"Vâ":484,"Tĩ":188,"Zu":199,"Võ":191,"i ":212782,"bó":2113,"cà":270,"gd":295,"cá":22579,"ge":11280,"câ":2231,"bú":210,"ga":12467,"bé":224,"fl":1616,"bã":190,"fg":215,"ff":1242,"fi":2497,"fs":160,"fr":3324,"fu":1164,"ft":684,"fo":4267,"bê":1228,"bí":976,"bì":10910,"j ":155,"cù":1871,"cú":386,"gy":681,"có":47444,"gw":161,"cô":5046,"dâ":28874,"dã":502,"dà":2537,"he":41577,"hb":191,"ha":43156,"gn":5754,"gm":577,"gl":1738,"gk":293,"gi":33763,"bă":263,"gh":11779,"gg":570,"cò":3292,"gu":10662,"gt":510,"gs":1016,"gr":2654,"go":8645,"dt":805,"du":4489,"dw":715,"dy":507,"g ":364697,"ea":15752,"eb":3649,"ec":8564,"ed":11541,"de":24490,"dd":556,"dg":298,"df":167,"di":32181,"dh":710,"dk":145,"dm":293,"dl":1043,"do":14691,"dn":264,"ds":1755,"dr":3533,"ew":3323,"ex":3581,"eu":6762,"ev":2827,"ey":3123,"ez":1216,"fa":5205,"h ":178273,"bà":2398,"bá":2351,"fe":2871,"eh":679,"eg":4460,"ef":1217,"ee":4546,"el":24442,"ek":799,"ej":311,"ei":13045,"ep":4148,"eo":14079,"en":49087,"em":10013,"et":12592,"es":40569,"er":51401,"eq":167,"ca":30360,"Xư":246,"e ":134279,"bw":303,"by":1138,"bs":628,"br":3660,"bu":6071,"bt":170,"bn":144,"bo":4357,"bl":1961,"bf":332,"bh":146,"bi":46026,"bb":920,"be":11159,"db":293,"da":38163,"f ":9188,"cy":1022,"cu":9388,"ct":7017,"cs":417,"cq":226,"cr":3098,"co":14606,"cm":248,"cn":200,"ck":4238,"cl":1934,"ci":14195,"ch":129179,"ce":13915,"cc":1731,"Vư":1101,"c ":282171,"az":1913,"ay":20261,"ba":27162,"d ":28581,"at":21123,"as":21308,"ar":46226,"aq":534,"ax":1123,"aw":1934,"av":3839,"au":17184,"ak":3208,"al":35399,"ai":30021,"aj":1274,"ao":21790,"ap":5292,"am":43172,"an":108096,"ac":18572,"ad":10374,"aa":985,"ab":4752,"ag":8446,"ah":2616,"ae":34413,"af":1148,"nu":5357,"nt":26825,"ns":10879,"nr":434,"nq":250,"np":246,"no":9747,"hĩ":3597,"nn":7993,"q ":277,"nz":1727,"dư":2566,"ny":2595,"nx":314,"nw":217,"nv":655,"oe":1614,"of":8008,"oc":9998,"od":5406,"oa":17234,"ob":3593,"ké":466,"om":14342,"kê":1778,"on":100425,"ok":1733,"kè":139,"ol":16267,"oi":9431,"oj":178,"og":4447,"oh":1218,"ot":8950,"m²":659,"hō":191,"os":13276,"ov":4515,"ou":16281,"kì":215,"op":11878,"oo":2896,"or":34485,"oq":166,"gũ":395,"kí":1225,"r ":23753,"ox":666,"ow":4522,"oz":1526,"oy":925,"là":155485,"lá":810,"pe":13642,"pf":220,"lâ":707,"lã":1014,"pa":8707,"ký":795,"lè":430,"pl":2303,"lé":393,"lê":819,"po":6064,"ph":59995,"pi":7555,"lo":48870,"ln":332,"hê":913,"lm":1499,"hé":1262,"hè":446,"ll":28312,"ls":5922,"hí":22956,"lp":3661,"hì":4519,"hó":4714,"lw":160,"hò":5943,"lv":1420,"lu":8343,"lt":3135,"bư":9431,"lz":2455,"hö":169,"ly":7272,"hô":9522,"hú":4659,"hù":1344,"o ":85116,"iß":177,"ià":688,"hü":788,"ma":19960,"mb":6117,"mg":163,"hă":499,"me":15863,"iá":6621,"cơ":2439,"iè":809,"ml":141,"mi":19185,"mn":579,"iê":19338,"mm":3914,"ié":147,"mp":6181,"mo":8059,"mt":201,"ms":1171,"mu":3841,"iô":221,"ió":194,"cư":776,"my":849,"p ":57766,"iú":305,"na":36440,"nb":2672,"nc":9194,"nd":29108,"ne":33625,"nf":985,"ng":422545,"nh":179739,"ni":21672,"nj":602,"nk":2141,"nl":3093,"nm":685,"ju":396,"jo":698,"ki":21387,"kh":39807,"gã":188,"gâ":871,"ke":3413,"gá":300,"gà":10665,"ka":4069,"m ":167316,"gó":565,"gô":2554,"ky":750,"ks":1201,"kt":384,"ku":945,"ko":1602,"cũ":2937,"kr":861,"kk":293,"kl":1148,"km":4687,"kn":974,"li":29575,"lh":510,"lk":1201,"le":28117,"há":50648,"hà":29720,"ld":3791,"hã":1199,"lg":997,"hâ":38191,"lf":811,"la":39723,"lc":719,"lb":2760,"n ":440934,"hr":3391,"hs":2273,"dò":649,"hw":1075,"ht":2057,"hu":96505,"hk":147,"hh":235,"că":337,"hi":59002,"hn":1134,"ho":33760,"hl":2514,"hm":909,"dé":1520,"id":34385,"ic":24617,"ib":3478,"ia":42159,"ih":435,"ig":7165,"if":3529,"ie":18418,"hy":2981,"dù":2108,"k ":5941,"iq":1214,"ir":10741,"is":30398,"it":19216,"iu":2880,"iv":3060,"iw":152,"eó":2057,"ix":1054,"ii":6395,"ij":559,"ik":1883,"il":38718,"im":11936,"in":70002,"io":10270,"ip":6214,"je":426,"ji":826,"iz":1625,"iy":348,"l ":17786,"ja":1818,"nơ":1994,"să":488,"xi":2236,"tê":7401,"xo":824,"té":201,"tì":8961,"xp":151,"tí":18614,"tò":332,"xt":572,"xu":3759,"mư":601,"sô":2011,"ww":348,"só":466,"z ":4461,"xc":234,"xa":2141,"tâ":11580,"tá":3122,"xe":1418,"tà":3376,"wh":1250,"ră":636,"wi":4079,"sè":470,"wl":199,"sé":203,"wn":1808,"sê":269,"wo":1048,"ws":516,"wt":183,"rò":801,"rõ":266,"rô":669,"lư":3756,"rö":667,"rù":551,"y ":123996,"rú":838,"rü":313,"wa":4838,"sâ":1032,"sá":4087,"we":3258,"rè":166,"ré":3552,"vi":14749,"râ":232,"rã":310,"vu":13359,"vr":721,"rì":2865,"rí":1219,"rê":17007,"vo":1414,"uz":955,"uy":40068,"ux":1932,"uw":188,"uv":1489,"ve":8349,"rá":1135,"rà":746,"va":5946,"x ":5085,"ui":7198,"uj":271,"uk":987,"ul":11719,"ue":8283,"uf":658,"ug":2145,"uh":313,"mũ":152,"ur":22852,"us":22737,"ut":11022,"um":8525,"un":37448,"uo":379,"up":2448,"ty":3384,"tz":1632,"tu":10835,"tt":6267,"tw":506,"tv":273,"ub":3534,"ua":12317,"ud":3186,"uc":4195,"w ":3929,"to":19941,"tn":373,"tm":750,"tl":2439,"ts":3488,"tr":168490,"lũ":299,"tp":612,"tg":165,"tf":340,"te":34125,"ti":45992,"th":244395,"v ":848,"tb":456,"tc":539,"ta":22518,"su":6738,"sv":185,"ss":11481,"st":25304,"sy":900,"sw":1422,"sl":2460,"sk":1966,"sn":3570,"sm":2007,"sp":6570,"so":7204,"sr":482,"sq":267,"oà":40273,"sd":636,"oß":224,"sc":6190,"sf":434,"se":16078,"oá":2469,"nă":29159,"sh":6976,"sg":779,"oã":161,"si":19668,"hư":18279,"rz":821,"u ":92839,"nú":1257,"sa":12158,"sb":1450,"rr":9518,"rs":7765,"rt":11056,"ru":33603,"rv":1083,"rw":648,"nó":3472,"nô":498,"ry":4815,"rq":206,"rp":2369,"lĩ":607,"ro":79309,"nê":766,"rn":10149,"né":3611,"rm":6127,"rl":2540,"nç":154,"rk":3126,"hơ":3447,"ri":45411,"rh":1015,"rg":11132,"nâ":296,"rf":2041,"re":31859,"rd":9664,"nà":32104,"า":167,"rc":4893,"rb":3024,"ra":48559,"mù":496,"t ":240212,"gư":23033,"mó":270,"mô":1896,"qu":33189,"ร":145,"mé":23563,"mì":570,"má":2261,"mã":976,"lý":2656,"mà":2647,"s ":83922,"lú":457,"lô":11642,"px":1137,"py":386,"pt":4331,"pu":3257,"lò":168,"pp":2831,"lí":1363,"pr":2803,"ps":2406,"hū":297,"vư":1017,"zè":171,"vũ":680,"tư":4765,"sơ":283,"yê":5321,"sư":822,"xá":866,"xâ":942,"xã":6617,"rư":7067,"xé":140,"vĩ":1312,"xí":212,"vă":2376,"vù":22603,"zz":263,"vâ":231,"zh":389,"zi":1581,"uý":467,"zb":261,"và":46943,"ze":2177,"za":3062,"yz":169,"vò":489,"võ":378,"vô":1031,"zu":1605,"zo":1512,"zn":191,"ví":191,"vì":1173,"zl":195,"yg":495,"yh":272,"tă":382,"ye":2354,"uá":1249,"uâ":5412,"yf":154,"yc":1911,"yd":753,"ya":3754,"yb":311,"tú":167,"tù":418,"nư":35853,"tô":1034,"xy":294,"yx":252,"uô":12078,"yu":633,"yt":872,"ys":3871,"yr":5371,"yp":2222,"sĩ":1785,"yo":1215,"yn":1357,"uê":505,"ym":1622,"ué":319,"yl":3067,"yi":713,"xư":530,"yū":142,"² ":668,"Á ":1673,"Áv":245,"Áo":1420,"Âu":2129,"Âm":150,"Îl":330,"àn":34510,"ào":9571,"àm":2558,"ài":40656,"ã ":15139,"ày":41288,"àu":3190,"ám":1101,"án":28484,"áo":4300,"áp":27542,"ái":6121,"ác":31049,"áy":2255,"áu":552,"át":6111,"âm":6839,"ân":71359,"âu":6947,"ât":496,"ây":27219,"ãn":2862,"ão":485,"ãi":672,"ãy":559,"à ":205928,"á ":8250,"ße":294,"Úc":1243,"Ý ":1285,"Ôn":1610,"アアア":304,"ôi":2574,"ôm":11781,"ôn":48478,"óa":2709,"õ ":900,"ói":993,"óc":731,"óp":293,"ón":6670,"óm":1531,"ô ":34032,"òa":5612,"òm":318,"òn":6337,"ó ":64834,"ña":207,"ò ":1069,"ín":13049,"ít":636,"ìn":20626,"ìm":8528,"íc":17864,"ía":12239,"í ":5056,"ên":48870,"êm":9168,"êu":3630,"éz":154,"ì ":3075,"él":169,"éo":764,"ép":2326,"ém":434,"én":3441,"és":341,"ét":23592,"ér":825,"év":213,"éb":181,"éd":152,"éc":499,"ée":3394,"ég":181,"èn":257,"èo":280,"èr":1433,"ès":603,"èv":444,"ê ":4050,"é ":1396,"Đưể":826,"è ":371,"är":168,"ăm":28997,"ăn":8563,"ăk":142,"đưể":28774,"ān":253,"ý ":5155,"ể":1508247,"ün":249,"ür":1564,"üt":177,"üc":207,"üd":322,"ùn":27807,"ùi":235,"ùa":1067,"úp":776,"ún":1686,"úy":219,"út":637,"úa":606,"ùy":248,"úi":1359,"úc":3127,"ù ":1286,"ú ":1439,"ôt":1632,"öt":180,"ör":366,"ös":634,"ön":312,"öl":155,"đĩ":597,"đó":3828,"đô":27703,"đú":182,"đă":220,"Đư":848," ể":80643,"đư":29695,"đơ":1908,"tưể":2647,"Đa":443,"Đo":196,"Đi":1420,"đe":478,"đa":1708,"đo":2470,"đi":17430,"Đ ":295,"Đì":322,"Đà":1638,"Đá":165,"Đâ":3555,"đí":392,"đì":460,"đê":8064,"đã":4348,"Đă":188,"đá":3730,"đâ":1604,"đà":1035,"Đô":12692,"đu":489,"Cể":8674,"Dể":759,"Bể":9876,"Hể":9168,"Gể":170,"Lể":3634,"Kể":5925,"ĩ ":4602,"ĩa":3526,"ĩn":1420,"ĩnh":1417,"dể":12219,"ĩa ":3523,"cể":67050,"bể":45726,"mể":131131,"ũ ":2155,"lể":23218,"kể":7585,"iể":166241,"hể":264262,"gể":17545,"Sể":1192,"Tể":7402,"Rể":525,"ō ":339,"Mể":5140,"vưể":475,"Nể":1896,"Xể":142,"Vể":1294,"rể":50434,"sể":54959,"tể":83275,"uể":92128,"nể":21381,"ū ":399,"oể":14719,"ũi":200,"ũn":2955,"vể":53705,"专专 ":169,"xể":2191,"yể":31245,"ơi":3100,"ơm":181,"ơn":18072,"ơ ":4182,"あ":270,"ア":496,"가가 ":224,"ươ":12314,"ư ":8494,"ưa":1622,"ưn":2592,"ưu":1733,"Để":19679,"để":91689,"Đan":304,"đa ":614,"ơm ":179,"ơn ":5934,"đai":310,"đan":664,"ơi ":3096,"đi ":743,"ơng":12128,"đen":294,"đo ":419,"đoà":1003,"đua":287,"乙":857,"乘":179,"之":2791,"丹":642,"临":665,"中":142,"並":1114,"丙":309,"丘":935,"丛":252,"专":2269,"且":143,"丈":196,"三":4224,"丁":2034,"万":989,"亞":563,"亂":327,"侏":215,"ểy ":15070,"ểu ":43780,"ểt ":179200,"Đây":3553,"Đào":412,"Đài":765,"Đà ":277,"Đôn":3441,"圓":161,"Đô ":9162,"Đìn":322,"冲":171,"đêm":8016," 丘":335,"đíc":372," 专":413," 三":1027," 丁":795,"đìn":459,"đây":1563,"đá ":2316,"倉":569,"đán":1131,"đã ":4325,"đào":392,"đài":257,"đàn":318,"đún":140," 倉":244,"ưể":121112," 侏":158,"đón":976,"đôi":461,"đôn":8728," 並":342," 临":320," 丹":351," 之":799," 乙":411,"đó ":2805,"đô ":18495," 亂":152,"大":197,"ểa ":61642,"ểc ":245982,"ểch":9163,"ểi ":112695,"ểk ":174,"ển ":203101,"ểm ":59200,"ểp ":25010,"ểng":124564,"ểnh":41635,"ểo ":9528,"Điể":1233,"ああ":156,"điể":16552,"đoể":920,"đăn":218,"đĩa":596,"ς ":202,"đơn":1904," ểc":15788," ển":5390," ểm":264," ểy":799,"アア":391," ể ":57997,"đươ":308,"đưa":612,"ск":150," vư":1017," xư":529," Áo":1420," Áv":245," Á ":1673," Ga":3043," Câ":289," Cá":2724," Ge":2570," Cà":157," I ":489," Bì":1773," Bí":387," Fo":1209," Fu":749," Fr":2319," Fi":1014," Fl":1075," Bé":190," Ha":7534," He":2474," Dâ":1282," Cô":3477," Có":398," Gy":285," Cú":325," J ":162," Go":1392," Gr":4156," Gu":2454," Gh":322," Gi":6622," Gl":488," Id":176," Ic":219," Ib":265," Hy":1924," Dô":340," Hu":4380," Ho":13959," Hi":2699," Ji":227," Je":694," L ":288," Ja":1791," Ir":1002," Is":1688," It":2091," Im":186," In":3565," Il":425," M ":229," Ka":2587," Ke":1169," Ki":2975," Kh":4951," Jo":1090," Ju":1029," N ":147," La":11244," Hà":3868," Há":6905," Le":5519," Hã":339," Li":5628," Kl":231," Kn":141," Ko":946," Kr":777," Gò":247," Ku":656," Gö":233," Ky":391," Ma":14506," O ":139," Cơ":380," Mi":7555," Me":5610," Hì":157," Lo":11086," Hé":321," Bư":341," Ly":614," Hó":455," Hò":670," Lu":1590," Ne":5220,"а ":296," P ":285," Na":14703," Ng":8844," Nh":15231," Ni":3593," Mo":5991," Cư":440," My":978," Mu":2713," A ":801," B ":314," C ":460," Ap":624," Am":2023," An":10467," Ak":163," Al":6944," Ai":1106," Ag":749," Ah":189," Ae":262," Af":957," Ac":1189," Ad":608," Ab":573," Ba":13586," D ":281," Az":1190," Ay":139," Av":424," Au":2992," At":1064," As":1419," Ar":5374," Aq":1657," Be":3504," Bi":2420," Bh":176," Bl":874," Bo":4376," Br":4006," Bu":3207," By":153," E ":175," Ca":14032," Ce":2572," Ci":1003," Ch":19001," Cl":1229," Cr":1732," Co":10896," Cu":1575," Cy":959," F ":217," Da":2548," Di":2876," De":2206," Dr":1245," Do":2436," Dy":152," Du":1262," Ea":529," Ec":908," Ed":358," G ":173," El":867," Ei":335," Et":365," Es":889," Er":614," Ep":314," En":763," Em":454," Ex":456," Eu":2122," Bà":785," Bá":846," Fe":894," Fa":1822," H ":178," Xu":1090," Tò":163," Tí":259," Tê":651," Xi":413," Tà":542," Xe":204," Tá":302," Tâ":9623," Sü":308," Xa":216," Só":240," Sô":411," Mư":225," Wo":905," Sé":358," Sè":329," Wi":1632," Wh":294," Sá":350," We":2007," Sâ":533," Sà":247," Wa":2017,"й ":151," Y ":281," Lư":805," Võ":190," Tĩ":188," Và":232," Ze":737," Vâ":484," Zh":184," Zi":450," Za":1260," Yv":187," Yu":290," Yp":238," Yo":868," Sĩ":506," Ya":432," Ye":349," Nư":140," Tô":962," Xy":153," Tú":282," Tù":160," Xí":179," Vĩ":455," Xô":549," Wü":541," Xã":2079," Vù":202," Vă":1148," Vũ":587," Tư":1025," a ":4962," Yê":501," Sư":226," Sơ":2029," R ":199," Kô":237," Ou":268," Ov":236," Os":655," Ot":299," Or":2938," Op":391," Po":3911," Lê":922," Lé":142," Pl":1371," Pi":2271," Ph":31029," Lã":279," Pf":1720," Lâ":831," Pe":2592," Là":800," Pa":7774," Dư":2196," Ny":327," Nu":290," No":7248," Ol":594," Ok":173," On":479," Om":200," Oh":202," Oi":748," Od":181," Oc":483," Oe":269," Ob":773," Oa":270," Ra":1894," Mü":182," T ":156," Mù":252," Mô":838," Qu":14182," Ro":3827," Re":2068," Ri":2185," Rh":4439," Py":3297," S ":230," Pr":3910," Ps":554," Pt":637," Pu":1471," Mé":244," Lý":663," Lü":151," Má":214," Lă":214," Mã":1026," Sy":607," Sw":578," Su":1915," St":3635," Ta":3810," V ":169," Th":42680," Ti":3850," Te":2931," Tr":21258," To":2625," Nó":11014," Ry":154," Nô":330," Ru":1162," Sa":11420," Hư":907," U ":154," Nă":720," Sh":1334," Si":2727," Sc":3070," Se":3434," So":3300," Sp":1984," Sr":367," Sk":306," Sl":517," Sm":206," Uy":393," Va":2209," X ":200," Ve":2261," Vi":16180," Ré":207," Vo":1912," Vu":317," Tu":2947," Tw":154," Ty":200," Ug":456," Uk":408," Ul":140," Um":165," Un":913," Ur":403," Ut":638," ja":224," l ":250," im":322," in":6639," is":5408," it":773," ka":329," m ":439," kh":38847," ki":18267," gâ":429," ke":373," gá":282," ju":151," cô":5020," có":47410," cú":382," cù":1871," ha":11491," dã":502," dâ":28872," he":621," dà":2524," gi":28288," bă":261," gh":729," gl":236," gr":899," go":250," gu":378," cò":3288," hy":276," dù":2107," că":333," hi":6669," dé":1144," ho":9851," ht":218," hu":16965," dò":646," nh":45517," ni":1927," ng":51853," ne":507," na":15500," cư":775," mu":1888," mo":1972," ké":437," on":1221," kê":1776," oc":375," of":6994," ob":204," dư":2565," nu":602," no":1173," hã":1017," hà":8670," há":923," le":1986," li":4644," la":5104," gó":504," kn":913," km":4476," cũ":2936," ko":246," me":1022," mi":9905," cơ":2426," hù":342,"я ":139," hú":203," ma":3748," lu":1700," hó":2026," hò":4796," ly":382," hô":283," bư":9431," hè":160," lo":35801," hì":2834," ag":160," ab":359," ac":560," ad":220,"Hểu":669," am":614,"Hểp":191," an":7056," ap":254," ai":278,"Hển":822," al":2427," au":545,"Hểi":3718," ar":2712,"Hểc":428," aq":275," at":395," as":1145," d ":2111," ba":20628," 가가":227," bi":39922," be":1810," bo":1086," bl":299," by":542," bu":1037," br":705," ca":18336," Xư":246,"Hể ":3004," Vư":1101," er":165," et":2265," es":168," en":1522," em":442," el":437," bà":2390," fe":289," bá":2320," fa":2087," eu":165," ex":489," fu":610," fr":2001," bí":964," bì":10908," fo":1760," bê":1224," bé":146," fl":771," fi":679," bã":190," ge":1821," cá":22553," câ":2231," cà":270," ga":2783," bú":206," bó":2103," cl":550," cm":154," co":7147," cr":532," ce":1064," ch":72993," ci":299," da":4945," cu":4863," cy":157," do":4301," dr":248," de":8416," di":19653," ec":238," ed":190," ea":304," du":2623," 三三":209," vù":22601," vă":2376," ví":173," vì":1170," võ":378," vô":1027," vò":489," và":46932," vâ":230," sĩ":1785,"ка":178," tù":416," tú":155," tô":909," nư":35851," tă":379," xo":207," tê":7377," nơ":1991," să":488," tò":331," xu":3665," tí":18540," tì":8960," mư":601," ww":167," só":461," sô":2005," tâ":11572," tà":3363," tá":3073," xe":994," xa":907," tư":4765," vũ":680," 三之":172," sư":822,"ов":213," yê":400," sơ":282," rư":159," vĩ":1312," xã":6617," xâ":941," xá":864," ru":574," nô":442," nó":3467," hư":1543," sa":4809," nú":1256," se":1352," sc":583," si":4586," sh":865," nă":29145," sn":2777," sm":592," sl":244," sp":4116," so":2264," qu":28552," mó":260,"ви":141," mô":1890," mù":492," ra":5117," re":1311," nà":32102," nâ":291," ri":1195," hơ":1747," né":300," ro":791," lĩ":607," nê":751," lò":161," pu":610," pr":1132," lí":1307," lú":446," s ":1052," lô":926," px":1128," py":148," mã":975," má":2233," mà":2646," lý":2654," mì":566," mé":12707," ot":153," kì":215," op":485," kí":1225," or":1862," lá":722," pe":891," là":155391," lã":1013," lâ":684," pa":1485," ký":784," lè":332," pl":606," po":832," lê":796," pi":462," ph":51377," wa":721," sâ":1031," sá":4080," we":797," rõ":266," y ":288," lư":3756," wo":408," wi":1339," wh":1197," sê":264," va":1100," ve":759," uy":141," vo":357," vu":12917," rã":285," vi":8649," ty":993," tu":4206," us":140," mũ":152," up":179," un":373," ta":1679," v ":243," sy":262," st":916," su":3809," lũ":299," tr":156052," to":6595," th":230858," ti":21975," te":899," đu":484," đa":1700," đe":474," đi":17419," đo":2466," Đá":164," Đà":1637," Đâ":3555," Đì":322," Đo":196," Đi":1416," Đa":443," đơ":1908," đư":29691," Đư":847," đí":392," đê":8032," đì":460," đá":3730," đâ":1604," đã":4347," Đă":188," đà":1035," Đô":12690," đă":220," đú":182," đô":27698," đó":3827," đĩ":596,"Lể ":569,"Lểi":178,"Lển":215,"Lểp":1280,"Lểc":1143," Bể":9869," Kể":5918," Hể":9143,"Kể ":5821," Gể":165," Cể":8663," Dể":757," Âm":150," Âu":2129," Îl":330," Ôn":1608,"Nể ":198,"Nển":165,"Nểi":1235," Úc":1243," Ý ":1274," áp":355," án":814," âm":3643," ít":431," ô ":353," ôn":1711,"Mể ":2527," ý ":503,"Mểc":807,"Mểt":1153,"Mểu":174,"Mển":285,"Mểi":146," ăn":626," 가":331," ươ":433," ưu":158,"가":830," hể":63957," gể":12621," lể":23214," kể":7585," cể":67038," dể":12218," bể":45724," Vể":1292," Tể":7366,"Rểp":306," Xể":142," Nể":1895," Lể":3615," Mể":5122," Rể":522," Sể":1093," vể":53702," xể":2191," yể":935," mể":131122," nể":21375," rể":4289," sể":54954," tể":83225,"Tểt":172,"Tểp":225,"Tểc":152,"Tểa":1075,"Tển":2741,"Tểi":245,"Tể ":2617,"Sể ":900,"Vểt":162,"Vển":442,"Vểi":163,"Vể ":500,"ưểt":382,"ưểu":183,"ưển":18802,"ưểm":9501,"ưểi":24657,"ưểc":67509," Để":19647," để":91683," ưể":501,"Ávi":245,"ال":152,"Áo ":1417,"三三 ":318,"三万 ":202,"Âu ":2118,"三专 ":318,"Âm ":149,"ươn":12134,"ươi":146,"가가":499,"Bể ":2169,"AO ":231,"AN ":149,"Bểt":140,"Bểc":4036,"Bển":2788,"Bểo":450,"Cể ":946,"Cểu":671,"Cểp":339,"Cểm":232,"Cển":5510,"Cểc":787,"Dể ":256,"Dểc":190,"Bà ":315,"Bá ":150,"Bài":310,"Bàn":152,"Bác":305,"Fel":162,"Fen":155,"Fer":312,"Fis":282,"Ext":290,"Fas":526,"Fal":176,"Far":151,"Fab":275,"Eri":170,"Ess":158,"Est":392,"Eth":271,"Eup":437,"Eur":1040,"El ":188,"Ele":184,"Eng":198,"Epi":248,"Ent":180,"Các":1801,"Ger":929,"Cát":277,"Geo":862,"Gen":359,"Gla":140,"Gha":245,"Gia":2324,"Gil":159,"Gir":424,"oể ":155,"oểt":2492,"Cá ":259,"oểc":3719,"Gan":147,"Gal":295,"Gam":240,"Gau":147,"Gar":1513,"oển":3941,"oểi":4411,"Gab":195,"Fus":252,"Fro":378,"Flo":588,"Fla":166,"Fle":174,"ũi ":200,"Fra":932,"Fri":349,"ũng":2953,"Fre":553,"Bín":197,"Bìn":1748,"Fon":217,"For":497,"Fou":186,"Dân":1220,"nểu":216,"II ":1176,"Hil":320,"Him":177,"Hin":145,"Hip":145,"nể ":1462,"Hel":390,"nểi":2679,"Hei":256,"nểm":15373,"nển":1144,"Hem":163,"Hen":196,"Hes":405,"nểa":304,"Her":528,"Cúp":236,"Hal":332,"Hai":401,"Han":467,"Ham":344,"Has":179,"Har":748,"Haw":533,"Hau":3745,"Côt":1585,"Guy":153,"Cô ":190,"Gua":732,"Có ":275,"Gui":1036,"Côn":1681,"Gre":1012,"Gri":151,"Gra":2331,"Gro":483,"Glo":169,"Giá":926,"Gon":156,"Goo":205,"Gol":188,"Gom":158,"Úc ":1233,"Inn":161,"Int":561,"Ins":197,"Ill":204,"Ind":2106,"mểc":13680,"mểm":11638,"mểi":2779,"mểu":420,"mểt":99606,"mển":1814,"mể ":1110,"Ibe":205,"亞 ":440,"Hyp":280,"Hyd":396,"Dôm":338,"Hy ":979,"Hun":464,"Huy":2731,"Hue":217,"IV ":160,"Hoà":1902,"Hor":294,"Hou":153,"Hom":153,"Hon":555,"Hok":148,"Hol":1270,"Hoa":8475,"Arg":562,"Are":201,"Arc":363,"Ard":1593,"Ara":960,"Arm":257,"Ari":480,"Aqu":1651,"Apo":203,"Ath":149,"Atl":649,"Ast":281,"Ass":392,"Asi":256,"Arr":175,"Art":235,"Ave":196,"Auv":549,"Aus":949,"Aur":157,"Aud":253,"Aug":204,"Aub":473,"lể ":2800,"Azu":1003,"lểp":5146,"lểt":155,"lểi":2389,"lển":5223,"lểa":430,"lểc":6489,"Ba ":889,"lểy":462,"Bai":215,"Bal":574,"Ban":6419,"Bac":146,"Bad":1148,"Bay":966,"Bar":929,"Bat":270,"Bas":1136,"Bau":155,"Abr":165,"Aca":233,"Acr":321,"Ach":200,"Ade":163,"Ai ":341,"Aga":200,"Afr":687,"Afg":186,"Air":488,"Ala":309,"Alb":681,"An ":1388,"Alg":185,"Ali":170,"Ale":299,"Alv":153,"Als":515,"Alt":493,"Alm":187,"All":366,"Alp":2942,"Ame":689,"Amb":210,"Ama":449,"Amp":158,"Anh":5927,"Ang":642,"Ana":331,"And":666,"Ant":595,"Ano":159,"Ann":219,"Bus":168,"Bul":625,"Bur":1284,"Buc":492,"Bru":412,"kể ":5372,"Cab":144,"kểt":1768,"Cae":179,"Cal":3283,"Cam":1757,"Cai":141,"Cas":3059,"Car":1359,"Cau":236,"Cat":533,"Cao":644,"Can":1671,"kểc":374,"Cap":594,"Bea":394,"Ber":1074,"Ben":559,"Bel":748,"Bin":143,"Bil":278,"Bis":150,"Bit":253,"Bir":234,"Blu":260,"CP ":196,"Biê":192,"CN ":900,"Bla":380,"Bre":721,"Bra":1413,"Bro":439,"Bri":863,"Bol":471,"Boi":232,"Bon":251,"Bor":635,"Bos":277,"Bot":225,"Bou":1517,"Cyp":409,"Cur":167,"Cub":268,"Cun":184,"Cup":164,"EE ":154,"Des":235,"Deu":424,"Del":231,"Dem":185,"Den":364,"Dam":166,"Dan":842,"Dar":270,"Dav":172,"Dal":154,"Cho":474,"Chr":351,"Che":539,"Chi":4142,"Cic":417,"Chu":975,"Cit":157,"Châ":2351,"Cle":204,"Cla":633,"iểt":19441,"iểu":22084,"iểy":197,"Cel":188,"iểm":11357,"iểp":3887,"iển":94986,"Cen":1295,"Cer":828,"iểc":3158,"iểi":7620,"iểa":1763,"Cha":5749,"Cri":167,"Cra":378,"Cre":395,"Chư":286,"Cro":546,"Chù":202,"Chú":672,"Chí":1230,"Coc":220,"Coe":184,"Cop":262,"Cos":1089,"Cor":1423,"Com":752,"Col":1893,"Con":3653,"Cou":867,"FA ":242,"Drô":335,"iể ":1731,"Edw":139,"Ông":1552,"Ect":200,"Ecu":469,"Eas":364,"Do ":273,"Diê":175,"Dic":144,"之三三":139,"Dit":152,"Dis":351,"hểo":739,"hểp":5189,"hểm":3873,"Dip":407,"hển":23819,"Dio":154,"hểy":11164,"hểu":6003,"Die":258,"hểt":14285,"hểa":1704,"hểi":18265,"hểc":23691,"Di ":179,"hể ":155404,"Dun":239,"Duy":294,"Du ":216,"Dri":386,"Dre":146,"Dra":192,"Dou":158,"Don":392,"Dom":257,"Dor":723,"Cươ":311,"Nev":160,"Neu":541,"Net":191,"Nep":895,"Neo":280,"Nas":316,"Nat":595,"Nav":156,"Nig":396,"Nie":1241,"Nic":337,"Nin":1068,"Nhi":250,"Nha":5926,"Nga":1678,"Ngh":1164,"Ngu":2389,"Ngo":273,"New":2499,"Myr":349,"xể ":903,"Mya":329,"Nak":165,"Nam":11941,"Nan":196,"Nag":208,"Na ":357,"xểp":906,"xểy":267,"Như":191,"Nym":236,"Nhó":149,"Nhà":676,"Nhâ":3285,"Ngô":642,"Ngà":567,"Ngâ":218,"Ngư":724,"Nhĩ":654,"Nov":205,"Ngũ":256,"Nor":4126,"Not":381,"Nob":171,"Noc":1779,"Oec":143,"Dươ":1846,"PG ":211,"Ois":715,"Ohi":151,"Oah":152,"Occ":238,"Obe":662,"Île":330,"Ott":171,"Ovu":166,"Kôn":235,"Oly":147,"Oli":201,"Giể":2035,"Ont":199,"Or ":550,"Opo":183,"Ora":158,"Ore":369,"Orc":304,"Ori":453,"Orn":566,"Ost":243,"Phú":926,"Phù":169,"Phò":192,"Phó":180,"Phá":21296,"Ple":538,"Phâ":188,"Pla":641,"Hiể":1343,"Lê ":891,"Pin":370,"Pit":142,"Phy":669,"Pie":506,"Pic":810,"Pho":672,"Phi":3036,"Pha":566,"Lãn":143,"vểy":569,"Lâm":707,"vển":2537,"vểt":17681,"Pfa":1704,"vểa":164,"vểc":13644,"vểi":7805,"Per":956,"Pet":409,"Pen":544,"Pel":140,"Lào":383,"vể ":11302,"Pay":1416,"Là ":298,"Pat":164,"Pas":888,"Par":1717,"Pau":274,"Pac":219,"Pan":548,"Pap":721,"Pal":1091,"Pak":192,"Pyr":3193,"Huể":468,"Pte":513,"Pun":221,"Pup":166,"Pue":171,"Puy":394,"Pro":2087,"Pri":425,"Pre":247,"Phư":678,"Pse":388,"Hoể":173,"Pra":808,"Pol":756,"Pom":148,"Pon":298,"Poi":1472,"Pot":227,"Por":309,"uểc":63038,"uểi":2825,"Lăn":196,"uểt":6647,"uển":17332,"Mã ":868,"uể ":2223,"Lý ":659,"Mùa":206,"SA ":174,"Ram":194,"Ran":617,"Quá":225,"Quâ":725,"Môn":650,"Quý":277,"Qua":706,"Qui":159,"Que":829,"Quy":457,"Ita":500,"Isl":594,"Isr":263,"It ":1456,"Ira":481,"Ire":363,"Isè":447,"tểm":507,"tển":38505,"tểi":9573,"tểc":3283,"tểa":923,"tể ":24294,"Jac":218,"Jav":319,"Jan":148,"Jam":357,"tểo":2243,"tểp":1747,"tểt":2043,"Jer":195,"Jea":217,"Biể":504,"Jos":191,"Jor":166,"Joh":334,"Jul":480,"sể ":37621,"sển":14954,"sểm":218,"sểc":1290,"sểa":158,"Kai":155,"Kam":181,"Kal":268,"Kan":358,"Kau":180,"Kat":153,"Kas":184,"Kar":496,"Kaz":203,"sểt":255,"sểp":188,"Ken":722,"Kir":203,"Kit":143,"Kin":907,"Kim":609,"Kho":491,"Khu":1438,"Kha":464,"Khi":230,"Chể":1285,"Khê":158,"Khá":594,"Khô":380,"Kon":253,"Kor":151,"Kre":398,"Gòn":201,"Cuể":281,"Kus":145,"Kur":182,"Hàn":1241,"Leu":183,"Les":367,"Lep":631,"Leo":339,"Len":152,"Hán":6856,"Lei":182,"rểc":1530,"Lea":285,"rển":39207,"rểm":291,"rểi":1137,"Hà ":2463,"Lau":510,"rể ":6793,"Le ":619,"Lak":163,"Lai":390,"Las":248,"Lat":742,"Lar":215,"Lao":140,"Lam":368,"Lan":4696,"Lac":165,"Lab":180,"倉 ":180,"La ":2717,"Liê":1950,"Hér":279,"Diể":335,"Lib":574,"Lie":155,"Lig":183,"Lim":511,"Lin":692,"Lio":171,"Lis":148,"Lit":507,"Liv":154,"Leó":2050,"Hãn":333,"rểt":1287,"Hòa":572,"Lud":184,"Luc":212,"Loà":1669,"Hìn":160,"Loz":163,"Lou":367,"Los":193,"Lot":580,"MS ":483,"Loi":3201,"Lor":2131,"Lon":1378,"Lom":271,"Loa":517,"Ma ":267,"Hóa":437,"Luâ":253,"Lyc":258,"Mei":187,"Men":179,"Mel":544,"Mes":227,"Mer":503,"Meu":1122,"Met":367,"Mec":579,"Meg":242,"Med":321,"Mex":918,"Man":2248,"Mal":1668,"Mar":4888,"Mas":469,"Mag":297,"Mad":710,"Mah":444,"Mai":1077,"Mac":532,"NE ":2847,"May":519,"Mau":531,"Mat":259,"Miê":150,"Mol":400,"Mon":1606,"Mos":1419,"Mor":654,"Mou":470,"Mot":424,"Moz":414,"Mid":2002,"Mic":1239,"Cơ ":351,"Mit":747,"Mir":161,"Mis":522,"Mil":319,"Min":1719,"Mun":171,"Mur":1848,"Mus":259,"Xià":174,"Phể":1906,"Tây":8477,"Tân":1027,"Tào":168,"Tàu":164,"Süd":288,"Sôn":404,"Sóc":214,"Wor":462,"Wol":216,"Séc":256,"Sèv":318,"Whi":209,"èvr":358,"Wik":174,"Wil":393,"Win":429,"Wie":149,"Wit":233,"ère":1422,"Sài":216,"Web":172,"Wei":433,"Lươ":358,"Wes":961,"Sân":446,"Was":264,"War":327,"Wal":818,"ès ":590,"Lưu":290,"Dưể":277,"èn ":152,"èo ":278,"ém ":263,"之丁":166,"QĐ ":168,"之三":478,"之万":178,"ée ":472,"之专":315,"之之":217,"ées":2904,"Vos":497,"Vor":516,"Vol":589,"éc ":283,"Nhể":3766,"Ngể":811,"Viê":165,"évi":139,"Tĩn":188,"ép ":1113,"Zea":402,"Zar":282,"Zam":723,"én ":239,"éo ":609,"éra":396,"ét ":23407,"éri":203,"éné":2942,"Zim":303,"Zel":153,"épa":1146,"Vân":484,"ên ":47944,"êm ":9120,"Yps":167,"Quể":10633,"Yve":176,"並三":153,"Sĩ ":505,"Yor":442,"You":143,"Yon":155,"ênh":268,"êng":589,"专专":219,"专三":225,"êu ":3625,"Yel":146,"三万":220,"三丁":213,"三三":777,"三专":394,"Tô ":277,"Xuâ":498,"三之":347,"Tôn":652,"Túc":179,"丁专":144,"丁丁":142,"Tên":660,"丁三":258,"Tín":160,"丁之":215,"Xuy":470,"ãi ":669,"Syn":143,"Syr":151,"Swi":186,"Swa":238,"Sur":243,"Sum":294,"Sul":327,"Sun":218,"Sud":207,"Str":573,"Stu":169,"Sti":380,"Sto":266,"Sta":800,"Ste":1346,"Ten":237,"Tel":150,"ãnh":975,"ãng":1319,"ão ":484,"Tam":802,"Tan":929,"Tas":235,"Tar":601,"ãn ":565,"Tai":151,"Tak":148,"Ski":144,"ãy ":559,"Khể":614,"Shi":359,"She":144,"Năm":661,"Sho":220,"Sha":353,"Sim":166,"Sil":271,"Sin":736,"Sie":417,"Sib":258,"Sic":157,"Ses":155,"Ser":590,"Sen":317,"Sel":193,"Hươ":208,"Sei":684,"Seg":435,"Sri":344,"TV ":172,"Spa":202,"Spi":140,"Sph":1036,"Spe":218,"Spr":184,"Sou":1403,"Sol":431,"Som":283,"Son":366,"Sor":294,"Kiể":703,"Slo":396,"Nôn":230,"Rus":514,"Nó ":10964,"Sai":3614,"Sam":307,"Sal":1166,"Saa":431,"Sac":786,"Sab":139,"Sco":422,"Sci":154,"Sch":2083,"Sca":289,"Sax":162,"Sav":348,"Sat":196,"Sau":596,"Sar":1013,"Sap":212,"San":1415,"Sao":173,"Hưn":444,"Sa ":225,"TA ":219,"Res":158,"Rhi":678,"Rhe":1850,"Riv":248,"Ris":546,"Rie":160,"Ric":612,"Red":234,"Rei":173,"Reg":216,"Ren":178,"Rep":253,"Rob":306,"Roc":356,"Rou":1296,"Rot":151,"Ros":295,"Rom":626,"SS ":368,"Rhô":1640,"Ven":831,"Vau":301,"Van":289,"Val":1014,"Var":300,"Vic":424,"Vie":766,"Vir":376,"Vil":850,"Vin":383,"Ver":694,"Vex":266,"Ukr":405,"Uni":646,"Miể":206,"Uy ":300,"Utt":447,"Tră":223,"Luể":194,"Trá":373,"Trà":189,"Trâ":155,"Trì":245,"Bưể":300,"Trư":1573,"Uga":441,"Tex":717,"Ter":1194,"Tha":1705,"The":9028,"Thi":2418,"Tho":351,"Thu":1030,"Til":178,"Tim":168,"Tin":432,"Thà":2636,"Thá":3215,"Liể":150,"Thü":723,"Thô":412,"Tiê":963,"Tor":743,"Tok":152,"Tol":222,"Tom":166,"Tou":295,"Thư":1102,"Tru":10246,"Tro":2116,"Tri":2061,"Tre":371,"Tra":816,"Toà":178,"Tuy":629,"Tur":1442,"Tun":141,"Mưể":195,"ày ":41264,"Tươ":169,"àu ":3188,"gểa":154,"gểc":1587,"gểi":5837,"gểp":336,"gểm":3968,"gển":2170,"gểy":212,"gểt":591,"ành":21823,"àng":7133,"gể ":2467,"ào ":9552,"àn ":5519,"àm ":2556,"ài ":40596,"dể ":1928,"bis":208,"bit":429,"biu":210,"bio":195,"biq":379,"bir":196,"bil":353,"bin":1156,"bii":441,"dểa":1072,"dểc":2450,"bo ":249,"dểi":171,"dểm":153,"dển":5451,"dểu":482,"dểy":237,"áy ":2251,"blo":143,"ble":788,"bli":464,"bla":343,"boa":544,"bol":192,"biê":756,"bon":625,"bom":252,"bop":200,"bor":571,"bot":181,"bos":169,"bou":707,"bbe":548,"be ":978,"áo ":4269,"ban":14532,"bal":489,"bai":195,"bac":1588,"bad":244,"bab":362,"án ":11049,"bay":2258,"bat":528,"bas":507,"bar":886,"bao":2943,"bea":250,"áp ":27496,"ánh":4002,"áng":13329,"bi ":208,"bei":269,"bee":755,"bed":546,"bec":391,"ber":5184,"ben":538,"bel":1263,"bek":171,"bes":289,"bet":259,"bfa":299,"áu ":550,"bia":2262,"bic":185,"bid":364,"át ":6081,"ách":6363,"áce":165,"ái ":6094,"ca ":5266,"car":2682,"cas":523,"cat":809,"cau":258,"can":2819,"cao":13635,"cap":271,"cac":552,"cae":343,"cad":152,"cam":352,"cal":1785,"cai":449,"ce ":3602,"ám ":1096,"bri":1032,"bro":469,"bra":914,"bre":597,"bru":440,"bsi":207,"bur":2940,"bul":333,"bun":198,"bum":722,"but":706,"bus":353,"by ":708,"bwe":288,"ác ":24475,"aka":675,"am ":27480,"ake":553,"aki":591,"akh":416,"aji":229,"ajo":231,"al ":6772,"aja":635,"aii":453,"ail":3696,"ain":10996,"air":827,"ais":1435,"ait":246,"ak ":354,"aig":201,"aid":285,"aic":180,"aia":148,"ây ":27201,"ahi":144,"ahu":249,"ahr":141,"aho":292,"aha":852,"agi":293,"agr":420,"agu":637,"agn":2270,"ago":1655,"aq ":141,"anu":911,"anz":946,"any":498,"ano":1266,"ann":1274,"anm":363,"ant":5267,"ans":1570,"ane":1647,"ang":23334,"anh":11504,"ani":4224,"anj":313,"ank":983,"ap ":200,"ana":4781,"anc":3852,"and":17225,"amu":239,"amm":581,"amo":823,"amp":3495,"ams":266,"ami":3273,"ame":2454,"amb":1921,"ama":1996,"ao ":21236,"alz":1868,"aly":679,"alv":524,"alu":519,"alt":1192,"als":583,"alp":280,"alo":1138,"alm":374,"all":4541,"alk":430,"alg":162,"ali":4610,"alc":275,"ald":946,"ale":3407,"alf":143,"ala":5532,"alb":1038,"an ":27435,"aku":180,"ako":211,"aba":1197,"abe":439,"abi":699,"abl":307,"abo":447,"abr":553,"abu":216,"abw":286,"ae ":31054,"aca":592,"aal":305,"aar":275,"ad ":1523,"ac ":1152,"âng":210,"ab ":257,"aft":152,"aff":222,"ai ":10857,"aga":1564,"age":954,"aeo":180,"aen":693,"ael":524,"aes":144,"aer":162,"Vươ":859,"aei":212,"ah ":482,"âte":406,"ado":1640,"adr":334,"adi":656,"âu ":6939,"ade":2368,"aea":378,"aec":197,"ag ":159,"ady":140,"adt":318,"adu":484,"aco":486,"ack":866,"aci":2053,"ach":4974,"ace":5973,"acc":246,"ada":2077,"af ":167,"act":895,"acu":424,"acr":438,"azo":203,"azi":604,"aze":208,"aza":466,"axi":240,"axo":326,"az ":215,"ayo":158,"ays":2306,"aya":1069,"aye":1477,"ân ":71107,"ba ":1967,"âm ":6828,"aqu":368,"at ":2191,"arh":179,"arg":1494,"are":4513,"ard":3817,"arc":1390,"arb":768,"ara":4118,"arp":777,"aro":1967,"arn":2152,"arm":452,"arl":768,"ark":1469,"ari":8943,"aru":469,"arv":290,"arr":2293,"ars":863,"art":4067,"au ":6244,"asa":466,"ary":947,"arz":380,"asi":1358,"ash":1142,"asc":1250,"ase":497,"aso":213,"asp":226,"ask":259,"asm":354,"aon":161,"ar ":3587,"apa":481,"ape":779,"api":791,"aph":710,"apl":205,"apo":627,"app":349,"apt":205,"apu":632,"as ":6065,"ava":1308,"ax ":315,"aux":509,"auv":229,"aut":4199,"avo":316,"avi":854,"ave":987,"awe":151,"ay ":14622,"awa":1004,"awi":403,"ata":3801,"asu":225,"ast":6128,"ass":2666,"atr":716,"ato":1406,"ate":3193,"atc":165,"ati":4840,"ath":1382,"aua":167,"auc":575,"aub":164,"att":609,"ats":390,"atu":1696,"aty":238,"aul":975,"aum":254,"aun":342,"aur":1043,"aus":1014,"aud":522,"aue":262,"aug":153,"aui":145,"bể ":9115,"Wür":527,"bểy":259,"bểt":2371,"bểu":602,"bểi":3447,"bểo":909,"Xã ":2077,"bển":18106,"bểc":10801,"Thể":19271,"Tiể":1514,"Trể":2534,"Vĩn":400,"Xíc":159,"Võ ":184,"cểu":3163,"cểt":394,"cểp":4267,"cểc":593,"cểa":46999,"cển":3734,"cểm":741,"cểi":1406,"Hưể":237,"Vùn":202,"cể ":5697,"Văn":1172,"Sư ":192,"Viể":12501,"Vũ ":518,"Tư ":617,"Tuể":240,"Xô ":542,"Yên":481,"Sơn":1964,"ji ":324,"jar":408,"jan":213,"biể":38109,"jo ":152,"itr":907,"ito":2297,"itu":456,"itt":1509,"its":449,"itz":828,"ity":598,"ism":206,"isl":191,"iso":476,"isp":337,"iss":3448,"ist":3624,"ita":3373,"itc":146,"ite":2019,"ith":2136,"iti":2423,"ivo":162,"ius":1319,"ium":1206,"iva":362,"ix ":837,"ivi":819,"ive":1549,"ipo":143,"ipp":1792,"ipu":171,"ipt":450,"ipi":254,"iph":349,"ipl":287,"ilô":10662,"is ":16454,"ion":4473,"iop":856,"ior":202,"ios":885,"iot":545,"iou":177,"ioi":173,"iol":823,"ipa":1057,"ipe":657,"ir ":1809,"iru":298,"irs":241,"ück":162,"iro":773,"irk":203,"irl":235,"iri":455,"isi":750,"ish":1324,"ise":1480,"isc":1025,"isa":361,"iqu":1196,"ire":3687,"irg":448,"ira":1107,"irc":652,"it ":1527,"ja ":441,"iya":187,"iz ":244,"eón":2056,"가가가":272,"izo":396,"ize":388,"iza":272,"kim":1056,"kil":10715,"kia":494,"kin":3453,"kip":325,"kir":466,"kis":481,"km ":3828,"chể":21772,"ki ":1183,"khi":3505,"út ":627,"khe":165,"kha":834,"khu":15081,"kho":6571,"gày":9377,"gái":216,"kel":215,"ken":731,"kes":174,"ker":740,"ket":226,"key":304,"gân":416,"gây":413,"ke ":634,"úp ":776,"gàn":962,"úng":1614,"kra":492,"kre":255,"kt ":229,"cũn":2434,"ểa":61690,"ku ":366,"km²":641,"kot":155,"kor":174,"kom":159,"kok":195,"ks ":691,"ể ":376292,"úy ":216,"cũ ":497,"kno":896,"kka":183,"khô":4285,"khó":360,"khí":730,"khú":467,"ko ":151,"khá":4090,"kle":735,"kla":228,"buể":254,"ểo":9548,"ểp":25031,"ểk":175,"ểm":59218,"ển":369560,"ểi":112828,"ểc":255331,"ểy":15079,"ểt":179295,"ểu":43805,"kaz":157,"gà ":270,"kat":204,"kar":238,"kas":219,"kan":739,"kal":182,"kam":185,"kai":366,"ka ":1184,"cùn":1840,"cúp":216,"ha ":8300,"ùng":27727,"ham":3795,"han":4769,"hao":550,"hap":378,"hai":4690,"hal":2163,"hau":2057,"hav":347,"har":4673,"has":721,"hat":786,"hae":501,"hag":376,"hab":337,"had":177,"hac":331,"hay":7652,"he ":18327,"dàn":837,"dài":1594,"hel":1664,"hei":3775,"hec":208,"hed":210,"hea":373,"hey":228,"hev":147,"het":420,"hes":679,"her":2719,"heo":10006,"hen":1600,"hem":538,"hi ":13142,"dây":222,"dân":28557,"dãy":398,"căn":327,"hig":332,"hie":278,"hid":1412,"hic":705,"hia":1555,"hip":346,"hio":999,"hin":3454,"him":2986,"ùy ":240,"hil":2244,"hik":232,"hii":300,"hiu":173,"his":1013,"hit":572,"hir":444,"hn ":286,"hla":242,"hle":1267,"hli":520,"hlo":240,"ho ":7256,"hma":350,"gma":174,"go ":1433,"giá":5603,"gme":307,"già":408,"glo":256,"gle":536,"gli":276,"gla":529,"gko":162,"gog":725,"gny":420,"ghĩ":2919,"gno":258,"gni":256,"gne":3863,"giú":291,"gna":708,"úa ":604,"giô":172,"gs ":297,"goz":262,"úc ":3114,"gom":139,"gol":384,"gon":1688,"gos":596,"gor":601,"gov":334,"gu ":148,"goà":839,"gro":663,"gra":1031,"gri":527,"gre":280,"gto":303,"gui":371,"gum":182,"gul":499,"có ":47334,"gua":512,"gue":1969,"gy ":222,"cô ":368,"guy":4577,"gur":185,"gus":453,"gun":159,"còn":3275,"úi ":1356,"côn":4644,"gyr":164,"iai":626,"iam":328,"ial":1014,"iao":1227,"ian":5609,"ias":397,"iar":265,"iat":696,"ic ":3037,"iac":1407,"iae":280,"ibl":173,"ibi":314,"ibo":164,"ibu":345,"id ":1469,"iba":306,"ibb":546,"ibe":1206,"ia ":29704,"iet":540,"ieu":473,"iel":1226,"ien":2075,"ier":2747,"ies":4767,"ied":1831,"ieg":187,"ig ":1226,"ifo":1413,"iff":148,"ife":614,"ifl":166,"ifi":693,"icr":1054,"ics":295,"ict":897,"icu":1741,"ico":2316,"ick":622,"ici":3591,"ich":3932,"ice":765,"ie ":3741,"ica":6048,"idu":239,"ids":175,"ido":567,"idi":2598,"ide":2455,"ida":26239,"iid":4750,"il ":3121,"ija":174,"iji":157,"im ":5476,"ika":371,"ige":770,"iga":742,"ii ":1370,"igm":416,"igh":923,"igi":710,"igu":318,"igs":187,"igr":220,"igo":300,"ign":1169,"iha":223,"ik ":169,"imo":742,"imm":158,"imp":567,"ime":1906,"imi":643,"ip ":810,"inc":1322,"ind":1704,"ina":4704,"inb":264,"imu":305,"inn":513,"ino":1469,"int":4526,"ins":1803,"inf":237,"ine":10837,"inh":13778,"ing":8141,"ini":3074,"inl":2046,"ink":351,"ioc":292,"iod":167,"inu":932,"inv":156,"inx":181,"iny":208,"iko":368,"iki":420,"ike":257,"ila":1297,"ilb":181,"in ":13262,"ilo":550,"ill":9682,"ilh":181,"ili":3385,"ild":355,"ile":3779,"ima":1310,"imb":551,"io ":1175,"ily":2239,"ils":2324,"ilu":323,"how":204,"hol":800,"hom":456,"hon":2401,"hoi":164,"hos":411,"hot":229,"hou":479,"hoo":159,"hop":241,"hor":2606,"hoa":5214,"hof":203,"hoe":206,"hod":441,"hoc":207,"hni":161,"hne":266,"dée":277,"hme":233,"hmi":203,"hiê":5040,"dép":1137,"hua":252,"htt":326,"htr":324,"hth":197,"hte":186,"hst":227,"hse":1600,"hoá":860,"hoà":1969,"hu ":18061,"hry":423,"hro":1154,"hre":321,"hri":577,"ùa ":1067,"ht ":687,"hra":468,"hya":190,"huê":158,"hyl":1269,"dòn":604,"hy ":171,"hwa":665,"hwe":313,"hum":443,"hun":1586,"hus":902,"hut":182,"hur":289,"huy":20578,"Vưể":237,"dùn":1738,"dù ":368,"hyt":176,"hys":223,"hyr":202,"huô":174,"ùi ":234,"ffe":313,"ffi":237,"fer":812,"báo":721,"bác":152,"fen":465,"bán":1218,"fel":1035,"fgh":188,"bà ":200,"fas":191,"far":156,"fam":2105,"fal":2041,"bày":158,"bàn":328,"bào":422,"bài":1285,"ff ":218,"eya":142,"ext":206,"eyr":325,"eyh":211,"eye":179,"exa":986,"ez ":316,"exi":1325,"exc":181,"ezu":350,"ezi":175,"eta":842,"ete":743,"eti":1014,"eth":666,"etn":165,"etl":616,"esp":684,"esn":283,"eso":340,"est":3808,"ess":1434,"esw":957,"ev ":202,"euc":337,"eud":540,"eui":263,"eum":201,"eto":465,"etr":999,"ets":459,"ett":1071,"etu":203,"etw":156,"etz":312,"ew ":2560,"eve":622,"eva":566,"evi":1144,"euv":222,"eut":564,"eur":1318,"eus":1354,"ex ":606,"euz":190,"eux":671,"ey ":1664,"ewa":232,"erö":586,"epe":234,"epi":495,"eph":665,"er ":9592,"epa":418,"eot":213,"eor":527,"eom":471,"eol":262,"eop":530,"eon":709,"es ":26910,"ept":1404,"epu":235,"epo":154,"erk":202,"erl":752,"eri":6361,"erg":3169,"erh":199,"ere":2445,"erf":557,"erc":1171,"erd":573,"era":3401,"erb":858,"et ":4591,"equ":162,"esl":202,"esh":1269,"esi":2021,"esc":975,"ese":753,"eu ":303,"esa":259,"erz":260,"ery":556,"erv":528,"eru":1012,"erw":278,"err":2985,"ert":1566,"ers":4623,"ern":4630,"erm":2107,"erp":282,"ero":2376,"eki":196,"en ":12018,"elb":206,"ela":2654,"eld":1258,"elf":146,"ele":1267,"eli":1798,"elg":160,"elm":262,"elk":404,"ell":9746,"elo":933,"elu":208,"els":642,"elt":280,"ely":341,"eo ":10593,"eiß":164,"emb":1047,"ema":1158,"eme":2947,"emm":256,"emo":539,"emi":1585,"emp":238,"ems":155,"emy":139,"enf":291,"ene":1945,"enh":484,"eng":730,"enb":2082,"ena":1558,"end":2473,"enc":2127,"eno":956,"enn":3389,"enk":343,"enl":192,"eni":2073,"enu":1664,"ens":4503,"ent":10489,"enr":274,"enz":420,"eny":515,"eoc":157,"ego":1228,"ege":478,"egg":139,"egi":670,"egr":229,"egu":327,"ek ":217,"eic":752,"eis":833,"eir":787,"eim":1035,"eil":952,"ein":4903,"eie":545,"eid":730,"eig":203,"eif":191,"el ":3452,"eiz":186,"eit":258,"em ":1658,"öst":587,"giu":194,"gis":185,"gil":310,"gin":1363,"gio":553,"gid":1547,"gic":199,"gia":8820,"ght":794,"băn":187,"gho":161,"ghi":3850,"ghe":189,"gha":488,"ggi":146,"gge":165,"câu":470,"cây":1629,"gi ":387,"gen":5062,"cán":798,"cáo":198,"ger":1519,"ges":1085,"gh ":607,"các":18946,"geb":333,"cái":701,"gem":243,"gel":544,"cá ":1776,"ge ":1808,"gae":147,"gai":1612,"gas":1474,"gar":1812,"gau":202,"gat":452,"gay":317,"gam":376,"gal":707,"gan":1692,"gap":295,"ga ":2819,"bút":167,"Tưể":239,"fur":264,"fus":239,"bón":2056,"ful":164,"fun":375,"ft ":439,"fra":309,"fre":507,"fri":815,"bín":794,"fro":1604,"fou":879,"for":2385,"fon":152,"fol":504,"bìn":10852,"bên":1143,"bí ":160,"fle":146,"fla":250,"fli":289,"flo":441,"fly":418,"fic":547,"fie":487,"fil":195,"fin":314,"fis":489,"da ":3697,"de ":8611,"dac":762,"dad":140,"dal":972,"dai":189,"dag":446,"dae":24708,"dat":480,"dar":398,"dap":183,"dan":4922,"dam":377,"cun":718,"cul":2298,"cum":328,"cua":546,"cty":284,"ctu":2164,"ctr":238,"cto":873,"cti":1458,"cte":647,"cta":670,"cy ":251,"cus":673,"cur":399,"cut":255,"cyc":140,"cks":263,"cki":166,"ckl":786,"cla":486,"chá":201,"cle":346,"châ":14860,"cky":262,"chí":8076,"chò":225,"clu":420,"chó":180,"cli":182,"ché":314,"chì":193,"clo":464,"chù":312,"co ":1548,"chú":1406,"coi":717,"cod":256,"coa":287,"cob":146,"coc":214,"con":3655,"col":1035,"com":2135,"cor":1035,"cos":565,"cop":801,"cot":443,"cou":1134,"coz":183,"cs ":366,"ct ":454,"cre":241,"cra":438,"chơ":592,"cri":479,"cro":1725,"chư":1623,"ccu":244,"cci":838,"cco":265,"cca":156,"cea":4824,"ch ":37737,"cer":1071,"ces":531,"cet":142,"cen":1512,"cep":386,"Xươ":220,"cel":1002,"ced":395,"cha":3033,"chw":543,"chu":6009,"chy":360,"cia":1452,"ck ":1564,"cie":3416,"cid":2524,"che":4294,"chl":1776,"chi":13490,"cho":7644,"chm":217,"chn":259,"chs":1959,"cht":448,"chr":711,"cil":2248,"cif":277,"cis":311,"cit":448,"cin":1085,"cio":750,"cip":1009,"cm ":153,"cke":753,"ed ":4935,"eba":285,"ebe":884,"ôn ":3722,"ebi":183,"ebo":301,"ebr":934,"ebs":216,"ebu":294,"ec ":362,"eac":334,"ôm ":271,"eag":170,"eaf":201,"eae":4646,"ead":460,"ean":1098,"eal":621,"ear":1037,"eas":698,"eat":882,"eau":1120,"eb ":303,"ea ":3947,"efo":223,"efe":249,"ei ":970,"ega":773,"een":1179,"eel":145,"eed":257,"ees":218,"eer":175,"eep":145,"eet":728,"edi":1118,"ede":1955,"ône":1757,"ông":42975,"eda":404,"eg ":341,"edt":284,"edo":1988,"edr":212,"eck":1046,"ech":639,"eci":3537,"ece":167,"eca":304,"ee ":1150,"ôme":730,"ecu":225,"ect":1210,"eco":767,"dwi":249,"dwe":183,"dwa":258,"dy ":278,"dur":468,"dus":275,"duy":1143,"ôi ":2569,"dor":2168,"dop":306,"don":2791,"dom":306,"dol":520,"dow":395,"dov":304,"dou":172,"dos":360,"ds ":1070,"doa":646,"doc":1372,"dog":488,"dun":458,"dul":398,"duc":230,"dri":731,"dra":523,"dt ":665,"dre":808,"du ":1084,"dro":986,"dha":326,"dge":229,"dic":469,"did":312,"dia":1872,"ôte":1594,"der":3477,"des":3199,"ômé":10659,"dea":701,"ded":323,"dec":231,"del":1465,"den":4157,"dem":911,"deo":220,"di ":3427,"dle":656,"dla":192,"do ":4210,"diu":260,"din":1244,"dio":353,"dis":2108,"dit":379,"die":2847,"dil":249,"rgy":150,"rgu":287,"rhe":221,"rha":208,"rho":196,"rga":532,"ri ":2301,"rgi":1202,"rgh":152,"rge":1773,"rgo":1290,"rgn":567,"ret":1055,"res":3724,"rev":398,"reu":912,"rex":297,"rey":288,"rfa":190,"rfl":255,"nân":179,"rdu":164,"rds":270,"rdr":159,"này":31504,"rg ":4949,"reb":939,"rea":2006,"ree":1006,"ref":247,"rec":523,"red":781,"rei":1635,"reg":1203,"rem":776,"ren":4076,"rel":1428,"rer":300,"reo":199,"rep":265,"rf ":1207,"rda":570,"rcu":715,"rct":554,"rdo":799,"nào":548,"rdi":1755,"rde":2543,"re ":9446,"rbu":335,"rco":417,"rci":274,"rch":1874,"rce":427,"rca":280,"ray":496,"raz":574,"rd ":2860,"rao":655,"rap":552,"raq":160,"rar":494,"ras":1804,"rat":1838,"rau":875,"rav":215,"rbi":1026,"rbo":389,"rba":580,"rbe":418,"rai":3535,"rah":190,"rag":1656,"ran":8266,"ram":1112,"ral":2485,"rak":217,"rab":584,"raf":217,"rae":749,"rad":1615,"rac":3183,"rpu":270,"rpo":754,"rs ":2330,"rpe":165,"rpa":404,"rpi":173,"rph":340,"ror":201,"ros":1675,"rot":1221,"rom":2423,"ron":57984,"lĩn":607,"roo":669,"rop":3656,"roy":149,"rou":1200,"rov":1781,"row":593,"rob":744,"roa":358,"rod":644,"roc":1935,"roi":481,"rol":951,"rof":216,"rog":648,"nên":713,"rno":358,"rns":159,"rna":1180,"rne":2695,"rni":1419,"riè":172,"ném":189,"riê":408,"rmo":497,"rms":184,"ro ":929,"rma":3617,"née":2905,"rme":709,"rmi":637,"rly":155,"rlo":157,"rli":457,"rld":399,"rle":351,"rla":627,"rn ":3576,"hơn":1695,"hơi":801,"rki":204,"rke":393,"rka":202,"né ":169,"rm ":302,"riz":418,"rix":394,"rl ":161,"rip":365,"rio":1072,"rit":3591,"ris":2983,"riv":318,"riu":456,"rig":1218,"rii":3008,"ril":1020,"rin":4090,"rim":450,"ria":5391,"rib":1175,"ric":5324,"rid":4461,"rie":2155,"rif":320,"rk ":1670,"hơ ":851,"rwe":155,"nói":685,"rz ":208,"hư ":5084,"nôn":377,"rya":216,"ryc":442,"rug":231,"rue":707,"ruc":377,"rup":171,"run":25178,"rum":705,"rul":242,"ruy":2675,"ruz":213,"rus":1414,"rva":295,"rvi":473,"rve":224,"rwa":347,"ry ":2417,"rsi":891,"rso":252,"roß":201,"rsc":361,"rsd":187,"rsa":1123,"rsb":257,"rsh":319,"rse":899,"rta":737,"óc ":726,"rst":546,"rto":415,"rtb":145,"rte":1749,"rth":2805,"rti":1215,"nó ":2643,"rub":265,"rts":371,"rtr":430,"rtu":180,"rtt":513,"rt ":1957,"óa ":2701,"rqu":185,"rro":1564,"rrh":197,"rri":1788,"rre":2216,"rra":3074,"ru ":477,"rry":300,"rru":147,"sab":140,"sac":1864,"sai":281,"sak":172,"sal":439,"sam":384,"sba":297,"sbe":425,"sao":776,"óng":4090,"san":1255,"sau":2887,"sat":228,"sas":328,"sar":660,"oà ":337,"óp ":288,"sa ":2015,"núi":1191,"óm ":1521,"ón ":2564,"rze":166,"hưa":582,"rys":387,"ryo":172,"ryp":167,"ryl":162,"ói ":993,"ryn":172,"hưn":1523,"sha":619,"năm":27971,"năn":1182,"sho":293,"shr":233,"sht":381,"she":876,"shi":1264,"si ":634,"oãn":159,"sge":580,"sie":368,"sid":739,"sic":687,"sia":3700,"sk ":591,"shw":300,"shu":294,"sit":709,"sis":3021,"sip":265,"sin":5091,"sio":465,"sil":1895,"sim":553,"sii":258,"sif":151,"sig":220,"scr":307,"scu":281,"òng":2223,"oài":34230,"oàn":5706,"sdo":465,"sbu":460,"se ":4575,"oá ":380,"sca":1351,"sce":236,"sci":1194,"sch":1792,"sco":719,"sey":198,"ser":1028,"ses":272,"set":418,"oát":273,"seu":551,"sh ":1939,"sfe":321,"sea":715,"sei":161,"see":284,"sed":245,"sec":229,"sep":202,"sen":3196,"oán":1638,"sem":1371,"sel":2101,"hươ":4318,"spo":375,"shū":247,"spr":259,"sph":157,"spe":3907,"spi":1229,"spa":351,"sot":292,"sou":945,"sol":467,"som":376,"son":1789,"sop":308,"sor":191,"sof":194,"soi":556,"soc":217,"su ":286,"sra":294,"st ":2960,"squ":256,"ss ":872,"sli":218,"sky":167,"kiể":2684,"sla":1569,"sle":323,"ski":288,"sks":212,"khể":3237,"ska":369,"sna":2980,"sni":207,"sne":250,"smo":583,"siê":264,"so ":947,"sma":1028,"smi":179,"swi":1048,"syn":165,"syl":224,"sse":3231,"soá":206,"ssa":1676,"sso":1413,"ssi":3339,"ssu":544,"ste":5951,"stf":168,"sth":161,"sta":3335,"sto":2068,"stp":174,"sti":4685,"stl":165,"stu":445,"str":4349,"sts":262,"sty":144,"sub":863,"sul":490,"sum":304,"sup":191,"sun":266,"sus":998,"sur":1961,"suy":191,"òa ":5602,"sy ":172,"swa":243,"tai":3180,"tak":236,"tal":2442,"tae":263,"tag":338,"tah":173,"tab":252,"tac":777,"tad":502,"tay":436,"tax":151,"tau":185,"tat":1298,"tas":231,"tar":1441,"tap":149,"tan":2995,"tam":442,"tch":446,"òm ":317,"te ":8300,"tbu":170,"òn ":4112,"ta ":6742,"ký ":793,"ozè":153,"pa ":420,"làm":1846,"làn":610,"lá ":624,"pe ":1111,"par":2272,"pat":396,"pas":155,"là ":152991,"pac":448,"pag":1801,"pal":1430,"pan":1032,"phe":584,"pha":2087,"phu":325,"phr":290,"pho":3352,"phn":208,"phi":5842,"pi ":273,"lãn":895,"ph ":150,"lâu":392,"lâm":192,"pea":417,"pec":3297,"ped":468,"pen":678,"per":2665,"pet":646,"pes":3121,"pel":638,"pla":748,"hiể":23255,"pli":245,"phâ":2752,"phá":7538,"ple":773,"lès":368,"phí":12064,"phê":328,"plo":417,"phé":481,"phò":631,"phó":453,"phy":787,"pia":524,"pid":686,"pic":879,"pie":144,"pil":547,"pin":2627,"pio":231,"pir":455,"pis":429,"pit":358,"por":1000,"pop":359,"pot":426,"pos":699,"pom":618,"pon":447,"pol":658,"poc":162,"pod":1012,"ps ":851,"hū ":248,"ppi":1358,"ppo":224,"ppe":777,"phú":224,"po ":176,"lí ":1217,"lên":761,"pta":227,"pse":181,"psi":853,"pso":273,"ptu":208,"pua":385,"pub":253,"puc":309,"pte":1527,"pti":1324,"pto":542,"ptr":151,"pra":304,"hoể":8808,"pt ":251,"phư":1981,"pri":732,"pre":749,"pro":835,"huể":53256,"lôn":185,"lôm":10657,"pur":817,"pus":345,"pun":212,"pul":573,"lô ":685,"px ":1130,"pyr":166,"lý ":2650,"lúc":371,"mà ":1433,"màn":167,"máy":1955,"mã ":867,"màu":877,"mét":23053,"méo":221,"mìn":517,"qua":5837,"mô ":773,"quy":3085,"que":2033,"qui":2180,"món":229,"môn":561,"môi":520,"quâ":3680,"quá":966,"quê":311,"quý":155,"mùa":374,"ra ":16536,"ngo":2830,"ngi":1741,"ngl":604,"ngk":252,"ngu":5422,"ngr":255,"ngt":407,"ngs":604,"ni ":1381,"nge":3237,"ngh":7783,"nga":2179,"nho":251,"ndé":306,"nhu":514,"nha":2433,"nhi":5815,"nhe":263,"neg":239,"nei":512,"nel":1599,"nen":680,"nem":262,"neo":282,"ner":1201,"net":904,"nes":4373,"nev":164,"neu":463,"ng ":357107,"nea":1462,"neb":278,"nec":300,"ned":346,"nee":182,"nfo":163,"ney":270,"nez":428,"nh ":132657,"nfe":333,"nct":449,"nco":534,"nci":1276,"ncl":257,"nce":3207,"nch":2383,"nca":570,"ne ":19277,"nbu":1513,"ndu":416,"ndr":1581,"nds":990,"ndo":2398,"ndl":619,"ndh":176,"ndi":4609,"nde":3318,"nda":1999,"ncy":170,"nal":1151,"nam":13111,"nan":913,"nar":774,"nac":1244,"nad":927,"nae":1024,"nag":697,"nai":3249,"nbo":145,"nbe":462,"nd ":12230,"nba":380,"nav":164,"nau":516,"nat":2078,"nas":580,"nay":2459,"na ":6835,"iúp":291,"가 ":328,"cư ":415,"iôn":176,"myc":163,"nya":523,"nyi":193,"nz ":267,"ny ":1333,"nvi":479,"nx ":222,"nul":298,"num":443,"nus":3075,"nut":506,"nty":550,"nto":2015,"ntu":367,"nts":334,"ntr":2166,"nti":3110,"nth":1365,"ntl":140,"nta":3026,"nte":4904,"nsu":730,"nsy":214,"nso":325,"nst":981,"nsf":180,"nse":669,"nsh":461,"nsi":2204,"nsl":567,"nsk":139,"nsc":152,"nsa":421,"nsb":373,"như":5336,"nt ":8221,"ngư":22262,"nqu":229,"ns ":3001,"noc":411,"nod":303,"hĩa":2885,"nob":365,"nol":370,"noi":432,"nop":786,"nom":551,"non":799,"not":862,"nos":776,"nor":939,"now":1063,"nov":236,"nou":281,"nne":5126,"nna":750,"nno":345,"nni":716,"nns":289,"nma":453,"niê":790,"nhâ":2593,"nn ":413,"nla":2159,"nhá":489,"nhà":6343,"nhó":1299,"nly":637,"no ":1110,"hĩ ":710,"nhì":354,"ngâ":223,"nke":271,"nki":377,"ngà":10009,"nka":598,"ngô":1896,"nkt":202,"nja":290,"nii":438,"nig":289,"nif":242,"nie":473,"nid":3745,"nic":2037,"nia":5524,"nk ":242,"nix":164,"niu":181,"niv":273,"nis":1435,"nit":1158,"nio":409,"nim":283,"nin":1178,"nik":149,"nil":357,"ogr":267,"ogu":214,"ogi":228,"ogl":349,"ogo":319,"ogn":1408,"oga":317,"oge":346,"oi ":1139,"ohn":303,"oha":229,"ohe":168,"ogy":195,"ois":1103,"oir":3370,"oit":1455,"oin":300,"oil":149,"oid":1389,"oie":174,"ok ":359,"ol ":657,"oce":820,"och":1882,"oci":330,"ock":741,"ocl":146,"oco":568,"ocr":154,"obu":172,"oe ":211,"oca":1110,"occ":493,"ode":1045,"odi":450,"odo":1089,"odr":210,"oct":1918,"ocy":317,"of ":6954,"oda":691,"dươ":848,"oen":367,"odu":285,"oed":204,"og ":551,"oft":282,"off":252,"ofe":161,"oa ":13629,"oc ":1250,"oan":1921,"oad":230,"oba":818,"od ":1168,"oar":504,"oas":324,"oat":240,"obo":175,"obr":145,"obl":325,"obi":968,"obe":655,"nym":211,"nza":905,"nze":176,"oya":255,"oxy":147,"oxi":202,"oz ":147,"guể":1293,"ows":383,"owl":142,"own":1769,"owi":183,"ozo":255,"oza":724,"otu":288,"oud":174,"oub":187,"ouc":419,"oua":154,"ow ":1038,"oti":1060,"oth":1496,"ote":697,"ott":720,"ots":282,"otr":764,"oto":966,"ost":2982,"osu":324,"ota":1031,"ov ":258,"osi":491,"osh":227,"ose":2073,"osg":493,"osp":425,"oss":826,"osm":547,"oso":413,"osn":140,"oy ":273,"owe":547,"ovi":954,"ovo":159,"ouv":263,"oux":242,"ova":705,"ove":2204,"oug":763,"oui":391,"oul":679,"oun":2537,"oup":387,"ous":2368,"our":3149,"out":2276,"opo":1519,"opp":188,"opi":1120,"opl":220,"ope":1422,"oph":3191,"opa":411,"os ":2470,"opu":314,"opt":1403,"ops":1255,"oon":440,"ool":189,"oom":247,"ook":283,"oog":197,"ood":513,"or ":3376,"oot":347,"oor":232,"ork":631,"orl":473,"orm":2975,"orn":1953,"oro":870,"orp":1047,"orr":2602,"orc":598,"ord":3003,"ore":2045,"orf":1239,"org":708,"ori":3584,"ou ":1707,"osa":1094,"osc":366,"ort":2762,"ors":1266,"oru":667,"ory":1225,"kín":427,"kíc":629,"ot ":1197,"goể":939,"m² ":639,"orb":599,"ora":2404,"oqu":150,"ola":2194,"old":517,"kê ":1566,"giể":12764,"on ":15999,"oli":2444,"oll":1993,"olf":295,"ole":1581,"ols":1043,"olt":149,"olm":148,"olo":2220,"oly":684,"olz":312,"olu":1314,"olv":159,"oka":251,"ghể":2336,"om ":2129,"okk":143,"oki":163,"oke":162,"oku":288,"ona":2358,"ond":2416,"onc":461,"onf":214,"one":2805,"ong":59905,"oni":4577,"onl":675,"onn":2036,"kên":176,"ono":1589,"ons":1629,"ont":3656,"onu":697,"onv":312,"ony":549,"gũ ":341,"kí ":158,"oma":3160,"oo ":152,"ome":1667,"omb":1058,"omi":1212,"omm":2408,"omp":760,"omo":798,"kéo":312,"omu":461,"omy":255,"op ":502,"kì ":200,"la ":10761,"ính":11878,"ín ":1003,"há ":535,"le ":10516,"lca":204,"ít ":628,"lch":163,"lf ":224,"lde":761,"ldb":159,"lda":161,"hào":150,"ldo":198,"hàn":21780,"hàm":435,"hài":213,"ldi":250,"lab":417,"lac":1406,"lad":738,"lae":401,"lah":182,"lag":424,"laj":292,"lai":1546,"lal":167,"lan":10384,"lam":1066,"lap":209,"lao":259,"lar":4422,"lat":2293,"las":1229,"law":585,"lau":512,"lav":645,"lay":1413,"lba":423,"hà ":7105,"ld ":1873,"lbe":635,"lbi":189,"lbo":527,"lbu":797,"gô ":876,"góc":144,"ky ":446,"ích":17834,"cuể":3904,"gôi":662,"góp":269,"gôn":1009,"hìn":3185,"llé":141,"hìm":147,"lpe":2886,"lpi":216,"lph":225,"ls ":3004,"híc":534,"hía":11942,"lok":158,"lon":3179,"lom":1001,"lop":1213,"lor":1602,"lod":250,"loc":750,"loe":167,"log":693,"loi":242,"los":940,"lot":496,"lou":372,"lov":598,"low":793,"hêm":276,"lob":302,"hí ":2215,"liê":1520,"hép":885,"lmo":317,"lme":324,"lma":282,"hì ":1109,"lti":486,"lto":187,"hó ":498,"lud":253,"luc":198,"lue":351,"lso":351,"lst":1066,"lta":363,"lte":462,"lu ":183,"lse":196,"loà":31500,"lsa":619,"ía ":12221,"hín":8169,"lt ":1144,"lhe":150,"lha":193,"hãn":1016,"lge":195,"li ":845,"lga":417,"hât":447,"hâu":5143,"hân":32338,"hâm":245,"lfe":172,"ley":541,"lex":375,"leu":725,"lev":279,"les":4804,"hát":4309,"let":890,"ler":1633,"leo":683,"háo":303,"lep":286,"háp":24791,"hám":208,"lem":456,"len":2814,"hán":13040,"lel":163,"lei":443,"hái":3807,"leg":371,"lef":140,"led":786,"hác":3511,"lec":514,"leb":324,"lea":958,"lls":526,"llu":1871,"lly":728,"lo ":703,"lla":8252,"llb":208,"lle":6069,"lli":4980,"llo":3130,"lks":330,"hê ":529,"diể":17680,"lka":390,"lm ":305,"ll ":2030,"hè ":211,"lit":1006,"lis":1811,"lip":1960,"lio":1480,"lin":3515,"lim":803,"liz":196,"liv":616,"liu":661,"lic":1528,"lid":3931,"lia":3554,"lk ":142,"lik":204,"lii":571,"lig":457,"lie":1623,"lif":1017,"ma ":3578,"húa":466,"húc":1589,"hún":1289,"hút":209,"húy":143,"mb ":269,"ìm ":8521,"mac":644,"mai":885,"maj":203,"mad":498,"mae":190,"ìn ":392,"mag":301,"hür":727,"mar":2810,"mas":488,"mal":1566,"man":6200,"maz":173,"mat":1698,"mba":981,"mbl":196,"mbi":1974,"mbe":1329,"mbr":351,"mbo":504,"me ":3769,"iá ":976,"iße":139,"mbu":270,"ình":20204,"iàn":475,"med":457,"meg":343,"mea":185,"iác":256,"mec":144,"met":1158,"iáp":2001,"mes":1080,"mer":2891,"iám":415,"mem":171,"mel":1053,"iáo":2698,"ián":260,"men":4045,"mei":235,"luy":242,"hòa":4573,"lva":958,"hô ":347,"lve":227,"lvi":160,"lul":235,"lun":153,"lum":1803,"lut":702,"lus":2401,"ly ":5413,"hóa":2227,"hòm":296,"hòn":1026,"lz ":1932,"hôi":152,"hón":422,"hóm":1446,"hôn":8959,"luô":144,"lyp":567,"lym":264,"lyn":185,"hù ":377,"hú ":960,"hùn":400,"hùa":429,"mpi":548,"mph":909,"mpe":699,"mpr":166,"mpo":339,"mpl":212,"mpu":526,"mps":257,"ms ":540,"moc":217,"mod":141,"mon":2835,"mop":418,"mol":919,"mor":1191,"mos":484,"mot":349,"mou":592,"mpa":2137,"mu ":149,"mua":252,"mst":192,"my ":346,"mur":466,"mus":478,"mul":387,"mun":1488,"hăm":190,"hăn":308,"mi ":443,"min":2275,"mil":2845,"mir":352,"mis":870,"mit":1161,"cơ ":2355,"mic":1181,"mib":195,"mia":637,"mie":192,"mid":343,"mo ":242,"ièr":623,"mm ":173,"iêu":3120,"mni":139,"iêm":793,"iên":15316,"mno":232,"mmu":465,"mmi":508,"miê":868,"mmo":992,"mma":550,"mme":1127,"xâm":158,"xây":774,"xã ":6613,"xác":753,"thể":105642,"tiể":16334,"vĩ ":1285,"Để ":4107,"suể":581,"Đểt":393,"Đểu":259,"Đểa":425,"Đểc":8666,"Đểi":2655,"Đển":2345,"Đểo":612,"văn":2376,"soể":246,"vô ":966,"vòn":456,"zue":365,"zur":1019,"ruể":225,"võ ":369,"hưể":6739,"vùn":22597,"vây":180,"vào":6478,"vàn":747,"zen":390,"zel":179,"zer":396,"ze ":541,"vài":326,"và ":39376,"zam":416,"zan":947,"zak":194,"zar":156,"ví ":164,"zon":909,"zo ":189,"vì ":1170,"zna":154,"riể":3937,"zia":217,"zie":194,"zin":147,"zil":497,"yré":2878,"yx ":207,"yth":348,"yst":455,"yso":284,"ysi":882,"yri":846,"yro":276,"yra":354,"yrg":171,"yre":315,"ys ":1775,"yph":446,"ypt":526,"ypr":406,"ypo":300,"ype":314,"yon":322,"uý ":440,"za ":604,"gưể":22834,"uôn":11800,"uôi":272,"quể":14720,"ye ":286,"uá ":683,"yca":261,"yce":225,"ych":303,"ycl":287,"yco":153,"yct":483,"ydr":465,"yer":937,"uán":332,"yen":509,"ya ":1624,"yat":304,"yan":957,"yal":151,"uê ":487,"yla":353,"yle":207,"yli":383,"yll":1078,"ylo":482,"ylv":243,"ylu":187,"yma":185,"sĩ ":1783,"yo ":184,"yme":163,"ymp":602,"ymn":164,"yna":220,"yne":184,"yno":257,"uân":5407,"yi ":308,"tăn":371,"yho":211,"yin":196,"tín":2825,"để ":24120,"tíc":15647,"đểy":569,"xtr":322,"đểu":7023,"đểt":4542,"đểa":6133,"đểi":9089,"đểc":6272,"đển":28910,"đểo":4093,"đểp":378,"đểm":552,"tên":7356,"tìn":624,"tìm":8334,"xon":351,"xoa":253,"tù ":245,"tô ":345,"tòa":324,"xuy":162,"xun":238,"tôn":573,"săn":488,"xi ":160,"tây":9977,"tâm":1507,"tán":178,"xem":772,"tác":2521,"tái":142,"tàn":309,"tàu":1978,"nơi":1970,"phể":19501,"xil":335,"xin":153,"xic":980,"xa ":336,"tài":1059,"xce":150,"xe ":304,"xas":712,"xan":855,"ww ":171,"www":171,"són":349,"sôn":1977,"wo ":144,"yểu":888,"yểt":2656,"yển":27686,"sên":250,"wn ":1674,"sèr":449,"ws ":411,"wor":456,"woo":295,"we ":324,"sân":742,"wes":568,"wer":566,"sáu":219,"sát":605,"wen":170,"sán":1258,"wel":193,"wei":504,"wed":169,"wee":268,"web":356,"sác":1906,"whe":719,"whi":453,"răn":535,"sâu":259,"wi ":419,"wit":1057,"wig":1125,"wid":265,"wic":172,"win":477,"wil":183,"rös":588,"lưu":884,"vuô":11318,"dưể":1608,"rùn":419,"wa ":340,"rúc":638,"wan":646,"wal":651,"way":264,"wat":547,"war":864,"was":494,"wai":552,"rüc":145,"ría":161,"vre":519,"rò ":634,"vua":1478,"vul":314,"rõ ":263,"ròn":162,"rôm":369,"via":1024,"vir":262,"vil":2132,"vin":903,"vig":163,"vic":424,"vid":453,"vie":338,"ngể":4112,"vit":212,"vis":359,"nhể":20937,"ré ":197,"niể":631,"rén":2896,"viê":2261,"rì ":216,"rên":16855,"rí ":838,"voi":343,"vol":291,"von":231,"vor":176,"rìn":2591,"vi ":814,"râu":162,"rãi":238,"ver":2511,"ves":443,"vet":169,"ràn":171,"rào":384,"rái":592,"rán":159,"ven":2308,"vel":746,"rác":292,"ve ":1535,"val":496,"vak":211,"van":1011,"var":683,"vat":444,"rà ":170,"vad":360,"vai":638,"va ":1421,"uyê":4853,"cưể":274,"uze":169,"uzn":158,"uya":181,"uxe":167,"uxo":172,"muể":253,"ux ":1397,"uvi":315,"uve":890,"uy ":4510,"usk":685,"ush":495,"usi":1086,"use":2256,"usc":486,"usa":422,"usu":188,"ust":2067,"uss":2125,"utm":305,"uth":2069,"uti":986,"ute":4039,"uta":488,"utt":513,"uts":241,"utu":168,"uto":356,"us ":12540,"ut ":1468,"urb":527,"ura":1745,"urc":370,"ure":2141,"urg":4458,"uri":3154,"urk":298,"urn":505,"uro":993,"urp":172,"urr":1188,"urs":436,"urt":1515,"uru":494,"ury":261,"ur ":3979,"uph":337,"upi":208,"upe":461,"upl":256,"umi":350,"umo":202,"uma":655,"umb":1047,"ume":427,"unt":1093,"uns":220,"uni":1404,"unn":257,"unc":850,"und":2117,"una":410,"ung":28650,"une":861,"up ":561,"uki":214,"um ":5338,"ulu":810,"ult":827,"ulo":594,"ulm":200,"ull":475,"uli":2981,"ulg":343,"ule":468,"ulc":170,"ula":2994,"ulb":224,"miể":7160,"un ":876,"uid":1911,"uil":817,"uin":1133,"uis":537,"uit":1805,"ul ":704,"ugh":635,"uge":202,"ugl":142,"ui ":422,"uga":249,"ugu":343,"uco":341,"uct":140,"ucu":155,"uda":464,"ude":797,"udi":503,"ubs":175,"ubr":196,"uca":423,"ue ":2123,"uce":268,"ucc":527,"uci":266,"uch":1204,"ucl":244,"uck":465,"uet":161,"uev":189,"uer":585,"ues":940,"uff":186,"udo":607,"udw":163,"uee":563,"ued":1142,"ueb":187,"uen":891,"uel":938,"ub ":179,"ua ":4516,"uay":450,"uat":643,"uar":339,"ual":262,"uan":4521,"ubi":473,"ubl":385,"ube":682,"ubf":310,"uba":515,"ud ":256,"uai":209,"uad":968,"tze":378,"tyl":438,"typ":380,"bưể":9335,"trư":5334,"trù":418,"ty ":2056,"trú":686,"trò":743,"trí":887,"trì":2564,"trê":16809,"trá":625,"trà":444,"tvi":145,"tuy":1965,"tur":1038,"tus":1579,"tut":187,"tui":1819,"tul":991,"tun":226,"tum":525,"tud":242,"tuc":215,"luể":1046,"tz ":904,"two":235,"tră":326,"ts ":2029,"lũn":205,"tre":2316,"loể":3367,"tt ":262,"tra":13075,"thơ":816,"tri":6787,"tru":17464,"tro":55540,"thư":5419,"tu ":263,"try":204,"toá":1052,"tsc":237,"toà":1057,"tsu":330,"tsw":157,"tta":873,"tte":2605,"tti":475,"ttl":380,"tto":705,"ttp":325,"tts":284,"thă":146,"tme":444,"tma":160,"thú":506,"thù":145,"to ":4755,"thô":2398,"tiê":3084,"tp ":325,"tna":209,"toe":205,"tod":450,"toc":558,"toi":213,"tog":204,"tob":196,"tou":1449,"tos":429,"tot":153,"tow":612,"tom":1725,"ton":3013,"tol":487,"tor":2310,"top":602,"tr ":327,"tii":370,"til":3476,"tif":586,"tie":501,"tig":741,"tir":204,"tiq":562,"tit":511,"tis":1648,"tin":5106,"tim":1567,"tip":239,"tio":2405,"thy":410,"thu":53072,"thw":183,"tia":1585,"tic":3507,"tid":1768,"tiu":237,"tiv":602,"tli":260,"thê":286,"thé":143,"thí":558,"thì":784,"liể":1722,"tla":967,"thâ":11890,"thà":11154,"tle":1005,"thá":12170,"tem":2257,"ten":2299,"tep":155,"tei":2098,"tel":2040,"tee":338,"teg":403,"tea":605,"tec":172,"ted":1492,"tfa":159,"th ":4032,"tev":154,"teu":168,"tet":184,"tes":3544,"ter":9430,"ti ":720,"tho":1935,"thm":205,"thr":908,"the":21046,"thi":5961,"tha":4235,"之三 ":187,"之万 ":161,"rưể":6336,"之专 ":252,"ăk ":141,"ăm ":28988,"ăn ":5275,"ăng":3284,"xưa":183,"vươ":541,"nưể":35806,"丘 ":240,"mưể":240,"专 ":1368,"xuể":3053,"並 ":377,"tươ":996,"lưể":2704,"三 ":1277,"丁 ":542,"万 ":771,"uyể":30286,"乙 ":247,"sư ":673,"tư ":1117,"zèr":162,"vũ ":670,"ürt":532,"üri":758,"viể":4820,"rươ":293,"rưn":427,"tuể":1284,"trể":43603,"yêu":353,"之 ":589,"yên":4958,"sơ ":163},"n_words":[13809827,17315344,13396979],"name":"vi"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/zh-cn b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/zh-cn new file mode 100644 index 000000000..904c61e39 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/zh-cn @@ -0,0 +1 @@ +{"freq":{"·":11798,"é":695,"и":659,"о":642,"а":705," 《":2860," 。":4044," 、":2042,"あ":2229,"。":93258,"、":80590,"》":12787,"《":12801,"ア":2133,"乱":17692,"书":4419,"习":841,"乡":1808,"九":2519,"也":8266,"乘":28571,"乐":5294,"乌":1217,"义":4779,"之":17358,"久":747,"主":15497,"为":43069,"举":3076,"丽":1041,"丼":1241,"丰":817,"临":983,"个":19411,"中":47239,"两":4794,"严":592,"丛":1367,"业":8072,"东":12690,"丞":9778,"专":3303,"丕":15196,"世":9256,"丈":146015,"三":7927,"上":15305,"下":7962,"不":69712,"与":14330,"一":51232,"丁":117148,"七":1693,"万":2760,"价":1006,"份":14596,"任":5559,"以":21926,"令":1161,"代":10675,"们":2426,"他":7464,"仙":673,"仅":1129,"仍":888,"从":3822,"今":2840,"亲":1398,"人":38353,"亡":667,"产":5405,"亦":2742,"交":20817,"京":3333,"云":2725,"五":3431,"亚":46408,"些":2757,"了":8577,"争":2347,"予":591,"事":19248,"二":6378,"于":42781,"使":59599,"低":1173,"住":1250,"位":13424,"但":4207,"作":14815,"何":21331,"体":8040,"伯":2492,"传":4668,"伦":1894,"伊":2356,"企":1149,"会":16875,"优":845,"休":48239,"众":1421,"信":7840,"俄":2213,"保":3387,"侧":721,"供":2204," 分":744," 公":1819,"商":3626,"哥":1688,"品":4389,"响":1404,"和":23304,"周":2010,"呼":663,"命":2331,"员":7153,"启":817,"含":1431,"吴":771,"名":20347,"同":8476,"后":12165,"吉":2174,"合":7745,"各":3613,"向":3047," 号":1564," 台":812,"域":2609,"城":5315,"培":3476,"基":6619," 名":675,"址":719,"坦":1302,"坡":2693,"土":2149,"圆":692,"场":5846,"地":26817,"在":35727,"圣":2664,"回":1392,"四":5911,"团":4373,"因":6183,"园":2775,"围":1767,"图":2777,"国":50445,"器":3296,"况":701,"冰":646,"决":1729,"冲":743,"农":1200,"军":7136,"写":2568,"册":628,"再":1221,"内":8287,"击":1569," 丕":929," 世":1671," 丈":5741," 不":1283," 一":646," 丁":3946," 万":1431,"兰":5551,"共":7134,"关":4776,"兴":1795,"其":12214,"具":2485,"兹":634,"养":660,"入":4429,"全":7377,"八":1932,"六":2119,"公":17034,"党":2412,"元":4144,"克":7641,"光":2911,"先":2098,"免":623,"停":661,"原":6718,"压":796,"厂":831,"历":4017,"厅":672,"去":1176,"县":5347,"厦":614,"变":2770,"受":2511,"取":2479,"发":12789,"双":1530,"反":2487,"及":17913,"友":732,"又":5333,"参":2872,"司":7147,"号":5641,"台":13293,"可":7699,"只":2126,"口":4422,"化":7453,"包":4823," 何":732,"区":18524,"医":1928," 位":590,"南":15302,"单":3024," 使":1450,"博":1783,"升":971,"千":1226,"十":5342,"协":2640,"华":6868,"半":2037,"卷":760,"印":3243,"即":2844,"卡":3152,"卫":1639,"力":4944," 人":2100,"办":2818,"动":10155,"助":1407,"加":7203,"务":5246,"势":871,"劳":804,"勞":1639," 休":920,"分":15267," 个":2399," 中":1862,"刘":669,"则":3203,"创":4231,"初":2398," 之":647,"别":3560,"利":8681,"到":6365,"制":7035," 乘":758,"前":10878," 乱":770,"剧":3129,"副":860," 亚":733," 天":581," 大":1004,"工":9317,"已":3013,"巴":5253,"州":7529,"川":3028,"山":12651,"属":10137,"展":3788,"屋":1097,"届":1515,"局":2483,"层":1590,"居":1947,"尼":5208,"就":2894,"尚":3502,"少":2443,"小":25275,"将":4225," 多":650,"岸":1431,"岭":590,"岩":988,"岛":4996,"岁":688,"录":1700,"归":696,"当":5254,"形":4076,"役":939,"影":4410,"式":6888,"异":925,"开":7255,"引":4831,"张":2153,"弹":947,"强":1613," 小":894,"念":1709,"往":1560,"律":1732,"得":4936," 家":600,"德":8327,"广":7680,"并":7400,"年":47488,"干":1556,"平":5989,"帝":2672,"帕":667,"师":2671,"希":2317,"布":7549,"常":6171,"席":1225,"带":2534,"延":769,"建":8867,"库":1470,"底":1106,"应":3484,"店":1431,"庙":584,"庆":953,"康":1164,"度":6769,"座":2603,"大":34268,"央":1321,"天":7035,"夫":2315,"太":3274,"头":2350,"失":939,"备":1259,"处":4116,"复":1700,"外":5857,"多":11036,"奥":3388,"女":3642,"好":1250,"奖":2274,"如":3936,"始":3351,"委":2437," 和":850,"增":971,"境":2254,"声":4998," 在":1140,"子":9623,"存":2538,"学":28915,"安":5174,"它":4574,"宁":1619,"定":6314,"实":4032,"宝":999,"宗":2085,"宫":1054,"客":2272,"宣":1095,"宾":780,"家":33525,"富":1265,"密":1755,"察":855,"导":2989,"对":7380,"威":2129,"媒":887," 国":713,"区,一":689,"更":2085,"曲":2749,"曾":3299,"是":61140,"映":608,"春":892,"显":972,"星":4368,"易":1898,"普":2707,"智":818,"晚":728,"架":926,"林":7036,"果":2196,"极":1459,"构":3349,"查":1580,"机":7949,"未":4221,"木":1876,"术":4302,"本":13564,"望":1007,"朝":3840,"期":7068,"朗":953,"月":15728,"有":24992,"服":2639,"最":10271,"松":1118,"杰":812,"杨":679,"来":9550,"条":3385,"村":1739,"李":1577,"杀":947,"杂":1265,"权":2775,"播":2492,"·丁":954,"·丈":771,"摄":716,"料":1677,"文":14966,"施":1293,"斯":13962,"断":823,"旁":959,"旅":1334,"族":3701," 或":968,"时":14785,"无":3416,"旧":1079,"日":21151,"早":2138,"放":2159,"改":3194,"收":1975,"支":2892,"教":9551,"故":1906,"数":7124,"整":1497,"括":3402,"拥":1168,"拉":7109,"拔":3550,"报":2620,"护":1665,"技":2723,"抗":915,"投":1684,"执":1062,"扩":636,"承":1002,"批":885,"所":11521,"手":3277," 年":38848," 平":1187,"打":1400,"户":1297,"房":1033,"戏":2673,"我":858,"成":16718,"或":10994,"战":6655,"提":4221,"推":2158,"控":1211,"接":3776,"排":1222,"换":868,"据":3024,"持":2131,"指":5889,"情":1949,"息":1214,"态":1462,"总":5550,"感":998,"游":3622,"温":1133,"港":10900,"清":2634,"湾":8336,"湖":3858,"源":3031,"满":827,"演":3628,"区,多":1252,"澳":2170,"气":1964,"民":10950,"水":5383,"江":5857,"汉":2630,"求":1033,"汇":1020,"沟":938,"沙":2368,"河":5488,"油":1041,"治":5001,"没":1471,"泽":750,"波":2738,"派":1913,"活":2831,"洲":5289,"测":1385,"济":2241,"流":4509,"消":1003,"深":1422,"横":631," 是":2568," 月":13702,"区,常":666,"武":2208,"此":5466,"止":1051,"正":4102,"死":6678,"歌":2416,"次":4906,"欧":2758,"款":923,"母":1743,"比":4805,"毕":833,"毒":762,"案":1633,"桥":1371,"树":1023,"标":3335,"样":1395,"栽":2997,"根":2240,"核":1380,"校":3605,"楼":1695,"植":5185," 日":10844,"概":864,"石":3358,"知":2149,"省":5247,"着":1639,"皇":2205,"的":145656,"盖":717,"监":811,"盘":598,"目":9318,"直":3003,"白":2529,"百":1846,"登":1073,"病":1344,"町":605,"画":2451,"甸":900,"电":10706,"田":1994,"由":17497,"用":13911,"生":19204,"甘":1358,"略":871,"留":781,"界":6597,"理":9553,"球":6996,"班":1750,"玛":789,"王":5331,"现":8430,"环":2438,"独":1820,"状":1446,"片":2527,"牌":1136,"物":13958,"特":10095,"爱":2167,"照":1002,"然":2677,"热":1483,"点":3443,"火":1816,"灵":903,"缅":631,"缘":1067,"编":2591,"缩":977,"罗":6436,"网":4079,"置":1765,"署":901,"美":10457,"群":2218,"纳":2534,"纽":906,"线":7551,"红":1720,"约":5717,"级":4065,"纪":4115,"结":3008,"统":6645,"绝":650,"络":1469,"给":1157,"细":1259,"织":2183,"组":5795,"经":8789,"终":1135,"维":3625,"综":661,"绿":800,"继":1038,"续":1408,"索":1233,"素":1524,"类":5149,"米":9738,"系":8292,"等":12322,"策":957,"笔":614,"第":11099,"篇":721,"简":4298,"算":1987,"究":2923,"空":3846," 的":2781,"程":4573,"竞":659,"站":6147,"立":9651,"童":907,"突":730,"票":886,"神":3463,"社":4420,"示":1536,"积":2267,"移":1075,"称":17001,"私":738,"科":10282,"离":1553,"福":3324,"确":1094,"础":692,"破":649,"码":1376,"要":8323,"视":4552,"规":2234,"观":2303,"见":2171,"览":667,"角":3015,"解":2300,"西":17559,"被":7905,"街":2230,"行":14959,"表":5479,"认":2753,"计":5438,"训":622,"讯":1488,"议":3045,"让":773,"记":2357,"设":6237,"许":1740,"论":3372,"该":4765,"说":3972,"诸":678,"诺":1644,"读":946,"证":1510,"识":1123,"评":1093,"词":2012,"译":3205,"诗":967,"试":1000,"话":1875,"警":737,"言":2970,"路":9754,"越":2100,"超":1907,"足":2749,"资":4130,"赛":5990,"起":4293,"负":1207,"贝":1346,"财":832,"责":1208,"败":623,"货":901,"质":2689,"购":664,"贵":1643,"费":1407,"象":1888,"调":1492,"谷":1826,"过":6354,"进":5216,"还":1606,"这":6952,"连":2790,"远":1319,"运":6417,"近":3105,"辽":711,"达":4214,"边":2785,"较":2013,"辖":1462,"输":1210,"辑":1374,"车":6585,"轨":655,"转":1925,"轮":727,"软":1659,"轻":756,"载":1404,"身":2869,"脑":1283,"脉":651,"腊":1076,"致":1313,"至":9855,"自":8792,"而":9496,"者":7418,"职":2157,"联":6161," 米":6968,"肃":1126,"股":1262,"育":2953,"胜":1031,"能":5645,"药":977,"荣":690,"草":3994,"获":2004,"莱":1327,"菲":926,"般":2569,"航":2316,"舰":942,"艺":2269,"艾":805,"色":3575,"花":3115,"节":2402,"英":9686,"苏":3117,"著":2998,"营":2531,"萨":1866,"落":1487,"蓝":701,"蒂":676,"虽":721," 英":812,"频":899,"题":1997,"预":942,"领":2926,"食":1377,"飞":1436,"风":2500,"顿":1362,"顺":631,"项":2377,"顶":716,"页":780,"馆":2371,"香":9519,"验":1104,"高":8988," 阿":664,"马":7083,"鲜":1464,"鲁":1516,"鱼":955," 香":692,"黑":1900,"黄":2293,"龙":3881,"造":2929,"选":3181,"送":619,"适":644,"通":7604,"速":2166,"遗":895,"邻":1194,"郡":912,"部":14531,"都":5243,"配":1056,"金":5677,"野":1099,"量":3834,"里":8179,"重":5583,"释":634,"银":1422,"铁":4586,"针":594,"钟":734,"长":12428,"镜":635,"镇":2371,"锡":594,"锦":662,"销":827,"闻":1352,"间":8313,"问":1446,"门":4685,"际":4272,"陆":5534,"陈":1215,"降":626,"限":2379,"陕":1187,"院":5166,"除":1569,"险":710,"队":3990,"阶":1080,"阴":725,"防":1166,"阳":2041,"阿":4439,"随":1152,"难":627,"隶":660,"青":2398,"非":3368,"面":6531,"需":1195,"音":4816,"韩":1018,"가":589,")":53342,"(":53630,"-":1381,",":211761,":":15751,";":5849," (":2857," )":2917," ,":8290,"国的特":945,"植物。":2891,"植物,":1199,"基丁教":662,"等地,":3010,"民共和":1261,"。 ":4085,"、 ":2429,"》 ":659,"地区,":3536,"。这":1769,"、陕":800," 、 ":1160,"、福":680,"。现":602,"、甘":833,"。由":929,"、西":1056,"、贵":865,"。该":1506,"四川、":1228,"、广":1717,"、山":2033,"国大陆":3832,"、安":622,"。它":1480,"、四":1328,"。在":1915,"、台":689,"。分":2961,"、印":861,"。其":1173,"、湖":1562,"、河":1285,"、江":1104,"。此":760,"》是":802,"、日":634,"ああ":1707,"、《":1198,"》、":1065,"》中":595,"《丈":900,"、休":601,"。他":1369,"、云":1236,"。乘":742,"、人":909,"。丁":940,"、不":1336,"、丁":2633,"、丈":4209,"、乘":1367,"、中":959,"。丈":1034,"アア":1643,"地区的":687,"》(":2220,"》,":1819,"在中国":1180,"栽培。":2912,"、贵州":848,"是香港":1721,"立于 ":1061,"从 ":609,"人 ":623,"以 ":631,"于 ":10544,"了 ":641,"亚·":946,"亚 ":1478,"休 ":1064,"会 ":652,"使 ":1090,"不、":2097,"不。":742,"丈》":600,"丈、":2959,"丈。":2119,"丁、":2210,"丁。":2121,"一。":1805,"东、":1223,"中、":800,"人。":1182,"事。":826,"亚、":1600,"亚。":687,"交。":780,"丈山":758,"丈属":948,"不家":1629,"之后":1285,"丈小":1097,"丈家":1182,"丁属":1251,"中国":13581,"丈子":859,"丈学":961,"一家":830,"乱丈":1142,"为台":739,"丈大":637,"举办":651,"丁大":616,"何。":612,"乘丁":814,"乘一":737,"乘丈":920,"中华":3016,"乘丛":864,"丈地":713,"之一":4710,"丁国":1036,"丁地":630,"东南":852,"主义":1789,"为主":1114,"为中":1501,"为丈":1939,"为一":949,"为丁":953,"丈和":636,"为了":902,"不同":2049,"中使":2667,"不区":1235,"中一":647,"不军":620,"个人":1067,"丈克":1016,"丈其":691,"不公":924,"两个":961,"不使":1931,"休。":1293,"休、":1110,"丁克":614,"东不":1592,"丛中":711,"丁军":992,"丁兰":618,"不交":3736,"不京":1465,"不事":949,"丈休":1776,"丈使":1087,"不休":658,"丕丈":949,"丈不":1018,"丈丈":10643,"丈丕":925,"丈丞":767,"丈中":605,"丁休":2172,"丈为":629,"丈之":694,"上不":1488,"一位":1048,"丈乘":1009,"丈乱":1342,"丁作":779,"丈事":642,"丁使":3178,"丈交":632,"不丈":1417,"不丁":1361,"丈亚":1470,"不不":1140,"与丈":673,"一丈":695,"丁丈":5202,"丁丁":3673,"丁不":1113,"一个":9742,"丁乘":875,"一亚":4760,"一些":1051,"丁乱":789,"丁亚":2029,"份、":719,"丈一":1128,"丈丁":6021,"主教":1120,"任何":656,"于山":605,"交大":1013,"企业":965,"为是":626,"中文":1113,"人口":1818,"一次":948,"丈林":809,"他们":991,"产品":768,"事场":701,"以丈":590,"人使":892,"丁是":769,"丈是":785,"一条":1013,"不拔":3372,"二十":706,"人乘":690,"云南":1737,"人丁":945,"人丈":706,"主席":689,"丁教":806,"于台":1035,"元 ":583,"丁斯":907,"丁文":660,"一所":719,"亚使":601,"交休":767,"事务":628,"乘大":1199,"亚丈":1056,"不式":1110,"亚丁":910,"中学":1267,"亚亚":814,"交不":722,"使。":1718,"使、":1407,"丁店":632,"一座":888,"中央":1281,"于丁":1020,"于不":3550,"于丈":1169,"事交":1241,"于中":1731,"中的":2873,"休如":834,"丈科":1509,"亚栽":2911,"东省":644,"份年":663,"使休":784,"使代":599,"使中":607,"二次":594,"使丈":1433,"使上":903,"使丁":935,"下的":912,"世界":3851,"上的":1685,"何丁":623,"丈的":3617,"于日":763,"乘江":1087,"位于":6910,"丁的":3074,"不生":996,"作为":1517,"不的":1824,"也有":715,"不现":1191,"份围":818,"人工":3099,"丈球":620,"休丈":1574,"休丁":1348,"以及":5720,"不治":1654,"也是":2441,"休休":1177,"休使":948,"交的":754,"何成":650,"但是":741,"人的":1301,"事的":883,"人物":960,"丁西":582,"产生":952,"亚的":1008,"一般":2436,"人民":2356,"丈至":636,"丈草":591,"使团":1466,"前 ":886,"作家":983,"作品":1438,"亚洲":979,"使兰":933,"世纪":2136,"乘的":934,"到 ":1169,"丈 ":2639,"丈·":660,"丁 ":1901,"丁·":957,"为 ":5249,"地、":838,"国、":813,"又译":658,"发行":1130,"可能":964,"南部":1207,"名称":1365,"后的":584,"名的":1485,"同的":919,"商业":792,"使(":777,"使,":2980,"又称":2280,"台湾":6649,"位,":691,"发现":998,"体,":607,"何,":1182,"作,":878,"发生":1318,"后来":990,"只有":591,"南等":606,"休(":899,"休,":2609,"和国":2085,"会,":853,"会(":981,"同时":1360,"在 ":4342,"命名":845,"份,":752,"国 ":738,"区的":1567,"和丈":1029,"和丁":641,"前身":709,"员会":1240,"交,":1266,"制造":737,"反应":687,"人,":2362,"化的":604,"事,":1473,"亚,":1453,"亚(":751,"亚:":3961,"华民":1238,"发展":2345,"多生长":627,"国的":3079,"国王":741,"城事":1744,"因此":1473,"国民":1000,"基丁":1219,"分,":694,"四川":1896,"地区":6955,"国大":4205,"在台":652," 公里":1220,"国家":4191,"在不":766,"在丈":1143,"在丁":899,"地不":1517,"在中":1500,"内,":588,"国国":1280,"因为":1284,"团体":692,"国丁":732,"国丈":695,"国不":1345,"国人":990,"培。":2913,"公园":1063,"全国":1074,"共和":2100,"共同":711,"军事":699,"公司":6085,"和 ":1051,"克斯":708,"分丁":674,"分为":837," 丈丈":703,"及 ":757,"内信":885,"其他":1807,"内丁":823,"公共":779,"其中":1933,"俄罗":1205,"交通":1010,"代表":1920,"使用":3270,"使理":2624,"使的":2300,"何的":1007,"之间":1601,"作用":691,"何用":717,"传统":899,"作的":824,"何能":734,"九龙":820,"于香":923,"会议":766,"人闻":930,"体育":809,"使究":2862,"不部":1509,"代的":607,"人类":940,"使本":654,"丁近":677,"举行":1293,"主要":4270,"于美":614,"一部":1591,"丈车":720,"他的":941,"专辑":636,"信息":699,"保护":898,"亚言":1720,"休画":658,"休的":1686,"会的":752,"不面":1014,"及丈":729,"及中":2186,"下,":946,"上,":1461,"丈(":2586,"丈,":5165,"参与":744,"半岛":715,"不,":1460,"一,":2377,"丁)":1039,"丁,":4237,"丁(":1706,"包括":3325,"参加":688,"动画":653,"中,":3371,"及其":661,"业,":586,"原名":724,"动物":1359,"名为":1425,"乘,":704,"各亚":724,"又名":874,"印度":2180,"可以":2687,"台不":1436,"乱,":730,"名使":755,"合作":595,"包含":732,"单位":907,"员。":605,"华人":1471,"协会":1039,"南不":934,"公路":1194,"区域":737," 世纪":1447,"化学":839,"分类":693,"利用":693,"医学":647,"历使":2363,"创立":811,"公里":2086,"前尚":2725,"内的":698,"关系":1044,"名。":910,"创作":725,"分别":959,"利亚":1729,"共有":696,"制作":1175,"创办":644,"具有":1055,"区、":855,"区。":806," 中国":719,"南、":2847,"分子":582,"分布":3839,"全球":752,"加乘":908,"州事":599,"工业":864,"工作":1348,"实际":605,"巴乘":819,"属的":3366,"学院":1919,"度、":646,"帝国":1098,"工引":2908,"平不":1296,"山谷":602,"并丁":847,"年代":1820,"广东":1877,"广乘":652,"布在":1655,"山西":700,"小都":652,"布于":1877,"建、":593,"巴使":874,"小说":1496,"、陕西":793,"场,":659,"尚未":2839,"定的":781,"州、":1204,"地,":4149,"川、":1254,"它的":633,"山坡":1678,"学的":914,"国,":704,"学生":932,"小的":1375,"德·":778,"就是":947,"家的":1013,"应用":955," 年 ":13492,"形式":842,"形成":784,"德国":1532,"或 ":819,"影响":1080,"德亚":680,"希腊":1007,"年的":1358,"广西":1228,"建立":1106,"当时":1404,"年至":809,"拔 ":3155,"外,":1036,"广场":674,"广州":765,"建于":690,"建丁":1787,"年在":775,"处,":614,"开始":2055,"工程":1106,"已经":808,"常生":724,"引亚":2921,"广播":596,"开发":1428,"大学":4751,"名:":4034,"后,":2099,"名,":804,"大战":639,"号,":798,"司,":904,"司(":706,"太平":714,"员,":1310,"委员":1628,"多生":1267,"处理":904,"国立":626,"动,":770,"基本":664,"境内":659,"声任":875,"区,":4940,"基础":690,"国际":3114,"大利":1318,"大使":1012,"家 ":943,"天休":592,"天主":779,"大丈":869,"学使":616,"大陆":4400,"它们":581,"安丁":901,"学名":3799,"定义":596,"存在":833,"岛、":590,"家亚":645,"家丈":713,"家丁":849,"学家":1872,"对于":704,"年 ":13993,"小丈":990,"家国":1673,"尼亚":1342,"学校":1549,"它是":712,"家律":640,"属于":2022,"宗教":606,"山东":748,"大的":1819,"品,":659,"未由人":2713,"学、":1095,"媒体":593,"家、":1079,"家。":1319,"学中":593,"大部":622,"是由":1948,"最大":1527,"成,":1007,"最早":864,"是美":1276,"日至":621,"林中":937,"林下":866,"林丈":747,"是日":749,"最丈":683,"教育":1765,"斯特":879,"是指":1893,"最后":916,"服务":2010,"时的":619," 日 ":1067,"有一":1032,"有丈":634,"有关":606,"栽培":2968,"曾经":583," 月 ":10460,"期的":814,"未由":2714,"有的":742,"来的":817,"是香":1732," 年,":2603," 年)":2400,"机构":1217,"有植":939,"有时":593,"时间":1469,"标何":1254,"故事":840,"教丁":619,"教会":604,"教休":765,"文使":804,"、湖不":767,"斯丁":803,"文化":2111,"、江西":640,"式,":710,"是台":693,"是在":1454,"早期":592,"时期":1763,"日本":5547,"数学":761,"、湖南":720,"名:)":3257,"时代":1179,"斯坦":867,"文学":1074,"数据":868,"是位":626,"是以":583,"是中":2851,"日在":675,"是丁":1437,"是一":8458,"是不":724,"是丈":2026,"是 ":2352,"推不":777," 年的":914,"或称":642,"成立":2637,"技术":1644,"成的":1249,"日 ":1181,"斯·":1031,"所有":1061,"拉丁":1110,"委员会":1211,"投资":588,"月 ":10522,"有 ":2350,"年(":1135,"年)":2514,"年,":3020," 年至":781,"提不":749,"提供":1571,"控制":687,"或者":862,"拥有":1075,"家(":883,"家,":2992,"学(":696,"学,":1273,"子,":932,"成。":674,"年间":605," 年在":695," 年代":1447," 平不":1027,"所以":844,"成员":1194,"属(":1286,"成为":2403,"战争":1282,"成何":673,"车站,":720,"总统":750,"小,":1060,"流行":630," 日)":775," 日,":1367,"没有":1287,"活动":1238,"比赛":1111,"江苏":807,"江西":972,"湖不":1117,"湖南":1294,"源于":655,"游戏":1924,"江、":1010,"斯(":605,"文:":2387,"毕业":667,"时,":1279,"死关":792,"日,":1548,"日)":813," 日至":616,"、广西":861,"民国":1569,"民主":899,"欧洲":1589,"民共":1266,"正式":1275,"河南":853,"月,":734,"民族":1066,"期,":613,"河不":810,"称为 ":1204,"根据":1261,"来自":905,"朝鲜":1221,"最高":965,"期间":1013,"有限":1519,"植物":4924," 是一":701,"概念":628," 日在":655,"社会":2250,"的西":629,"的重":753,"第 ":1806,"的第":1619,"物,":2113,"目的":1041,"的是":1254,"的最":739,"的植":2910,"称 ":1447,"积 ":789,"生长":4500,"直接":612,"的特":1539,"的电":996,"的小":1525,"的家":638,"电脑":1011,"的大":1230,"的国":1201,"的基":581,"的地":4246,"电视":2674,"目前":4402,"的丁":3401,"的一":9462,"用的":1236,"生的":842,"球队":888,"生物":1143,"甘肃":1053,"的名":795,"的发":604,"的休":1722,"的使":1923,"的何":678,"的作":618,"的主":1363,"的中":1197,"的丈":5079,"的不":2462,"的乱":628,"的乘":866,"的人":1919,"的交":1075,"的亚":598,"的份":596,"用来":773,"电影":2044,"理论":1071,"生活":843,"生在":746,"电子":1067,"的。":902,"的《":764,"由人":3013,"由于":1683,"用于":1226,"生于":2477,"生产":971,"理学":1070,"王朝":657,"独立":1054,"现在":1080,"环境":892,"的 ":3036,"用。":732,"现代":899,"班丁":801,"物理":701,"特有":1087,"由 ":647,"特别":1034,"澳门":921,"、福建":587,"物。":3636,"而成":666,"网络":1319,"等,":840,"。由于":637,"结构":811,"称,":606,"统治":615,"美国":6262,"有限公":1342,"经济":1788,"线的":727,"统的":590,"群岛":661,"罗斯":1403,"组织":2012,"联休":1568,"联合":1420,"经营":801,"美洲":847,"站,":1417,"站(":605,"立,":948,"约丈":612,"系统":2897,"、甘肃":804,"结丁":584,"纪念":701,"缩写":612,"至 ":5691,"肃、":800,"自 ":728,"组成":1458,"米的":3087,"米至":2745,"空间":581,"简称":3399,"目,":621,"系使":1617,"等地":3350,"的,":1232,"算机":592,"约 ":1747,"天主教":743,"立的":1250,"立于":1279,"生,":616,"用,":772,"科技":622,"第三":1132,"第一":3441,"第二":2122,"科丈":1055,"等。":1256,"科学":1716,"福建":1133,"称为":4237,"站。":627,"角色":608,"认为":1515,"西部":624,"计份":1242,"译为":652,"西班":773,"要的":1104,"视台":583,"被称":1048,"设计":1764,"越南":953,"贵州":1074,"计算":1077,"设立":673,"赛事":631,"过 ":590,"达 ":635,"许多":1084,"这亚":795,"这些":921,"这个":1485,"运动":2493,"选举":733,"超过":649,"软交":1060,"路线":871,"负责":846,"资讯":628,"足球":1709,"行,":1162,"资料":726,"都是":704,"说,":693,"进行":2271,"华民国":1215,"过程":791,"部分":2341,"部份":779,"车站":2410,"通常":1655,"连接":661,"系,":584,"英亚":2018,"自治":726,"自然":791,"英国":2374,"艺术":1217,"自由":876,"般生":684,"航空":1141,"草地":757," 米的":3008,"罗马":1148,"自丁":786," 米至":2742,"米,":928,"联赛":872,"者,":759,"节目":923,"英文":2834,"苏联":584,"获得":1131,"线,":677,"著名":1735,"是台湾":602,"虽然":581,"行。":771,"规份":679,"西南":748,"行的":1255,"西份":1008,"西亚":1199,"西不":1211,"行为":642,"行不":2204,"西、":2735,"中,目":813,"马来":712,"香港":8632,"高丁":607,"间,":1121,"队,":590,"高速":865," 香港":632,"及中国":2044,"公里,":1108,"是一个":2236,"是一亚":2252,"是位于":587,"丈(学":778,"是中国":2142,"部的":1067,"通过":1270,"赛,":689,"长 ":666,"路,":847,"重要":1745,"的第一":601,"铁家":726,"重要的":693,"长于":3283,"长在":1116,"部,":1121,"除了":587,"限公":1343,"阿亚":611,"间的":1117,"阿拉":760,"铁路":1902,"银行":879,"陆的":3096,"里,":1518,"陕西":1134,"音乐":1761,"面积":1528,"问题":913,"非洲":689,"领域":706,"需要":625,"项目":737,"有植物":938,"的特有":970,"华人民":1156,"是美国":1183,"生长在":1097,"的植物":2905,"生长于":3254,"日至 ":606,"前尚未":2719,"最大的":950,"加乘大":716,"是日本":698,"目前尚":2723,"的地区":3123,"甘肃、":797,"的一部":774,"的主要":669,"年),":737,"的一亚":1477,"的一个":3092,"限公司":1342,"年( ":710,"长于不":2913," )是":697," ,是":1072,"南等地":586,"),":14139,"()":3758,"(,":1176,",)":1561,":,":733,":)":4083,"由人工":2914,",有":1486,",最":1122,",曾":1063,",是":13170,")是":10848,",此":660,",总":746,",当":886,",并":4017,",常":1051,",故":644,",指":584,",所":997,",或":1328,",成":1293,")的":2201,",目":3648,",第":777,",简":2029,",现":1341,",由":3911,",用":638,",生":3542,",西":833,",被":862,",该":1018,",经":598,",美":598,",而":3223,",英":974,"(英":2411,",香":721,",这":1581,",通":884,",《":690,")。":3713,")、":2880,"(丁":582,"(学":3658,",它":1417,",属":841,",小":789,",因":2416,",在":4524,",多":1573,",大":803,",如":965,",前":662,",分":865,",南":723,",即":1029,",包":1287,")和":952,",后":1255,",同":895,",台":750,",可":1101,",又":2947,",原":1270,",与":1258,",不":2776,",东":861,",中":1697,",主":1658,",为":3616,"(今":666,",乘":1464,",也":3256,",乱":593,"(丈":745,")为":2108,",丈":5138,",丁":4254,",一":2351,",休":1379,",但":3353,",位":2756,",使":1942,",交":917,",亦":1195,",于":2786,",人":883,",以":3498,",他":1341,",从":880,",份":844,",共":756,",其":3552,",全":1258,"( ":4029,") ":1194,", ":8207,"- ":821,": ":1177,"于台湾":746,"云南、":1087,"丁属(":793,"中国的":1325,"中国大":3854,"之一,":2267,"不拔 ":3152,"于不拔":2931,"于中国":1363,"丈属的":710,"人工引":2908," ),":840,"乘江、":593,"特有植":935,"位于香":588,"于日本":718,"交大利":915,"以及中":2006,"一般生":684,"英文:":1509,"亚栽培":2910,"陕西、":802,"人民共":1261,"广西、":800,":)为":1432,":)是":1905,"),又":980,"),是":2411,"()是":1113,",),":1007,"著名的":779,"(),":1527,"年至 ":713,"面积 ":773,"于香港":916,"之间的":629,"内丁使":615,"成立于":917,"英亚:":1340,"俄罗斯":1205,",香港":708,"物。分":2814,"公司(":690,"公司,":865,"行不区":1022,"共和国":1949,"分布于":1823,"分布在":1639,"》、《":946,")是丈":621,")是一":2670,",是一":2180,",是中":1286,"湖南、":689,"あああ":1321,"尚未由":2713,"地,生":2896,",并丁":652,",常生":669,",所以":699,",又称":1386,",台湾":584,",因此":1152,",多生":1256,"(学名":3651,"。分布":2922,"、印度":793,"、乘江":625,"、云南":1182,"被称为":866,"、山坡":669,"、广东":743,"、四川":1251,"大陆的":3080,"アアア":1275,"学名:":3527,"(英文":1335,"(英亚":1020,",目前":3438,",生长":2942,"西班丁":773,",简称":1929,"工引亚":2908,"平不公":791,"贵州、":836,"广东、":761,"引亚栽":2908,",包括":1127,"米的地":2908,",又名":585,",在 ":658,",其中":943,",以及":1003,",也是":1477,",位于":2555,",一般":1217,",主要":1207,",为中":658,",中国":911,"属的植":2824,",于 ":2118,"丁使、":641,"丈丈丁":631,"计算机":592,"江西、":618,"湖不、":763,"不同的":722,"米至 ":2743,"之一。":1753,"中华民":1237,"中华人":1156,"为中国":948,"不公里":767,"丈丈,":642},"n_words":[4792118,1709982,314544],"name":"zh-cn"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/zh-tw b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/zh-tw new file mode 100644 index 000000000..674b28d12 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Profiles/zh-tw @@ -0,0 +1 @@ +{"freq":{"·":11773,"é":695,"區,常":664,"и":659,"о":642,"а":705," 《":2780," 。":1867," 、":1053,"あ":2229,"。":93215,"、":80530,"》":12775,"《":12789,"」":16776,"「":16978,"ア":2133,"九":2518,"也":8240,"乘":27365,"之":17356,"久":750,"主":15490,"丼":1230,"中":47219,"並":6623,"丞":85837,"丕":96789,"世":9230,"丈":143774,"三":7943,"上":15307,"下":7965,"不":69580,"一":51222,"丁":112603,"七":1691,"份":8990,"任":5556,"以":21889,"令":1163,"代":10588,"他":7458,"仙":669,"仍":884,"今":2840,"人":38053,"亡":666,"亦":2741,"交":18627,"京":3334,"五":3430,"些":2759,"亞":10406,"了":8549,"予":591,"事":19252,"二":6375,"使":59515,"低":1174,"住":1250,"位":13512,"但":4206,"作":14816,"何":16276,"佐":33991,"伯":2485,"伊":2316,"企":1149,"休":48236,"信":7776,"俄":2093,"係":1210,"保":3393,"來":9528,"供":2206," 分":709,"單":3071,"問":1448," 公":2117,"商":3624,"員":7098,"哥":1699,"品":4392,"和":23261,"周":1446,"呼":664,"命":2330,"含":1432,"名":20323,"同":8443,"吉":2089,"合":7724," 倫":1516,"各":3613,"向":3031,"域":2612,"城":5349,"執":1078,"培":3458,"基":6608," 名":633,"址":721,"坦":1100,"坡":2688,"團":4364,"土":2148,"園":2775,"圖":2763,"國":50470,"地":26714,"在":35708,"回":1107,"四":5909,"因":6124,"嚴":592," 勞":1513,"器":3287,"冰":646,"再":1221," 丞":2854," 丕":3070," 世":1592," 丈":4439," 不":917," 丁":3186,"優":845,"共":7054,"其":12215,"具":2485,"入":4421,"內":8167,"兩":4796,"全":7445,"八":1932,"六":2118,"公":17482,"兒":1569,"元":4231,"克":7487,"光":2846,"先":2097,"免":625,"傳":4645,"價":1006,"倫":51626,"個":19430,"們":2429,"停":661,"原":6791,"去":1179,"受":2509,"取":2465,"反":2477,"及":17959,"友":732,"又":5332,"參":2854,"司":7145,"台":11564,"可":7754,"只":1856," 個":2397,"口":4174,"化":7454,"包":4825," 佐":611," 位":594,"南":15370,"協":2646," 使":1198,"博":1769,"升":830,"千":1228,"十":5341,"區":18522,"半":2039,"卷":655,"印":3241,"即":2842,"卡":3151,"劃":2056,"劇":3028,"力":4955," 人":1795,"助":1406,"加":7145,"勞":44204,"務":5038,"動":10173," 休":691,"分":15261," 中":1418,"初":2396,"別":3548,"利":8617,"到":6362,"制":3819," 乘":601,"則":3204,"前":10854,"副":861,"創":4236," 大":752,"工":9304,"已":3034,"巴":5247,"州":7520,"川":3027,"山":12644,"屬":10111,"展":3787,"屋":1099,"局":2380,"居":1946,"尼":4905,"就":2895,"尚":3522,"少":2442,"對":12131,"小":25320,"導":2988,"專":3315,"將":4225,"島":4996," 多":609,"岸":1457,"岩":955,"彈":1036,"形":4081,"役":939,"影":4543,"式":7142,"引":4806,"張":2155,"強":1613," 小":712,"念":1686,"往":1561,"律":1728,"後":11603,"得":4825,"從":3819,"德":8443,"幹":610,"年":47473,"平":5943,"帝":2671,"帕":627,"希":2358,"布":6774,"常":6175,"帶":2450,"師":2700,"席":1237,"延":769,"建":8865,"廣":7680,"廠":829,"底":1070,"店":1431,"康":1164,"度":6845,"座":2605,"大":34205,"央":1335,"天":6785,"夫":2310,"太":3614,"失":939,"外":5866,"多":11013,"奧":3348,"女":3636,"好":1255,"如":3939,"始":3424,"委":2437,"場":5840,"報":2620," 和":619,"增":971,"境":2254," 在":1006,"子":9582,"存":2418,"學":28894,"安":5183,"它":4320,"定":6314,"宗":2121,"宮":11665,"客":2255,"宣":1095,"家":33259,"富":1263,"密":1751,"察":902,"寫":2568,"實":4042,"威":2163,"媒":887,"更":2088,"曲":2693,"曾":3297,"書":4421,"是":61135,"映":606,"春":891,"星":4383,"易":1898,"普":2726,"智":821,"時":14789,"晚":728,"架":926,"林":7015,"果":2193,"查":1544,"未":4199,"木":1871,"本":13516,"望":1009,"朝":3760,"期":7068,"朗":950,"月":15722,"有":25006,"服":2638,"最":10258,"會":16872,"松":993,"東":12692,"村":1739,"李":1578,"播":2488,"擊":1563,"據":2801,"·丁":953,"·丕":684,"·丈":742,"料":1908,"文":14926,"於":85512,"施":1293,"斯":13761,"旁":958,"旅":1333,"族":3698," 或":592,"日":21067,"早":2137,"放":2161,"改":3194,"收":1971,"支":2879,"教":9547,"故":1906,"數":7013,"整":1506,"括":3403,"拉":7094,"拔":3534,"技":2726,"抗":915,"投":1689,"承":1001,"批":886,"所":11497,"手":3280," 年":38814," 平":1137,"打":1356,"戰":6668,"戲":2673,"房":1031,"我":858,"成":16686,"或":10999,"提":4217,"推":2160,"控":1213,"接":3506,"排":1256,"持":2131,"指":5892,"情":1951,"息":1210,"應":3488,"感":1000,"愛":2219,"游":601,"測":1417,"港":10903,"清":2633,"湖":3859,"源":2955,"滿":823,"漢":2629,"演":3758,"澳":2170,"濟":2246,"民":10942,"水":5379,"氣":1960,"江":5858,"求":1019,"決":1728,"沒":1469,"沙":2360,"河":5480,"油":1041,"治":5045,"波":2725,"派":1934,"活":2827,"洲":5278,"流":4541,"消":1003,"深":1422,"機":7988,"樓":1698,"標":3283,"樂":5292," 是":2270," 月":13683,"武":2208,"此":5462,"止":1051,"正":4102,"歷":3537,"歲":679,"死":6673,"歌":2412,"歐":2776,"次":4908,"款":922,"權":2775,"母":1810,"比":4792,"毒":761,"殺":3118,"案":1653,"栽":2979,"根":2237,"核":1380,"校":3603,"條":3385,"楊":679,"業":8348,"植":5169,"構":3354," 日":10789,"概":795,"石":3331,"知":2143,"省":5241,"眾":1402,"皇":2166,"的":145617,"目":9288,"直":3002,"發":12643,"白":2538,"百":1845,"登":1101,"病":1342,"町":605,"甸":897,"田":1992,"由":17477,"用":13939,"產":5389,"生":19162,"甘":1400,"當":5199,"畫":2821,"略":871,"留":781,"界":6587,"環":2430,"理":9565,"球":7020,"區,一":683,"現":8423,"班":1762,"王":5328,"獎":2259,"獲":1989,"片":2524,"牌":1136,"物":13950,"特":9797,"爭":2331,"爾":10487,"營":2531,"照":1001,"然":2724,"無":3430,"灣":8336,"火":1815,"置":1766,"署":979,"羅":6361,"美":10443,"群":2244,"義":5695,"習":841,"總":5592,"縣":5350,"繼":1038,"續":1407,"索":1368,"素":1525,"納":2465,"約":5697,"紀":4111,"級":4056,"統":6648,"組":5814,"結":3076,"綠":801,"維":3676,"網":4429,"經":8789,"綜":642,"編":2471,"線":7038,"簡":4320,"米":9228,"系":6773,"等":12258,"策":935,"第":11129,"篇":721,"節":2370,"算":1983,"積":2283,"究":2927,"空":4143," 的":1486,"程":4595,"稱":17006,"種":13270,"站":6147,"立":9659,"競":659,"童":907,"突":731,"票":889,"神":3459,"區,多":1245,"社":4421,"示":1588,"移":1020,"私":736,"科":10232,"福":3334,"破":649,"要":8322,"規":2224,"視":4488,"親":1395,"觀":2300,"角":3003,"解":2370,"西":17796,"被":7902,"製":3213," 萬":1397,"衛":1641,"街":2230,"術":4294,"行":14995,"表":5436,"變":2770,"譯":3201,"警":737,"議":3043,"護":1664,"證":1490,"調":1479,"說":3940,"語":12000,"認":2740,"論":3370," 號":1554,"設":6262,"記":2497,"計":5475,"訊":1564,"言":2973,"該":4761,"話":1875,"評":1093,"路":11367,"越":2102,"超":1905,"足":2739,"起":4291,"賓":786,"資":4396,"賽":6003,"質":2688,"費":1408,"貨":906,"責":1207,"象":1864,"谷":1752,"近":3107,"辦":2818,"農":1197,"轉":1925,"較":2015,"載":1405,"車":6562,"身":2869,"致":1208,"至":9837,"自":8751,"而":9484,"者":7426,"聞":13745,"聖":2663," 米":6617,"聯":14082,"聲":1069,"肅":1122,"股":1263,"育":2954,"能":5599,"草":3974,"菲":888,"華":6888,"般":2564,"航":2033,"興":1795,"舉":3075,"與":14328,"艦":940,"艾":758,"色":3577,"花":3113,"英":9681,"藝":2269,"藥":973,"葉":1953,"著":4637,"萬":2757,"落":1486,"蒂":673,"處":4121,"號":5640,"蘭":5557,"蘇":3088," 英":759,"風":2494,"食":1389,"飛":1667,"領":2927,"預":955,"項":2370,"類":5147,"馬":6983,"香":9518,"館":2367,"體":9444,"高":8889," 阿":586," 香":621,"點":3460,"黑":1831,"黃":2289,"黨":2390,"龍":3877,"連":2837,"造":2926,"進":5235,"送":620,"這":6954,"通":7591,"速":2179,"遺":895,"選":3181,"過":6349,"運":6466,"遊":3024,"達":4169,"還":1604,"邊":2782,"郡":912,"部":14529,"都":5256,"配":1052,"醫":1928,"金":5699,"野":1096,"量":3732,"里":6615,"重":5591,"銀":1423,"錄":1696,"鎮":2372,"鐵":4592,"間":8271,"開":7281,"門":4672,"降":626,"限":2369,"院":5168,"除":1568,"陳":1215,"陸":5523,"陽":2042,"防":1167,"阿":4360,"離":1505,"難":627,"電":10735,"雲":2700,"隊":3986,"際":4571,"青":2396,"非":3371,"面":6432,"需":1196,"響":1404,"音":4823,"가":589,")":53309,"(":53597,"-":1381,",":211682,":":15729,";":5850," (":1546," )":2103," ,":4859,"車站,":720,"國的特":944,"植物。":2875,"植物,":1199,"基丁教":662,"等地,":2994,"民共和":1261,"。 ":3480,"、 ":1427,"」 ":591,"》 ":624,"國大陸":3816,"地區,":3519,"。這":1771,"、雲":1235,"」的":1264,"、福":680,"。現":601,"、甘":835,"。由":929,"、西":1055,"。該":1503,"四川、":1228,"、廣":1717,"、山":2030,"、安":622,"。它":1379,"、四":1327,"。在":1916,"、台":622,"。分":2945,"、勞":792,"、印":867,"、倫":1945,"。其":1173,"、湖":1562,"、河":1284,"、江":1104,"。此":759,"》是":802,"、日":634,"ああ":1707,"、《":1196,"、「":974,"》、":1063,"」、":966,"」。":2150,"》中":594,"「丕":727,"「丞":592,"《丈":880,"、休":613,"。他":1366,"「丈":1131,"《丕":588,"。乘":718,"、人":863,"、丞":3044,"。丁":930,"、丕":3444,"、不":1334,"、丁":2563,"、丈":4244,"、乘":1329,"。丞":586,"。丕":1165,"、中":959,"。丈":1017,"アア":1643,"地區的":687,"」(":1271,"」,":3388,"」)":800,"》(":2216,"》,":1818,"在中國":1179,"立於 ":1061,"栽培。":2896,"是香港":1720,"休 ":665,"使 ":756,"不、":2094,"不。":739,"丈」":981,"丈》":585,"丈、":2906,"丈。":2027,"丁、":2136,"丁。":1921,"一。":1804,"丞、":1947,"丞。":1850,"丕」":693,"丕。":1789,"丕、":2245,"中、":800,"人。":1182,"事。":826,"交。":660,"亞、":852,"倫 ":745,"丈山":729,"丈屬":937,"不家":1629,"丈小":1088,"丈家":1181,"丁屬":1243,"中國":13565,"丈學":945,"丈子":859,"一家":831,"丕大":655,"乘倫":1335,"丈大":605,"丕地":870,"丁大":588,"乘丁":705,"乘一":736,"佐。":1221,"乘丈":663,"佐、":761,"丈地":748,"丞和":584,"之一":4708,"丁國":1032,"丞勞":850,"丕勞":1045,"丈和":615,"不同":2051,"不勞":723,"中使":2667,"不區":1235,"中一":646,"丞使":1157,"丞倫":1278,"丈勞":1514,"丞人":604,"丈克":1050,"丈其":690,"丕使":877,"一勞":758,"丞佐":1297,"不公":954,"丁勞":1850,"並丁":839,"丕倫":1815,"丞休":1067,"丈倫":1781,"不使":1931,"休。":1287,"休、":1097,"丁克":614,"丞丈":3784,"丞不":839,"丞丁":2627,"丞丕":3712,"丕休":1238,"丞丞":2873,"丕佐":865,"不交":3733,"不京":1465,"不事":953,"丈休":1744,"一個":9748,"丈使":1114,"丈佐":1124,"丁倫":2045,"丕丞":2819,"丕丕":4439,"不休":656,"丕不":779,"丕丈":4929,"丕丁":2910,"丕乘":689,"丈不":986,"丈丈":10533,"丈丕":5787,"丈丞":4591,"丁休":2124,"丈之":678,"上不":1486,"一位":1048,"丈乘":1046,"丁佐":630,"丈事":641,"丁使":3115,"不丈":1385,"不丁":1326,"不丕":1047,"不不":1140,"不丞":1080,"一丈":689,"丁丕":3008,"丁丞":3158,"丁丈":5062,"丁丁":3771,"丁不":1124,"丁乘":842,"一些":1051,"份、":614,"丈一":1125,"丈丁":5951,"丕樂":705,"主教":1120,"任何":653,"丞業":742,"中文":1114,"人口":1812,"一次":950,"丈林":808,"一條":1013,"之後":1287,"種栽培":2894,"丕於":989,"他們":991,"事場":701,"丞於":627,"丈於":1045,"人使":893,"丁是":707,"丈是":753,"不拔":3356,"二十":705,"人丁":915,"人丈":695,"主席":690,"丁教":802,"丁斯":911,"丁於":991,"丁文":610,"一所":718,"交休":759,"乘大":1193,"事務":628,"不式":1114,"中學":1267,"交不":718,"使。":1730,"使、":1391,"丁店":631,"一座":888,"中央":1281,"丕小":677,"丕屬":955,"事交":1241,"丞家":1096,"丞寫":642,"佐勞":651,"中的":2868,"休如":836,"丈科":1482,"一種":4747,"丞的":2226,"份年":660,"使休":786,"使代":599,"使中":614,"二次":594,"使丈":1261,"使上":902,"使丁":966,"使丞":904,"使丕":680,"下的":914,"世界":3842,"上的":1685,"丈的":3553,"乘江":1087,"佐丞":598,"佐丕":890,"丁的":2951,"佐不":741,"佐丈":1040,"佐丁":1316,"不生":995,"交於":631,"丕的":2516,"不的":1824,"倫。":904,"倫、":1101,"丈爾":927,"丕然":602,"丁爾":1156,"也有":714,"不現":1191,"人工":3084,"丈球":618,"休丈":1588,"休丁":1289,"休丕":1088,"休丞":1470,"以及":5705,"不治":1653,"休倫":752,"也是":2445,"乘斯":612,"休佐":739,"休休":1180,"休使":949,"丁語":647,"交的":662,"何成":648,"丕西":1266,"但是":741,"人的":1304,"丕語":843,"主義":1789,"丁蘭":617,"事的":883,"人物":959,"企業":965,"丁西":590,"中華":3016,"一般":2431,"不聯":718,"人民":2356,"丈至":635,"丈草":589,"使團":1465,"前 ":869,"作家":983,"作品":1437,"使倫":938,"世紀":2133,"亞洲":978,"丁聯":1080,"乘的":932,"到 ":1125,"丞 ":1327,"丕 ":1248,"稱於「":1031,"丈 ":1426,"丈·":665,"丁 ":1214,"丁·":957,"地、":843,"商業":792,"國、":913,"倫,":2201,"又譯":655,"問宮":915,"單位":908,"員會":1240,"可能":966,"南部":1208,"名稱":1366,"參與":743,"各種":710,"名的":1486,"同的":917,"又稱":2281,"使(":775,"使,":3019,"位,":692,"佐,":2446,"台灣":5826,"何,":895,"作,":878,"只有":589,"南等":606,"休(":898,"休,":2604,"同時":1361,"和國":2079,"名於":1540,"在 ":4228,"命名":845,"和丕":658,"和丞":617,"區的":1565,"創辦":644,"和丈":1045,"和丁":617,"前身":709,"交,":1096,"人,":2364,"反應":687,"分類":693,"化的":604,"事,":1473,"勞立":1122,"國王":742,"城事":1733,"因此":1472,"國民":1001,"基丁":1219,"基丞":778,"因於":1311,"多生聞":623,"分,":730,"國大":4188,"四川":1895,"地區":6934,"國國":1282,"在台":591,"國家":4180," 公里":1210,"國丁":723,"國丈":683,"國不":1346,"國人":979,"內,":588,"在丕":590,"在不":766,"在丈":1169,"在丁":857,"地不":1518,"在中":1499,"培。":2897,"保護":897,"公園":1063,"全國":1075,"共和":2094,"共同":713,"公司":6083,"和 ":817,"分丁":734,"勞。":848,"勞、":713,"使蘭":928,"佐責":846,"倫爾":803,"及 ":587,"來自":904,"人類":938,"其他":1807,"公共":721,"倫用":717,"內信":886,"其中":1932,"兩個":962,"倫的":1758,"俄羅":1193,"內丁":817,"交通":965,"代表":1917,"使用":3276,"使理":2623,"來的":817,"使的":2298,"何的":820,"佐的":1260,"作用":690,"之間":1600,"倫州":1179,"作的":823,"何能":735,"倫有":1307,"九龍":820,"倫斯":769,"使究":2861,"倫何":704,"不部":1510,"倫休":862,"代的":605,"倫倫":983,"倫克":676,"使於":674,"使本":654,"位於":6989,"個人":1069,"丁近":678,"作於":1594,"丈車":636,"主要":4266,"一部":1589,"他的":940,"倫丈":1719,"倫丁":1808,"倫丞":1219,"倫丕":1126,"倫中":896,"信息":690,"丈體":712,"倫多":1308,"倫勞":1159,"休畫":658,"人聞":943,"休的":1677,"不面":1013,"及丈":747,"及中":2170,"丕(":1556,"丕,":3869,"下,":946,"上,":1460,"丈(":2498,"丈,":5085,"半島":716,"不,":1457,"一,":2375,"丁)":1026,"丁,":3944,"丁(":1688,"包括":3326,"參加":686,"員。":603,"中,":3370,"及其":661,"創立":812,"原名":722,"丞,":4229,"丞(":1428,"乘,":704,"動物":1355,"又名":874,"勞灣":831,"印度":2180,"可以":2687,"台不":1162,"勞的":1695,"協會":1036,"名使":755,"動畫":650,"合作":595,"包含":733,"南不":932,"公路":1194,"化學":839,"於香港":1347,"利用":694," 世紀":1443,"區域":760,"公里":2070,"內的":698,"倫體":1121,"前尚":2709,"分於":856,"勞丞":1027,"勞休":691,"勞任":888,"勞不":751,"勞丈":1379,"勞丁":1206,"勞丕":1033,"勞倫":1202,"勞佐":918,"名。":909,"分別":960,"利亞":1460,"傳統":899,"共有":696,"具有":1054,"區。":805,"區、":855,"南、":2848,"創作":724,"分布":3537,"全球":780,"加乘":907,"場,":657,"州事":599,"工作":1351,"巴乘":819,"學院":1919,"屬的":3350,"度、":646,"帝國":1099,"工引":2892,"平不":1295,"山谷":592,"年代":1818,"布在":1588,"山西":699,"小都":651,"實際":604,"建、":593,"小說":1488,"巴使":882,"希丕":1033,"尚未":2823,"定的":781,"州、":1207,"地,":4121,"川、":1254,"、雲南":1181,"對於":1252,"它的":613,"學的":914,"山坡":1674,"國,":702,"學生":932,"小的":1375,"山東":747,"屬於":2028,"德·":729,"定義":598,"媒體":593,"就是":946,"家的":1003," 年 ":13455,"形式":845,"形成":781,"德國":1532,"後來":987,"廣播":596,"廣東":1877,"建於":727,"年的":1359,"建立":1105,"引種":2905,"年至":809,"拔 ":3138,"廣乘":652,"外,":1036,"工業":864,"布於":1775,"建佐":1764,"年在":773,"廣州":765,"工程":1106,"已經":809,"常生":722,"廣場":674,"團體":692,"大學":4750,"國際":3079,"名:":4017,"名,":805,"大戰":639,"司,":903,"司(":707,"太平":715,"委員":1628,"多生":1260,"動,":770,"勞,":1822,"國立":626,"國的":3067,"基本":664,"境內":659,"區,":4922,"大利":1318,"大使":1011,"家 ":671,"天休":592,"天主":779,"大丈":858,"大丕":898,"學中":593,"大陸":4384,"學使":615,"安丁":874,"存在":831,"學名":3781,"家丈":660,"家丁":836,"學家":1871,"島、":590,"年 ":13925,"小丕":726,"小丈":935,"家國":1674,"專倫":637,"對係":1024,"尼亞":1180,"學校":1548,"它是":687,"家律":639,"宗教":606,"山丞":856,"大的":1820,"品,":659,"學、":1095,"未由人":2697,"員,":1301,"太空":651,"家、":1074,"家。":1302,"大部":622,"東不":1591,"是由":1946,"有對":649,"於美":890,"最大":1529,"成,":1008,"最早":863,"是美":1276,"日至":621,"最後":917,"時的":620,"朝宮":1146,"林中":937,"林下":865,"林丈":744,"林丕":654,"東南":851,"是於":666,"是日":750,"最丈":682,"教育":1764,"斯特":828,"是指":1896,"服務":1801," 日 ":1059,"時期":1763,"有一":1032,"有丈":631,"栽培":2950,"時間":1470," 月 ":10453,"期的":813,"未由":2698,"有的":742,"東省":644,"是香":1731," 年,":2603," 年)":2399,"有植":939,"有時":596,"會的":752,"於香":1366,"故事":841,"後,":2045,"教丁":618,"教休":765,"文使":808,"、湖不":767,"斯丁":773,"文化":2109,"、江西":640,"於丁":1931,"於一":1279,"於丈":3104,"於不":3971,"於丕":2015,"於丞":1568,"於中":3228,"於主":1138,"式,":713,"於「":3160,"是「":751,"是台":621,"時代":1179,"是在":1454,"東、":1223,"於是":782,"於日":1024,"早期":592,"日本":5548,"於倫":790,"、湖南":720,"名:)":3240,"於了":898,"於人":919,"斯坦":674,"文學":1074,"於台":1510,"數學":761,"於勞":777,"數據":647,"於山":668,"是位":626,"是丕":1220,"是丞":853,"是中":2852,"日在":676,"是丁":1400,"是一":8457,"是不":724,"是丈":2046,"教會":604,"是 ":1586,"推不":777," 年的":915,"或稱":642,"成立":2635,"戰爭":1266,"成的":1247,"日 ":1136,"於 ":12568,"斯·":1030,"所有":1063,"應用":957,"拉丁":1113,"成於":2501,"投資":589,"月 ":10505,"有 ":1922,"技術":1647,"年(":1135,"年)":2513,"年,":3020," 年至":781,"提不":748,"提供":1573,"控制":697,"或者":865,"宮,":689,"家(":883,"家,":2956,"學(":695,"學,":1273,"子,":930,"成。":673,"年間":605,"廣西":1228," 年在":693,"屬(":1280," 年代":1445," 平不":1026,"成員":1192,"所以":843,"成何":668,"影響":1080,"小,":1059,"委員會":1211,"流行":628,"業,":586," 日)":775," 日,":1367,"源於":682,"爾·":762,"沒有":1285,"活動":1238,"比賽":1111,"江蘇":807,"江西":972,"湖不":1117,"湖南":1294,"江、":1010,"斯(":607,"文:":2388,"機構":1217,"死對":1361,"、廣東":743,"日,":1544,"日)":813,"歷使":2356," 日至":616,"民國":1569,"歐洲":1588,"民主":899,"民共":1266,"正式":1274,"時,":1278,"河南":853,"月,":734,"、廣西":861,"會,":853,"會(":980,"民族":1066,"期,":613,"河不":810,"根據":1260,"會議":766,"最高":966,"期間":1013,"有限":1519,"標佐":1052,"植物":4908," 是一":681,"概念":627," 日在":656,"的電":999,"稱「":1043,"的西":633,"發行":1127,"的重":753,"第 ":1807,"的發":596,"的第":1621,"物,":2112,"目的":1040,"的是":1255,"的最":739,"的植":2894,"直接":612,"發現":996,"的特":1537,"積 ":785,"發生":1316,"的對":648,"的小":1527,"的家":632,"發展":2338,"的大":1229,"的國":1195,"的地":4227,"目前":4386,"的丁":3310,"的一":9461,"用的":1238,"生的":842,"產生":949,"生產":964,"球隊":888,"生物":1143,"生聞":4477,"甘肅":1049,"的名":796,"的勞":1368,"的倫":1653,"的休":1719,"的使":1916,"的佐":1046,"的作":651,"的主":1361,"的中":1197,"的丕":3244,"的丞":2994,"的丈":5094,"的不":2456,"的乘":747,"的人":1899,"的交":1021,"生於":2502,"用於":1261,"由於":1686,"理論":1080,"當時":1405,"生活":843,"生在":746,"產品":771,"的。":900,"的《":764,"的「":1273,"環境":892,"由人":2997,"用來":777,"理學":1070,"現在":1079,"王朝":657,"現代":897,"獲得":1128,"的 ":1662,"用。":731,"班丁":801,"物理":701,"特有":1087,"特別":1033,"澳門":921,"、福建":587,"物。":3616,"聯合":1423,"而成":666,"聞在":1114,"等,":840,"聞於":3447,"肅、":797,"網路":1657,"總統":750,"稱,":608,"種,":743,"美國":6254,"有限公":1342,"義大":928,"群島":661,"羅斯":1391,"聯事":701,"美洲":846,"站,":1417,"站(":605,"聯休":1628,"立,":947,"經濟":1788,"統的":590,"經營":801,"、甘肅":803,"線的":712,"至 ":5663,"自 ":699,"紀念":700,"簡稱":3399,"組成":1456,"。由於":638,"聞 ":661,"米的":3024,"結構":812,"米至":2731,"系統":2899,"統治":615,"目,":621,"結丁":586,"組佐":2037,"約丈":598,"系使":1485,"節目":923,"立於":1349,"等地":3334,"的,":1232,"天主教":743,"立的":1251,"生,":616,"用,":772,"程式":650,"科技":622,"約 ":1720,"第三":1132,"第一":3441,"第二":2120,"稱於":4215,"種栽":2894,"科丈":1047,"等。":1259,"科學":1716,"福建":1133,"社會":2251,"站。":627,"角色":606,"計算":1063,"設立":673,"西部":622,"製造":737,"認於":1497,"西班":773,"要的":1104,"被稱":1048,"計劃":875,"越南":953,"資料":957,"賽事":631,"語言":1720,"設計":1777,"號,":798,"處,":614,"譯於":650,"超過":651,"路線":849,"足球":1703,"資訊":664,"行,":1162,"醫學":647,"進行":2272,"都是":704,"過程":791,"這種":792,"部分":2342,"部份":776,"遊戲":1924,"連接":662,"通常":1653,"運動":2496,"語:":3929,"說,":690,"車站":2410,"這個":1488,"這些":923,"於日本":917,"自治":728,"自然":792,"英國":2374,"自由":877,"般生":678,"線,":642,"航空":1143,"草地":752," 米的":2958,"自丁":786,"羅馬":1149,"與丈":666," 米至":2728,"米,":753,"聯賽":916,"華民":1238,"英語":2016,"者,":759,"舉行":1293,"英文":2836,"舉辦":651,"華人":1471,"著名":1732,"蘇聯":599,"處理":911,"藝術":1217,"行。":771,"聞,":628,"行於":853,"製作":1162,"西南":747,"行的":1255,"西份":1005,"西亞":1235,"西不":1211,"行不":2204,"語 ":675,"西、":2735,"中,目":813,"是位於":586,"間,":1121,"是一種":2255,"香港":8631,"高丁":607,"體的":647,"隊,":588,"高速":865,"體育":810,"及中國":2028,"公里,":1100,"體,":795,"是一個":2235,"丈(學":765,"是中國":2143,"於台灣":1145,"選舉":733,"通過":1270,"部的":1066,"賽,":689,"路,":930,"重要":1746,"銀行":879,"鐵家":726,"的第一":601,"重要的":694,"開始":2056,"部,":1123,"除了":587,"限公":1343,"鐵路":1902,"電勞":1154,"雲南":1736,"阿拉":770,"間的":1117,"開發":1451,"陸的":3080,"里,":1236,"電影":2042,"阿爾":603,"電子":1071,"面積":1525,"非洲":681,"領域":708,"項目":726,"電視":2609,"音樂":1761,"需要":625,"馬來":712,"有植物":938,"的特有":970,"是美國":1183,"的植物":2889,"日至 ":606,"前尚未":2703,"最大的":952,"於美國":799,"加乘大":716,"是日本":699,"目前尚":2707,"的地區":3107,"生聞在":1091,"生聞於":3237,"甘肅、":794,"的一部":774,"的主要":668,"的一種":1474,"年),":737,"的一個":3094,"限公司":1342,"年( ":710,"於不拔":2919,"於中國":2310," ,是":653,"南等地":586,"),":14128,"()":3756,"(,":1173,",)":1558,":,":731,":)":4068,"由人工":2898,",東":861,",有":1487,",最":1123,",曾":1063,",是":13163,")是":10839,",於":6392,",此":660,",後":1253,",從":882,",常":1047,",故":644,")於":2446,",指":584,",所":993,",或":1331,",成":1293,")的":2203,",目":3631,",簡":2031,",第":778,",現":1338,",由":3905,",用":642,",生":3524,",當":880,",西":834,",被":860,",該":1017,",經":598,",總":744,",美":597,",而":3222,",英":973,",與":1255,"(英":2412,",香":721,",通":885,",這":1582,",「":615,",《":690,")。":3711,")、":2876,"(學":3641,",它":1379,",屬":841,",小":787,",對":650,",因":2415,",在":4525,",多":1566,",大":803,",如":966,",前":662,",分":861,",南":727,",即":1028,",勞":1219,",包":1288,")和":952,",同":897,",台":652,",可":1102,",又":2944,",原":1271,",不":2771,",丕":3583,",丞":2297,",並":3993,",中":1698,",主":1659,"(今":666,",乘":1385,",也":3255,"(丈":751,",丈":5090,",丁":3996,",一":2348,",休":1371,",但":3353,",位":2751,",佐":784,",使":1949,",交":834,",亦":1195,",人":871,",以":3497,",他":1340,",份":756,",倫":1535,",共":754,",其":3556,",全":1257,"( ":3933,") ":996,", ":7569,"- ":815,"雲南、":1086,"丁屬(":787,"華民國":1215,"廣西、":800,"中國的":1325,"中國大":3838,"之一,":2265,"英語:":1339,"不拔 ":3137,"引種栽":2892,"丈屬的":703,"人工引":2892," ),":596,"乘江、":593,"特有植":935,"以及中":1990,"一般生":678,"中華人":1156,"英文:":1510,"丕西、":804,"中華民":1237,"廣東、":761,"華人民":1156,"人民共":1261,":)於":1432,":)是":1898,"),又":978,"),是":2411,"()是":1113,",),":1004,"著名的":780,"(),":1524,"位於香":588,"年至 ":713,"面積 ":770,"倫州、":844,"之間的":628,"成立於":922,"內丁使":611,"俄羅斯":1193,",香港":708,"物。分":2798,"公司(":691,"公司,":864,"行不區":1022,"共和國":1943,"分布於":1717,"分布在":1578,"》、《":944,"」、「":864,",於中":674,")是丈":645,")是一":2670,",是一":2178,",是中":1286,"湖南、":689,"あああ":1321,"尚未由":2697,"地,生":2880,",常生":667,",於 ":2197,",所以":698,",又稱":1386,",因此":1151,",多生":1249,"聞於不":2897,"(學名":3634,"。分布":2903,"、印度":793,"、乘江":625,"、丕西":798,"、倫州":850,"、山坡":668,"被稱於":856,"、四川":1250,"大陸的":3064,"アアア":1275,"學名:":3509,"(英語":1020,"(英文":1336,"義大利":914,",目前":3420,"西班丁":773,",生聞":2926,",簡稱":1929,"平不公":818,"工引種":2892,",包括":1128,"米的地":2889,",又名":585,",在 ":642,",其中":943,",以及":1003,",也是":1481,",一般":1212,",主要":1207,",位於":2550,",並丁":649,",中國":911,"屬的植":2808,"丁使、":633,"丈丈丁":628,"江西、":618,"湖不、":763,"不同的":723,"米至 ":2729,"之一。":1752,"不公里":761,"丈丈,":616},"n_words":[4924775,1867501,309785],"name":"zh-tw"}
\ No newline at end of file diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/LangProfile.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/LangProfile.cs new file mode 100644 index 000000000..0413edfad --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/LangProfile.cs @@ -0,0 +1,118 @@ +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace NLangDetect.Core.Utils +{ + public class LangProfile + { + private const int MinimumFreq = 2; + private const int LessFreqRatio = 100000; + + public string name { get; set; } + + public Dictionary<string, int> freq { get; set; } + public int[] n_words { get; set; } + + #region Constructor(s) + + public LangProfile() + { + freq = new Dictionary<string, int>(); + n_words = new int[NGram.GramsCount]; + } + + public LangProfile(string name) + { + this.name = name; + freq = new Dictionary<string, int>(); + n_words = new int[NGram.GramsCount]; + } + + #endregion + + #region Public methods + + public void Add(string gram) + { + if (name == null || gram == null) return; // Illegal + int len = gram.Length; + if (len < 1 || len > NGram.GramsCount) return; // Illegal + + n_words[len - 1]++; + + if (freq.ContainsKey(gram)) + { + freq[gram] = freq[gram] + 1; + } + else + { + freq.Add(gram, 1); + } + } + + public void OmitLessFreq() + { + if (name == null) return; // Illegal + int threshold = n_words[0] / LessFreqRatio; + if (threshold < MinimumFreq) threshold = MinimumFreq; + + ICollection<string> keys = freq.Keys; + int roman = 0; + // TODO IMM HI: move up? + Regex regex1 = new Regex("^[A-Za-z]$", RegexOptions.Compiled); + List<string> keysToRemove = new List<string>(); + + foreach (string key in keys) + { + int count = freq[key]; + + if (count <= threshold) + { + n_words[key.Length - 1] -= count; + keysToRemove.Add(key); + } + else + { + if (regex1.IsMatch(key)) + { + roman += count; + } + } + } + + foreach (string keyToRemove in keysToRemove) + { + freq.Remove(keyToRemove); + } + + // roman check + keysToRemove = new List<string>(); + + if (roman < n_words[0] / 3) + { + ICollection<string> keys2 = freq.Keys; + + // TODO IMM HI: move up? + Regex regex2 = new Regex(".*[A-Za-z].*", RegexOptions.Compiled); + + foreach (string key in keys2) + { + int count = freq[key]; + + if (regex2.IsMatch(key)) + { + n_words[key.Length - 1] -= count; + keysToRemove.Add(key); + } + } + + foreach (string keyToRemove in keysToRemove) + { + freq.Remove(keyToRemove); + } + } + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/Messages.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/Messages.cs new file mode 100644 index 000000000..1d605cc47 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/Messages.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Linq; +using System; + +namespace NLangDetect.Core.Utils +{ + public static class Messages + { + private static readonly Dictionary<string, string> _messages; + + static Messages() + { + _messages = LoadMessages(); + } + + public static string getString(string key) + { + string value; + + return + _messages.TryGetValue(key, out value) + ? value + : string.Format("!{0}!", key); + } + + private static Dictionary<string, string> LoadMessages() + { + var manifestName = typeof(Messages).Assembly.GetManifestResourceNames().FirstOrDefault(i => i.IndexOf("messages.properties", StringComparison.Ordinal) != -1) ; + + Stream messagesStream = + typeof(Messages).Assembly + .GetManifestResourceStream(manifestName); + + if (messagesStream == null) + { + throw new InternalException(string.Format("Couldn't get embedded resource named '{0}'.", manifestName)); + } + + using (messagesStream) + using (var sr = new StreamReader(messagesStream)) + { + var messages = new Dictionary<string, string>(); + + while (!sr.EndOfStream) + { + string line = sr.ReadLine(); + + if (string.IsNullOrEmpty(line)) + { + continue; + } + + string[] keyValue = line.Split('='); + + if (keyValue.Length != 2) + { + throw new InternalException(string.Format("Invalid format of the 'Messages.properties' resource. Offending line: '{0}'.", line.Trim())); + } + + string key = keyValue[0]; + string value = UnescapeUnicodeString(keyValue[1]); + + messages.Add(key, value); + } + + return messages; + } + } + + /// <remarks> + /// Taken from: http://stackoverflow.com/questions/1615559/converting-unicode-strings-to-escaped-ascii-string/1615860#1615860 + /// </remarks> + private static string UnescapeUnicodeString(string s) + { + if (s == null) + { + return null; + } + + return + Regex.Replace( + s, + @"\\u(?<Value>[a-zA-Z0-9]{4})", + match => ((char)int.Parse(match.Groups["Value"].Value, NumberStyles.HexNumber)).ToString()); + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/NGram.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/NGram.cs new file mode 100644 index 000000000..b1738f7ca --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/NGram.cs @@ -0,0 +1,330 @@ +// TODO IMM HI: check which classes can be made internal? + +using System.Collections.Generic; +using System.Text; +using NLangDetect.Core.Extensions; + +namespace NLangDetect.Core.Utils +{ + public class NGram + { + public const int GramsCount = 3; + + private static readonly string Latin1Excluded = Messages.getString("NGram.LATIN1_EXCLUDE"); + + private static readonly string[] CjkClass = + { + #region CJK classes + + Messages.getString("NGram.KANJI_1_0"), + Messages.getString("NGram.KANJI_1_2"), + Messages.getString("NGram.KANJI_1_4"), + Messages.getString("NGram.KANJI_1_8"), + Messages.getString("NGram.KANJI_1_11"), + Messages.getString("NGram.KANJI_1_12"), + Messages.getString("NGram.KANJI_1_13"), + Messages.getString("NGram.KANJI_1_14"), + Messages.getString("NGram.KANJI_1_16"), + Messages.getString("NGram.KANJI_1_18"), + Messages.getString("NGram.KANJI_1_22"), + Messages.getString("NGram.KANJI_1_27"), + Messages.getString("NGram.KANJI_1_29"), + Messages.getString("NGram.KANJI_1_31"), + Messages.getString("NGram.KANJI_1_35"), + Messages.getString("NGram.KANJI_2_0"), + Messages.getString("NGram.KANJI_2_1"), + Messages.getString("NGram.KANJI_2_4"), + Messages.getString("NGram.KANJI_2_9"), + Messages.getString("NGram.KANJI_2_10"), + Messages.getString("NGram.KANJI_2_11"), + Messages.getString("NGram.KANJI_2_12"), + Messages.getString("NGram.KANJI_2_13"), + Messages.getString("NGram.KANJI_2_15"), + Messages.getString("NGram.KANJI_2_16"), + Messages.getString("NGram.KANJI_2_18"), + Messages.getString("NGram.KANJI_2_21"), + Messages.getString("NGram.KANJI_2_22"), + Messages.getString("NGram.KANJI_2_23"), + Messages.getString("NGram.KANJI_2_28"), + Messages.getString("NGram.KANJI_2_29"), + Messages.getString("NGram.KANJI_2_30"), + Messages.getString("NGram.KANJI_2_31"), + Messages.getString("NGram.KANJI_2_32"), + Messages.getString("NGram.KANJI_2_35"), + Messages.getString("NGram.KANJI_2_36"), + Messages.getString("NGram.KANJI_2_37"), + Messages.getString("NGram.KANJI_2_38"), + Messages.getString("NGram.KANJI_3_1"), + Messages.getString("NGram.KANJI_3_2"), + Messages.getString("NGram.KANJI_3_3"), + Messages.getString("NGram.KANJI_3_4"), + Messages.getString("NGram.KANJI_3_5"), + Messages.getString("NGram.KANJI_3_8"), + Messages.getString("NGram.KANJI_3_9"), + Messages.getString("NGram.KANJI_3_11"), + Messages.getString("NGram.KANJI_3_12"), + Messages.getString("NGram.KANJI_3_13"), + Messages.getString("NGram.KANJI_3_15"), + Messages.getString("NGram.KANJI_3_16"), + Messages.getString("NGram.KANJI_3_18"), + Messages.getString("NGram.KANJI_3_19"), + Messages.getString("NGram.KANJI_3_22"), + Messages.getString("NGram.KANJI_3_23"), + Messages.getString("NGram.KANJI_3_27"), + Messages.getString("NGram.KANJI_3_29"), + Messages.getString("NGram.KANJI_3_30"), + Messages.getString("NGram.KANJI_3_31"), + Messages.getString("NGram.KANJI_3_32"), + Messages.getString("NGram.KANJI_3_35"), + Messages.getString("NGram.KANJI_3_36"), + Messages.getString("NGram.KANJI_3_37"), + Messages.getString("NGram.KANJI_3_38"), + Messages.getString("NGram.KANJI_4_0"), + Messages.getString("NGram.KANJI_4_9"), + Messages.getString("NGram.KANJI_4_10"), + Messages.getString("NGram.KANJI_4_16"), + Messages.getString("NGram.KANJI_4_17"), + Messages.getString("NGram.KANJI_4_18"), + Messages.getString("NGram.KANJI_4_22"), + Messages.getString("NGram.KANJI_4_24"), + Messages.getString("NGram.KANJI_4_28"), + Messages.getString("NGram.KANJI_4_34"), + Messages.getString("NGram.KANJI_4_39"), + Messages.getString("NGram.KANJI_5_10"), + Messages.getString("NGram.KANJI_5_11"), + Messages.getString("NGram.KANJI_5_12"), + Messages.getString("NGram.KANJI_5_13"), + Messages.getString("NGram.KANJI_5_14"), + Messages.getString("NGram.KANJI_5_18"), + Messages.getString("NGram.KANJI_5_26"), + Messages.getString("NGram.KANJI_5_29"), + Messages.getString("NGram.KANJI_5_34"), + Messages.getString("NGram.KANJI_5_39"), + Messages.getString("NGram.KANJI_6_0"), + Messages.getString("NGram.KANJI_6_3"), + Messages.getString("NGram.KANJI_6_9"), + Messages.getString("NGram.KANJI_6_10"), + Messages.getString("NGram.KANJI_6_11"), + Messages.getString("NGram.KANJI_6_12"), + Messages.getString("NGram.KANJI_6_16"), + Messages.getString("NGram.KANJI_6_18"), + Messages.getString("NGram.KANJI_6_20"), + Messages.getString("NGram.KANJI_6_21"), + Messages.getString("NGram.KANJI_6_22"), + Messages.getString("NGram.KANJI_6_23"), + Messages.getString("NGram.KANJI_6_25"), + Messages.getString("NGram.KANJI_6_28"), + Messages.getString("NGram.KANJI_6_29"), + Messages.getString("NGram.KANJI_6_30"), + Messages.getString("NGram.KANJI_6_32"), + Messages.getString("NGram.KANJI_6_34"), + Messages.getString("NGram.KANJI_6_35"), + Messages.getString("NGram.KANJI_6_37"), + Messages.getString("NGram.KANJI_6_39"), + Messages.getString("NGram.KANJI_7_0"), + Messages.getString("NGram.KANJI_7_3"), + Messages.getString("NGram.KANJI_7_6"), + Messages.getString("NGram.KANJI_7_7"), + Messages.getString("NGram.KANJI_7_9"), + Messages.getString("NGram.KANJI_7_11"), + Messages.getString("NGram.KANJI_7_12"), + Messages.getString("NGram.KANJI_7_13"), + Messages.getString("NGram.KANJI_7_16"), + Messages.getString("NGram.KANJI_7_18"), + Messages.getString("NGram.KANJI_7_19"), + Messages.getString("NGram.KANJI_7_20"), + Messages.getString("NGram.KANJI_7_21"), + Messages.getString("NGram.KANJI_7_23"), + Messages.getString("NGram.KANJI_7_25"), + Messages.getString("NGram.KANJI_7_28"), + Messages.getString("NGram.KANJI_7_29"), + Messages.getString("NGram.KANJI_7_32"), + Messages.getString("NGram.KANJI_7_33"), + Messages.getString("NGram.KANJI_7_35"), + Messages.getString("NGram.KANJI_7_37"), + + #endregion + }; + + private static readonly Dictionary<char, char> _cjkMap; + + private StringBuilder _grams; + private bool _capitalword; + + #region Constructor(s) + + static NGram() + { + _cjkMap = new Dictionary<char, char>(); + + foreach (string cjk_list in CjkClass) + { + char representative = cjk_list[0]; + + for (int i = 0; i < cjk_list.Length; i++) + { + _cjkMap.Add(cjk_list[i], representative); + } + } + } + + public NGram() + { + _grams = new StringBuilder(" "); + _capitalword = false; + } + + #endregion + + #region Public methods + + public static char Normalize(char ch) + { + UnicodeBlock? unicodeBlock = ch.GetUnicodeBlock(); + + if (!unicodeBlock.HasValue) + { + return ch; + } + + switch (unicodeBlock.Value) + { + case UnicodeBlock.BasicLatin: + { + if (ch < 'A' || (ch < 'a' && ch > 'Z') || ch > 'z') + { + return ' '; + } + + break; + } + + case UnicodeBlock.Latin1Supplement: + { + if (Latin1Excluded.IndexOf(ch) >= 0) + { + return ' '; + } + + break; + } + + case UnicodeBlock.GeneralPunctuation: + { + return ' '; + } + + case UnicodeBlock.Arabic: + { + if (ch == '\u06cc') + { + return '\u064a'; + } + + break; + } + + case UnicodeBlock.LatinExtendedAdditional: + { + if (ch >= '\u1ea0') + { + return '\u1ec3'; + } + + break; + } + + case UnicodeBlock.Hiragana: + { + return '\u3042'; + } + + case UnicodeBlock.Katakana: + { + return '\u30a2'; + } + + case UnicodeBlock.Bopomofo: + case UnicodeBlock.BopomofoExtended: + { + return '\u3105'; + } + + case UnicodeBlock.CjkUnifiedIdeographs: + { + if (_cjkMap.ContainsKey(ch)) + { + return _cjkMap[ch]; + } + + break; + } + + case UnicodeBlock.HangulSyllables: + { + return '\uac00'; + } + } + + return ch; + } + + public void AddChar(char ch) + { + ch = Normalize(ch); + char lastchar = _grams[_grams.Length - 1]; + if (lastchar == ' ') + { + _grams = new StringBuilder(" "); + _capitalword = false; + if (ch == ' ') return; + } + else if (_grams.Length >= GramsCount) + { + _grams.Remove(0, 1); + } + _grams.Append(ch); + + if (char.IsUpper(ch)) + { + if (char.IsUpper(lastchar)) _capitalword = true; + } + else + { + _capitalword = false; + } + } + + public string Get(int n) + { + if (_capitalword) + { + return null; + } + + int len = _grams.Length; + + if (n < 1 || n > 3 || len < n) + { + return null; + } + + if (n == 1) + { + char ch = _grams[len - 1]; + + if (ch == ' ') + { + return null; + } + + return ch.ToString(); + } + + // TODO IMM HI: is ToString() here effective? + return _grams.ToString().SubSequence(len - n, len); + } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/TagExtractor.cs b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/TagExtractor.cs new file mode 100644 index 000000000..896fd0960 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/TagExtractor.cs @@ -0,0 +1,76 @@ +using System.Text; + +namespace NLangDetect.Core.Utils +{ + public class TagExtractor + { + // TODO IMM HI: do the really need to be internal? + internal string Target; + internal int Threshold; + internal StringBuilder StringBuilder; + internal string Tag; + + #region Constructor(s) + + public TagExtractor(string tag, int threshold) + { + Target = tag; + Threshold = threshold; + Count = 0; + Clear(); + } + + #endregion + + #region Public methods + + public void Clear() + { + StringBuilder = new StringBuilder(); + Tag = null; + } + + public void SetTag(string tag) + { + Tag = tag; + } + + public void Add(string line) + { + if (Tag == Target && line != null) + { + StringBuilder.Append(line); + } + } + + public void CloseTag(LangProfile profile) + { + if (profile != null && Tag == Target && StringBuilder.Length > Threshold) + { + var gram = new NGram(); + + for (int i = 0; i < StringBuilder.Length; i++) + { + gram.AddChar(StringBuilder[i]); + + for (int n = 1; n <= NGram.GramsCount; n++) + { + profile.Add(gram.Get(n)); + } + } + + Count++; + } + + Clear(); + } + + #endregion + + #region Properties + + public int Count { get; private set; } + + #endregion + } +} diff --git a/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/messages.properties b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/messages.properties new file mode 100644 index 000000000..7967efff0 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/NLangDetect/Utils/messages.properties @@ -0,0 +1,128 @@ +NGram.CJK_KANJI_EXCLUDE=\u0020\uFF08\uFF09 +NGram.LATIN1_EXCLUDE=\u00A0\u00AB\u00B0\u00BB +NGram.KANJI_1_0=\u4F7C\u6934 +NGram.KANJI_1_2=\u88CF\u95B2 +NGram.KANJI_1_4=\u7027\u7DCB +NGram.KANJI_1_8=\u4E80\u4E9C\u4EEE\u5263\u5264\u5270\u52C5\u52E7\u52F2\u53B3\u5449\u58CA\u58CC\u5968\u59C9\u59EB\u5D8B\u5DE3\u5E30\u6075\u622F\u623B\u6255\u629C\u629E\u62DD\u62E1\u633F\u635C\u63FA\u6442\u6589\u658E\u6669\u66A6\u66FD\u6804\u685C\u6B69\u6B6F\u6BBB\u6C37\u6C5A\u6D44\u6E09\u6E0B\u6E13\u6EDD\u713C\u72A0\u731F\u7363\u7A32\u7A42\u7A93\u7ADC\u7C8B\u7C9B\u7DD1\u7E01\u7E04\u7E26\u7E4A\u7E4B\u7E70\u8074\u8107\u8133\u81D3\u820E\u8217\u8358\u83D3\u85AC\u8987\u899A\u8B21\u8B72\u8B83\u8CDB\u9045\u90F7\u91C8\u9271\u9283\u92AD\u9665\u967A\u96A0\u96A3\u96B7\u970A\u983C\u9854\u9855\u99C6\u9A12\u9ED9\u9F62 +NGram.KANJI_1_11=\u67D8\u831C +NGram.KANJI_1_12=\u5742\u57FC\u5800 +NGram.KANJI_1_13=\u4E3C\u4E98\u4FE3\u4FF5\u5072\u51A8\u53A9\u5451\u546A\u5504\u5516\u55A9\u55B0\u5618\u5642\u565B\u567A\u56A2\u57F4\u5840\u5841\u58F1\u59F6\u5A2F\u5B22\u5B8D\u5DCC\u5EFB\u5F10\u60A9\u60E3\u61D0\u62F6\u63B4\u63BB\u63C3\u6681\u685F\u6955\u6962\u696F\u698A\u698E\u69FB\u6A2B\u6A7F\u6B53\u6BD8\u6D99\u6E07\u7460\u7473\u7560\u7573\u758E\u7690\u7815\u783A\u7962\u7A4F\u7A63\u7AEA\u7BED\u7CA7\u7D18\u7D3A\u7E4D\u8061\u8218\u8276\u82C5\u8597\u85AB\u86CD\u874B\u88FE\u8ACF\u8B90\u8D0B\u8FBF\u9013\u9061\u914E\u9154\u918D\u9190\u91A4\u91B8\u9262\u929A\u92ED\u92F3\u932C\u96EB\u96F0\u976D\u97EE\u981A\u99C4\u9A28\u9AC4\u9B8E\u9C10\u9D0E\u9D5C\u9D8F\u9E78\u9EB9\u9EBA\u9EBF +NGram.KANJI_1_14=\u5F66\u7984\u7985 +NGram.KANJI_1_16=\u5861\u7B25\u844E\u9419\u9D07 +NGram.KANJI_1_18=\u5039\u514E\u51E7\u51EA\u5301\u5302\u5859\u58F7\u59AC\u5C2D\u5CA8\u5EFC\u6357\u64B9\u67CA\u6802\u6834\u68BC\u6900\u6919\u691B\u69D9\u6AE8\u6D9C\u6E8C\u6F09\u6F45\u701E\u7026\u7114\u72DB\u7577\u75E9\u783F\u7895\u7A50\u7AC3\u7B48\u7B86\u7BAA\u7C7E\u7C82\u7C8D\u7CCE\u7D2C\u7F6B\u7FEB\u8557\u85AE\u86CE\u877F\u8997\u8ACC\u8CB0\u8CCE\u8FE9\u9197\u920E\u9266\u927E\u92F2\u9306\u9453\u9784\u982C\u9834\u99C8\u9BF5\u9C2F\u9D2C +NGram.KANJI_1_22=\u6762\u6A17\u887F +NGram.KANJI_1_27=\u4E21\u4E57\u4ECF\u4F1D\u4FA1\u4FF3\u5024\u50CD\u5150\u5186\u51E6\u52B4\u52B9\u5358\u53CE\u55B6\u56E3\u56F2\u56F3\u570F\u5727\u5869\u5897\u58F2\u5909\u5B9F\u5BDB\u5BFE\u5C02\u5DFB\u5E2F\u5E81\u5E83\u5EC3\u5F3E\u5F93\u5FB3\u5FB4\u5FDC\u60AA\u6226\u6238\u6271\u62E0\u6319\u63B2\u6483\u64AE\u67A0\u67FB\u691C\u697D\u69D8\u6A29\u6B73\u6B74\u6BCE\u6C17\u6CA2\u6D5C\u6E08\u6E80\u702C\u7523\u767A\u770C\u7D4C\u7D75\u7D76\u7D99\u7D9A\u7DCF\u8535\u8846\u89A7\u89B3\u8A33\u8AAC\u8AAD\u8C4A\u8EE2\u8EFD\u8FBA\u8FBC\u9244\u9332\u95A2\u95D8\u96D1\u99C5\u9A13\u9ED2 +NGram.KANJI_1_29=\u4F0E\u4FFA\u5036\u53E1\u54B2\u5506\u583A\u5C3B\u5CAC\u5CE0\u5CEF\u6803\u68B6\u6A0B\u6A8E\u73C2\u7551\u7826\u7881\u79B0\u7B39\u8429\u8599\u8FBB\u9162\u95C7\u9688\u96BC\u9AEA\u9DF2 +NGram.KANJI_1_31=\u5553\u938C +NGram.KANJI_1_35=\u51B4\u564C\u57DC\u5B2C\u6822\u685D\u690B\u6973\u6C93\u7511\u7887\u7A17\u83D6\u847A\u8494\u8526\u854E\u85C1\u86F8\u88B4\u93A7\u9B92\u9C39\u9C48\u9C52 +NGram.KANJI_2_0=\u4E2B\u4EC3\u4F09\u4F57\u4F6F\u4F70\u4FD1\u4FDA\u500C\u5043\u516E\u5189\u5241\u530D\u5310\u5412\u54AB\u54AF\u5514\u5556\u55B1\u561F\u573B\u586D\u587D\u58C5\u58D1\u5914\u5A62\u5A6A\u5AE6\u5B40\u5B5B\u5B70\u5BB8\u5CD2\u5D01\u5D34\u5E11\u5EA0\u5F0B\u5F2D\u5F87\u607F\u621B\u6221\u6289\u63A3\u6452\u646D\u64D8\u652B\u6600\u6631\u6641\u66F7\u6773\u67B8\u67DD\u67DE\u6829\u68FB\u69AD\u6A47\u6C10\u6C68\u6C74\u6C85\u6CD3\u6D31\u6D93\u6D94\u6DB8\u6DBF\u6DC5\u6E6E\u6EA7\u6EB4\u6EC2\u6F2A\u6F2F\u6FB9\u6FC2\u6FDB\u6FEE\u70AF\u70FD\u7166\u726F\u729B\u739F\u73DE\u740A\u746D\u749C\u749F\u74E0\u759D\u75A3\u75CD\u75DE\u7600\u7620\u7688\u7738\u7762\u776B\u777D\u77E3\u781D\u7837\u78A3\u7946\u7B60\u7F44\u7F54\u7F5F\u7FAF\u8026\u807F\u80C4\u80DB\u80ED\u81E7\u824B\u82B7\u82E3\u8392\u846D\u84D3\u8548\u85B9\u86DE\u873F\u8753\u8782\u87AB\u87B3\u87D1\u87E0\u87FE\u8821\u88D8\u88E8\u8913\u891A\u892B\u8983\u8C3F\u8C49\u8C82\u8D6D\u8DE4\u8E1D\u8E1E\u8E7C\u8FE5\u8FE8\u9005\u9035\u9050\u9082\u9083\u9095\u90E2\u911E\u91AE\u91B4\u93D6\u9621\u968D\u96B9\u96D2\u9711\u9713\u973E\u9AB0\u9AB7\u9AE6\u9B03\u9B23\u9EDC\u9EEF +NGram.KANJI_2_1=\u4E82\u4F48\u4F54\u50F9\u5167\u528D\u52DE\u532F\u537B\u53C3\u5433\u555F\u55AE\u56B4\u570D\u5716\u58D3\u58DE\u5920\u5967\u5A1B\u5BEB\u5BEC\u5C08\u5C0D\u5C46\u5C6C\u5CFD\u5E36\u5E6B\u5EC8\u5EF3\u5F48\u5F91\u5F9E\u5FB5\u6046\u60E1\u61F7\u6232\u6236\u64C7\u64CA\u64D4\u64DA\u64F4\u651D\u6578\u65B7\u6649\u6A13\u6A23\u6A6B\u6A94\u6AA2\u6B0A\u6B50\u6B61\u6B72\u6B77\u6B78\u6C92\u6EAB\u6EFF\u6FD5\u6FDF\u71DF\u722D\u72C0\u734E\u737B\u746A\u7522\u773E\u78BC\u7A69\u7C3D\u7CB5\u7D55\u7D72\u7DA0\u7DAB\u7DE3\u7E5E\u7E6A\u7E7C\u7E8C\u8072\u807D\u8085\u812B\u8166\u8173\u81D8\u8209\u820A\u8332\u838A\u840A\u85E5\u860B\u8655\u865B\u88DD\u89BA\u89BD\u89C0\u8AAA\u8B6F\u8B7D\u8B8A\u8B93\u8C50\u8CF4\u8E64\u8F15\u8F49\u8FA6\u8FAD\u9109\u9130\u91AB\u91CB\u92B7\u9304\u9322\u95CA\u96A8\u96AA\u96B1\u96B8\u96D6\u96D9\u96DC\u9748\u975C\u986F\u9918\u99DB\u9A57\u9B25\u9EA5\u9EC3\u9EDE\u9F52 +NGram.KANJI_2_4=\u514C\u51AA\u5614\u56AE\u56C2\u582F\u58FA\u5B0C\u5D11\u5DD2\u5DD6\u5E40\u5E5F\u5EEC\u6137\u6417\u6488\u64F2\u652A\u6582\u6689\u689F\u68D7\u69D3\u6A97\u6AB8\u6ABB\u6AC3\u6ADA\u6B7F\u6BB2\u6EA5\u6EC4\u6EF2\u7009\u701D\u7028\u703E\u7165\u71BE\u721B\u7463\u7464\u7469\u7515\u7526\u75FA\u7621\u779E\u79B1\u7A1F\u7AC4\u7AC7\u7B8F\u7BE9\u7D2E\u7D68\u7D8F\u7DB8\u7DBA\u7E46\u7E79\u7F4C\u7F88\u8070\u8073\u8076\u81BE\u82BB\u83A2\u858A\u8591\u861A\u8778\u87EC\u8805\u880D\u893B\u8A1B\u8A25\u8A36\u8A85\u8AA6\u8B17\u8B28\u8CB6\u8CE4\u8D16\u8D1B\u8ECB\u9112\u9214\u9249\u93AC\u9594\u9598\u95BB\u95D5\u965E\u96B4\u97DC\u9821\u9824\u9921\u9952\u9A55\u9A5B\u9B1A\u9C13\u9D09\u9DAF\u9E1A\u9E75\u9F67 +NGram.KANJI_2_9=\u4E9F\u4F6C\u4FDE\u4FFE\u5029\u5140\u51A2\u5345\u539D\u53FB\u54C7\u5599\u560E\u561B\u563B\u566C\u5676\u5729\u574D\u57E4\u595A\u598D\u5A1F\u5A25\u5A77\u5AB2\u5AD6\u5BF0\u5C2C\u5CEA\u5E37\u5F08\u6059\u606A\u6096\u609A\u62A8\u6555\u6556\u66E6\u675E\u68E3\u69BB\u6BCB\u6BD3\u6C1F\u6C26\u6C81\u6DC4\u6DDE\u6E32\u6E44\u6E4D\u6F33\u6F7C\u6FA7\u701A\u701B\u715C\u741B\u7428\u7480\u74A8\u7504\u752C\u768B\u76CE\u78CA\u78FA\u79BA\u7C27\u8046\u81FB\u8331\u8393\u83C1\u8403\u8438\u843C\u8446\u85B0\u87D2\u8862\u8DC6\u9074\u9131\u9672\u96EF\u9704\u9706\u977C\u9ABC\u9E92\u9ECF +NGram.KANJI_2_10=\u51BD\u5704\u7350\u73A5 +NGram.KANJI_2_11=\u4E15\u4EA2\u4F5A\u50D6\u5349\u53DF\u5484\u5958\u5B34\u5B5A\u5C91\u5E1B\u5F77\u61CB\u61FF\u620C\u620D\u622E\u6248\u6538\u660A\u664F\u678B\u67E9\u69B7\u69C3\u6CB1\u6CD7\u6D5A\u6DAA\u6DC7\u7099\u71EE\u7325\u7425\u7455\u747E\u749E\u75B5\u7678\u7693\u76C2\u77B0\u77BF\u78CB\u7957\u795A\u797A\u7A79\u7B08\u7B75\u7BB4\u7F9A\u7FB2\u7FDF\u80E5\u81BA\u8340\u837C\u8398\u8559\u85A8\u86DF\u8734\u8882\u88F4\u8936\u900D\u907D\u9642\u96C9\u9AFB\u9E9D\u9EBE +NGram.KANJI_2_12=\u5F57\u7940 +NGram.KANJI_2_13=\u5191\u7791\u792C\u7D46 +NGram.KANJI_2_15=\u5713\u58FD\u5D17\u5D19\u5DBC\u5F4C\u6191\u64A5\u687F\u69AE\u6AFB\u6EEC\u6F3F\u6FE4\u6FF1\u6FFE\u700B\u74CA\u76E1\u76E7\u7926\u792B\u79AE\u7AA9\u7C43\u7C4C\u7C64\u7DBD\u81A0\u856D\u8594\u8606\u8A62\u8AF7\u8CC8\u8CE3\u8D99\u8F1B\u8F3B\u9059\u9127\u9264\u947D\u95A9\u97CB\u980C\u9838\u9846\u99AE\u9A19\u9B06\u9B91\u9F4A\u9F4B +NGram.KANJI_2_16=\u4E69\u4EC4\u4EDF\u4EF3\u4F0B\u4F5E\u5000\u5028\u50E5\u513B\u5157\u51DC\u52D7\u530F\u5379\u53F5\u5471\u5477\u5555\u555C\u557B\u5594\u55B2\u55C9\u560D\u5616\u562E\u5630\u5653\u5657\u566F\u56A8\u56B6\u5820\u5880\u58CE\u58D9\u5950\u5969\u596D\u599E\u59B3\u59CD\u59D2\u5A40\u5AA7\u5ABC\u5AD7\u5AD8\u5B0B\u5B24\u5B38\u5B53\u5C5C\u5D06\u5D47\u5D94\u5D9D\u5E57\u5EC4\u5F46\u5FAC\u60BD\u60D8\u6123\u615D\u615F\u6175\u618A\u61AB\u61E3\u623E\u6308\u636B\u645F\u6519\u6595\u6698\u66B8\u67D9\u6840\u695D\u696E\u6979\u69C1\u69E8\u6AEC\u6AFA\u6B5F\u6CAC\u6CE0\u6CEF\u6D0C\u6D36\u6DD2\u6DD9\u6DE6\u6DEC\u6E5F\u6FA0\u6FEC\u7156\u71C4\u71DC\u71EC\u71FC\u720D\u7230\u7292\u7296\u72A2\u72CE\u7357\u737A\u7380\u7386\u73A8\u73EE\u743F\u74A6\u74CF\u74D4\u74DA\u755A\u75A5\u75B3\u75C2\u75E0\u75F1\u75FF\u7601\u7609\u7646\u7658\u769A\u76B0\u774F\u775C\u778B\u77BD\u77C7\u7843\u787F\u78F4\u79C8\u7A88\u7A95\u7AFD\u7B1E\u7B67\u7B9D\u7BCC\u7C0D\u7C11\u7C37\u7C40\u7C6E\u7CB3\u7CBD\u7D09\u7D31\u7D40\u7D5B\u7D70\u7D91\u7D9E\u7DB0\u7DD9\u7DF9\u7E08\u7E11\u7E1D\u7E35\u7E52\u7FB6\u7FBF\u7FEE\u8012\u801C\u8028\u8052\u8123\u8188\u81C3\u81DA\u81FE\u8210\u82BE\u83A0\u83D4\u8407\u8435\u8477\u849E\u84C6\u84CA\u85F9\u867A\u86B5\u86B6\u86C4\u8706\u8707\u870A\u8768\u87BB\u8831\u8839\u8879\u8921\u8938\u8964\u89A6\u89AC\u8A10\u8A3E\u8AC2\u8ADB\u8AF3\u8B2B\u8B41\u8B4E\u8B5F\u8B6B\u8B92\u8C55\u8C62\u8C73\u8C8A\u8C8D\u8CB2\u8CB3\u8CD2\u8CE1\u8CFB\u8D0D\u8E34\u8E7A\u8E8A\u8ED4\u8EFE\u8F0A\u8F1C\u8F1E\u8F26\u8FAE\u9088\u90C3\u90FE\u9134\u9148\u91D9\u91E9\u9238\u9239\u923D\u924D\u925A\u9296\u92AC\u92BB\u9315\u9319\u931A\u9321\u9370\u9394\u93A2\u93D8\u93E4\u943A\u9477\u9582\u958E\u95A1\u95C8\u95CC\u95D4\u9658\u966C\u970F\u973D\u9744\u975B\u9766\u97A3\u97A6\u97C1\u97C6\u980A\u9837\u9853\u9870\u98AF\u98B3\u98BA\u98E9\u98ED\u9912\u991B\u991E\u993D\u993F\u99D1\u99DF\u9A01\u9A3E\u9A43\u9A4D\u9ACF\u9AE1\u9B22\u9B58\u9C25\u9C3E\u9C54\u9C56\u9D15\u9D23\u9D89\u9DC2\u9DD3\u9E82\u9E8B\u9EA9\u9EE0\u9EF7\u9F07\u9F2F\u9F34\u9F3E\u9F5F\u9F6C +NGram.KANJI_2_18=\u5155\u520E\u55DF\u56C0\u56C1\u5793\u5FD6\u5FF8\u6029\u60FA\u613E\u6147\u615A\u62C8\u6384\u6883\u6894\u68F9\u6AA3\u6AAE\u6AC2\u6E63\u7032\u70A4\u7146\u71FB\u7228\u72F7\u7370\u7441\u74BF\u75B8\u75E3\u7622\u76CD\u7768\u79E3\u7A60\u7B6E\u7BC1\u7C5F\u7D06\u7E2F\u7E39\u8146\u81CF\u8703\u8729\u8737\u87EF\u88D2\u8A22\u8AC4\u8AF6\u8E59\u8F33\u8F42\u9169\u91B1\u9278\u93C3\u93DD\u9460\u946A\u9785\u9AD1\u9B4D\u9B4E\u9C31\u9D12\u9ECC +NGram.KANJI_2_21=\u502A\u544E\u59AE\u59EC\u5D1B\u66A8\u6BD7\u6C76\u6E1D\u70EF\u742A\u7459\u7FE1\u82EF\u8343\u85C9\u8A79\u90DD +NGram.KANJI_2_22=\u4EDE\u4F7B\u504C\u50EE\u52E3\u52F0\u536E\u54A9\u54BB\u54BF\u54C2\u54E6\u550F\u556A\u55E8\u564E\u5664\u5671\u568F\u56DD\u572F\u57A0\u5809\u5924\u59A3\u59A4\u59E3\u5A13\u5A23\u5B51\u5B73\u5C50\u5C8C\u6035\u60C6\u6106\u6215\u62CE\u62FD\u64ED\u6549\u6554\u655D\u659B\u65CE\u65D6\u6615\u6624\u665E\u6677\u669D\u66E9\u6772\u677C\u696B\u6A84\u6AA0\u6BFD\u6C16\u6C86\u6C94\u6CD6\u6D2E\u6D39\u6F78\u6FB6\u705E\u70CA\u7168\u723B\u7256\u7284\u73B3\u740D\u742F\u7498\u74A9\u752D\u75F3\u7634\u768E\u76B4\u76E5\u77A0\u77DC\u781F\u782D\u7AA0\u7BFE\u7FF1\u80AB\u8174\u81EC\u8202\u8222\u8228\u82DC\u8306\u83FD\u8469\u84FF\u859C\u8617\u86B1\u8722\u8C89\u8D67\u8DCE\u8E49\u8E76\u8E87\u8FE2\u8FE4\u8FF8\u9016\u905B\u9174\u982B\u98E7\u9955\u9B32 +NGram.KANJI_2_23=\u4F8F\u5055\u524C\u548E\u5583\u594E\u5CB7\u5ED6\u5F5D\u6021\u66B9\u66F0\u6C55\u6C7E\u6C82\u6E2D\u6EC7\u6ED5\u70B3\u71B9\u72C4\u73C0\u7426\u745C\u748B\u7696\u777F\u79A7\u79B9\u7F8C\u8153\u8339\u8386\u8725\u90B5\u9102\u962E\u9716\u97F6 +NGram.KANJI_2_28=\u5733\u57D4\u838E\u8FEA +NGram.KANJI_2_29=\u50ED\u5F29\u62EE\u6A9C\u7BC6\u80F1\u8129\u8171\u822B\u8AEB +NGram.KANJI_2_30=\u4EB3\u4F15\u4FB7\u5006\u509A\u50A2\u5102\u5109\u5115\u5137\u5138\u513C\u524B\u524E\u5277\u528A\u52E6\u52FB\u5331\u5436\u5443\u54FD\u5538\u555E\u55C6\u55C7\u5679\u5690\u5695\u56C9\u56D1\u56EA\u588A\u58E2\u5AFB\u5B2A\u5B43\u5B7F\u5BE2\u5C37\u5D27\u5D84\u5D87\u5DD4\u5EC1\u5EDD\u5F12\u5FA0\u60F1\u616B\u61F5\u61F6\u61FE\u62DA\u6371\u6399\u63C0\u6451\u647B\u6493\u64BB\u64BF\u64C4\u64F1\u64F7\u650F\u652C\u665D\u6684\u6688\u66EC\u672E\u68E7\u69A6\u69ED\u69F3\u6A01\u6AAF\u6AE5\u6BA4\u6BAE\u6BAF\u6BC6\u6C08\u6C2C\u6C59\u6D87\u6EBC\u6ECC\u6EF7\u6F6F\u6F80\u6F86\u6FD8\u6FF0\u6FFA\u7006\u7018\u7030\u7051\u7192\u71C9\u71D9\u71F4\u71FE\u7274\u7377\u74A3\u750C\u7613\u7627\u7661\u7662\u7665\u766E\u7671\u7672\u76BA\u775E\u776A\u778C\u78E7\u7955\u7A08\u7AC5\u7B4D\u7C2B\u7C6C\u7CF0\u7D02\u7D1C\u7D73\u7DA2\u7DB5\u7DDE\u7E09\u7E0A\u7E37\u7E43\u7E61\u7E7D\u7E93\u7F3D\u7FF9\u81A9\u8271\u83F8\u84C0\u8514\u85BA\u86A9\u86FB\u879E\u8814\u8836\u889E\u8932\u896A\u896F\u8993\u89B2\u8A15\u8A16\u8A1D\u8A5B\u8A6C\u8A6D\u8A7C\u8AA1\u8AA3\u8AA5\u8B0A\u8B4F\u8B59\u8B96\u8C48\u8C54\u8CBD\u8CFA\u8D13\u8E89\u8E8B\u8EAA\u8EC0\u8EDB\u8EFC\u8F12\u8F1F\u8F3E\u8F45\u8FFA\u9015\u9183\u919E\u91A3\u91D7\u91F5\u9209\u9215\u923E\u9240\u9251\u9257\u927B\u9293\u92A8\u92C5\u92C7\u92F0\u9333\u935A\u9382\u938A\u9398\u93B3\u93D7\u93DF\u93E2\u93FD\u942B\u942E\u9433\u9463\u9470\u9472\u947E\u95D0\u96CB\u97C3\u97CC\u981C\u9839\u986B\u98B6\u98EA\u9909\u991A\u9935\u993E\u9951\u99A5\u99B1\u99D9\u99DD\u99F1\u9A2B\u9A62\u9A65\u9AAF\u9AD2\u9AEF\u9B0D\u9B28\u9B77\u9BFD\u9C49\u9C5F\u9C78\u9D3F\u9D72\u9DD7\u9E1B\u9EB4\u9EF4\u9F66\u9F94 +NGram.KANJI_2_31=\u5DBD\u63C6\u6E3E\u7587\u8AF1\u8B5A\u9695 +NGram.KANJI_2_32=\u53A5\u589F\u5CD9\u7109\u7F79\u8006\u8654\u8944\u968B\u96CD +NGram.KANJI_2_35=\u4F47\u4F91\u4FCE\u4FDF\u527D\u535E\u55DA\u56A5\u5879\u5A11\u5B7A\u5CAB\u5CF4\u5EBE\u5F7F\u5FA8\u601B\u606B\u60B8\u610D\u6134\u619A\u61FA\u6369\u6523\u65CC\u66C4\u6727\u6968\u6A05\u6A48\u6B59\u6BEC\u6D35\u6D38\u6E19\u701F\u7064\u711C\u716C\u71A8\u71E7\u7258\u743A\u746F\u75BD\u75D9\u75F2\u7669\u766C\u76DE\u7729\u77BC\u78EC\u792A\u7A37\u7A62\u7BE6\u7C2A\u7C50\u7D07\u7DD8\u7E5A\u7F8B\u7FD5\u7FF3\u8151\u81CD\u8317\u83F4\u85EA\u85FA\u8823\u895E\u89F4\u8A0C\u8A41\u8AA8\u8ACD\u8B10\u8CC1\u8D05\u8D73\u8E4A\u8E85\u8E91\u8EFB\u8F13\u9087\u914A\u91C9\u923F\u93B0\u9403\u95A8\u95AD\u9730\u9865\u9903\u9945\u9949\u99AD\u99E2\u9A6A\u9D26\u9E1E\u9EDD\u9F2C\u9F72 +NGram.KANJI_2_36=\u4E9E\u4F86\u5011\u50B3\u5152\u5169\u5340\u5718\u5B78\u5BE6\u5BF6\u5C07\u5EE3\u61C9\u6230\u6703\u689D\u6A02\u6C23\u7063\u7368\u756B\u7576\u767C\u7A31\u7D93\u7E23\u7E3D\u81FA\u8207\u842C\u85DD\u865F\u8B49\u8B80\u8CFD\u908A\u9435\u95DC\u965D\u9AD4\u9EE8 +NGram.KANJI_2_37=\u5480\u5580\u5C39\u67EF\u68B5\u6D85\u8521\u90B1 +NGram.KANJI_2_38=\u4E1F\u4F96\u4FE0\u50F1\u5118\u522A\u5291\u52C1\u52DB\u52F3\u52F5\u52F8\u53B2\u55CE\u562F\u580A\u5862\u58AE\u58D8\u58DF\u58E9\u58EF\u5925\u593E\u599D\u5ABD\u5C62\u5EC2\u5EDA\u5EE2\u5F4E\u5F65\u6085\u6158\u61FC\u6200\u62CB\u633E\u6416\u6436\u6490\u64CB\u64E0\u64FA\u6514\u651C\u6524\u6558\u6583\u66B1\u66C6\u66C9\u66E0\u6A11\u6A1E\u6A38\u6A62\u6AB3\u6B16\u6B98\u6BBC\u6C2B\u6DDA\u6DE8\u6DEA\u6DFA\u6EEF\u6EFE\u6F32\u6F51\u6F5B\u700F\u71D2\u7210\u7246\u7260\u72A7\u72F9\u7375\u7378\u758A\u760B\u76DC\u76EA\u77DA\u77FD\u78DA\u7919\u797F\u79AA\u7A05\u7A4C\u7ACA\u7C72\u7D81\u7DDD\u7E31\u7E69\u7E6B\u7E73\u7E96\u7E9C\u81BD\u81C9\u81DF\u8259\u8277\u8396\u83A7\u8523\u8525\u860A\u863F\u8667\u87A2\u87F2\u881F\u883B\u89F8\u8B20\u8B74\u8B9A\u8C4E\u8C6C\u8C93\u8CEC\u8D0A\u8D0F\u8D95\u8E10\u8F4E\u8FAF\u8FF4\u905E\u9072\u9081\u908F\u91AC\u91C0\u91C1\u91D0\u921E\u9223\u9245\u929C\u92B3\u92C1\u9336\u934A\u93C8\u9444\u9452\u947C\u947F\u9592\u95B1\u95C6\u95D6\u95E1\u95E2\u96DE\u9742\u978F\u984F\u9871\u98B1\u98C4\u99ED\u9A37\u9A45\u9A5F\u9AEE\u9B27\u9BCA\u9C77\u9D51\u9D5D\u9E79\u9E7C\u9E7D\u9EB5\u9EBC\u9F61\u9F63\u9F90\u9F9C +NGram.KANJI_3_1=\u5283\u7562\u7DEC\u88E1\u8F2F +NGram.KANJI_3_2=\u5009\u502B\u5049\u5075\u507D\u5091\u5098\u50B5\u50B7\u50BE\u5100\u5104\u511F\u518A\u525B\u5289\u5442\u5805\u589C\u58C7\u5922\u596A\u5A66\u5B6B\u5BE7\u5BE9\u5DBA\u5E63\u5E7E\u5FB9\u6163\u616E\u6176\u61B2\u61B6\u61F8\u639B\u63DA\u63EE\u640D\u64B2\u64C1\u64EC\u6557\u6575\u6607\u66AB\u68C4\u6A39\u6C96\u6CC1\u6E1B\u6E6F\u6E9D\u6EC5\u6F01\u6F64\u6FC3\u7058\u707D\u7344\u7642\u76E4\u7832\u790E\u7B46\u7D05\u7D0B\u7D14\u7D19\u7D1B\u7D39\u7D61\u7DB1\u7DCA\u7DD2\u7DE0\u7DE9\u7DEF\u7DF4\u7E2E\u7E3E\u8105\u8108\u81E8\u8266\u84CB\u84EE\u85A9\u885D\u88DC\u8972\u8A02\u8A0E\u8A13\u8A17\u8A2A\u8A34\u8A3A\u8A3C\u8A69\u8A73\u8A95\u8AA0\u8AA4\u8AB2\u8AC7\u8ACB\u8B00\u8B1B\u8B1D\u8B5C\u8C9D\u8C9E\u8CA2\u8CA8\u8CA9\u8CAB\u8CAC\u8CB7\u8CBF\u8CC0\u8CDE\u8CE2\u8CFC\u8D08\u8DE1\u8E8D\u8ECC\u8EDF\u8EF8\u8F14\u8F1D\u8F2A\u8F44\u9055\u9069\u9077\u907C\u90F5\u91DD\u9285\u92FC\u9326\u932F\u9375\u9396\u93AE\u93E1\u9451\u9589\u95A3\u9663\u9670\u9673\u96BB\u9801\u9802\u9803\u9806\u9808\u9810\u983B\u984D\u9858\u9867\u98EF\u98F2\u98FE\u990A\u99D0\u9A0E\u9A5A\u9B5A\u9CE5\u9DB4\u9E97\u9F8D +NGram.KANJI_3_3=\u543E\u5BEE\u5F18\u6590\u725F\u83C5\u85E9\u9E93 +NGram.KANJI_3_4=\u5016\u53AD\u5606\u5629\u58BE\u5F14\u6065\u6144\u646F\u647A\u67F5\u6953\u6C3E\u6F2C\u6F97\u6FB1\u7169\u71E6\u71ED\u74BD\u79BF\u7A1C\u7A4E\u7AAF\u7CDE\u7D17\u7D43\u7E55\u7FA8\u807E\u8139\u8490\u8569\u856A\u87FB\u8A23\u8AB9\u8AE6\u8AFA\u8B2C\u8CD1\u91D8\u92F8\u9318\u96DB\u99B4\u9BC9\u9C2D\u9CF6\u9D61\u9DFA +NGram.KANJI_3_5=\u4E26\u4F75\u4FC2\u500B\u5074\u5099\u512A\u5225\u5247\u5275\u5287\u52D5\u52D9\u52DD\u52E2\u5354\u54E1\u554F\u5712\u57F7\u5831\u5834\u5BAE\u5C0E\u5C64\u5CA1\u5CF6\u5E2B\u5E79\u5EAB\u5F35\u5F37\u5F8C\u5FA9\u611B\u614B\u63A1\u63DB\u6642\u66F8\u6771\u696D\u6975\u69CB\u6A19\u6A4B\u6A5F\u6BBA\u6C7A\u6E2C\u6E96\u6F22\u70BA\u7121\u71B1\u7372\u73FE\u74B0\u7570\u76E3\u78BA\u7A2E\u7A4D\u7AF6\u7BC0\u7BC4\u7BC9\u7C21\u7D00\u7D04\u7D0D\u7D1A\u7D30\u7D42\u7D44\u7D50\u7D66\u7D71\u7DAD\u7DDA\u7DE8\u7E54\u7F85\u7FA9\u7FD2\u8056\u805E\u8077\u8208\u83EF\u8449\u8853\u885B\u88FD\u8907\u898B\u898F\u8996\u89AA\u8A08\u8A18\u8A2D\u8A31\u8A55\u8A5E\u8A66\u8A71\u8A72\u8A8C\u8A8D\u8A9E\u8ABF\u8AD6\u8AF8\u8B58\u8B70\u8B77\u8CA0\u8CA1\u8CB4\u8CBB\u8CC7\u8CEA\u8ECA\u8ECD\u8F03\u8F09\u8F38\u8FB2\u9023\u9031\u9032\u904A\u904B\u904E\u9054\u9060\u9078\u907A\u9084\u9280\u9577\u9580\u958B\u9593\u9678\u967D\u968A\u968E\u969B\u96E2\u96E3\u96F2\u96FB\u97D3\u97FF\u9805\u9818\u982D\u984C\u985E\u98A8\u98DB\u9928\u99AC\u9BAE +NGram.KANJI_3_8=\u5F6B\u6C4E\u7B87\u8A70 +NGram.KANJI_3_9=\u540B\u5B5C\u826E +NGram.KANJI_3_11=\u4F83\u4FF8\u51CB\u52BE\u53F1\u548B\u558B\u5CB1\u5D69\u5F3C\u620E\u621F\u64E2\u67DA\u6854\u69CC\u6A35\u6C8C\u6E1A\u6F15\u6FE0\u717D\u7252\u7AFA\u82D3\u83DF\u8431\u9041\u9149\u9798 +NGram.KANJI_3_12=\u4ED5\u55E3\u572D\u57A3\u587E\u5983\u5A9B\u5C90\u5E61\u672D\u6960\u6F5F\u72D9\u72E9\u757F\u7949\u7950\u7E82\u7FCC\u82B8\u90B8\u91DC\u961C\u9B45 +NGram.KANJI_3_13=\u55AB\u6249\u643E\u6841\u68B1\u725D\u7B8B\u7C95\u7E1E\u7F36\u8A03\u8A6B\u8E74\u95A4 +NGram.KANJI_3_15=\u50AD\u50D1\u5132\u51F1\u55AC\u5617\u5687\u584A\u59EA\u5B30\u5BF5\u5C0B\u5C4D\u5EDF\u6182\u61A4\u64AB\u64FE\u66A2\u6897\u694A\u69CD\u6B3D\u6BC0\u6D29\u6F38\u7015\u7149\u71C8\u723A\u7336\u7345\u755D\u76C3\u78A9\u798D\u7AAE\u7DFB\u7E2B\u7F75\u7F77\u81E5\u834A\u852D\u85CD\u8755\u8A3B\u8A54\u8AE7\u8B02\u8B39\u8CAA\u8CE6\u8DA8\u8E5F\u8F5F\u905C\u912D\u919C\u92D2\u932B\u937E\u9418\u9583\u9812\u985B\u9905\u99B3\u99C1\u99D5\u9A30\u9CF3\u9D3B\u9D6C +NGram.KANJI_3_16=\u6D6C\u72FD\u77A5\u8956\u9C0D +NGram.KANJI_3_18=\u5919\u5F4A\u6063\u63AC\u649A\u6715\u6AD3\u71D0\u758B\u834F\u85F7\u88DF\u8F61\u93D1\u98F4\u9D60 +NGram.KANJI_3_19=\u4F50\u7DB2\u962A +NGram.KANJI_3_22=\u5E96\u75D4\u91C6 +NGram.KANJI_3_23=\u5E9A\u6C40\u821C\u839E\u8FED\u9EDB +NGram.KANJI_3_27=\u5F01\u66DC +NGram.KANJI_3_29=\u5023\u5208\u531D\u536F\u53E9\u54C9\u598A\u59BE\u5A20\u5D6F\u5DF3\u66C7\u66D6\u66F3\u6775\u6A3D\u6ADB\u6B86\u6C72\u6E25\u73EA\u7435\u760D\u7656\u7825\u78D0\u7A14\u7A6B\u7B20\u7BE0\u7CF8\u7DAC\u7DBB\u7DBE\u80E4\u80F4\u837B\u8466\u8568\u867B\u8A63\u91E7\u9320\u935B\u9591\u965B\u98E2\u990C\u9913\u9BAB +NGram.KANJI_3_30=\u60B6\u8AD2\u8CC2\u9237\u9328\u934D\u9397\u9830 +NGram.KANJI_3_31=\u4FB6\u50D5\u51CD\u559A\u55AA\u5674\u5857\u585A\u5875\u58B3\u596E\u59E6\u5A41\u5D50\u5E25\u5E33\u5F59\u61C7\u61F2\u6368\u6383\u65AC\u68DF\u68F2\u6A3A\u6B04\u6DBC\u6DF5\u6E26\u6E4A\u6E67\u6F54\u6F70\u6FC1\u6FEB\u7159\u727D\u7652\u77EF\u78EF\u798E\u7A40\u7AAA\u7BE4\u7C60\u7CE7\u7CFE\u7D21\u7D33\u7D5E\u7D79\u7DB4\u7DBF\u7E1B\u7E8F\u7F70\u814E\u816B\u8178\u819A\u84BC\u85A6\u865C\u8766\u8A1F\u8A50\u8A60\u8A6E\u8A87\u8A98\u8AB0\u8ADC\u8AED\u8AEE\u8B0E\u8B19\u8CA7\u8CAF\u8CB8\u8CBC\u8CC3\u8CC4\u8CCA\u8CDC\u8CE0\u8CED\u8ED2\u8F29\u8F3F\u91E3\u920D\u9234\u925B\u9298\u9310\u934B\u958F\u95A5\u9727\u97FB\u9811\u984E\u98FC\u98FD\u99D2\u99FF\u9B31\u9BE8\u9C57\u9CE9\u9CF4\u9D28\u9DF9 +NGram.KANJI_3_32=\u4E1E\u502D\u51A5\u5321\u58EC\u5A3C\u5BC5\u5CE8\u61A9\u620A\u65A1\u6714\u6853\u6893\u6C50\u6C5D\u7436\u745A\u745B\u773A\u7941\u7947\u8543\u865E\u8C5A\u914B\u99A8\u9AB8 +NGram.KANJI_3_35=\u4E99\u5BA5\u5DFD\u608C\u60C7\u60DA\u6190\u61A7\u6753\u6777\u6787\u6B4E\u6F23\u6FE1\u6FEF\u7337\u7827\u786F\u7893\u7ABA\u7B94\u7BB8\u7C3E\u7D62\u7E6D\u80B1\u81BF\u81C6\u821B\u82E7\u83F0\u84D1\u86ED\u8888\u8B01\u8B04\u8F4D\u9291\u92E4\u932E\u9354\u936C\u939A\u9957\u9AED\u9BAA\u9BAD\u9BD6\u9BDB\u9C3B\u9D1B +NGram.KANJI_3_36=\u50C5\u53E2\u5EE0\u65BC\u70CF\u723E\u7D10\u7D9C\u806F\u8607\u862D\u8A0A\u8AFE\u8CD3\u9019\u9813\u9B6F +NGram.KANJI_3_37=\u4EA8\u4F3D\u5384\u5EFF\u60DF\u66DD\u6E5B\u8087\u82D1\u8FE6\u9640\u9E9F +NGram.KANJI_3_38=\u5147\u525D\u5678\u617E\u6372\u79A6\u8ABC\u92EA\u9438\u9817 +NGram.KANJI_4_0=\u6D3C\u718F\u74EE\u8712 +NGram.KANJI_4_9=\u4F84\u54C6\u5565\u68F1\u6D82\u83C7 +NGram.KANJI_4_10=\u4FE9\u4FED\u51FF\u523D\u5300\u5364\u538C\u5450\u5455\u545C\u54D1\u54D7\u5578\u56A3\u58F6\u592F\u5CE6\u5D2D\u5E90\u6073\u607C\u60EB\u61D2\u62E2\u62E3\u631A\u6320\u6323\u6361\u63B7\u63B8\u63BA\u6405\u65A9\u65F7\u6619\u6655\u67A3\u67E0\u6805\u6808\u6866\u6868\u6869\u6A71\u6BE1\u6C79\u6CA5\u6CDE\u6DA4\u6DA7\u6DA9\u6E85\u70DB\u70E6\u70EB\u7115\u724D\u7410\u759F\u75AE\u75EA\u75F9\u762B\u763E\u76B1\u77EB\u783E\u79C3\u7A8D\u7A9C\u7B5D\u7BF1\u7EC5\u7ED2\u7EDE\u7EE3\u7EF7\u7EF8\u7EFD\u7F00\u7F0E\u7F15\u7F1A\u7F20\u7F24\u7F28\u7FA1\u7FD8\u8038\u803B\u804B\u80AE\u817B\u82C7\u8327\u835E\u8367\u83BA\u8424\u864F\u8681\u8682\u8715\u8717\u8721\u8747\u874E\u8845\u886C\u889C\u88E4\u89C5\u8BB6\u8BB9\u8BC0\u8BC5\u8BE1\u8BEB\u8BEC\u8BF5\u8C0E\u8C1A\u8D2E\u8D31\u8D43\u8D4E\u8D58\u8F67\u8F7F\u9489\u9499\u949D\u94A0\u94A5\u94AE\u94BE\u94D0\u94DB\u94F2\u9508\u950C\u951A\u9525\u952D\u952F\u9530\u953B\u9540\u9550\u9570\u9576\u95F0\u960E\u9668\u96CF\u97E7\u9885\u988A\u98A4\u9965\u9975\u997A\u997F\u9985\u998D\u998F\u9A6E\u9A6F\u9A74\u9A79\u9A7C\u9A82\u9A87\u9CA4\u9CC4\u9CCD\u9CD6\u9E20\u9E25\u9E35\u9E3D\u9E45\u9E49\u9E4A\u9E66 +NGram.KANJI_4_16=\u576F\u579B\u6345\u78B4\u79EB\u79F8 +NGram.KANJI_4_17=\u4E13\u4E1A\u4E1C\u4E24\u4E25\u4E2A\u4E3E\u4E49\u4E50\u4E66\u4E9A\u4EA7\u4EBF\u4ECE\u4EEC\u4EF7\u4F17\u4F20\u5170\u5173\u519B\u51B3\u51E4\u51FB\u5219\u521B\u522B\u529E\u52A1\u52A8\u52BF\u534F\u5355\u536B\u5386\u53BF\u53D1\u53D8\u542F\u5458\u54CD\u56E2\u56ED\u56F4\u56FE\u573A\u5904\u590D\u5934\u5B81\u5B9E\u5BF9\u5BFC\u5C14\u5C9B\u5E26\u5E7F\u5E94\u5F00\u5F20\u5F3A\u603B\u6218\u65E0\u65F6\u663E\u672F\u6743\u6784\u6807\u6C14\u6C49\u707E\u70ED\u73AF\u73B0\u7535\u76D1\u786E\u79CD\u79EF\u7B80\u7C7B\u7EA2\u7EA6\u7EA7\u7EAA\u7EBF\u7EC4\u7EC7\u7ED3\u7EDF\u7EE7\u7EED\u7EF4\u7F16\u7F57\u804C\u8054\u817E\u8282\u82CF\u83B7\u8425\u89C1\u89C2\u89C4\u89C6\u8BA1\u8BA4\u8BAE\u8BAF\u8BB0\u8BB8\u8BBA\u8BBE\u8BC1\u8BC4\u8BD1\u8BDD\u8BE5\u8BED\u8BF4\u8C03\u8D22\u8D23\u8D28\u8D39\u8D44\u8D5B\u8F66\u8F6C\u8F83\u8FBE\u8FC7\u8FD0\u8FD8\u8FD9\u8FDB\u8FDE\u9009\u94C1\u957F\u95E8\u95EE\u95F4\u95FB\u961F\u9633\u9645\u9646\u96BE\u9879\u9884\u9886\u9898\u98CE\u9A6C\u9F99 +NGram.KANJI_4_18=\u51DB\u67B7 +NGram.KANJI_4_22=\u4FA5\u545B\u5499\u5520\u5570\u56F1\u5A76\u5C96\u60AF\u60ED\u618B\u61A8\u62A0\u62A1\u62E7\u6363\u6390\u63B0\u6400\u6402\u6512\u6748\u70C1\u732C\u765E\u7663\u76CF\u7741\u781A\u7980\u79C6\u79FD\u7AA5\u7B0B\u7B8D\u7BA9\u7BAB\u7BD3\u7CAA\u7EAB\u7ECA\u7EE2\u7F2D\u7F30\u8110\u8113\u81CA\u835A\u8360\u84D6\u852B\u87E5\u8869\u8A8A\u8BA5\u8BF2\u8C05\u8C12\u8D30\u8D4A\u8D61\u8DF7\u8E6D\u8E8F\u8F95\u8F99\u8FAB\u94B3\u94C6\u94E3\u9504\u954A\u9563\u95FA\u9893\u9981\u9992\u9AA1\u9CAB\u9E2F\u9E33\u9EB8 +NGram.KANJI_4_24=\u4E22\u4E8F\u4F1E\u4FA3\u5151\u517D\u51BB\u51D1\u5220\u529D\u52CB\u5367\u5389\u5395\u53E0\u53F9\u5413\u548F\u5524\u575E\u575F\u5784\u5792\u57A6\u57AB\u58F3\u5986\u5988\u5A04\u5A07\u5BA0\u5C18\u5C82\u5DE9\u5E10\u5E1C\u5F2F\u60E9\u6124\u629B\u6321\u6324\u635E\u63FD\u6401\u644A\u6491\u655B\u658B\u6635\u67AB\u67DC\u680B\u692D\u6984\u6A31\u6B7C\u6BD9\u6C22\u6CA6\u6CA7\u6CEA\u6CFB\u6CFC\u6D46\u6D47\u6D4A\u6D51\u6DA1\u6E0A\u6E83\u6EE4\u6EE5\u6F9C\u6FD2\u70C2\u7237\u727A\u730E\u7574\u75AF\u7792\u7816\u7845\u78B1\u7A77\u7A91\u7A9D\u7AD6\u7B3C\u7B5B\u7CAE\u7EA4\u7EB1\u7EBA\u7ECE\u7ED1\u7EF0\u7EF3\u7F14\u7F1D\u7F34\u7F62\u8042\u806A\u80A0\u80A4\u80BE\u80BF\u80C0\u810F\u8138\u8231\u8270\u829C\u82CD\u8350\u83B9\u841D\u8574\u8680\u8BB3\u8BBC\u8BBD\u8BC8\u8BF1\u8BFD\u8C0A\u8C0D\u8C1C\u8C24\u8C26\u8C2C\u8C2D\u8C34\u8D1E\u8D2C\u8D3C\u8D41\u8D42\u8D4C\u8D50\u8D5A\u8F69\u8F88\u8F90\u8FA9\u915D\u9171\u9493\u949E\u94A7\u94A9\u94BB\u94C3\u94C5\u94DD\u94F8\u9505\u9510\u9523\u9524\u95EF\u95F7\u95F9\u9600\u9610\u96F3\u97F5\u987D\u9882\u9888\u9896\u98D8\u9971\u9972\u9976\u997C\u9A84\u9A86\u9A8F\u9A97\u9A9A\u9AA4\u9CB8\u9CDE\u9E26\u9E43\u9E64\u9E70\u9F7F\u9F9F +NGram.KANJI_4_28=\u534E\u62A5\u7ECF\u7F51 +NGram.KANJI_4_34=\u4E34\u4E3D\u4E4C\u4E54\u4E60\u4E61\u4E70\u4EB2\u4EC5\u4EEA\u4F18\u4F1F\u4F24\u4F26\u4FA7\u50A8\u513F\u5174\u517B\u518C\u519C\u51B5\u51CF\u5218\u521A\u5267\u52B3\u5356\u5382\u5385\u538B\u53A6\u5434\u5706\u5723\u5757\u575A\u575B\u575D\u5907\u591F\u593A\u5956\u5B59\u5BA1\u5BAB\u5BBD\u5BBE\u5BFB\u5C42\u5C81\u5E01\u5E08\u5E86\u5E93\u5F02\u5F39\u5F52\u5F55\u5F7B\u6000\u6001\u6076\u620F\u6237\u6267\u6269\u626C\u62A2\u62A4\u62DF\u62E5\u62E9\u6325\u635F\u6362\u6444\u6653\u6682\u6740\u6742\u6768\u6781\u6811\u6837\u6865\u68C0\u6B22\u6BC1\u6BD5\u6C47\u6C9F\u6CAA\u6CFD\u6D4B\u6DA8\u6E10\u6EE1\u6EE8\u706D\u7075\u70DF\u7231\u739B\u7597\u76D6\u76D8\u77FF\u7801\u7840\u79BB\u7A33\u7ADE\u7B14\u7B7E\u7CA4\u7D27\u7EB3\u7EBD\u7EC3\u7EC6\u7EC8\u7ECD\u7ED5\u7ED9\u7EDC\u7EDD\u7EE9\u7EFC\u7EFF\u7F13\u7F29\u8083\u80DC\u8111\u814A\u8230\u827A\u8363\u836F\u8428\u84DD\u867D\u8865\u88AD\u89C8\u8BA2\u8BA8\u8BA9\u8BAD\u8BB2\u8BBF\u8BC6\u8BCD\u8BD5\u8BEF\u8BF7\u8BF8\u8BFA\u8BFB\u8C08\u8D1D\u8D1F\u8D21\u8D25\u8D27\u8D2D\u8D2F\u8D35\u8D38\u8DC3\u8F6E\u8F6F\u8F7B\u8F7D\u8F86\u8F91\u8F93\u8F96\u8FB9\u8FBD\u8FC1\u8FDC\u8FDD\u9002\u9057\u90BB\u90D1\u91CA\u9488\u949F\u94A2\u94B1\u94F6\u9500\u9526\u9547\u9614\u9634\u9635\u9636\u9648\u9655\u9669\u9690\u97E9\u9875\u9876\u987A\u987B\u987E\u987F\u9891\u989D\u98DE\u9986\u9A7B\u9A8C\u9C81\u9C9C\u9F50 +NGram.KANJI_4_39=\u4E1B\u4E1D\u4E27\u4EA9\u4ED1\u4ED3\u4F2A\u4FA6\u4FA8\u503A\u503E\u507F\u5188\u51AF\u51C0\u51C9\u51ED\u51EF\u5242\u5251\u52B2\u5362\u53A2\u5415\u5417\u5428\u55B7\u5760\u5899\u5939\u594B\u5987\u5A31\u5A74\u5BAA\u5C1D\u5C7F\u5C97\u5CAD\u5E05\u5E2E\u5E99\u5E9E\u5E9F\u5F03\u5FC6\u5FE7\u60AC\u60CA\u60EF\u626B\u6270\u629A\u62E6\u62E8\u6446\u6447\u654C\u67AA\u680F\u6863\u68A6\u6C64\u6D01\u6D53\u6D9D\u6DA6\u6E14\u6E17\u6EDA\u6EE9\u707F\u70BC\u70E7\u7275\u72B9\u72EE\u72F1\u743C\u7545\u76D0\u7855\u7978\u7B79\u7BEE\u7EA0\u7EAC\u7EAF\u7EB2\u7EB5\u7EB7\u7EB8\u7EB9\u7ED8\u7EEA\u7EF5\u7F05\u7F06\u7F18\u7F5A\u80C1\u80F6\u8109\u8206\u8273\u82F9\u8346\u8361\u83B2\u8427\u8651\u867E\u8854\u89C9\u8BC9\u8BCA\u8BD7\u8BDA\u8BDE\u8BE2\u8BE6\u8BFE\u8C01\u8C0B\u8C10\u8C13\u8C22\u8C23\u8C28\u8C31\u8D24\u8D26\u8D29\u8D2A\u8D2B\u8D34\u8D37\u8D3A\u8D3E\u8D3F\u8D4B\u8D4F\u8D54\u8D56\u8D5E\u8D60\u8D62\u8D75\u8D76\u8D8B\u8F68\u8F70\u8F74\u8F85\u8F89\u8FC8\u8FDF\u900A\u9012\u903B\u9093\u90AE\u917F\u9274\u94A6\u94DC\u94ED\u94FA\u94FE\u9501\u950B\u9519\u9521\u952E\u955C\u95EA\u95ED\u95F2\u95F8\u95FD\u9601\u9605\u9647\u96B6\u96FE\u9877\u9881\u9887\u9897\u989C\u98A0\u996D\u996E\u9970\u9A70\u9A71\u9A73\u9A76\u9A7E\u9A91\u9C7C\u9E1F\u9E21\u9E23\u9E2D\u9E3F\u9E4F\u9F84 +NGram.KANJI_5_10=\u5239\u8EAF +NGram.KANJI_5_11=\u51C4\u8471 +NGram.KANJI_5_12=\u6DC0\u7C98 +NGram.KANJI_5_13=\u5631\u5815\u8695 +NGram.KANJI_5_14=\u4E71\u4FA0\u5265\u52B1\u5374\u53A8\u53D9\u58EE\u5BDD\u5BFF\u5C3D\u5C4A\u5CE1\u5F25\u5F84\u604B\u60A6\u60E7\u60E8\u631F\u636E\u643A\u663C\u664B\u67A2\u6816\u697C\u6B8B\u6BB4\u6D45\u6E7F\u6EDE\u6F5C\u706F\u7089\u72ED\u732A\u732B\u76D7\u793C\u7977\u7A0E\u7A83\u80C6\u811A\u8131\u82A6\u830E\u848B\u865A\u866B\u86EE\u89E6\u8A89\u8DF5\u8E0A\u8E2A\u8F9E\u9065\u968F\u9759\u9EA6 +NGram.KANJI_5_18=\u601C\u75D2 +NGram.KANJI_5_26=\u4E07\u4E0E\u4E89\u4F1A\u4F53\u515A\u5185\u5199\u533A\u533B\u53C2\u53CC\u53F7\u58F0\u5965\u5B66\u5B9D\u5C06\u5C5E\u5F53\u62C5\u6570\u65AD\u65E7\u6761\u6765\u6A2A\u6B27\u6CA1\u6E29\u6E7E\u70B9\u72B6\u72EC\u732E\u753B\u79F0\u88C5\u9EC4 +NGram.KANJI_5_29=\u693F\u82EB +NGram.KANJI_5_34=\u53F6\u6D9B\u83B1 +NGram.KANJI_5_39=\u5C61\u788D +NGram.KANJI_6_0=\u4E10\u4E52\u4EC6\u4F88\u4FD0\u51F3\u533E\u53ED\u53EE\u5406\u541D\u5429\u5435\u5440\u5490\u5495\u54B1\u54C4\u54FC\u557C\u55D3\u5669\u56E4\u5777\u5992\u59E8\u5B7D\u5BDE\u5BE5\u5C79\u5C94\u5DCD\u5E18\u5E1A\u5E54\u5FF1\u604D\u6064\u60F6\u6127\u6177\u6233\u6252\u625B\u6273\u6296\u62C2\u62C7\u62F4\u638F\u6396\u63E3\u63EA\u6413\u6479\u64A9\u64C2\u659F\u667E\u6760\u6845\u6963\u6A90\u6B83\u6C13\u6C5E\u6D8E\u6D95\u6DCC\u6ED4\u6F13\u6F3E\u6FA1\u7076\u70D8\u710A\u71CE\u7239\u72E1\u73B7\u7599\u759A\u75A4\u75CA\u7629\u7682\u76C5\u76EF\u778E\u77AA\u787C\u7889\u788C\u78BE\u79E7\u7A96\u7A98\u7B77\u7C7D\u7CB1\u7D0A\u7D6E\u7F94\u7FCE\u8116\u814B\u814C\u819B\u828D\u82DF\u8301\u83E0\u85D5\u8611\u86A3\u8708\u8822\u8C4C\u8DB4\u8DEA\u8E42\u8E66\u8E72\u8EBA\u901B\u9157\u970E\u97ED +NGram.KANJI_6_3=\u62FC\u88D4\u9B4F +NGram.KANJI_6_9=\u4ED7\u4F63\u4FCF\u5018\u50BB\u50F5\u5154\u5201\u522E\u5254\u527F\u5306\u5462\u5492\u5496\u54A8\u54AA\u554A\u5561\u5564\u5566\u5885\u5938\u5AC2\u5AE9\u5CED\u5F64\u6084\u608D\u60A8\u60D5\u61C2\u61C8\u6254\u626F\u62AC\u6346\u634D\u640F\u6454\u6487\u6495\u64D2\u6746\u6789\u68B3\u68F5\u695E\u6986\u6995\u69A8\u6A44\u6AAC\u6B79\u6C28\u6C2E\u6CF5\u6DE4\u6E34\u6E3A\u6E89\u6F29\u70AB\u70AC\u7130\u715E\u7184\u71AC\u7238\u7281\u72E0\u74E3\u74F7\u7529\u7578\u761F\u7626\u76D4\u775B\u7779\u7784\u77BB\u780C\u780D\u7838\u7898\u78C5\u78F7\u7AED\u7B28\u7BE1\u7C07\u7CD5\u7CD9\u7CEF\u7F38\u800D\u8084\u809A\u8165\u816E\u832B\u8334\u840D\u8774\u886B\u888D\u88D9\u88F9\u8C41\u8D81\u8D9F\u8E22\u8E29\u8EB2\u8F9C\u9165\u918B\u9631\u964B\u964C\u9661\u9709\u9739\u9776\u9AD3\u9ED4 +NGram.KANJI_6_10=\u4E53\u5582\u5600\u6342\u7B06 +NGram.KANJI_6_11=\u5288\u543C\u5475\u5486\u54EE\u5598\u56BC\u5962\u5A36\u5A9A\u5B75\u5BA6\u5C38\u5C4E\u5F8A\u5F98\u627C\u62CC\u62D7\u63C9\u6930\u6954\u69D0\u6BEF\u6C90\u6CBD\u6CBE\u6F31\u6F88\u70D9\u7329\u75BC\u75F0\u7737\u77D7\u7B19\u7FB9\u803F\u80D6\u813E\u81C0\u8205\u8309\u83BD\u846B\u8517\u868C\u8759\u8815\u8859\u8B6C\u8E81\u8EAC\u90A2\u9698\u9B44 +NGram.KANJI_6_12=\u722C\u7FD4 +NGram.KANJI_6_16=\u5228\u5315\u542E\u54CE\u5509\u5527\u5543\u55B3\u55E1\u5636\u568E\u5FFF\u61E6\u6376\u642A\u6726\u74E4\u76F9\u7736\u7BD9\u8019\u80F0\u80F3\u812F\u818A\u8200\u8214\u8638\u869C\u86C0\u86C6\u86D4\u87C6\u88B1\u8902\u8C7A\u8E4B\u9119 +NGram.KANJI_6_18=\u67D2\u6ED3\u87C0\u87CB\u8DDB\u901E\u9163 +NGram.KANJI_6_20=\u4F5B\u52D2\u54C8\u62FF\u66FC\u6D59\u704C\u7586\u9ECE +NGram.KANJI_6_21=\u4E48\u4EFF\u4F19\u4FF1\u5021\u5077\u5195\u5212\u5269\u5401\u541E\u5427\u54EA\u5587\u558A\u55BB\u566A\u573E\u574E\u5783\u57AE\u584C\u58E4\u5960\u5976\u59CA\u5A1C\u5DE2\u5F99\u600E\u6015\u6263\u626D\u6293\u62C6\u62D6\u62EF\u62F1\u6316\u632A\u6380\u6389\u63D2\u641E\u64C5\u64CE\u65F1\u6664\u6735\u6770\u67EC\u6846\u684C\u68AD\u6B47\u6B49\u6B67\u6C1B\u6C27\u6C2F\u6C5B\u6C89\u6DF9\u6EAF\u70AE\u70E4\u731C\u7334\u73BB\u7470\u76FC\u788E\u789F\u78B0\u78B3\u7A0D\u7A3B\u7A57\u7CB9\u7F69\u8335\u8354\u84BF\u8DCC\u8DD1\u904F\u90A8\u9189\u9677\u9738\u978B +NGram.KANJI_6_22=\u5162\u53E8\u542D\u5501\u552C\u5639\u563F\u56B7\u6043\u60B4\u6194\u61CA\u634E\u63CD\u6414\u64AC\u6DAE\u6E43\u6F66\u7095\u7316\u733E\u7728\u7830\u78D5\u7ABF\u7FE9\u8018\u80EF\u8198\u8693\u86AA\u86AF\u874C\u8783\u879F\u8892\u8E6C +NGram.KANJI_6_23=\u4FD8\u4FEF\u501A\u5085\u5180\u526A\u5323\u54ED\u5634\u56CA\u58A9\u58F9\u5955\u5978\u59DA\u5A49\u5B55\u5BC7\u5BE8\u5D4C\u5E62\u6467\u64BC\u6500\u655E\u6572\u658C\u6670\u68CD\u68D5\u68E0\u6912\u6A0A\u6BB7\u6C9B\u6D3D\u6DC6\u6E23\u6F8E\u7011\u7092\u714C\u73AB\u7405\u7624\u76D2\u7960\u79C9\u7A20\u7BF7\u7F50\u804A\u8086\u81C2\u8292\u82DE\u852C\u857E\u859B\u8760\u8C6B\u8DBE\u8E48\u8F9F\u96A7 +NGram.KANJI_6_25=\u4E8E\u5DF2\u5FB7\u7AD9 +NGram.KANJI_6_28=\u4E58\u4ECD\u4EFD\u4F30\u4F60\u4F69\u503C\u5047\u51B0\u51F0\u5361\u5377\u53E6\u54E5\u552E\u5708\u5740\u5761\u57C3\u5821\u589E\u5979\u59C6\u5B69\u5B83\u5E15\u5E76\u5F17\u5F88\u6208\u622A\u624E\u627E\u62D4\u62DC\u63ED\u641C\u6536\u6548\u65C1\u665A\u6668\u67E5\u6B65\u6BCF\u6C61\u6CDB\u6D4E\u6D89\u6DB5\u6E38\u6EAA\u6FB3\u70B8\u745F\u7538\u7A97\u7F3A\u7F55\u805A\u8258\u827E\u82AC\u8303\u83F2\u8482\u85CF\u8DDF\u903E\u9080\u970D\u9760\u9ED1\u9ED8 +NGram.KANJI_6_29=\u634F\u6518\u7B50\u809B +NGram.KANJI_6_30=\u54A7\u57C2\u5AB3\u60CB\u6886\u8378\u85D0\u8671 +NGram.KANJI_6_32=\u5080\u5121\u51A4\u54AC\u55DC\u592D\u5DEB\u6292\u68D8\u69B4\u6A59\u6E24\u7FC5\u80DA\u8180\u86DB\u8700\u8DCB\u9761 +NGram.KANJI_6_34=\u4E30\u51E0\u542C\u613F +NGram.KANJI_6_35=\u4E56\u547B\u55FD\u5C41\u606C\u6115\u6CAE\u7119\u795F\u7CDC\u86C9\u86F9\u8713\u873B\u8757\u8925\u892A\u96F9 +NGram.KANJI_6_37=\u51B2\u5308\u5398\u54B8\u59DC\u5C4F\u5D14\u5F6D\u60E0\u6241\u6350\u699C\u6BEB\u6C6A\u6CC4\u6DEE\u6F58\u6F6D\u7199\u77EE\u7ADF\u8058\u820D\u8212\u8389\u8587\u884D\u8881\u8FA8\u8FF9\u96D5 +NGram.KANJI_6_39=\u574F\u6251\u6302 +NGram.KANJI_7_0=\u52FA\u5544\u60F0\u6994\u86A4\u86E4 +NGram.KANJI_7_3=\u4E59\u4E7E\u4EAD\u4EF0\u4EF2\u4F0F\u4F10\u4FAF\u4FCA\u500D\u501F\u5076\u508D\u50E7\u5112\u5146\u5192\u51AC\u51DD\u51FD\u5200\u5237\u524A\u52A3\u52C3\u52C7\u52DF\u5351\u5352\u5353\u5378\u537F\u53E5\u5439\u54FA\u574A\u5782\u57CB\u5893\u58C1\u5915\u5937\u5949\u5951\u5974\u59B9\u5A18\u5A5A\u5ACC\u5B54\u5B5D\u5B64\u5B8F\u5BBF\u5BD2\u5C3A\u5C6F\u5CB3\u5D07\u5DE7\u5E84\u5E8A\u5F26\u5F69\u5F70\u5F90\u5FAA\u5FCD\u6012\u6016\u602A\u60A0\u60B2\u60BC\u6148\u6162\u6170\u6291\u6298\u62AB\u62BC\u62BD\u62D2\u62D3\u62D8\u62F3\u6311\u638C\u6398\u63E1\u642C\u6458\u64A4\u654F\u656C\u659C\u65E2\u65E8\u65EC\u6606\u6614\u6676\u6691\u6696\u66F9\u6749\u676F\u679A\u679D\u67CF\u67D4\u67F1\u67F3\u67F4\u6817\u6842\u6843\u6851\u68A8\u68CB\u68D2\u6B20\u6B32\u6BBF\u6C57\u6C88\u6CCA\u6D17\u6D1E\u6D69\u6D6E\u6D78\u6DE1\u6DFB\u6E58\u6EB6\u6F0F\u6F20\u7070\u708E\u70AD\u7126\u718A\u71C3\u7267\u72C2\u731B\u7384\u73A9\u73CD\u7434\u75AB\u75DB\u76C6\u76FE\u773C\u7891\u78C1\u795D\u7965\u79D2\u79DF\u79E6\u7A00\u7B11\u7B51\u7B54\u7C89\u7C92\u7CD6\u7D2B\u7F8A\u7FBD\u7FFC\u8010\u80A5\u80CE\u8150\u8179\u819C\u8247\u829D\u82B3\u82D7\u82E6\u8302\u8336\u8352\u83CA\u83CC\u83DC\u845B\u846C\u84B2\u84B8\u84C4\u8584\u864E\u86C7\u8861\u8863\u8870\u888B\u8896\u88D5\u8986\u8C46\u8DA3\u8E0F\u8F9B\u8FC5\u8FEB\u8FF7\u9003\u9006\u902E\u9042\u9063\u90ED\u963B\u9676\u96EA\u9756\u9B3C\u9B42\u9F3B +NGram.KANJI_7_6=\u4E01\u4E03\u4E45\u4E5D\u4E88\u4E92\u4EA1\u4ECB\u4EE4\u4F01\u4F0A\u4F2F\u4F3C\u4F4E\u4F4F\u4F55\u4F8B\u4F9D\u4FBF\u4FEE\u505C\u50CF\u516B\u516D\u5175\u5177\u5178\u5207\u520A\u5224\u526F\u529F\u52A9\u5343\u5348\u535A\u5370\u53BB\u53CB\u53F3\u5409\u542B\u544A\u547C\u5584\u5747\u5802\u590F\u592B\u5931\u5947\u597D\u5A01\u5A92\u5B63\u5B8C\u5B97\u5BA2\u5BA3\u5BA4\u5BB3\u5BB9\u5BC6\u5BCC\u5BDF\u5C04\u5C1A\u5C45\u5C4B\u5CB8\u5DE6\u5E0C\u5E1D\u5E2D\u5E55\u5E8F\u5E95\u5E97\u5EA7\u5EB7\u5EF6\u5F8B\u5FAE\u5FC5\u5FD7\u5FF5\u601D\u6025\u606F\u60F3\u611F\u623F\u6253\u6279\u627F\u6295\u6297\u62EC\u6388\u6392\u63F4\u6545\u6551\u6574\u6599\u65C5\u65E9\u6613\u6620\u6625\u666E\u666F\u66B4\u66F4\u670D\u671B\u6728\u672B\u6751\u677E\u67B6\u6838\u6839\u6848\u68EE\u690D\u6982\u6A21\u6B4C\u6B62\u6B66\u6BB5\u6BCD\u6C0F\u6C38\u6C42\u6CBF\u6CE2\u6CE8\u6D0B\u6D3E\u6D88\u6DF1\u6E05\u6E56\u706B\u7167\u7206\u7236\u7247\u7387\u7530\u7537\u7559\u7565\u7591\u75C5\u767B\u767D\u767E\u7687\u76DB\u76DF\u771F\u7763\u77ED\u7834\u79FB\u7A81\u7AE0\u7AEF\u7B56\u7B97\u7C4D\u7CBE\u7D20\u7D22\u7F72\u7FA4\u8001\u8003\u81F4\u822A\u826F\u82B1\u8349\u843D\u878D\u8857\u89D2\u8B66\u8C37\u8D70\u8D85\u8D8A\u8DB3\u8FF0\u8FFD\u9001\u901F\u90A3\u90A6\u914D\u91CE\u9632\u963F\u9644\u964D\u9664\u96C4\u96E8\u9752\u9769\u98DF +NGram.KANJI_7_7=\u4E09\u4E0A\u4E0B\u4E0D\u4E16\u4E3B\u4E8B\u4E8C\u4EE3\u4EE5\u4F4D\u4F5C\u4F7F\u5165\u5168\u516C\u5171\u51FA\u5206\u5229\u5236\u524D\u529B\u52A0\u5316\u5317\u5357\u539F\u53CA\u53F0\u5408\u540C\u540D\u548C\u5730\u57FA\u5916\u591A\u5929\u5B50\u5B9A\u5BB6\u5C0F\u5C71\u5DDE\u5DE5\u5E02\u5E73\u5EA6\u5EFA\u5F0F\u6027\u6210\u6240\u6307\u653F\u6587\u65B0\u65B9\u660E\u6700\u6709\u671F\u672C\u6B21\u6B63\u6C11\u6CBB\u6CD5\u6D77\u7269\u7279\u7406\u751F\u7528\u7531\u754C\u76EE\u76F8\u793E\u79D1\u7ACB\u7B2C\u7B49\u7CFB\u8005\u80FD\u81EA\u82F1\u884C\u8868\u897F\u8981\u901A\u9053\u90E8\u90FD\u91CD\u9AD8 +NGram.KANJI_7_9=\u4E4D\u4F36\u5319\u6A61\u6DCB\u7194 +NGram.KANJI_7_11=\u4E5E\u4F43\u5026\u50FB\u515C\u5243\u5420\u5446\u54B3\u54BD\u553E\u55A7\u5703\u5984\u5AC9\u5B09\u5C51\u5DFE\u5ED3\u5F1B\u6055\u618E\u62D9\u65A7\u6652\u6977\u6EBA\u707C\u75D8\u79E4\u7AFF\u7B4F\u7CA5\u808B\u8098\u80B4\u8235\u82DB\u849C\u8549\u868A\u86FE\u8718\u914C +NGram.KANJI_7_12=\u4E08\u4E38\u4F8D\u50DA\u5203\u5256\u52C9\u52D8\u52FE\u5320\u533F\u5375\u53D4\u540F\u54E8\u56DA\u5806\u5996\u5999\u59A5\u59A8\u59FF\u5AE1\u5BB0\u5BF8\u5C09\u5C3F\u5C48\u5C65\u5D29\u5E06\u5E4C\u5EB5\u5EB6\u5EB8\u5F13\u5FCC\u5FD8\u6052\u606D\u609F\u60D1\u614E\u6247\u62B1\u6349\u64E6\u6577\u65ED\u6674\u6734\u67C4\u6850\u690E\u6A58\u6B3A\u6B89\u6C41\u6CBC\u6CCC\u6CF3\u6D74\u6DAF\u6DF3\u6ECB\u6F02\u6F84\u71E5\u7261\u7272\u72AC\u72FC\u733F\u7409\u755C\u76F2\u7720\u77AC\u77E2\u7802\u786B\u78E8\u7901\u7948\u79E9\u7A1A\u7A74\u7AE3\u7B4B\u7B52\u7BB1\u7C3F\u8015\u8096\u809D\u80A2\u80A9\u80AA\u80BA\u80F8\u8102\u810A\u8154\u8155\u8170\u817A\u81A8\u81ED\u820C\u8236\u82BD\u8305\u83E9\u83F1\u840C\u85FB\u8650\u8702\u8A93\u8E44\u8FB0\u9038\u9091\u90AA\u916C\u9175\u9177\u9685\u96C0\u96C7\u96CC\u97AD +NGram.KANJI_7_13=\u63D6\u803D +NGram.KANJI_7_16=\u602F\u7566 +NGram.KANJI_7_18=\u634C\u7C38 +NGram.KANJI_7_19=\u4E18\u4E73\u4E95\u4EAB\u4EC1\u4ED8\u4ED9\u4F11\u4F34\u4F38\u4F59\u4FB5\u4FC3\u4FD7\u5012\u5019\u5065\u50AC\u5144\u5145\u514D\u517C\u51A0\u51B7\u5211\u5238\u523A\u523B\u5272\u52E4\u5360\u5371\u539A\u541B\u5426\u5438\u5473\u54F2\u5510\u552F\u5531\u559C\u5609\u56F0\u56FA\u591C\u5948\u594F\u59BB\u59D3\u5B85\u5B87\u5B88\u5B99\u5B9C\u5BC4\u5BFA\u5C0A\u5C3E\u5CA9\u5D0E\u5DE1\u5DE8\u5DEE\u5DF1\u5E45\u5E78\u5E7B\u5E7C\u5EAD\u5EF7\u5F1F\u5F31\u5F79\u5F7C\u5F85\u5F92\u5FA1\u5FE0\u6050\u60A3\u6212\u62DB\u632F\u6355\u63A2\u63AA\u63CF\u642D\u6469\u64CD\u653B\u6563\u660C\u662D\u667A\u6697\u66FF\u6750\u675F\u677F\u6790\u67D3\u682A\u6885\u68B0\u6B8A\u6B96\u6BDB\u6C60\u6CB9\u6CC9\u6D25\u6D66\u6DB2\u6DF7\u6E21\u6ED1\u6F2B\u6F6E\u6FC0\u7235\u725B\u72AF\u7389\u7532\u7533\u756A\u75BE\u75C7\u76AE\u76CA\u7740\u786C\u7956\u7968\u796D\u7981\u79C0\u79C1\u79CB\u79D8\u7A3F\u7AE5\u7AF9\u7E41\u7F6A\u7FFB\u8089\u80CC\u80DE\u81E3\u821E\u8239\u82E5\u8328\u8377\u85E4\u8840\u88C1\u88C2\u8C6A\u8D64\u8DDD\u8FCE\u8FD4\u9000\u9014\u907F\u90CA\u90CE\u90E1\u9152\u9178\u9686\u9694\u969C\u9707\u9732\u9AA8\u9B54\u9E7F\u9EBB +NGram.KANJI_7_20=\u4E39\u4E43\u4EAE\u4F73\u504F\u505A\u51C6\u51CC\u52AA\u5339\u5347\u53EB\u53EC\u5448\u5766\u57F9\u5854\u585E\u58A8\u5B8B\u5C01\u5CF0\u5E72\u5EC9\u5F80\u5F81\u5FBD\u5FEB\u6069\u6211\u624D\u628A\u62B5\u62CD\u6309\u63A7\u64AD\u6566\u6597\u65CB\u65D7\u6628\u6717\u6731\u674E\u675C\u683D\u6881\u6B3E\u6BD2\u6C7D\u6C99\u6CE5\u6CF0\u6D1B\u6D2A\u70C8\u719F\u724C\u7259\u73E0\u73ED\u745E\u74E6\u7518\u751A\u7686\u770B\u7B26\u8033\u80A1\u80E1\u821F\u83AB\u8499\u8D74\u8DE8\u900F\u9010\u9047\u904D\u906D\u9675\u96C5\u96F6\u96F7\u9700\u9F13 +NGram.KANJI_7_21=\u5764\u59D0\u5A03\u6062\u6108\u68C9\u7164\u79BE\u7BAD\u903C +NGram.KANJI_7_23=\u4EA5\u50B2\u532A\u5366\u543B\u54E9\u5632\u59D1\u5BB5\u5DF7\u5F6A\u5F6C\u5FFD\u6070\u6168\u61BE\u63A0\u63A9\u6478\u65A4\u68A7\u6A1F\u6CAB\u70F9\u711A\u723D\u7262\u72F8\u751C\u754F\u75B9\u76C8\u7709\u7897\u7CCA\u7F9E\u8299\u82AD\u82B9\u82D4\u8304\u84C9\u84EC\u854A\u85AF\u86D9\u8FA3\u9187\u97A0 +NGram.KANJI_7_25=\u4E14\u4E5F\u4F46\u514B\u5176\u5230\u5373\u53EA\u540E\u5982\u5C3C\u5DF4\u6216\u62C9\u65AF\u66FE\u6B64\u6D32\u6D6A\u7BC7\u800C +NGram.KANJI_7_28=\u4E4E\u4E9B\u4EA6\u4EC0\u4FC4\u5403\u5957\u5C24\u6089\u6258\u67D0\u758F\u7FF0\u8D6B +NGram.KANJI_7_29=\u4FAE\u5944\u5A29\u6101\u62ED\u6328\u637B\u6666\u6687\u66AE\u673D\u6756\u67FF\u6813\u68A2\u699B\u7078\u708A\u7396\u7422\u7525\u75E2\u76BF\u7766\u77B3\u7A3C\u7A92\u819D\u81FC\u8237\u8338\u8511\u88F3\u8FC2 +NGram.KANJI_7_32=\u4E11\u4F3A\u4F51\u5197\u51B6\u51F9\u52FF\u541F\u5507\u5589\u5993\u5A7F\u5AC1\u5B9B\u5BC2\u5BE1\u5F04\u5F0A\u5F27\u6020\u6028\u6068\u6094\u6109\u611A\u614C\u621A\u62B9\u62D0\u62F7\u62FE\u632B\u633D\u6367\u660F\u6627\u6643\u66D9\u674F\u6795\u67AF\u67D1\u6876\u68DA\u68FA\u6905\u69FD\u6A80\u6B6A\u6CB8\u6CE3\u6DD1\u6DEB\u6E9C\u6EA2\u6EF4\u6F06\u714E\u716E\u722A\u7280\u74A7\u752B\u75B2\u75D5\u75F4\u77AD\u77E9\u785D\u79BD\u7A3D\u7A9F\u7B1B\u7B95\u7C9F\u7CDF\u80C3\u8106\u817F\u818F\u81B3\u828B\u82A5\u82AF\u840E\u851A\u853D\u8776\u87F9\u8877\u8910\u8912\u8C79\u8D66\u8FB1\u9017\u90C1\u916A\u9699\u96C1\u971C\u9774\u978D +NGram.KANJI_7_33=\u4E4B\u4E86\u4E94\u4EA4\u4EAC\u4ECA\u4ED6\u4EF6\u4EFB\u4F9B\u4FDD\u4FE1\u5143\u5148\u5149\u518D\u5217\u521D\u5305\u5341\u534A\u53C8\u53CD\u53D6\u53D7\u53E3\u53E4\u53EF\u53F2\u53F8\u5404\u5411\u5468\u547D\u54C1\u5546\u5668\u56DB\u56DE\u56E0\u571F\u578B\u57CE\u57DF\u5883\u58EB\u592A\u592E\u5973\u59CB\u59D4\u5B57\u5B58\u5B89\u5B98\u5C11\u5C31\u5C40\u5C55\u5DDD\u5E03\u5E38\u5E9C\u5F15\u5F62\u5F71\u5F97\u5FC3\u60C5\u610F\u624B\u6280\u6301\u63A5\u63A8\u63D0\u652F\u6539\u653E\u6559\u65BD\u65CF\u661F\u66F2\u671D\u672A\u6797\u679C\u6821\u683C\u6B7B\u6BD4\u6C34\u6C5F\u6CB3\u6D3B\u6D41\u6E2F\u6E90\u6F14\u7136\u7248\u738B\u7403\u76F4\u7701\u77E5\u77F3\u7814\u793A\u795E\u798F\u7A0B\u7A76\u7A7A\u7BA1\u7C73\u7F6E\u7F8E\u80B2\u81F3\u822C\u8272\u8457\u88AB\u89E3\u8A00\u8C61\u8D77\u8DEF\u8EAB\u8FD1\u9020\u91CC\u91CF\u91D1\u9650\u9662\u96C6\u975E\u9762\u97F3\u9996\u9999 +NGram.KANJI_7_35=\u55C5\u57A2\u58D5\u59E5\u637A\u74E2\u7CE0\u895F +NGram.KANJI_7_37=\u4E19\u4E32\u4E4F\u4E91\u4EC7\u4ED4\u4F0D\u5141\u51E1\u51F6\u51F8\u52AB\u535C\u53C9\u53DB\u540A\u5410\u54C0\u559D\u5750\u5751\u576A\u57E0\u5824\u582A\u5830\u5835\u5851\u5858\u586B\u5954\u59FB\u5A46\u5B5F\u5BB4\u5BD3\u5C16\u5C60\u5CFB\u5D16\u5E16\u5E3D\u5E7D\u5E87\u5ECA\u5FD9\u60DC\u60F9\u6155\u6167\u6234\u626E\u6276\u6284\u633A\u6377\u6492\u649E\u64B0\u6562\u6591\u65A5\u65E6\u65FA\u6602\u670B\u676D\u68AF\u695A\u6B23\u6BC5\u6C70\u6C83\u6CE1\u6D8C\u6DD8\u6E20\u71D5\u72D0\u72D7\u73B2\u73CA\u7433\u7483\u74DC\u74F6\u7554\u764C\u7761\u77DB\u78A7\u7A46\u7A7F\u7A84\u7C97\u7D2F\u7FC1\u7FE0\u8000\u8017\u808C\u80AF\u8404\u8461\u8463\u8475\u8513\u85AA\u8679\u86CB\u871C\u87BA\u88F8\u8C8C\u8DF3\u8FC4\u901D\u9022\u906E\u9075\u9192\u91C7\u966A\u971E\u9910\u9B41\u9F0E\u9F20 diff --git a/Emby.Server.Implementations/TextEncoding/TextEncoding.cs b/Emby.Server.Implementations/TextEncoding/TextEncoding.cs new file mode 100644 index 000000000..9eb9be7ea --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/TextEncoding.cs @@ -0,0 +1,265 @@ +using System; +using System.Text; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Text; +using NLangDetect.Core; +using UniversalDetector; + +namespace Emby.Server.Implementations.TextEncoding +{ + public class TextEncoding : ITextEncoding + { + private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; + private IJsonSerializer _json; + + public TextEncoding(IFileSystem fileSystem, ILogger logger, IJsonSerializer json) + { + _fileSystem = fileSystem; + _logger = logger; + _json = json; + } + + public Encoding GetASCIIEncoding() + { + return Encoding.ASCII; + } + + private Encoding GetInitialEncoding(byte[] buffer, int count) + { + if (count >= 3) + { + if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf) + return Encoding.UTF8; + } + + if (count >= 2) + { + if (buffer[0] == 0xfe && buffer[1] == 0xff) + return Encoding.Unicode; + } + + if (count >= 4) + { + if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff) + return Encoding.UTF32; + } + + if (count >= 3) + { + if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76) + return Encoding.UTF7; + } + + var result = new TextEncodingDetect().DetectEncoding(buffer, count); + + switch (result) + { + case TextEncodingDetect.CharacterEncoding.Ansi: + return Encoding.ASCII; + case TextEncodingDetect.CharacterEncoding.Ascii: + return Encoding.ASCII; + case TextEncodingDetect.CharacterEncoding.Utf16BeBom: + return Encoding.UTF32; + case TextEncodingDetect.CharacterEncoding.Utf16BeNoBom: + return Encoding.UTF32; + case TextEncodingDetect.CharacterEncoding.Utf16LeBom: + return Encoding.UTF32; + case TextEncodingDetect.CharacterEncoding.Utf16LeNoBom: + return Encoding.UTF32; + case TextEncodingDetect.CharacterEncoding.Utf8Bom: + return Encoding.UTF8; + case TextEncodingDetect.CharacterEncoding.Utf8Nobom: + return Encoding.UTF8; + default: + return null; + } + } + + private bool _langDetectInitialized; + public string GetDetectedEncodingName(byte[] bytes, int count, string language, bool enableLanguageDetection) + { + var index = 0; + + var encoding = GetInitialEncoding(bytes, count); + + if (encoding != null && encoding.Equals(Encoding.UTF8)) + { + return "utf-8"; + } + + if (string.IsNullOrWhiteSpace(language) && enableLanguageDetection) + { + if (!_langDetectInitialized) + { + _langDetectInitialized = true; + LanguageDetector.Initialize(_json); + } + + language = DetectLanguage(bytes, index, count); + + if (!string.IsNullOrWhiteSpace(language)) + { + _logger.Debug("Text language detected as {0}", language); + } + } + + var charset = DetectCharset(bytes, index, count, language); + + if (!string.IsNullOrWhiteSpace(charset)) + { + if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase)) + { + return "utf-8"; + } + + if (!string.Equals(charset, "windows-1252", StringComparison.OrdinalIgnoreCase)) + { + return charset; + } + } + + if (!string.IsNullOrWhiteSpace(language)) + { + return GetFileCharacterSetFromLanguage(language); + } + + return null; + } + + private string DetectLanguage(byte[] bytes, int index, int count) + { + try + { + return LanguageDetector.DetectLanguage(Encoding.UTF8.GetString(bytes, index, count)); + } + catch (NLangDetectException ex) + { + } + + try + { + return LanguageDetector.DetectLanguage(Encoding.ASCII.GetString(bytes, index, count)); + } + catch (NLangDetectException ex) + { + } + + try + { + return LanguageDetector.DetectLanguage(Encoding.Unicode.GetString(bytes, index, count)); + } + catch (NLangDetectException ex) + { + } + + return null; + } + + public Encoding GetEncodingFromCharset(string charset) + { + if (string.IsNullOrWhiteSpace(charset)) + { + throw new ArgumentNullException("charset"); + } + + _logger.Debug("Getting encoding object for character set: {0}", charset); + + try + { + return Encoding.GetEncoding(charset); + } + catch (ArgumentException) + { + charset = charset.Replace("-", string.Empty); + _logger.Debug("Getting encoding object for character set: {0}", charset); + + return Encoding.GetEncoding(charset); + } + } + + public Encoding GetDetectedEncoding(byte[] bytes, int size, string language, bool enableLanguageDetection) + { + var charset = GetDetectedEncodingName(bytes, size, language, enableLanguageDetection); + + return GetEncodingFromCharset(charset); + } + + private string GetFileCharacterSetFromLanguage(string language) + { + // https://developer.xamarin.com/api/type/System.Text.Encoding/ + + switch (language.ToLower()) + { + case "hun": + return "windows-1252"; + case "pol": + case "cze": + case "ces": + case "slo": + case "srp": + case "hrv": + case "rum": + case "ron": + case "rup": + return "windows-1250"; + // albanian + case "alb": + case "sqi": + return "windows-1250"; + // slovak + case "slk": + case "slv": + return "windows-1250"; + case "ara": + return "windows-1256"; + case "heb": + return "windows-1255"; + case "grc": + return "windows-1253"; + // greek + case "gre": + case "ell": + return "windows-1253"; + case "crh": + case "ota": + case "tur": + return "windows-1254"; + // bulgarian + case "bul": + case "bgr": + return "windows-1251"; + case "rus": + return "windows-1251"; + case "vie": + return "windows-1258"; + case "kor": + return "cp949"; + default: + return "windows-1252"; + } + } + + private string DetectCharset(byte[] bytes, int index, int count, string language) + { + var detector = new CharsetDetector(); + detector.Feed(bytes, index, count); + detector.DataEnd(); + + var charset = detector.Charset; + + // This is often incorrectly indetected. If this happens, try to use other techniques instead + if (string.Equals("x-mac-cyrillic", charset, StringComparison.OrdinalIgnoreCase)) + { + if (!string.IsNullOrWhiteSpace(language)) + { + return null; + } + } + + return charset; + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/TextEncodingDetect.cs b/Emby.Server.Implementations/TextEncoding/TextEncodingDetect.cs new file mode 100644 index 000000000..a0395a21b --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/TextEncodingDetect.cs @@ -0,0 +1,409 @@ +namespace Emby.Server.Implementations.TextEncoding +{ + // Copyright 2015-2016 Jonathan Bennett <jon@autoitscript.com> + // + // https://www.autoitscript.com + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + /// <summary> + /// Credit: https://github.com/AutoIt/text-encoding-detect + /// </summary> + public class TextEncodingDetect + { + private readonly byte[] _utf16BeBom = + { + 0xFE, + 0xFF + }; + + private readonly byte[] _utf16LeBom = + { + 0xFF, + 0xFE + }; + + private readonly byte[] _utf8Bom = + { + 0xEF, + 0xBB, + 0xBF + }; + + private bool _nullSuggestsBinary = true; + private double _utf16ExpectedNullPercent = 70; + private double _utf16UnexpectedNullPercent = 10; + + public enum CharacterEncoding + { + None, // Unknown or binary + Ansi, // 0-255 + Ascii, // 0-127 + Utf8Bom, // UTF8 with BOM + Utf8Nobom, // UTF8 without BOM + Utf16LeBom, // UTF16 LE with BOM + Utf16LeNoBom, // UTF16 LE without BOM + Utf16BeBom, // UTF16-BE with BOM + Utf16BeNoBom // UTF16-BE without BOM + } + + /// <summary> + /// Sets if the presence of nulls in a buffer indicate the buffer is binary data rather than text. + /// </summary> + public bool NullSuggestsBinary + { + set + { + _nullSuggestsBinary = value; + } + } + + public double Utf16ExpectedNullPercent + { + set + { + if (value > 0 && value < 100) + { + _utf16ExpectedNullPercent = value; + } + } + } + + public double Utf16UnexpectedNullPercent + { + set + { + if (value > 0 && value < 100) + { + _utf16UnexpectedNullPercent = value; + } + } + } + + /// <summary> + /// Gets the BOM length for a given Encoding mode. + /// </summary> + /// <param name="encoding"></param> + /// <returns>The BOM length.</returns> + public static int GetBomLengthFromEncodingMode(CharacterEncoding encoding) + { + int length; + + switch (encoding) + { + case CharacterEncoding.Utf16BeBom: + case CharacterEncoding.Utf16LeBom: + length = 2; + break; + + case CharacterEncoding.Utf8Bom: + length = 3; + break; + + default: + length = 0; + break; + } + + return length; + } + + /// <summary> + /// Checks for a BOM sequence in a byte buffer. + /// </summary> + /// <param name="buffer"></param> + /// <param name="size"></param> + /// <returns>Encoding type or Encoding.None if no BOM.</returns> + public CharacterEncoding CheckBom(byte[] buffer, int size) + { + // Check for BOM + if (size >= 2 && buffer[0] == _utf16LeBom[0] && buffer[1] == _utf16LeBom[1]) + { + return CharacterEncoding.Utf16LeBom; + } + + if (size >= 2 && buffer[0] == _utf16BeBom[0] && buffer[1] == _utf16BeBom[1]) + { + return CharacterEncoding.Utf16BeBom; + } + + if (size >= 3 && buffer[0] == _utf8Bom[0] && buffer[1] == _utf8Bom[1] && buffer[2] == _utf8Bom[2]) + { + return CharacterEncoding.Utf8Bom; + } + + return CharacterEncoding.None; + } + + /// <summary> + /// Automatically detects the Encoding type of a given byte buffer. + /// </summary> + /// <param name="buffer">The byte buffer.</param> + /// <param name="size">The size of the byte buffer.</param> + /// <returns>The Encoding type or Encoding.None if unknown.</returns> + public CharacterEncoding DetectEncoding(byte[] buffer, int size) + { + // First check if we have a BOM and return that if so + CharacterEncoding encoding = CheckBom(buffer, size); + if (encoding != CharacterEncoding.None) + { + return encoding; + } + + // Now check for valid UTF8 + encoding = CheckUtf8(buffer, size); + if (encoding != CharacterEncoding.None) + { + return encoding; + } + + // Now try UTF16 + encoding = CheckUtf16NewlineChars(buffer, size); + if (encoding != CharacterEncoding.None) + { + return encoding; + } + + encoding = CheckUtf16Ascii(buffer, size); + if (encoding != CharacterEncoding.None) + { + return encoding; + } + + // ANSI or None (binary) then + if (!DoesContainNulls(buffer, size)) + { + return CharacterEncoding.Ansi; + } + + // Found a null, return based on the preference in null_suggests_binary_ + return _nullSuggestsBinary ? CharacterEncoding.None : CharacterEncoding.Ansi; + } + + /// <summary> + /// Checks if a buffer contains text that looks like utf16 by scanning for + /// newline chars that would be present even in non-english text. + /// </summary> + /// <param name="buffer">The byte buffer.</param> + /// <param name="size">The size of the byte buffer.</param> + /// <returns>Encoding.none, Encoding.Utf16LeNoBom or Encoding.Utf16BeNoBom.</returns> + private static CharacterEncoding CheckUtf16NewlineChars(byte[] buffer, int size) + { + if (size < 2) + { + return CharacterEncoding.None; + } + + // Reduce size by 1 so we don't need to worry about bounds checking for pairs of bytes + size--; + + var leControlChars = 0; + var beControlChars = 0; + + uint pos = 0; + while (pos < size) + { + byte ch1 = buffer[pos++]; + byte ch2 = buffer[pos++]; + + if (ch1 == 0) + { + if (ch2 == 0x0a || ch2 == 0x0d) + { + ++beControlChars; + } + } + else if (ch2 == 0) + { + if (ch1 == 0x0a || ch1 == 0x0d) + { + ++leControlChars; + } + } + + // If we are getting both LE and BE control chars then this file is not utf16 + if (leControlChars > 0 && beControlChars > 0) + { + return CharacterEncoding.None; + } + } + + if (leControlChars > 0) + { + return CharacterEncoding.Utf16LeNoBom; + } + + return beControlChars > 0 ? CharacterEncoding.Utf16BeNoBom : CharacterEncoding.None; + } + + /// <summary> + /// Checks if a buffer contains any nulls. Used to check for binary vs text data. + /// </summary> + /// <param name="buffer">The byte buffer.</param> + /// <param name="size">The size of the byte buffer.</param> + private static bool DoesContainNulls(byte[] buffer, int size) + { + uint pos = 0; + while (pos < size) + { + if (buffer[pos++] == 0) + { + return true; + } + } + + return false; + } + + /// <summary> + /// Checks if a buffer contains text that looks like utf16. This is done based + /// on the use of nulls which in ASCII/script like text can be useful to identify. + /// </summary> + /// <param name="buffer">The byte buffer.</param> + /// <param name="size">The size of the byte buffer.</param> + /// <returns>Encoding.none, Encoding.Utf16LeNoBom or Encoding.Utf16BeNoBom.</returns> + private CharacterEncoding CheckUtf16Ascii(byte[] buffer, int size) + { + var numOddNulls = 0; + var numEvenNulls = 0; + + // Get even nulls + uint pos = 0; + while (pos < size) + { + if (buffer[pos] == 0) + { + numEvenNulls++; + } + + pos += 2; + } + + // Get odd nulls + pos = 1; + while (pos < size) + { + if (buffer[pos] == 0) + { + numOddNulls++; + } + + pos += 2; + } + + double evenNullThreshold = numEvenNulls * 2.0 / size; + double oddNullThreshold = numOddNulls * 2.0 / size; + double expectedNullThreshold = _utf16ExpectedNullPercent / 100.0; + double unexpectedNullThreshold = _utf16UnexpectedNullPercent / 100.0; + + // Lots of odd nulls, low number of even nulls + if (evenNullThreshold < unexpectedNullThreshold && oddNullThreshold > expectedNullThreshold) + { + return CharacterEncoding.Utf16LeNoBom; + } + + // Lots of even nulls, low number of odd nulls + if (oddNullThreshold < unexpectedNullThreshold && evenNullThreshold > expectedNullThreshold) + { + return CharacterEncoding.Utf16BeNoBom; + } + + // Don't know + return CharacterEncoding.None; + } + + /// <summary> + /// Checks if a buffer contains valid utf8. + /// </summary> + /// <param name="buffer">The byte buffer.</param> + /// <param name="size">The size of the byte buffer.</param> + /// <returns> + /// Encoding type of Encoding.None (invalid UTF8), Encoding.Utf8NoBom (valid utf8 multibyte strings) or + /// Encoding.ASCII (data in 0.127 range). + /// </returns> + /// <returns>2</returns> + private CharacterEncoding CheckUtf8(byte[] buffer, int size) + { + // UTF8 Valid sequences + // 0xxxxxxx ASCII + // 110xxxxx 10xxxxxx 2-byte + // 1110xxxx 10xxxxxx 10xxxxxx 3-byte + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4-byte + // + // Width in UTF8 + // Decimal Width + // 0-127 1 byte + // 194-223 2 bytes + // 224-239 3 bytes + // 240-244 4 bytes + // + // Subsequent chars are in the range 128-191 + var onlySawAsciiRange = true; + uint pos = 0; + + while (pos < size) + { + byte ch = buffer[pos++]; + + if (ch == 0 && _nullSuggestsBinary) + { + return CharacterEncoding.None; + } + + int moreChars; + if (ch <= 127) + { + // 1 byte + moreChars = 0; + } + else if (ch >= 194 && ch <= 223) + { + // 2 Byte + moreChars = 1; + } + else if (ch >= 224 && ch <= 239) + { + // 3 Byte + moreChars = 2; + } + else if (ch >= 240 && ch <= 244) + { + // 4 Byte + moreChars = 3; + } + else + { + return CharacterEncoding.None; // Not utf8 + } + + // Check secondary chars are in range if we are expecting any + while (moreChars > 0 && pos < size) + { + onlySawAsciiRange = false; // Seen non-ascii chars now + + ch = buffer[pos++]; + if (ch < 128 || ch > 191) + { + return CharacterEncoding.None; // Not utf8 + } + + --moreChars; + } + } + + // If we get to here then only valid UTF-8 sequences have been processed + + // If we only saw chars in the range 0-127 then we can't assume UTF8 (the caller will need to decide) + return onlySawAsciiRange ? CharacterEncoding.Ascii : CharacterEncoding.Utf8Nobom; + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/CharsetDetector.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/CharsetDetector.cs new file mode 100644 index 000000000..942fda8d1 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/CharsetDetector.cs @@ -0,0 +1,125 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System.IO; + +namespace UniversalDetector +{ + /// <summary> + /// Default implementation of charset detection interface. + /// The detector can be fed by a System.IO.Stream: + /// <example> + /// <code> + /// using (FileStream fs = File.OpenRead(filename)) { + /// CharsetDetector cdet = new CharsetDetector(); + /// cdet.Feed(fs); + /// cdet.DataEnd(); + /// Console.WriteLine("{0}, {1}", cdet.Charset, cdet.Confidence); + /// </code> + /// </example> + /// + /// or by a byte a array: + /// + /// <example> + /// <code> + /// byte[] buff = new byte[1024]; + /// int read; + /// while ((read = stream.Read(buff, 0, buff.Length)) > 0 && !done) + /// Feed(buff, 0, read); + /// cdet.DataEnd(); + /// Console.WriteLine("{0}, {1}", cdet.Charset, cdet.Confidence); + /// </code> + /// </example> + /// </summary> + public class CharsetDetector : Core.UniversalDetector, ICharsetDetector + { + private string charset; + + private float confidence; + + //public event DetectorFinished Finished; + + public CharsetDetector() : base(FILTER_ALL) + { + + } + + public void Feed(Stream stream) + { + byte[] buff = new byte[1024]; + int read; + while ((read = stream.Read(buff, 0, buff.Length)) > 0 && !done) + { + Feed(buff, 0, read); + } + } + + public bool IsDone() + { + return done; + } + + public override void Reset() + { + this.charset = null; + this.confidence = 0.0f; + base.Reset(); + } + + public string Charset { + get { return charset; } + } + + public float Confidence { + get { return confidence; } + } + + protected override void Report(string charset, float confidence) + { + this.charset = charset; + this.confidence = confidence; +// if (Finished != null) { +// Finished(charset, confidence); +// } + } + } + + //public delegate void DetectorFinished(string charset, float confidence); + +} + diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Big5Prober.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Big5Prober.cs new file mode 100644 index 000000000..760fca9bd --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Big5Prober.cs @@ -0,0 +1,106 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class Big5Prober : CharsetProber + { + //void GetDistribution(PRUint32 aCharLen, const char* aStr); + private CodingStateMachine codingSM; + private BIG5DistributionAnalyser distributionAnalyser; + private byte[] lastChar = new byte[2]; + + public Big5Prober() + { + this.codingSM = new CodingStateMachine(new BIG5SMModel()); + this.distributionAnalyser = new BIG5DistributionAnalyser(); + this.Reset(); + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int codingState = 0; + int max = offset + len; + + for (int i = offset; i < max; i++) { + codingState = codingSM.NextState(buf[i]); + if (codingState == SMModel.ERROR) { + state = ProbingState.NotMe; + break; + } + if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + break; + } + if (codingState == SMModel.START) { + int charLen = codingSM.CurrentCharLen; + if (i == offset) { + lastChar[1] = buf[offset]; + distributionAnalyser.HandleOneChar(lastChar, 0, charLen); + } else { + distributionAnalyser.HandleOneChar(buf, i-1, charLen); + } + } + } + lastChar[0] = buf[max-1]; + + if (state == ProbingState.Detecting) + if (distributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + return state; + } + + public override void Reset() + { + codingSM.Reset(); + state = ProbingState.Detecting; + distributionAnalyser.Reset(); + } + + public override string GetCharsetName() + { + return "Big-5"; + } + + public override float GetConfidence() + { + return distributionAnalyser.GetConfidence(); + } + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/BitPackage.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/BitPackage.cs new file mode 100644 index 000000000..16483e661 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/BitPackage.cs @@ -0,0 +1,98 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kohei TAKETA <k-tak@void.in> (Java port) + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class BitPackage + { + public static int INDEX_SHIFT_4BITS = 3; + public static int INDEX_SHIFT_8BITS = 2; + public static int INDEX_SHIFT_16BITS = 1; + + public static int SHIFT_MASK_4BITS = 7; + public static int SHIFT_MASK_8BITS = 3; + public static int SHIFT_MASK_16BITS = 1; + + public static int BIT_SHIFT_4BITS = 2; + public static int BIT_SHIFT_8BITS = 3; + public static int BIT_SHIFT_16BITS = 4; + + public static int UNIT_MASK_4BITS = 0x0000000F; + public static int UNIT_MASK_8BITS = 0x000000FF; + public static int UNIT_MASK_16BITS = 0x0000FFFF; + + private int indexShift; + private int shiftMask; + private int bitShift; + private int unitMask; + private int[] data; + + public BitPackage(int indexShift, int shiftMask, + int bitShift, int unitMask, int[] data) + { + this.indexShift = indexShift; + this.shiftMask = shiftMask; + this.bitShift = bitShift; + this.unitMask = unitMask; + this.data = data; + } + + public static int Pack16bits(int a, int b) + { + return ((b << 16) | a); + } + + public static int Pack8bits(int a, int b, int c, int d) + { + return Pack16bits((b << 8) | a, (d << 8) | c); + } + + public static int Pack4bits(int a, int b, int c, int d, + int e, int f, int g, int h) + { + return Pack8bits((b << 4) | a, (d << 4) | c, + (f << 4) | e, (h << 4) | g); + } + + public int Unpack(int i) + { + return (data[i >> indexShift] >> + ((i & shiftMask) << bitShift)) & unitMask; + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CharDistributionAnalyser.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CharDistributionAnalyser.cs new file mode 100644 index 000000000..8b5bc37d3 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CharDistributionAnalyser.cs @@ -0,0 +1,3173 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + /// <summary> + /// Base class for the Character Distribution Method, used for + /// the CJK encodings + /// </summary> + public abstract class CharDistributionAnalyser + { + + protected const float SURE_YES = 0.99f; + protected const float SURE_NO = 0.01f; + protected const int MINIMUM_DATA_THRESHOLD = 4; + protected const int ENOUGH_DATA_THRESHOLD = 1024; + + //If this flag is set to PR_TRUE, detection is done and conclusion has been made + protected bool done; + + // The number of characters whose frequency order is less than 512 + protected int freqChars; + + //Total character encounted. + protected int totalChars; + + // Mapping table to get frequency order from char order (get from GetOrder()) + protected int[] charToFreqOrder; + + // Size of above table + protected int tableSize; + + //This is a constant value varies from language to language, it is used + // in calculating confidence. + protected float typicalDistributionRatio; + + public CharDistributionAnalyser() + { + Reset(); + } + + /// <summary> + /// Feed a block of data and do distribution analysis + /// </summary> + /// </param> + //public abstract void HandleData(byte[] buf, int offset, int len); + + /// <summary> + /// we do not handle character base on its original encoding string, but + /// convert this encoding string to a number, here called order. + /// This allow multiple encoding of a language to share one frequency table + /// </summary> + /// <param name="buf">A <see cref="System.Byte"/></param> + /// <param name="offset"></param> + /// <returns></returns> + public abstract int GetOrder(byte[] buf, int offset); + + /// <summary> + /// Feed a character with known length + /// </summary> + /// <param name="buf">A <see cref="System.Byte"/></param> + /// <param name="offset">buf offset</param> + public void HandleOneChar(byte[] buf, int offset, int charLen) + { + //we only care about 2-bytes character in our distribution analysis + int order = (charLen == 2) ? GetOrder(buf, offset) : -1; + if (order >= 0) { + totalChars++; + if (order < tableSize) { // order is valid + if (512 > charToFreqOrder[order]) + freqChars++; + } + } + } + + public virtual void Reset() + { + done = false; + totalChars = 0; + freqChars = 0; + } + + /// <summary> + /// return confidence base on received data + /// </summary> + /// <returns></returns> + public virtual float GetConfidence() + { + //if we didn't receive any character in our consideration range, or the + // number of frequent characters is below the minimum threshold, return + // negative answer + if (totalChars <= 0 || freqChars <= MINIMUM_DATA_THRESHOLD) + return SURE_NO; + if (totalChars != freqChars) { + float r = freqChars / ((totalChars - freqChars) * typicalDistributionRatio); + if (r < SURE_YES) + return r; + } + //normalize confidence, (we don't want to be 100% sure) + return SURE_YES; + } + + //It is not necessary to receive all data to draw conclusion. For charset detection, + // certain amount of data is enough + public bool GotEnoughData() + { + return totalChars > ENOUGH_DATA_THRESHOLD; + } + + } + + public class GB18030DistributionAnalyser : CharDistributionAnalyser + { + // GB2312 most frequently used character table + // Char to FreqOrder table, from hz6763 + /****************************************************************************** + * 512 --> 0.79 -- 0.79 + * 1024 --> 0.92 -- 0.13 + * 2048 --> 0.98 -- 0.06 + * 6768 --> 1.00 -- 0.02 + * + * Idea Distribution Ratio = 0.79135/(1-0.79135) = 3.79 + * Random Distribution Ration = 512 / (3755 - 512) = 0.157 + * + * Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + *****************************************************************************/ + + private static float GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9f; + + private static int GB2312_TABLE_SIZE = 3760; + + private static int[] GB2312_CHAR2FREQ_ORDER = { + 1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, + 2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, + 2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, + 1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, + 1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, + 1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, + 2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, + 3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, + 1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, + 2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, + 2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, + 1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, + 3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, + 1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, + 2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, + 1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, + 3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, + 1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, + 2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, + 1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, + 3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, + 3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, + 3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, + 1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, + 3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, + 2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, + 1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, + 1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, + 4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, + 3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, + 3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, + 1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, + 2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, + 1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, + 1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, + 3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, + 3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, + 4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, + 3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, + 1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, + 1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, + 4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, + 3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, + 1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, + 1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, + 2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, + 3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, + 4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, + 3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, + 2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, + 2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, + 2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, + 2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, + 3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, + 2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, + 2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, + 1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, + 2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, + 1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, + 1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, + 1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, + 2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, + 3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, + 2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, + 2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, + 2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, + 3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, + 1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, + 1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, + 2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, + 1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, + 3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, + 1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, + 1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, + 3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, + 2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, + 1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, + 4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, + 1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, + 1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, + 3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, + 1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, + 1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, + 1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, + 1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, + 3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, + 4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, + 3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, + 2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, + 2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, + 1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, + 3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, + 2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, + 1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, + 1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, + 2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, + 2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, + 3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, + 4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, + 3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, + 3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, + 2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, + 1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, + 3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, + 4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, + 2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, + 1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, + 1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, + 1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, + 3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, + 1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, + 1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, + 2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, + 2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, + 2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, + 1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, + 1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, + 2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, + 1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, + 1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, + 2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, + 2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, + 3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, + 1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, + 4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, + 3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, + 1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, + 3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, + 1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, + 4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, + 1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, + 2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, + 1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, + 1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, + 3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, + 2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, + 1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, + 1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, + 1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, + 3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, + 2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, + 3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, + 3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, + 3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, + 2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, + 2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, + 1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, + 1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, + 3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, + 3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, + 1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, + 1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, + 3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, + 2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, + 2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, + 1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, + 3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, + 4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, + 1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, + 2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, + 3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, + 3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, + 1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, + 2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, + 1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, + 1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, + 1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, + 1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, + 1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, + 1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, //last 512 + + /*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + + 5508,6484,3900,3414,3974,4441,4024,3537,4037,5628,5099,3633,6485,3148,6486,3636, + 5509,3257,5510,5973,5445,5872,4941,4403,3174,4627,5873,6276,2286,4230,5446,5874, + 5122,6102,6103,4162,5447,5123,5323,4849,6277,3980,3851,5066,4246,5774,5067,6278, + 3001,2807,5695,3346,5775,5974,5158,5448,6487,5975,5976,5776,3598,6279,5696,4806, + 4211,4154,6280,6488,6489,6490,6281,4212,5037,3374,4171,6491,4562,4807,4722,4827, + 5977,6104,4532,4079,5159,5324,5160,4404,3858,5359,5875,3975,4288,4610,3486,4512, + 5325,3893,5360,6282,6283,5560,2522,4231,5978,5186,5449,2569,3878,6284,5401,3578, + 4415,6285,4656,5124,5979,2506,4247,4449,3219,3417,4334,4969,4329,6492,4576,4828, + 4172,4416,4829,5402,6286,3927,3852,5361,4369,4830,4477,4867,5876,4173,6493,6105, + 4657,6287,6106,5877,5450,6494,4155,4868,5451,3700,5629,4384,6288,6289,5878,3189, + 4881,6107,6290,6495,4513,6496,4692,4515,4723,5100,3356,6497,6291,3810,4080,5561, + 3570,4430,5980,6498,4355,5697,6499,4724,6108,6109,3764,4050,5038,5879,4093,3226, + 6292,5068,5217,4693,3342,5630,3504,4831,4377,4466,4309,5698,4431,5777,6293,5778, + 4272,3706,6110,5326,3752,4676,5327,4273,5403,4767,5631,6500,5699,5880,3475,5039, + 6294,5562,5125,4348,4301,4482,4068,5126,4593,5700,3380,3462,5981,5563,3824,5404, + 4970,5511,3825,4738,6295,6501,5452,4516,6111,5881,5564,6502,6296,5982,6503,4213, + 4163,3454,6504,6112,4009,4450,6113,4658,6297,6114,3035,6505,6115,3995,4904,4739, + 4563,4942,4110,5040,3661,3928,5362,3674,6506,5292,3612,4791,5565,4149,5983,5328, + 5259,5021,4725,4577,4564,4517,4364,6298,5405,4578,5260,4594,4156,4157,5453,3592, + 3491,6507,5127,5512,4709,4922,5984,5701,4726,4289,6508,4015,6116,5128,4628,3424, + 4241,5779,6299,4905,6509,6510,5454,5702,5780,6300,4365,4923,3971,6511,5161,3270, + 3158,5985,4100, 867,5129,5703,6117,5363,3695,3301,5513,4467,6118,6512,5455,4232, + 4242,4629,6513,3959,4478,6514,5514,5329,5986,4850,5162,5566,3846,4694,6119,5456, + 4869,5781,3779,6301,5704,5987,5515,4710,6302,5882,6120,4392,5364,5705,6515,6121, + 6516,6517,3736,5988,5457,5989,4695,2457,5883,4551,5782,6303,6304,6305,5130,4971, + 6122,5163,6123,4870,3263,5365,3150,4871,6518,6306,5783,5069,5706,3513,3498,4409, + 5330,5632,5366,5458,5459,3991,5990,4502,3324,5991,5784,3696,4518,5633,4119,6519, + 4630,5634,4417,5707,4832,5992,3418,6124,5993,5567,4768,5218,6520,4595,3458,5367, + 6125,5635,6126,4202,6521,4740,4924,6307,3981,4069,4385,6308,3883,2675,4051,3834, + 4302,4483,5568,5994,4972,4101,5368,6309,5164,5884,3922,6127,6522,6523,5261,5460, + 5187,4164,5219,3538,5516,4111,3524,5995,6310,6311,5369,3181,3386,2484,5188,3464, + 5569,3627,5708,6524,5406,5165,4677,4492,6312,4872,4851,5885,4468,5996,6313,5709, + 5710,6128,2470,5886,6314,5293,4882,5785,3325,5461,5101,6129,5711,5786,6525,4906, + 6526,6527,4418,5887,5712,4808,2907,3701,5713,5888,6528,3765,5636,5331,6529,6530, + 3593,5889,3637,4943,3692,5714,5787,4925,6315,6130,5462,4405,6131,6132,6316,5262, + 6531,6532,5715,3859,5716,5070,4696,5102,3929,5788,3987,4792,5997,6533,6534,3920, + 4809,5000,5998,6535,2974,5370,6317,5189,5263,5717,3826,6536,3953,5001,4883,3190, + 5463,5890,4973,5999,4741,6133,6134,3607,5570,6000,4711,3362,3630,4552,5041,6318, + 6001,2950,2953,5637,4646,5371,4944,6002,2044,4120,3429,6319,6537,5103,4833,6538, + 6539,4884,4647,3884,6003,6004,4758,3835,5220,5789,4565,5407,6540,6135,5294,4697, + 4852,6320,6321,3206,4907,6541,6322,4945,6542,6136,6543,6323,6005,4631,3519,6544, + 5891,6545,5464,3784,5221,6546,5571,4659,6547,6324,6137,5190,6548,3853,6549,4016, + 4834,3954,6138,5332,3827,4017,3210,3546,4469,5408,5718,3505,4648,5790,5131,5638, + 5791,5465,4727,4318,6325,6326,5792,4553,4010,4698,3439,4974,3638,4335,3085,6006, + 5104,5042,5166,5892,5572,6327,4356,4519,5222,5573,5333,5793,5043,6550,5639,5071, + 4503,6328,6139,6551,6140,3914,3901,5372,6007,5640,4728,4793,3976,3836,4885,6552, + 4127,6553,4451,4102,5002,6554,3686,5105,6555,5191,5072,5295,4611,5794,5296,6556, + 5893,5264,5894,4975,5466,5265,4699,4976,4370,4056,3492,5044,4886,6557,5795,4432, + 4769,4357,5467,3940,4660,4290,6141,4484,4770,4661,3992,6329,4025,4662,5022,4632, + 4835,4070,5297,4663,4596,5574,5132,5409,5895,6142,4504,5192,4664,5796,5896,3885, + 5575,5797,5023,4810,5798,3732,5223,4712,5298,4084,5334,5468,6143,4052,4053,4336, + 4977,4794,6558,5335,4908,5576,5224,4233,5024,4128,5469,5225,4873,6008,5045,4729, + 4742,4633,3675,4597,6559,5897,5133,5577,5003,5641,5719,6330,6560,3017,2382,3854, + 4406,4811,6331,4393,3964,4946,6561,2420,3722,6562,4926,4378,3247,1736,4442,6332, + 5134,6333,5226,3996,2918,5470,4319,4003,4598,4743,4744,4485,3785,3902,5167,5004, + 5373,4394,5898,6144,4874,1793,3997,6334,4085,4214,5106,5642,4909,5799,6009,4419, + 4189,3330,5899,4165,4420,5299,5720,5227,3347,6145,4081,6335,2876,3930,6146,3293, + 3786,3910,3998,5900,5300,5578,2840,6563,5901,5579,6147,3531,5374,6564,6565,5580, + 4759,5375,6566,6148,3559,5643,6336,6010,5517,6337,6338,5721,5902,3873,6011,6339, + 6567,5518,3868,3649,5722,6568,4771,4947,6569,6149,4812,6570,2853,5471,6340,6341, + 5644,4795,6342,6012,5723,6343,5724,6013,4349,6344,3160,6150,5193,4599,4514,4493, + 5168,4320,6345,4927,3666,4745,5169,5903,5005,4928,6346,5725,6014,4730,4203,5046, + 4948,3395,5170,6015,4150,6016,5726,5519,6347,5047,3550,6151,6348,4197,4310,5904, + 6571,5581,2965,6152,4978,3960,4291,5135,6572,5301,5727,4129,4026,5905,4853,5728, + 5472,6153,6349,4533,2700,4505,5336,4678,3583,5073,2994,4486,3043,4554,5520,6350, + 6017,5800,4487,6351,3931,4103,5376,6352,4011,4321,4311,4190,5136,6018,3988,3233, + 4350,5906,5645,4198,6573,5107,3432,4191,3435,5582,6574,4139,5410,6353,5411,3944, + 5583,5074,3198,6575,6354,4358,6576,5302,4600,5584,5194,5412,6577,6578,5585,5413, + 5303,4248,5414,3879,4433,6579,4479,5025,4854,5415,6355,4760,4772,3683,2978,4700, + 3797,4452,3965,3932,3721,4910,5801,6580,5195,3551,5907,3221,3471,3029,6019,3999, + 5908,5909,5266,5267,3444,3023,3828,3170,4796,5646,4979,4259,6356,5647,5337,3694, + 6357,5648,5338,4520,4322,5802,3031,3759,4071,6020,5586,4836,4386,5048,6581,3571, + 4679,4174,4949,6154,4813,3787,3402,3822,3958,3215,3552,5268,4387,3933,4950,4359, + 6021,5910,5075,3579,6358,4234,4566,5521,6359,3613,5049,6022,5911,3375,3702,3178, + 4911,5339,4521,6582,6583,4395,3087,3811,5377,6023,6360,6155,4027,5171,5649,4421, + 4249,2804,6584,2270,6585,4000,4235,3045,6156,5137,5729,4140,4312,3886,6361,4330, + 6157,4215,6158,3500,3676,4929,4331,3713,4930,5912,4265,3776,3368,5587,4470,4855, + 3038,4980,3631,6159,6160,4132,4680,6161,6362,3923,4379,5588,4255,6586,4121,6587, + 6363,4649,6364,3288,4773,4774,6162,6024,6365,3543,6588,4274,3107,3737,5050,5803, + 4797,4522,5589,5051,5730,3714,4887,5378,4001,4523,6163,5026,5522,4701,4175,2791, + 3760,6589,5473,4224,4133,3847,4814,4815,4775,3259,5416,6590,2738,6164,6025,5304, + 3733,5076,5650,4816,5590,6591,6165,6592,3934,5269,6593,3396,5340,6594,5804,3445, + 3602,4042,4488,5731,5732,3525,5591,4601,5196,6166,6026,5172,3642,4612,3202,4506, + 4798,6366,3818,5108,4303,5138,5139,4776,3332,4304,2915,3415,4434,5077,5109,4856, + 2879,5305,4817,6595,5913,3104,3144,3903,4634,5341,3133,5110,5651,5805,6167,4057, + 5592,2945,4371,5593,6596,3474,4182,6367,6597,6168,4507,4279,6598,2822,6599,4777, + 4713,5594,3829,6169,3887,5417,6170,3653,5474,6368,4216,2971,5228,3790,4579,6369, + 5733,6600,6601,4951,4746,4555,6602,5418,5475,6027,3400,4665,5806,6171,4799,6028, + 5052,6172,3343,4800,4747,5006,6370,4556,4217,5476,4396,5229,5379,5477,3839,5914, + 5652,5807,4714,3068,4635,5808,6173,5342,4192,5078,5419,5523,5734,6174,4557,6175, + 4602,6371,6176,6603,5809,6372,5735,4260,3869,5111,5230,6029,5112,6177,3126,4681, + 5524,5915,2706,3563,4748,3130,6178,4018,5525,6604,6605,5478,4012,4837,6606,4534, + 4193,5810,4857,3615,5479,6030,4082,3697,3539,4086,5270,3662,4508,4931,5916,4912, + 5811,5027,3888,6607,4397,3527,3302,3798,2775,2921,2637,3966,4122,4388,4028,4054, + 1633,4858,5079,3024,5007,3982,3412,5736,6608,3426,3236,5595,3030,6179,3427,3336, + 3279,3110,6373,3874,3039,5080,5917,5140,4489,3119,6374,5812,3405,4494,6031,4666, + 4141,6180,4166,6032,5813,4981,6609,5081,4422,4982,4112,3915,5653,3296,3983,6375, + 4266,4410,5654,6610,6181,3436,5082,6611,5380,6033,3819,5596,4535,5231,5306,5113, + 6612,4952,5918,4275,3113,6613,6376,6182,6183,5814,3073,4731,4838,5008,3831,6614, + 4888,3090,3848,4280,5526,5232,3014,5655,5009,5737,5420,5527,6615,5815,5343,5173, + 5381,4818,6616,3151,4953,6617,5738,2796,3204,4360,2989,4281,5739,5174,5421,5197, + 3132,5141,3849,5142,5528,5083,3799,3904,4839,5480,2880,4495,3448,6377,6184,5271, + 5919,3771,3193,6034,6035,5920,5010,6036,5597,6037,6378,6038,3106,5422,6618,5423, + 5424,4142,6619,4889,5084,4890,4313,5740,6620,3437,5175,5307,5816,4199,5198,5529, + 5817,5199,5656,4913,5028,5344,3850,6185,2955,5272,5011,5818,4567,4580,5029,5921, + 3616,5233,6621,6622,6186,4176,6039,6379,6380,3352,5200,5273,2908,5598,5234,3837, + 5308,6623,6624,5819,4496,4323,5309,5201,6625,6626,4983,3194,3838,4167,5530,5922, + 5274,6381,6382,3860,3861,5599,3333,4292,4509,6383,3553,5481,5820,5531,4778,6187, + 3955,3956,4324,4389,4218,3945,4325,3397,2681,5923,4779,5085,4019,5482,4891,5382, + 5383,6040,4682,3425,5275,4094,6627,5310,3015,5483,5657,4398,5924,3168,4819,6628, + 5925,6629,5532,4932,4613,6041,6630,4636,6384,4780,4204,5658,4423,5821,3989,4683, + 5822,6385,4954,6631,5345,6188,5425,5012,5384,3894,6386,4490,4104,6632,5741,5053, + 6633,5823,5926,5659,5660,5927,6634,5235,5742,5824,4840,4933,4820,6387,4859,5928, + 4955,6388,4143,3584,5825,5346,5013,6635,5661,6389,5014,5484,5743,4337,5176,5662, + 6390,2836,6391,3268,6392,6636,6042,5236,6637,4158,6638,5744,5663,4471,5347,3663, + 4123,5143,4293,3895,6639,6640,5311,5929,5826,3800,6189,6393,6190,5664,5348,3554, + 3594,4749,4603,6641,5385,4801,6043,5827,4183,6642,5312,5426,4761,6394,5665,6191, + 4715,2669,6643,6644,5533,3185,5427,5086,5930,5931,5386,6192,6044,6645,4781,4013, + 5745,4282,4435,5534,4390,4267,6045,5746,4984,6046,2743,6193,3501,4087,5485,5932, + 5428,4184,4095,5747,4061,5054,3058,3862,5933,5600,6646,5144,3618,6395,3131,5055, + 5313,6396,4650,4956,3855,6194,3896,5202,4985,4029,4225,6195,6647,5828,5486,5829, + 3589,3002,6648,6397,4782,5276,6649,6196,6650,4105,3803,4043,5237,5830,6398,4096, + 3643,6399,3528,6651,4453,3315,4637,6652,3984,6197,5535,3182,3339,6653,3096,2660, + 6400,6654,3449,5934,4250,4236,6047,6401,5831,6655,5487,3753,4062,5832,6198,6199, + 6656,3766,6657,3403,4667,6048,6658,4338,2897,5833,3880,2797,3780,4326,6659,5748, + 5015,6660,5387,4351,5601,4411,6661,3654,4424,5935,4339,4072,5277,4568,5536,6402, + 6662,5238,6663,5349,5203,6200,5204,6201,5145,4536,5016,5056,4762,5834,4399,4957, + 6202,6403,5666,5749,6664,4340,6665,5936,5177,5667,6666,6667,3459,4668,6404,6668, + 6669,4543,6203,6670,4276,6405,4480,5537,6671,4614,5205,5668,6672,3348,2193,4763, + 6406,6204,5937,5602,4177,5669,3419,6673,4020,6205,4443,4569,5388,3715,3639,6407, + 6049,4058,6206,6674,5938,4544,6050,4185,4294,4841,4651,4615,5488,6207,6408,6051, + 5178,3241,3509,5835,6208,4958,5836,4341,5489,5278,6209,2823,5538,5350,5206,5429, + 6675,4638,4875,4073,3516,4684,4914,4860,5939,5603,5389,6052,5057,3237,5490,3791, + 6676,6409,6677,4821,4915,4106,5351,5058,4243,5539,4244,5604,4842,4916,5239,3028, + 3716,5837,5114,5605,5390,5940,5430,6210,4332,6678,5540,4732,3667,3840,6053,4305, + 3408,5670,5541,6410,2744,5240,5750,6679,3234,5606,6680,5607,5671,3608,4283,4159, + 4400,5352,4783,6681,6411,6682,4491,4802,6211,6412,5941,6413,6414,5542,5751,6683, + 4669,3734,5942,6684,6415,5943,5059,3328,4670,4144,4268,6685,6686,6687,6688,4372, + 3603,6689,5944,5491,4373,3440,6416,5543,4784,4822,5608,3792,4616,5838,5672,3514, + 5391,6417,4892,6690,4639,6691,6054,5673,5839,6055,6692,6056,5392,6212,4038,5544, + 5674,4497,6057,6693,5840,4284,5675,4021,4545,5609,6418,4454,6419,6213,4113,4472, + 5314,3738,5087,5279,4074,5610,4959,4063,3179,4750,6058,6420,6214,3476,4498,4716, + 5431,4960,4685,6215,5241,6694,6421,6216,6695,5841,5945,6422,3748,5946,5179,3905, + 5752,5545,5947,4374,6217,4455,6423,4412,6218,4803,5353,6696,3832,5280,6219,4327, + 4702,6220,6221,6059,4652,5432,6424,3749,4751,6425,5753,4986,5393,4917,5948,5030, + 5754,4861,4733,6426,4703,6697,6222,4671,5949,4546,4961,5180,6223,5031,3316,5281, + 6698,4862,4295,4934,5207,3644,6427,5842,5950,6428,6429,4570,5843,5282,6430,6224, + 5088,3239,6060,6699,5844,5755,6061,6431,2701,5546,6432,5115,5676,4039,3993,3327, + 4752,4425,5315,6433,3941,6434,5677,4617,4604,3074,4581,6225,5433,6435,6226,6062, + 4823,5756,5116,6227,3717,5678,4717,5845,6436,5679,5846,6063,5847,6064,3977,3354, + 6437,3863,5117,6228,5547,5394,4499,4524,6229,4605,6230,4306,4500,6700,5951,6065, + 3693,5952,5089,4366,4918,6701,6231,5548,6232,6702,6438,4704,5434,6703,6704,5953, + 4168,6705,5680,3420,6706,5242,4407,6066,3812,5757,5090,5954,4672,4525,3481,5681, + 4618,5395,5354,5316,5955,6439,4962,6707,4526,6440,3465,4673,6067,6441,5682,6708, + 5435,5492,5758,5683,4619,4571,4674,4804,4893,4686,5493,4753,6233,6068,4269,6442, + 6234,5032,4705,5146,5243,5208,5848,6235,6443,4963,5033,4640,4226,6236,5849,3387, + 6444,6445,4436,4437,5850,4843,5494,4785,4894,6709,4361,6710,5091,5956,3331,6237, + 4987,5549,6069,6711,4342,3517,4473,5317,6070,6712,6071,4706,6446,5017,5355,6713, + 6714,4988,5436,6447,4734,5759,6715,4735,4547,4456,4754,6448,5851,6449,6450,3547, + 5852,5318,6451,6452,5092,4205,6716,6238,4620,4219,5611,6239,6072,4481,5760,5957, + 5958,4059,6240,6453,4227,4537,6241,5761,4030,4186,5244,5209,3761,4457,4876,3337, + 5495,5181,6242,5959,5319,5612,5684,5853,3493,5854,6073,4169,5613,5147,4895,6074, + 5210,6717,5182,6718,3830,6243,2798,3841,6075,6244,5855,5614,3604,4606,5496,5685, + 5118,5356,6719,6454,5960,5357,5961,6720,4145,3935,4621,5119,5962,4261,6721,6455, + 4786,5963,4375,4582,6245,6246,6247,6076,5437,4877,5856,3376,4380,6248,4160,6722, + 5148,6456,5211,6457,6723,4718,6458,6724,6249,5358,4044,3297,6459,6250,5857,5615, + 5497,5245,6460,5498,6725,6251,6252,5550,3793,5499,2959,5396,6461,6462,4572,5093, + 5500,5964,3806,4146,6463,4426,5762,5858,6077,6253,4755,3967,4220,5965,6254,4989, + 5501,6464,4352,6726,6078,4764,2290,5246,3906,5438,5283,3767,4964,2861,5763,5094, + 6255,6256,4622,5616,5859,5860,4707,6727,4285,4708,4824,5617,6257,5551,4787,5212, + 4965,4935,4687,6465,6728,6466,5686,6079,3494,4413,2995,5247,5966,5618,6729,5967, + 5764,5765,5687,5502,6730,6731,6080,5397,6467,4990,6258,6732,4538,5060,5619,6733, + 4719,5688,5439,5018,5149,5284,5503,6734,6081,4607,6259,5120,3645,5861,4583,6260, + 4584,4675,5620,4098,5440,6261,4863,2379,3306,4585,5552,5689,4586,5285,6735,4864, + 6736,5286,6082,6737,4623,3010,4788,4381,4558,5621,4587,4896,3698,3161,5248,4353, + 4045,6262,3754,5183,4588,6738,6263,6739,6740,5622,3936,6741,6468,6742,6264,5095, + 6469,4991,5968,6743,4992,6744,6083,4897,6745,4256,5766,4307,3108,3968,4444,5287, + 3889,4343,6084,4510,6085,4559,6086,4898,5969,6746,5623,5061,4919,5249,5250,5504, + 5441,6265,5320,4878,3242,5862,5251,3428,6087,6747,4237,5624,5442,6266,5553,4539, + 6748,2585,3533,5398,4262,6088,5150,4736,4438,6089,6267,5505,4966,6749,6268,6750, + 6269,5288,5554,3650,6090,6091,4624,6092,5690,6751,5863,4270,5691,4277,5555,5864, + 6752,5692,4720,4865,6470,5151,4688,4825,6753,3094,6754,6471,3235,4653,6755,5213, + 5399,6756,3201,4589,5865,4967,6472,5866,6473,5019,3016,6757,5321,4756,3957,4573, + 6093,4993,5767,4721,6474,6758,5625,6759,4458,6475,6270,6760,5556,4994,5214,5252, + 6271,3875,5768,6094,5034,5506,4376,5769,6761,2120,6476,5253,5770,6762,5771,5970, + 3990,5971,5557,5558,5772,6477,6095,2787,4641,5972,5121,6096,6097,6272,6763,3703, + 5867,5507,6273,4206,6274,4789,6098,6764,3619,3646,3833,3804,2394,3788,4936,3978, + 4866,4899,6099,6100,5559,6478,6765,3599,5868,6101,5869,5870,6275,6766,4527,6767, + *******************************************************************************/ + }; + + public GB18030DistributionAnalyser() : base() + { + charToFreqOrder = GB2312_CHAR2FREQ_ORDER; + tableSize = GB2312_TABLE_SIZE; + typicalDistributionRatio = GB2312_TYPICAL_DISTRIBUTION_RATIO; + } + + /// <summary> + /// for GB2312 encoding, we are interested + /// first byte range: 0xb0 -- 0xfe + /// second byte range: 0xa1 -- 0xfe + /// no validation needed here. State machine has done that + /// </summary> + /// <returns></returns> + public override int GetOrder(byte[] buf, int offset) + { + if (buf[offset] >= 0xB0 && buf[offset+1] >= 0xA1) + return 94 * (buf[offset] - 0xb0) + buf[offset+1] - 0xA1; + else + return -1; + } + } + + public class EUCTWDistributionAnalyser : CharDistributionAnalyser + { + // EUCTW frequency table + // Converted from big5 work + // by Taiwan's Mandarin Promotion Council + // <http://www.edu.tw:81/mandr/> + /****************************************************************************** + * 128 --> 0.42261 + * 256 --> 0.57851 + * 512 --> 0.74851 + * 1024 --> 0.89384 + * 2048 --> 0.97583 + * + * Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 + * Random Distribution Ration = 512/(5401-512)=0.105 + * + * Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + *****************************************************************************/ + + private static float EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75f; + + private static int EUCTW_TABLE_SIZE = 8102; + + private static int[] EUCTW_CHAR2FREQ_ORDER = { + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, // 2742 + 3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, // 2758 + 1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, // 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, // 2790 + 3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, // 2806 + 4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, // 2822 + 7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, // 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, // 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, // 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, // 2886 + 2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, // 2902 + 1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, // 2918 + 3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, // 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, // 2950 + 1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, // 2966 + 3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, // 2982 + 2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, // 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, // 3014 + 3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, // 3030 + 1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, // 3046 + 7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, // 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, // 3078 + 7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, // 3094 + 1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, // 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, // 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, // 3142 + 3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, // 3158 + 3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, // 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, // 3190 + 2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, // 3206 + 2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, // 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, // 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, // 3254 + 3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, // 3270 + 1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, // 3286 + 1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, // 3302 + 1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, // 3318 + 2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, // 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, // 3350 + 4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, // 3366 + 1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, // 3382 + 7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, // 3398 + 2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, // 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, // 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, // 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, // 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, // 3478 + 7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, // 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, // 3510 + 1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, // 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, // 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, // 3558 + 7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, // 3574 + 1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, // 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, // 3606 + 3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, // 3622 + 4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, // 3638 + 3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, // 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, // 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, // 3686 + 1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, // 3702 + 4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, // 3718 + 3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, // 3734 + 3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, // 3750 + 2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, // 3766 + 7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, // 3782 + 3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, // 3798 + 7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, // 3814 + 1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, // 3830 + 2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, // 3846 + 1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, // 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, // 3878 + 1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, // 3894 + 4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, // 3910 + 3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, // 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, // 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, // 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, // 3974 + 2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, // 3990 + 7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, // 4006 + 1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, // 4022 + 2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, // 4038 + 1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, // 4054 + 1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, // 4070 + 7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, // 4086 + 7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, // 4102 + 7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, // 4118 + 3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, // 4134 + 4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, // 4150 + 1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, // 4166 + 7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, // 4182 + 2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, // 4198 + 7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, // 4214 + 3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, // 4230 + 3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, // 4246 + 7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, // 4262 + 2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, // 4278 + 7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, // 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, // 4310 + 4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, // 4326 + 2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, // 4342 + 7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, // 4358 + 3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, // 4374 + 2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, // 4390 + 2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, // 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, // 4422 + 2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, // 4438 + 1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, // 4454 + 1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, // 4470 + 2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, // 4486 + 1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, // 4502 + 7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, // 4518 + 7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, // 4534 + 2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, // 4550 + 4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, // 4566 + 1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, // 4582 + 7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, // 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, // 4614 + 4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, // 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, // 4646 + 2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, // 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, // 4678 + 1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, // 4694 + 1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, // 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, // 4726 + 3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, // 4742 + 3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, // 4758 + 1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, // 4774 + 3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, // 4790 + 7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, // 4806 + 7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, // 4822 + 1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, // 4838 + 2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, // 4854 + 1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, // 4870 + 3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, // 4886 + 2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, // 4902 + 3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, // 4918 + 2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, // 4934 + 4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, // 4950 + 4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, // 4966 + 3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, // 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, // 4998 + 3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, // 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, // 5030 + 3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, // 5046 + 3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, // 5062 + 3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, // 5078 + 1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, // 5094 + 7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, // 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, // 5126 + 7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, // 5142 + 1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, // 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, // 5174 + 4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, // 5190 + 3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, // 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, // 5222 + 2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, // 5238 + 2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, // 5254 + 3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, // 5270 + 1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, // 5286 + 4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, // 5302 + 2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, // 5318 + 1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, // 5334 + 1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, // 5350 + 2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, // 5366 + 3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, // 5382 + 1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, // 5398 + 7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, // 5414 + 1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, // 5430 + 4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, // 5446 + 1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, // 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, // 5478 + 1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, // 5494 + 3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, // 5510 + 3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, // 5526 + 2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, // 5542 + 1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, // 5558 + 4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, // 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, // 5590 + 7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, // 5606 + 2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, // 5622 + 3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, // 5638 + 4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, // 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, // 5670 + 7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, // 5686 + 7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, // 5702 + 1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, // 5718 + 4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, // 5734 + 3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, // 5750 + 2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, // 5766 + 3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, // 5782 + 3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, // 5798 + 2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, // 5814 + 1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, // 5830 + 4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, // 5846 + 3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, // 5862 + 3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, // 5878 + 2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, // 5894 + 4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, // 5910 + 7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, // 5926 + 3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, // 5942 + 2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, // 5958 + 3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, // 5974 + 1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, // 5990 + 2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, // 6006 + 3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, // 6022 + 4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, // 6038 + 2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, // 6054 + 2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, // 6070 + 7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, // 6086 + 1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, // 6102 + 2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, // 6118 + 1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, // 6134 + 3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, // 6150 + 4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, // 6166 + 2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, // 6182 + 3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, // 6198 + 3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, // 6214 + 2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, // 6230 + 4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, // 6246 + 2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, // 6262 + 3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, // 6278 + 4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, // 6294 + 7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, // 6310 + 3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, // 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, // 6342 + 1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, // 6358 + 4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, // 6374 + 1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, // 6390 + 4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, // 6406 + 7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, // 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, // 6438 + 7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, // 6454 + 2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, // 6470 + 1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, // 6486 + 1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, // 6502 + 3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, // 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, // 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, // 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, // 6566 + 3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, // 6582 + 2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, // 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, // 6614 + 7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, // 6630 + 1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, // 6646 + 3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, // 6662 + 7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, // 6678 + 1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, // 6694 + 7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, // 6710 + 4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, // 6726 + 1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, // 6742 + 2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, // 6758 + 2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, // 6774 + 4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, // 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, // 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, // 6822 + 3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, // 6838 + 3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, // 6854 + 1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, // 6870 + 2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, // 6886 + 7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, // 6902 + 1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, // 6918 + 1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, // 6934 + 3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, // 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, // 6966 + 1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, // 6982 + 4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, // 6998 + 7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, // 7014 + 2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, // 7030 + 3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, // 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, // 7062 + 1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, // 7078 + 2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, // 7094 + 2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, // 7110 + 7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, // 7126 + 7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, // 7142 + 7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, // 7158 + 2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, // 7174 + 2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, // 7190 + 1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, // 7206 + 4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, // 7222 + 3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, // 7238 + 3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, // 7254 + 4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, // 7270 + 4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, // 7286 + 2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, // 7302 + 2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, // 7318 + 7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, // 7334 + 4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, // 7350 + 7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, // 7366 + 2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, // 7382 + 1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, // 7398 + 3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, // 7414 + 4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, // 7430 + 2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, // 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, // 7462 + 2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, // 7478 + 1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, // 7494 + 2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, // 7510 + 2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, // 7526 + 4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, // 7542 + 7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, // 7558 + 1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, // 7574 + 3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, // 7590 + 7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, // 7606 + 1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, // 7622 + 8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, // 7638 + 2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, // 7654 + 8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, // 7670 + 2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, // 7686 + 2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, // 7702 + 8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, // 7718 + 8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, // 7734 + 8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, // 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, // 7766 + 8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, // 7782 + 4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, // 7798 + 3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, // 7814 + 8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, // 7830 + 1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, // 7846 + 8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, // 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, // 7878 + 1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, // 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, // 7910 + 4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, // 7926 + 1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, // 7942 + 4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, // 7958 + 1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, // 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, // 7990 + 3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, // 8006 + 4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, // 8022 + 8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, // 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, // 8054 + 3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, // 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, // 8086 + 2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, // 8102 + + /*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + + 2515,1613,4582,8119,3312,3866,2516,8120,4058,8121,1637,4059,2466,4583,3867,8122, // 8118 + 2493,3016,3734,8123,8124,2192,8125,8126,2162,8127,8128,8129,8130,8131,8132,8133, // 8134 + 8134,8135,8136,8137,8138,8139,8140,8141,8142,8143,8144,8145,8146,8147,8148,8149, // 8150 + 8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8160,8161,8162,8163,8164,8165, // 8166 + 8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181, // 8182 + 8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197, // 8198 + 8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213, // 8214 + 8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229, // 8230 + 8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245, // 8246 + 8246,8247,8248,8249,8250,8251,8252,8253,8254,8255,8256,8257,8258,8259,8260,8261, // 8262 + 8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276,8277, // 8278 + 8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,8290,8291,8292,8293, // 8294 + 8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,8308,8309, // 8310 + 8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325, // 8326 + 8326,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341, // 8342 + 8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357, // 8358 + 8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373, // 8374 + 8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389, // 8390 + 8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,8405, // 8406 + 8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421, // 8422 + 8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,8435,8436,8437, // 8438 + 8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,8450,8451,8452,8453, // 8454 + 8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,8465,8466,8467,8468,8469, // 8470 + 8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,8480,8481,8482,8483,8484,8485, // 8486 + 8486,8487,8488,8489,8490,8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501, // 8502 + 8502,8503,8504,8505,8506,8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517, // 8518 + 8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533, // 8534 + 8534,8535,8536,8537,8538,8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549, // 8550 + 8550,8551,8552,8553,8554,8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,8565, // 8566 + 8566,8567,8568,8569,8570,8571,8572,8573,8574,8575,8576,8577,8578,8579,8580,8581, // 8582 + 8582,8583,8584,8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597, // 8598 + 8598,8599,8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613, // 8614 + 8614,8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629, // 8630 + 8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,8645, // 8646 + 8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,8660,8661, // 8662 + 8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,8675,8676,8677, // 8678 + 8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,8693, // 8694 + 8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705,8706,8707,8708,8709, // 8710 + 8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,8720,8721,8722,8723,8724,8725, // 8726 + 8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741, // 8742 //13973 + ****************************************************************************************/ + }; + + public EUCTWDistributionAnalyser() + { + charToFreqOrder = EUCTW_CHAR2FREQ_ORDER; + tableSize = EUCTW_TABLE_SIZE; + typicalDistributionRatio = EUCTW_TYPICAL_DISTRIBUTION_RATIO; + } + + /// <summary> + /// first byte range: 0xc4 -- 0xfe + /// second byte range: 0xa1 -- 0xfe + /// no validation needed here. State machine has done that + /// </summary> + public override int GetOrder(byte[] buf, int offset) + { + if (buf[offset] >= 0xC4) + return 94 * (buf[offset] - 0xC4) + buf[offset+1] - 0xA1; + else + return -1; + } + } + + public class EUCKRDistributionAnalyser : CharDistributionAnalyser + { + // Sampling from about 20M text materials include literature and computer technology + /* + * 128 --> 0.79 + * 256 --> 0.92 + * 512 --> 0.986 + * 1024 --> 0.99944 + * 2048 --> 0.99999 + * + * Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 + * Random Distribution Ration = 512 / (2350-512) = 0.279. + */ + + public const float EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0f; + + public const int EUCKR_TABLE_SIZE = 2352; + + // Char to FreqOrder table + public static int[] EUCKR_CHAR2FREQ_ORDER = { + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, + 1397, 1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, + 1399, 1729, 1730, 1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945, 1400, 1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, + 1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, + 1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, + 1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, + 1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, + 1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, + 1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, + 1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, + 1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, + 1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, + 1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, + 1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, + 1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, + 1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, + 1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, + 1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, + 1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, + 1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, + 1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, + 1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, + 1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, + 1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, + 1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, + 1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, + 1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, + 1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, + 1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, + 2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, + 2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, + 2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, + 2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, + 2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, + 1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, + 2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, + 1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, + 2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, + 2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, + 1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, + 2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, + 2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, + 2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, + 1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, + 2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, + 2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, + 2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, + 2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, + 2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, + 2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, + 1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, + 2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, + 2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, + 2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, + 2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, + 2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, + 1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, + 1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, + 2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, + 1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, + 2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, + 1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, + 2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, + 2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, + 2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, + 2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, + 2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, + 1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, + 1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, + 2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, + 1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, + 2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, + 2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, + 1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, + 2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, + 1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, + 2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, + 1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, + 2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, + 2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, + 1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, + 1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, + 2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, + 2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, + 2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, + 2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, + 2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, + 2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, + 1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, + 2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, + 2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, + 2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, + 2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, + 2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, + 2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, + 1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, + 2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, //512, 256 + + /*************************************************************************************** + * Everything below is of no interest for detection purpose + *************************************************************************************** + + 2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658, + 2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674, + 2675,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690, + 2691,2692,2693,2694,2695,2696,2697,2698,2699,1542, 880,2700,2701,2702,2703,2704, + 2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720, + 2721,2722,2723,2724,2725,1543,2726,2727,2728,2729,2730,2731,2732,1544,2733,2734, + 2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750, + 2751,2752,2753,2754,1545,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765, + 2766,1546,2767,1547,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779, + 2780,2781,2782,2783,2784,2785,2786,1548,2787,2788,2789,1109,2790,2791,2792,2793, + 2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809, + 2810,2811,2812,1329,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824, + 2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840, + 2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856, + 1549,2857,2858,2859,2860,1550,2861,2862,1551,2863,2864,2865,2866,2867,2868,2869, + 2870,2871,2872,2873,2874,1110,1330,2875,2876,2877,2878,2879,2880,2881,2882,2883, + 2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899, + 2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915, + 2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,1331, + 2931,2932,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,1552,2944,2945, + 2946,2947,2948,2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961, + 2962,2963,2964,1252,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976, + 2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992, + 2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008, + 3009,3010,3011,3012,1553,3013,3014,3015,3016,3017,1554,3018,1332,3019,3020,3021, + 3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037, + 3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,1555,3051,3052, + 3053,1556,1557,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066, + 3067,1558,3068,3069,3070,3071,3072,3073,3074,3075,3076,1559,3077,3078,3079,3080, + 3081,3082,3083,1253,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095, + 3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,1152,3109,3110, + 3111,3112,3113,1560,3114,3115,3116,3117,1111,3118,3119,3120,3121,3122,3123,3124, + 3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140, + 3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156, + 3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172, + 3173,3174,3175,3176,1333,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187, + 3188,3189,1561,3190,3191,1334,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201, + 3202,3203,3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217, + 3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233, + 3234,1562,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248, + 3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264, + 3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,1563,3278,3279, + 3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,3295, + 3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311, + 3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327, + 3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343, + 3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359, + 3360,3361,3362,3363,3364,1335,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374, + 3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,1336,3388,3389, + 3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402,3403,3404,3405, + 3406,3407,3408,3409,3410,3411,3412,3413,3414,1337,3415,3416,3417,3418,3419,1338, + 3420,3421,3422,1564,1565,3423,3424,3425,3426,3427,3428,3429,3430,3431,1254,3432, + 3433,3434,1339,3435,3436,3437,3438,3439,1566,3440,3441,3442,3443,3444,3445,3446, + 3447,3448,3449,3450,3451,3452,3453,3454,1255,3455,3456,3457,3458,3459,1567,1191, + 3460,1568,1569,3461,3462,3463,1570,3464,3465,3466,3467,3468,1571,3469,3470,3471, + 3472,3473,1572,3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486, + 1340,3487,3488,3489,3490,3491,3492,1021,3493,3494,3495,3496,3497,3498,1573,3499, + 1341,3500,3501,3502,3503,3504,3505,3506,3507,3508,3509,3510,3511,1342,3512,3513, + 3514,3515,3516,1574,1343,3517,3518,3519,1575,3520,1576,3521,3522,3523,3524,3525, + 3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541, + 3542,3543,3544,3545,3546,3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557, + 3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573, + 3574,3575,3576,3577,3578,3579,3580,1577,3581,3582,1578,3583,3584,3585,3586,3587, + 3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603, + 3604,1579,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618, + 3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,1580,3630,3631,1581,3632, + 3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,3643,3644,3645,3646,3647,3648, + 3649,3650,3651,3652,3653,3654,3655,3656,1582,3657,3658,3659,3660,3661,3662,3663, + 3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679, + 3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695, + 3696,3697,3698,3699,3700,1192,3701,3702,3703,3704,1256,3705,3706,3707,3708,1583, + 1257,3709,3710,3711,3712,3713,3714,3715,3716,1584,3717,3718,3719,3720,3721,3722, + 3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738, + 3739,3740,3741,3742,3743,3744,3745,1344,3746,3747,3748,3749,3750,3751,3752,3753, + 3754,3755,3756,1585,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,1586,3767, + 3768,3769,3770,3771,3772,3773,3774,3775,3776,3777,3778,1345,3779,3780,3781,3782, + 3783,3784,3785,3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,1346,1587,3796, + 3797,1588,3798,3799,3800,3801,3802,3803,3804,3805,3806,1347,3807,3808,3809,3810, + 3811,1589,3812,3813,3814,3815,3816,3817,3818,3819,3820,3821,1590,3822,3823,1591, + 1348,3824,3825,3826,3827,3828,3829,3830,1592,3831,3832,1593,3833,3834,3835,3836, + 3837,3838,3839,3840,3841,3842,3843,3844,1349,3845,3846,3847,3848,3849,3850,3851, + 3852,3853,3854,3855,3856,3857,3858,1594,3859,3860,3861,3862,3863,3864,3865,3866, + 3867,3868,3869,1595,3870,3871,3872,3873,1596,3874,3875,3876,3877,3878,3879,3880, + 3881,3882,3883,3884,3885,3886,1597,3887,3888,3889,3890,3891,3892,3893,3894,3895, + 1598,3896,3897,3898,1599,1600,3899,1350,3900,1351,3901,3902,1352,3903,3904,3905, + 3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921, + 3922,3923,3924,1258,3925,3926,3927,3928,3929,3930,3931,1193,3932,1601,3933,3934, + 3935,3936,3937,3938,3939,3940,3941,3942,3943,1602,3944,3945,3946,3947,3948,1603, + 3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964, + 3965,1604,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3977,1353,3978, + 3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,1354,3992,3993, + 3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009, + 4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,1355,4024, + 4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040, + 1605,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055, + 4056,4057,4058,4059,4060,1606,4061,4062,4063,4064,1607,4065,4066,4067,4068,4069, + 4070,4071,4072,4073,4074,4075,4076,1194,4077,4078,1608,4079,4080,4081,4082,4083, + 4084,4085,4086,4087,1609,4088,4089,4090,4091,4092,4093,4094,4095,4096,4097,4098, + 4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,1259,4109,4110,4111,4112,4113, + 4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,1195,4125,4126,4127,1610, + 4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,1356,4138,4139,4140,4141,4142, + 4143,4144,1611,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157, + 4158,4159,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4170,4171,4172,4173, + 4174,4175,4176,4177,4178,4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189, + 4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205, + 4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,1612,4220, + 4221,4222,4223,4224,4225,4226,4227,1357,4228,1613,4229,4230,4231,4232,4233,4234, + 4235,4236,4237,4238,4239,4240,4241,4242,4243,1614,4244,4245,4246,4247,4248,4249, + 4250,4251,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265, + 4266,4267,4268,4269,4270,1196,1358,4271,4272,4273,4274,4275,4276,4277,4278,4279, + 4280,4281,4282,4283,4284,4285,4286,4287,1615,4288,4289,4290,4291,4292,4293,4294, + 4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310, + 4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326, + 4327,4328,4329,4330,4331,4332,4333,4334,1616,4335,4336,4337,4338,4339,4340,4341, + 4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357, + 4358,4359,4360,1617,4361,4362,4363,4364,4365,1618,4366,4367,4368,4369,4370,4371, + 4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387, + 4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403, + 4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,1619,4417,4418, + 4419,4420,4421,4422,4423,4424,4425,1112,4426,4427,4428,4429,4430,1620,4431,4432, + 4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,1260,1261,4443,4444,4445,4446, + 4447,4448,4449,4450,4451,4452,4453,4454,4455,1359,4456,4457,4458,4459,4460,4461, + 4462,4463,4464,4465,1621,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476, + 4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,1055,4490,4491, + 4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507, + 4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,1622,4519,4520,4521,1623, + 4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,1360,4536, + 4537,4538,4539,4540,4541,4542,4543, 975,4544,4545,4546,4547,4548,4549,4550,4551, + 4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567, + 4568,4569,4570,4571,1624,4572,4573,4574,4575,4576,1625,4577,4578,4579,4580,4581, + 4582,4583,4584,1626,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,1627, + 4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611, + 4612,4613,4614,4615,1628,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626, + 4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642, + 4643,4644,4645,4646,4647,4648,4649,1361,4650,4651,4652,4653,4654,4655,4656,4657, + 4658,4659,4660,4661,1362,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672, + 4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,1629,4683,4684,4685,4686,4687, + 1630,4688,4689,4690,4691,1153,4692,4693,4694,1113,4695,4696,4697,4698,4699,4700, + 4701,4702,4703,4704,4705,4706,4707,4708,4709,4710,4711,1197,4712,4713,4714,4715, + 4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731, + 4732,4733,4734,4735,1631,4736,1632,4737,4738,4739,4740,4741,4742,4743,4744,1633, + 4745,4746,4747,4748,4749,1262,4750,4751,4752,4753,4754,1363,4755,4756,4757,4758, + 4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,1634,4769,4770,4771,4772,4773, + 4774,4775,4776,4777,4778,1635,4779,4780,4781,4782,4783,4784,4785,4786,4787,4788, + 4789,1636,4790,4791,4792,4793,4794,4795,4796,4797,4798,4799,4800,4801,4802,4803, + 4804,4805,4806,1637,4807,4808,4809,1638,4810,4811,4812,4813,4814,4815,4816,4817, + 4818,1639,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832, + 4833,1077,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847, + 4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863, + 4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879, + 4880,4881,4882,4883,1640,4884,4885,1641,4886,4887,4888,4889,4890,4891,4892,4893, + 4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909, + 4910,4911,1642,4912,4913,4914,1364,4915,4916,4917,4918,4919,4920,4921,4922,4923, + 4924,4925,4926,4927,4928,4929,4930,4931,1643,4932,4933,4934,4935,4936,4937,4938, + 4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954, + 4955,4956,4957,4958,4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970, + 4971,4972,4973,4974,4975,4976,4977,4978,4979,4980,1644,4981,4982,4983,4984,1645, + 4985,4986,1646,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999, + 5000,5001,5002,5003,5004,5005,1647,5006,1648,5007,5008,5009,5010,5011,5012,1078, + 5013,5014,5015,5016,5017,5018,5019,5020,5021,5022,5023,5024,5025,5026,5027,5028, + 1365,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,1649,5040,5041,5042, + 5043,5044,5045,1366,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,1650,5056, + 5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072, + 5073,5074,5075,5076,5077,1651,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087, + 5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103, + 5104,5105,5106,5107,5108,5109,5110,1652,5111,5112,5113,5114,5115,5116,5117,5118, + 1367,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,1653,5130,5131,5132, + 5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148, + 5149,1368,5150,1654,5151,1369,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161, + 5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177, + 5178,1370,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192, + 5193,5194,5195,5196,5197,5198,1655,5199,5200,5201,5202,1656,5203,5204,5205,5206, + 1371,5207,1372,5208,5209,5210,5211,1373,5212,5213,1374,5214,5215,5216,5217,5218, + 5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234, + 5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,1657,5248,5249, + 5250,5251,1658,1263,5252,5253,5254,5255,5256,1375,5257,5258,5259,5260,5261,5262, + 5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278, + 5279,5280,5281,5282,5283,1659,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293, + 5294,5295,5296,5297,5298,5299,5300,1660,5301,5302,5303,5304,5305,5306,5307,5308, + 5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,1376,5322,5323, + 5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,1198,5334,5335,5336,5337,5338, + 5339,5340,5341,5342,5343,1661,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353, + 5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369, + 5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385, + 5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,1264,5399,5400, + 5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,1662,5413,5414,5415, + 5416,1663,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430, + 5431,5432,5433,5434,5435,5436,5437,5438,1664,5439,5440,5441,5442,5443,5444,5445, + 5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461, + 5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477, + 5478,1154,5479,5480,5481,5482,5483,5484,5485,1665,5486,5487,5488,5489,5490,5491, + 5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507, + 5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523, + 5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539, + 5540,5541,5542,5543,5544,5545,5546,5547,5548,1377,5549,5550,5551,5552,5553,5554, + 5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570, + 1114,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585, + 5586,5587,5588,5589,5590,5591,5592,1378,5593,5594,5595,5596,5597,5598,5599,5600, + 5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,1379,5615, + 5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631, + 5632,5633,5634,1380,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646, + 5647,5648,5649,1381,1056,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660, + 1666,5661,5662,5663,5664,5665,5666,5667,5668,1667,5669,1668,5670,5671,5672,5673, + 5674,5675,5676,5677,5678,1155,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688, + 5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,1669,5699,5700,5701,5702,5703, + 5704,5705,1670,5706,5707,5708,5709,5710,1671,5711,5712,5713,5714,1382,5715,5716, + 5717,5718,5719,5720,5721,5722,5723,5724,5725,1672,5726,5727,1673,1674,5728,5729, + 5730,5731,5732,5733,5734,5735,5736,1675,5737,5738,5739,5740,5741,5742,5743,5744, + 1676,5745,5746,5747,5748,5749,5750,5751,1383,5752,5753,5754,5755,5756,5757,5758, + 5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,1677,5769,5770,5771,5772,5773, + 1678,5774,5775,5776, 998,5777,5778,5779,5780,5781,5782,5783,5784,5785,1384,5786, + 5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,5799,5800,1679,5801, + 5802,5803,1115,1116,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815, + 5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831, + 5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847, + 5848,5849,5850,5851,5852,5853,5854,5855,1680,5856,5857,5858,5859,5860,5861,5862, + 5863,5864,1681,5865,5866,5867,1682,5868,5869,5870,5871,5872,5873,5874,5875,5876, + 5877,5878,5879,1683,5880,1684,5881,5882,5883,5884,1685,5885,5886,5887,5888,5889, + 5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905, + 5906,5907,1686,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, + 5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,1687, + 5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951, + 5952,1688,1689,5953,1199,5954,5955,5956,5957,5958,5959,5960,5961,1690,5962,5963, + 5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979, + 5980,5981,1385,5982,1386,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993, + 5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009, + 6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025, + 6026,6027,1265,6028,6029,1691,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039, + 6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055, + 6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,6070,6071, + 6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,1692,6085,6086, + 6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100,6101,6102, + 6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118, + 6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,1693,6132,6133, + 6134,6135,6136,1694,6137,6138,6139,6140,6141,1695,6142,6143,6144,6145,6146,6147, + 6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163, + 6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179, + 6180,6181,6182,6183,6184,6185,1696,6186,6187,6188,6189,6190,6191,6192,6193,6194, + 6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210, + 6211,6212,6213,6214,6215,6216,6217,6218,6219,1697,6220,6221,6222,6223,6224,6225, + 6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241, + 6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,1698,6254,6255,6256, + 6257,6258,6259,6260,6261,6262,6263,1200,6264,6265,6266,6267,6268,6269,6270,6271, //1024 + 6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287, + 6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,1699, + 6303,6304,1700,6305,6306,6307,6308,6309,6310,6311,6312,6313,6314,6315,6316,6317, + 6318,6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333, + 6334,6335,6336,6337,6338,6339,1701,6340,6341,6342,6343,6344,1387,6345,6346,6347, + 6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363, + 6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379, + 6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395, + 6396,6397,6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411, + 6412,6413,1702,6414,6415,6416,6417,6418,6419,6420,6421,6422,1703,6423,6424,6425, + 6426,6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,1704,6439,6440, + 6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456, + 6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472, + 6473,6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488, + 6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,1266, + 6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,6519, + 6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535, + 6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551, + 1705,1706,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565, + 6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581, + 6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597, + 6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613, + 6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626,6627,6628,6629, + 6630,6631,6632,6633,6634,6635,6636,6637,1388,6638,6639,6640,6641,6642,6643,6644, + 1707,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,6655,6656,6657,6658,6659, + 6660,6661,6662,6663,1708,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674, + 1201,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689, + 6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705, + 6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721, + 6722,6723,6724,6725,1389,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736, + 1390,1709,6737,6738,6739,6740,6741,6742,1710,6743,6744,6745,6746,1391,6747,6748, + 6749,6750,6751,6752,6753,6754,6755,6756,6757,1392,6758,6759,6760,6761,6762,6763, + 6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779, + 6780,1202,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6794, + 6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,1711, + 6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820,6821,6822,6823,6824,6825, + 6826,6827,6828,6829,6830,6831,6832,6833,6834,6835,6836,1393,6837,6838,6839,6840, + 6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856, + 6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872, + 6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888, + 6889,6890,6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,6901,6902,1712,6903, + 6904,6905,6906,6907,6908,6909,6910,1713,6911,6912,6913,6914,6915,6916,6917,6918, + 6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934, + 6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950, + 6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966, + 6967,6968,6969,6970,6971,6972,6973,6974,1714,6975,6976,6977,6978,6979,6980,6981, + 6982,6983,6984,6985,6986,6987,6988,1394,6989,6990,6991,6992,6993,6994,6995,6996, + 6997,6998,6999,7000,1715,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011, + 7012,7013,7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027, + 7028,1716,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042, + 7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058, + 7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074, + 7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,7090, + 7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105,7106, + 7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122, + 7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138, + 7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154, + 7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167,7168,7169,7170, + 7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186, + 7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202, + 7203,7204,7205,7206,7207,1395,7208,7209,7210,7211,7212,7213,1717,7214,7215,7216, + 7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229,7230,7231,7232, + 7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245,7246,7247,7248, + 7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264, + 7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280, + 7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,7296, + 7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308,7309,7310,7311,7312, + 7313,1718,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327, + 7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343, + 7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,7358,7359, + 7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,7373,7374,7375, + 7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391, + 7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,7403,7404,7405,7406,7407, + 7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423, + 7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439, + 7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455, + 7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471, + 7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487, + 7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503, + 7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519, + 7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535, + 7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551, + 7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, + 7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583, + 7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599, + 7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615, + 7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631, + 7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647, + 7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663, + 7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679, + 7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695, + 7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711, + 7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727, + 7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743, + 7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759, + 7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775, + 7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791, + 7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807, + 7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823, + 7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839, + 7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855, + 7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871, + 7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887, + 7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903, + 7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919, + 7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, + 7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, + 7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, + 7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, + 7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, + 8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, + 8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, + 8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, + 8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, + 8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, + 8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, + 8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, + 8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, + 8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, + 8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, + 8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, + 8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, + 8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, + 8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, + 8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, + 8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, + 8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, + 8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287, + 8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303, + 8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319, + 8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,8330,8331,8332,8333,8334,8335, + 8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351, + 8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,8364,8365,8366,8367, + 8368,8369,8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383, + 8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398,8399, + 8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415, + 8416,8417,8418,8419,8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431, + 8432,8433,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447, + 8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463, + 8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479, + 8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495, + 8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,8510,8511, + 8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527, + 8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8540,8541,8542,8543, + 8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559, + 8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575, + 8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587,8588,8589,8590,8591, + 8592,8593,8594,8595,8596,8597,8598,8599,8600,8601,8602,8603,8604,8605,8606,8607, + 8608,8609,8610,8611,8612,8613,8614,8615,8616,8617,8618,8619,8620,8621,8622,8623, + 8624,8625,8626,8627,8628,8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,8639, + 8640,8641,8642,8643,8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655, + 8656,8657,8658,8659,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671, + 8672,8673,8674,8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687, + 8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, + 8704,8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719, + 8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,8735, + 8736,8737,8738,8739,8740,8741 */ }; + + public EUCKRDistributionAnalyser() + { + charToFreqOrder = EUCKR_CHAR2FREQ_ORDER; + tableSize = EUCKR_TABLE_SIZE; + typicalDistributionRatio = EUCKR_TYPICAL_DISTRIBUTION_RATIO; + } + + /// <summary> + /// first byte range: 0xb0 -- 0xfe + /// second byte range: 0xa1 -- 0xfe + /// no validation needed here. State machine has done that + /// </summary> + public override int GetOrder(byte[] buf, int offset) + { + if (buf[offset] >= 0xB0) + return 94 * (buf[offset] - 0xB0) + buf[offset+1] - 0xA1; + else + return -1; + } + } + + public class BIG5DistributionAnalyser : CharDistributionAnalyser + { + // Big5 frequency table + // by Taiwan's Mandarin Promotion Council + // <http://www.edu.tw:81/mandr/> + /****************************************************************************** + * 128 --> 0.42261 + * 256 --> 0.57851 + * 512 --> 0.74851 + * 1024 --> 0.89384 + * 2048 --> 0.97583 + * + * Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 + * Random Distribution Ration = 512/(5401-512)=0.105 + * + * Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + *****************************************************************************/ + + private static float BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75f; + + private static int BIG5_TABLE_SIZE = 5376; + + private static int[] BIG5_CHAR2FREQ_ORDER = { + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, // 16 + 3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, // 32 + 1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, // 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, // 64 + 3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, // 80 + 4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, // 96 + 5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, // 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, // 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, // 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, // 160 + 2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, // 176 + 1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, // 192 + 3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, // 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, // 224 + 1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, // 240 + 3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, // 256 + 2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, // 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, // 288 + 3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, // 304 + 1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, // 320 + 5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, // 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, // 352 + 5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, // 368 + 1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, // 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, // 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, // 416 + 3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, // 432 + 3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, // 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, // 464 + 2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, // 480 + 2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, // 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, // 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, // 528 + 3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, // 544 + 1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, // 560 + 1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, // 576 + 1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, // 592 + 2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, // 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, // 624 + 4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, // 640 + 1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, // 656 + 5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, // 672 + 2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, // 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, // 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, // 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, // 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, // 752 + 5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, // 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, // 784 + 1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, // 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, // 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, // 832 + 5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, // 848 + 1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, // 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, // 880 + 3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, // 896 + 4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, // 912 + 3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, // 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, // 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, // 960 + 1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, // 976 + 4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, // 992 + 3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, // 1008 + 3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, // 1024 + 2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, // 1040 + 5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, // 1056 + 3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, // 1072 + 5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, // 1088 + 1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, // 1104 + 2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, // 1120 + 1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, // 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, // 1152 + 1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, // 1168 + 4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, // 1184 + 3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, // 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, // 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, // 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, // 1248 + 2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, // 1264 + 5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, // 1280 + 1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, // 1296 + 2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, // 1312 + 1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, // 1328 + 1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, // 1344 + 5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, // 1360 + 5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, // 1376 + 5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, // 1392 + 3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, // 1408 + 4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, // 1424 + 4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, // 1440 + 2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, // 1456 + 5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, // 1472 + 3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, // 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, // 1504 + 5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, // 1520 + 5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, // 1536 + 1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, // 1552 + 2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, // 1568 + 3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, // 1584 + 4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, // 1600 + 5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, // 1616 + 3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, // 1632 + 4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, // 1648 + 1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, // 1664 + 1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, // 1680 + 4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, // 1696 + 1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, // 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, // 1728 + 1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, // 1744 + 1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, // 1760 + 3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, // 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, // 1792 + 5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, // 1808 + 2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, // 1824 + 1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, // 1840 + 1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, // 1856 + 5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, // 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, // 1888 + 4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, // 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, // 1920 + 2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, // 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, // 1952 + 1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, // 1968 + 1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, // 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, // 2000 + 4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, // 2016 + 4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, // 2032 + 1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, // 2048 + 3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, // 2064 + 5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, // 2080 + 5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, // 2096 + 1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, // 2112 + 2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, // 2128 + 1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, // 2144 + 3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, // 2160 + 2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, // 2176 + 3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, // 2192 + 2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, // 2208 + 4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, // 2224 + 4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, // 2240 + 3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, // 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, // 2272 + 3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, // 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, // 2304 + 3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, // 2320 + 4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, // 2336 + 3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, // 2352 + 1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, // 2368 + 5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, // 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, // 2400 + 5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, // 2416 + 1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, // 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, // 2448 + 4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, // 2464 + 4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, // 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, // 2496 + 2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, // 2512 + 2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, // 2528 + 3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, // 2544 + 1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, // 2560 + 4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, // 2576 + 2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, // 2592 + 1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, // 2608 + 1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, // 2624 + 2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, // 2640 + 3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, // 2656 + 1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, // 2672 + 5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, // 2688 + 1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, // 2704 + 4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, // 2720 + 1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, // 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, // 2752 + 1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, // 2768 + 4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, // 2784 + 4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, // 2800 + 2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, // 2816 + 1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, // 2832 + 4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, // 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, // 2864 + 5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, // 2880 + 2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, // 2896 + 3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, // 2912 + 4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, // 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, // 2944 + 5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, // 2960 + 5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, // 2976 + 1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, // 2992 + 4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, // 3008 + 4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, // 3024 + 2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, // 3040 + 3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, // 3056 + 3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, // 3072 + 2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, // 3088 + 1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, // 3104 + 4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, // 3120 + 3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, // 3136 + 3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, // 3152 + 2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, // 3168 + 4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, // 3184 + 5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, // 3200 + 3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, // 3216 + 2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, // 3232 + 3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, // 3248 + 1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, // 3264 + 2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, // 3280 + 3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, // 3296 + 4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, // 3312 + 2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, // 3328 + 2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, // 3344 + 5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, // 3360 + 1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, // 3376 + 2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, // 3392 + 1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, // 3408 + 3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, // 3424 + 4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, // 3440 + 2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, // 3456 + 3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, // 3472 + 3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, // 3488 + 2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, // 3504 + 4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, // 3520 + 2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, // 3536 + 3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, // 3552 + 4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, // 3568 + 5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, // 3584 + 3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, // 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, // 3616 + 1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, // 3632 + 4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, // 3648 + 1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, // 3664 + 4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, // 3680 + 5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, // 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, // 3712 + 5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, // 3728 + 5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, // 3744 + 2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, // 3760 + 3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, // 3776 + 2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, // 3792 + 2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, // 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, // 3824 + 1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, // 3840 + 4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, // 3856 + 3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, // 3872 + 3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, // 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, // 3904 + 2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, // 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, // 3936 + 2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, // 3952 + 4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, // 3968 + 1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, // 3984 + 4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, // 4000 + 1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, // 4016 + 3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, // 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, // 4048 + 3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, // 4064 + 5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, // 4080 + 5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, // 4096 + 3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, // 4112 + 3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, // 4128 + 1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, // 4144 + 2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, // 4160 + 5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, // 4176 + 1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, // 4192 + 1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, // 4208 + 3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, // 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, // 4240 + 1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, // 4256 + 4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, // 4272 + 5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, // 4288 + 2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, // 4304 + 3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, // 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, // 4336 + 1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, // 4352 + 2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, // 4368 + 2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, // 4384 + 5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, // 4400 + 5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, // 4416 + 5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, // 4432 + 2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, // 4448 + 2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, // 4464 + 1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, // 4480 + 4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, // 4496 + 3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, // 4512 + 3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, // 4528 + 4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, // 4544 + 4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, // 4560 + 2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, // 4576 + 2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, // 4592 + 5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, // 4608 + 4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, // 4624 + 5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, // 4640 + 4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, // 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, // 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, // 4688 + 1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, // 4704 + 3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, // 4720 + 4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, // 4736 + 1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, // 4752 + 5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, // 4768 + 2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, // 4784 + 2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, // 4800 + 3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, // 4816 + 5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, // 4832 + 1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, // 4848 + 3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, // 4864 + 5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, // 4880 + 1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, // 4896 + 5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, // 4912 + 2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, // 4928 + 3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, // 4944 + 2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, // 4960 + 3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, // 4976 + 3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, // 4992 + 3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, // 5008 + 4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, // 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, // 5040 + 2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, // 5056 + 4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, // 5072 + 3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, // 5088 + 5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, // 5104 + 1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, // 5120 + 5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, // 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, // 5152 + 1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, // 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, // 5184 + 4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, // 5200 + 1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, // 5216 + 4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, // 5232 + 1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, // 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, // 5264 + 3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, // 5280 + 4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, // 5296 + 5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, // 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, // 5328 + 3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, // 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, // 5360 + 2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, // 5376 //last 512 + + /*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + + 2522,1613,4812,5799,3345,3945,2523,5800,4162,5801,1637,4163,2471,4813,3946,5802, // 5392 + 2500,3034,3800,5803,5804,2195,4814,5805,2163,5806,5807,5808,5809,5810,5811,5812, // 5408 + 5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828, // 5424 + 5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844, // 5440 + 5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860, // 5456 + 5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876, // 5472 + 5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892, // 5488 + 5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906,5907,5908, // 5504 + 5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924, // 5520 + 5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940, // 5536 + 5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952,5953,5954,5955,5956, // 5552 + 5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5970,5971,5972, // 5568 + 5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984,5985,5986,5987,5988, // 5584 + 5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004, // 5600 + 6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020, // 5616 + 6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036, // 5632 + 6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052, // 5648 + 6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068, // 5664 + 6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084, // 5680 + 6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100, // 5696 + 6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116, // 5712 + 6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132, // 5728 + 6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145,6146,6147,6148, // 5744 + 6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,6164, // 5760 + 6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,6180, // 5776 + 6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196, // 5792 + 6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212, // 5808 + 6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,3670,6224,6225,6226,6227, // 5824 + 6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243, // 5840 + 6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259, // 5856 + 6260,6261,6262,6263,6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275, // 5872 + 6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,4815,6286,6287,6288,6289,6290, // 5888 + 6291,6292,4816,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305, // 5904 + 6306,6307,6308,6309,6310,6311,4817,4818,6312,6313,6314,6315,6316,6317,6318,4819, // 5920 + 6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334, // 5936 + 6335,6336,6337,4820,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349, // 5952 + 6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365, // 5968 + 6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381, // 5984 + 6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397, // 6000 + 6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,3441,6411,6412, // 6016 + 6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,4440,6426,6427, // 6032 + 6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443, // 6048 + 6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,4821,6455,6456,6457,6458, // 6064 + 6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474, // 6080 + 6475,6476,6477,3947,3948,6478,6479,6480,6481,3272,4441,6482,6483,6484,6485,4442, // 6096 + 6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,4822,6497,6498,6499,6500, // 6112 + 6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516, // 6128 + 6517,6518,6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532, // 6144 + 6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548, // 6160 + 6549,6550,6551,6552,6553,6554,6555,6556,2784,6557,4823,6558,6559,6560,6561,6562, // 6176 + 6563,6564,6565,6566,6567,6568,6569,3949,6570,6571,6572,4824,6573,6574,6575,6576, // 6192 + 6577,6578,6579,6580,6581,6582,6583,4825,6584,6585,6586,3950,2785,6587,6588,6589, // 6208 + 6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605, // 6224 + 6606,6607,6608,6609,6610,6611,6612,4826,6613,6614,6615,4827,6616,6617,6618,6619, // 6240 + 6620,6621,6622,6623,6624,6625,4164,6626,6627,6628,6629,6630,6631,6632,6633,6634, // 6256 + 3547,6635,4828,6636,6637,6638,6639,6640,6641,6642,3951,2984,6643,6644,6645,6646, // 6272 + 6647,6648,6649,4165,6650,4829,6651,6652,4830,6653,6654,6655,6656,6657,6658,6659, // 6288 + 6660,6661,6662,4831,6663,6664,6665,6666,6667,6668,6669,6670,6671,4166,6672,4832, // 6304 + 3952,6673,6674,6675,6676,4833,6677,6678,6679,4167,6680,6681,6682,3198,6683,6684, // 6320 + 6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,4834,6698,6699, // 6336 + 6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715, // 6352 + 6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731, // 6368 + 6732,6733,6734,4443,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,4444, // 6384 + 6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761, // 6400 + 6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777, // 6416 + 6778,6779,6780,6781,4168,6782,6783,3442,6784,6785,6786,6787,6788,6789,6790,6791, // 6432 + 4169,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806, // 6448 + 6807,6808,6809,6810,6811,4835,6812,6813,6814,4445,6815,6816,4446,6817,6818,6819, // 6464 + 6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,6834,6835, // 6480 + 3548,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,4836,6847,6848,6849, // 6496 + 6850,6851,6852,6853,6854,3953,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864, // 6512 + 6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,3199,6878,6879, // 6528 + 6880,6881,6882,4447,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894, // 6544 + 6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,4170,6905,6906,6907,6908,6909, // 6560 + 6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,6924,6925, // 6576 + 6926,6927,4837,6928,6929,6930,6931,6932,6933,6934,6935,6936,3346,6937,6938,4838, // 6592 + 6939,6940,6941,4448,6942,6943,6944,6945,6946,4449,6947,6948,6949,6950,6951,6952, // 6608 + 6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968, // 6624 + 6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984, // 6640 + 6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,3671,6995,6996,6997,6998,4839, // 6656 + 6999,7000,7001,7002,3549,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013, // 6672 + 7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029, // 6688 + 7030,4840,7031,7032,7033,7034,7035,7036,7037,7038,4841,7039,7040,7041,7042,7043, // 6704 + 7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059, // 6720 + 7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,2985,7071,7072,7073,7074, // 6736 + 7075,7076,7077,7078,7079,7080,4842,7081,7082,7083,7084,7085,7086,7087,7088,7089, // 6752 + 7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105, // 6768 + 7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,4450,7119,7120, // 6784 + 7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136, // 6800 + 7137,7138,7139,7140,7141,7142,7143,4843,7144,7145,7146,7147,7148,7149,7150,7151, // 6816 + 7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167, // 6832 + 7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183, // 6848 + 7184,7185,7186,7187,7188,4171,4172,7189,7190,7191,7192,7193,7194,7195,7196,7197, // 6864 + 7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213, // 6880 + 7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229, // 6896 + 7230,7231,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245, // 6912 + 7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261, // 6928 + 7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277, // 6944 + 7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293, // 6960 + 7294,7295,7296,4844,7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308, // 6976 + 7309,7310,7311,7312,7313,7314,7315,7316,4451,7317,7318,7319,7320,7321,7322,7323, // 6992 + 7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339, // 7008 + 7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,4173,7354, // 7024 + 7355,4845,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369, // 7040 + 7370,7371,7372,7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385, // 7056 + 7386,7387,7388,4846,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400, // 7072 + 7401,7402,7403,7404,7405,3672,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415, // 7088 + 7416,7417,7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431, // 7104 + 7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447, // 7120 + 7448,7449,7450,7451,7452,7453,4452,7454,3200,7455,7456,7457,7458,7459,7460,7461, // 7136 + 7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,4847,7475,7476, // 7152 + 7477,3133,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491, // 7168 + 7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,3347,7503,7504,7505,7506, // 7184 + 7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,4848, // 7200 + 7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537, // 7216 + 7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,3801,4849,7550,7551, // 7232 + 7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, // 7248 + 7568,7569,3035,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582, // 7264 + 7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598, // 7280 + 7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614, // 7296 + 7615,7616,4850,7617,7618,3802,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628, // 7312 + 7629,7630,7631,7632,4851,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643, // 7328 + 7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659, // 7344 + 7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,4453,7671,7672,7673,7674, // 7360 + 7675,7676,7677,7678,7679,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690, // 7376 + 7691,7692,7693,7694,7695,7696,7697,3443,7698,7699,7700,7701,7702,4454,7703,7704, // 7392 + 7705,7706,7707,7708,7709,7710,7711,7712,7713,2472,7714,7715,7716,7717,7718,7719, // 7408 + 7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,3954,7732,7733,7734, // 7424 + 7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750, // 7440 + 3134,7751,7752,4852,7753,7754,7755,4853,7756,7757,7758,7759,7760,4174,7761,7762, // 7456 + 7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778, // 7472 + 7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794, // 7488 + 7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,4854,7806,7807,7808,7809, // 7504 + 7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825, // 7520 + 4855,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7536 + 7841,7842,7843,7844,7845,7846,7847,3955,7848,7849,7850,7851,7852,7853,7854,7855, // 7552 + 7856,7857,7858,7859,7860,3444,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870, // 7568 + 7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886, // 7584 + 7887,7888,7889,7890,7891,4175,7892,7893,7894,7895,7896,4856,4857,7897,7898,7899, // 7600 + 7900,2598,7901,7902,7903,7904,7905,7906,7907,7908,4455,7909,7910,7911,7912,7913, // 7616 + 7914,3201,7915,7916,7917,7918,7919,7920,7921,4858,7922,7923,7924,7925,7926,7927, // 7632 + 7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943, // 7648 + 7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7958,7959, // 7664 + 7960,7961,7962,7963,7964,7965,7966,7967,7968,7969,7970,7971,7972,7973,7974,7975, // 7680 + 7976,7977,7978,7979,7980,7981,4859,7982,7983,7984,7985,7986,7987,7988,7989,7990, // 7696 + 7991,7992,7993,7994,7995,7996,4860,7997,7998,7999,8000,8001,8002,8003,8004,8005, // 7712 + 8006,8007,8008,8009,8010,8011,8012,8013,8014,8015,8016,4176,8017,8018,8019,8020, // 7728 + 8021,8022,8023,4861,8024,8025,8026,8027,8028,8029,8030,8031,8032,8033,8034,8035, // 7744 + 8036,4862,4456,8037,8038,8039,8040,4863,8041,8042,8043,8044,8045,8046,8047,8048, // 7760 + 8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063,8064, // 7776 + 8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080, // 7792 + 8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096, // 7808 + 8097,8098,8099,4864,4177,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110, // 7824 + 8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,4178,8121,8122,8123,8124,8125, // 7840 + 8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141, // 7856 + 8142,8143,8144,8145,4865,4866,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155, // 7872 + 8156,8157,8158,8159,8160,8161,8162,8163,8164,8165,4179,8166,8167,8168,8169,8170, // 7888 + 8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181,4457,8182,8183,8184,8185, // 7904 + 8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201, // 7920 + 8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213,8214,8215,8216,8217, // 7936 + 8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229,8230,8231,8232,8233, // 7952 + 8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245,8246,8247,8248,8249, // 7968 + 8250,8251,8252,8253,8254,8255,8256,3445,8257,8258,8259,8260,8261,8262,4458,8263, // 7984 + 8264,8265,8266,8267,8268,8269,8270,8271,8272,4459,8273,8274,8275,8276,3550,8277, // 8000 + 8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,4460,8290,8291,8292, // 8016 + 8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,4867, // 8032 + 8308,8309,8310,8311,8312,3551,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322, // 8048 + 8323,8324,8325,8326,4868,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337, // 8064 + 8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353, // 8080 + 8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,4869,4461,8364,8365,8366,8367, // 8096 + 8368,8369,8370,4870,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382, // 8112 + 8383,8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398, // 8128 + 8399,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,4871,8411,8412,8413, // 8144 + 8414,8415,8416,8417,8418,8419,8420,8421,8422,4462,8423,8424,8425,8426,8427,8428, // 8160 + 8429,8430,8431,8432,8433,2986,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443, // 8176 + 8444,8445,8446,8447,8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459, // 8192 + 8460,8461,8462,8463,8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475, // 8208 + 8476,8477,8478,4180,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490, // 8224 + 8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506, // 8240 + 8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522, // 8256 + 8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538, // 8272 + 8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554, // 8288 + 8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,4872,8565,8566,8567,8568,8569, // 8304 + 8570,8571,8572,8573,4873,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584, // 8320 + 8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,8600, // 8336 + 8601,8602,8603,8604,8605,3803,8606,8607,8608,8609,8610,8611,8612,8613,4874,3804, // 8352 + 8614,8615,8616,8617,8618,8619,8620,8621,3956,8622,8623,8624,8625,8626,8627,8628, // 8368 + 8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,2865,8639,8640,8641,8642,8643, // 8384 + 8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,4463,8657,8658, // 8400 + 8659,4875,4876,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672, // 8416 + 8673,8674,8675,8676,8677,8678,8679,8680,8681,4464,8682,8683,8684,8685,8686,8687, // 8432 + 8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, // 8448 + 8704,8705,8706,8707,8708,8709,2261,8710,8711,8712,8713,8714,8715,8716,8717,8718, // 8464 + 8719,8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,4181, // 8480 + 8734,8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749, // 8496 + 8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,4877,8764, // 8512 + 8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,8780, // 8528 + 8781,8782,8783,8784,8785,8786,8787,8788,4878,8789,4879,8790,8791,8792,4880,8793, // 8544 + 8794,8795,8796,8797,8798,8799,8800,8801,4881,8802,8803,8804,8805,8806,8807,8808, // 8560 + 8809,8810,8811,8812,8813,8814,8815,3957,8816,8817,8818,8819,8820,8821,8822,8823, // 8576 + 8824,8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839, // 8592 + 8840,8841,8842,8843,8844,8845,8846,8847,4882,8848,8849,8850,8851,8852,8853,8854, // 8608 + 8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,8870, // 8624 + 8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,3202,8885, // 8640 + 8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8901, // 8656 + 8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917, // 8672 + 8918,8919,8920,8921,8922,8923,8924,4465,8925,8926,8927,8928,8929,8930,8931,8932, // 8688 + 4883,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,2214,8944,8945,8946, // 8704 + 8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,8960,8961,8962, // 8720 + 8963,8964,8965,4884,8966,8967,8968,8969,8970,8971,8972,8973,8974,8975,8976,8977, // 8736 + 8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,8990,8991,8992,4885, // 8752 + 8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,9008, // 8768 + 9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,4182,9022,9023, // 8784 + 9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,9038,9039, // 8800 + 9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,9053,9054,9055, // 8816 + 9056,9057,9058,9059,9060,9061,9062,9063,4886,9064,9065,9066,9067,9068,9069,4887, // 8832 + 9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,9083,9084,9085, // 8848 + 9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9101, // 8864 + 9102,9103,9104,9105,9106,9107,9108,9109,9110,9111,9112,9113,9114,9115,9116,9117, // 8880 + 9118,9119,9120,9121,9122,9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133, // 8896 + 9134,9135,9136,9137,9138,9139,9140,9141,3958,9142,9143,9144,9145,9146,9147,9148, // 8912 + 9149,9150,9151,4888,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162,9163, // 8928 + 9164,9165,9166,9167,9168,9169,9170,9171,9172,9173,9174,9175,4889,9176,9177,9178, // 8944 + 9179,9180,9181,9182,9183,9184,9185,9186,9187,9188,9189,9190,9191,9192,9193,9194, // 8960 + 9195,9196,9197,9198,9199,9200,9201,9202,9203,4890,9204,9205,9206,9207,9208,9209, // 8976 + 9210,9211,9212,9213,9214,9215,9216,9217,9218,9219,9220,9221,9222,4466,9223,9224, // 8992 + 9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240, // 9008 + 9241,9242,9243,9244,9245,4891,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255, // 9024 + 9256,9257,4892,9258,9259,9260,9261,4893,4894,9262,9263,9264,9265,9266,9267,9268, // 9040 + 9269,9270,9271,9272,9273,4467,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283, // 9056 + 9284,9285,3673,9286,9287,9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298, // 9072 + 9299,9300,9301,9302,9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314, // 9088 + 9315,9316,9317,9318,9319,9320,9321,9322,4895,9323,9324,9325,9326,9327,9328,9329, // 9104 + 9330,9331,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345, // 9120 + 9346,9347,4468,9348,9349,9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360, // 9136 + 9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9372,9373,4896,9374,4469, // 9152 + 9375,9376,9377,9378,9379,4897,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389, // 9168 + 9390,9391,9392,9393,9394,9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405, // 9184 + 9406,4470,9407,2751,9408,9409,3674,3552,9410,9411,9412,9413,9414,9415,9416,9417, // 9200 + 9418,9419,9420,9421,4898,9422,9423,9424,9425,9426,9427,9428,9429,3959,9430,9431, // 9216 + 9432,9433,9434,9435,9436,4471,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446, // 9232 + 9447,9448,9449,9450,3348,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461, // 9248 + 9462,9463,9464,9465,9466,9467,9468,9469,9470,9471,9472,4899,9473,9474,9475,9476, // 9264 + 9477,4900,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,3349,9489,9490, // 9280 + 9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506, // 9296 + 9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,4901,9521, // 9312 + 9522,9523,9524,9525,9526,4902,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536, // 9328 + 9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,9551,9552, // 9344 + 9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568, // 9360 + 9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584, // 9376 + 3805,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599, // 9392 + 9600,9601,9602,4903,9603,9604,9605,9606,9607,4904,9608,9609,9610,9611,9612,9613, // 9408 + 9614,4905,9615,9616,9617,9618,9619,9620,9621,9622,9623,9624,9625,9626,9627,9628, // 9424 + 9629,9630,9631,9632,4906,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643, // 9440 + 4907,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658, // 9456 + 9659,9660,9661,9662,9663,9664,9665,9666,9667,9668,9669,9670,9671,9672,4183,9673, // 9472 + 9674,9675,9676,9677,4908,9678,9679,9680,9681,4909,9682,9683,9684,9685,9686,9687, // 9488 + 9688,9689,9690,4910,9691,9692,9693,3675,9694,9695,9696,2945,9697,9698,9699,9700, // 9504 + 9701,9702,9703,9704,9705,4911,9706,9707,9708,9709,9710,9711,9712,9713,9714,9715, // 9520 + 9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731, // 9536 + 9732,9733,9734,9735,4912,9736,9737,9738,9739,9740,4913,9741,9742,9743,9744,9745, // 9552 + 9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,4914,9759,9760, // 9568 + 9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776, // 9584 + 9777,9778,9779,9780,9781,9782,4915,9783,9784,9785,9786,9787,9788,9789,9790,9791, // 9600 + 9792,9793,4916,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806, // 9616 + 9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822, // 9632 + 9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838, // 9648 + 9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854, // 9664 + 9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,4917,9869, // 9680 + 9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885, // 9696 + 9886,9887,9888,9889,9890,9891,9892,4472,9893,9894,9895,9896,9897,3806,9898,9899, // 9712 + 9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,4918, // 9728 + 9915,9916,9917,4919,9918,9919,9920,9921,4184,9922,9923,9924,9925,9926,9927,9928, // 9744 + 9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944, // 9760 + 9945,9946,4920,9947,9948,9949,9950,9951,9952,9953,9954,9955,4185,9956,9957,9958, // 9776 + 9959,9960,9961,9962,9963,9964,9965,4921,9966,9967,9968,4473,9969,9970,9971,9972, // 9792 + 9973,9974,9975,9976,9977,4474,9978,9979,9980,9981,9982,9983,9984,9985,9986,9987, // 9808 + 9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001,10002,10003, // 9824 + 10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019, // 9840 + 10020,10021,4922,10022,4923,10023,10024,10025,10026,10027,10028,10029,10030,10031,10032,10033, // 9856 + 10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,4924, // 9872 + 10049,10050,10051,10052,10053,10054,10055,10056,10057,10058,10059,10060,10061,10062,10063,10064, // 9888 + 10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080, // 9904 + 10081,10082,10083,10084,10085,10086,10087,4475,10088,10089,10090,10091,10092,10093,10094,10095, // 9920 + 10096,10097,4476,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110, // 9936 + 10111,2174,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125, // 9952 + 10126,10127,10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,3807, // 9968 + 4186,4925,10141,10142,10143,10144,10145,10146,10147,4477,4187,10148,10149,10150,10151,10152, // 9984 + 10153,4188,10154,10155,10156,10157,10158,10159,10160,10161,4926,10162,10163,10164,10165,10166, //10000 + 10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182, //10016 + 10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,3203,10193,10194,10195,10196,10197, //10032 + 10198,10199,10200,4478,10201,10202,10203,10204,4479,10205,10206,10207,10208,10209,10210,10211, //10048 + 10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227, //10064 + 10228,10229,10230,10231,10232,10233,10234,4927,10235,10236,10237,10238,10239,10240,10241,10242, //10080 + 10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258, //10096 + 10259,10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,4480, //10112 + 4928,4929,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,10284,10285,10286,10287, //10128 + 10288,10289,10290,10291,10292,10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303, //10144 + 10304,10305,10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319, //10160 + 10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,10334,4930, //10176 + 10335,10336,10337,10338,10339,10340,10341,10342,4931,10343,10344,10345,10346,10347,10348,10349, //10192 + 10350,10351,10352,10353,10354,10355,3088,10356,2786,10357,10358,10359,10360,4189,10361,10362, //10208 + 10363,10364,10365,10366,10367,10368,10369,10370,10371,10372,10373,10374,10375,4932,10376,10377, //10224 + 10378,10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10392,4933, //10240 + 10393,10394,10395,4934,10396,10397,10398,10399,10400,10401,10402,10403,10404,10405,10406,10407, //10256 + 10408,10409,10410,10411,10412,3446,10413,10414,10415,10416,10417,10418,10419,10420,10421,10422, //10272 + 10423,4935,10424,10425,10426,10427,10428,10429,10430,4936,10431,10432,10433,10434,10435,10436, //10288 + 10437,10438,10439,10440,10441,10442,10443,4937,10444,10445,10446,10447,4481,10448,10449,10450, //10304 + 10451,10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,10464,10465,10466, //10320 + 10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,10478,10479,10480,10481,10482, //10336 + 10483,10484,10485,10486,10487,10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498, //10352 + 10499,10500,10501,10502,10503,10504,10505,4938,10506,10507,10508,10509,10510,2552,10511,10512, //10368 + 10513,10514,10515,10516,3447,10517,10518,10519,10520,10521,10522,10523,10524,10525,10526,10527, //10384 + 10528,10529,10530,10531,10532,10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543, //10400 + 4482,10544,4939,10545,10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557, //10416 + 10558,10559,10560,10561,10562,10563,10564,10565,10566,10567,3676,4483,10568,10569,10570,10571, //10432 + 10572,3448,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,10585,10586, //10448 + 10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602, //10464 + 10603,10604,10605,10606,10607,10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618, //10480 + 10619,10620,10621,10622,10623,10624,10625,10626,10627,4484,10628,10629,10630,10631,10632,4940, //10496 + 10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,10647,10648, //10512 + 10649,10650,10651,10652,10653,10654,10655,10656,4941,10657,10658,10659,2599,10660,10661,10662, //10528 + 10663,10664,10665,10666,3089,10667,10668,10669,10670,10671,10672,10673,10674,10675,10676,10677, //10544 + 10678,10679,10680,4942,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,10692, //10560 + 10693,10694,10695,10696,10697,4485,10698,10699,10700,10701,10702,10703,10704,4943,10705,3677, //10576 + 10706,10707,10708,10709,10710,10711,10712,4944,10713,10714,10715,10716,10717,10718,10719,10720, //10592 + 10721,10722,10723,10724,10725,10726,10727,10728,4945,10729,10730,10731,10732,10733,10734,10735, //10608 + 10736,10737,10738,10739,10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751, //10624 + 10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,4946,10762,10763,10764,10765,10766, //10640 + 10767,4947,4948,10768,10769,10770,10771,10772,10773,10774,10775,10776,10777,10778,10779,10780, //10656 + 10781,10782,10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796, //10672 + 10797,10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,10812, //10688 + 10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,10824,10825,10826,10827,10828, //10704 + 10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844, //10720 + 10845,10846,10847,10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860, //10736 + 10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,10872,10873,10874,10875,10876, //10752 + 10877,10878,4486,10879,10880,10881,10882,10883,10884,10885,4949,10886,10887,10888,10889,10890, //10768 + 10891,10892,10893,10894,10895,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906, //10784 + 10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,4487,10920,10921, //10800 + 10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,4950,10933,10934,10935,10936, //10816 + 10937,10938,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948,10949,4488,10950,10951, //10832 + 10952,10953,10954,10955,10956,10957,10958,10959,4190,10960,10961,10962,10963,10964,10965,10966, //10848 + 10967,10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,10980,10981,10982, //10864 + 10983,10984,10985,10986,10987,10988,10989,10990,10991,10992,10993,10994,10995,10996,10997,10998, //10880 + 10999,11000,11001,11002,11003,11004,11005,11006,3960,11007,11008,11009,11010,11011,11012,11013, //10896 + 11014,11015,11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,11028,11029, //10912 + 11030,11031,11032,4951,11033,11034,11035,11036,11037,11038,11039,11040,11041,11042,11043,11044, //10928 + 11045,11046,11047,4489,11048,11049,11050,11051,4952,11052,11053,11054,11055,11056,11057,11058, //10944 + 4953,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069,11070,11071,4954,11072, //10960 + 11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,11088, //10976 + 11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,11100,11101,11102,11103,11104, //10992 + 11105,11106,11107,11108,11109,11110,11111,11112,11113,11114,11115,3808,11116,11117,11118,11119, //11008 + 11120,11121,11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,4955, //11024 + 11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150, //11040 + 11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,4956,11162,11163,11164,11165, //11056 + 11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11179,11180,4957, //11072 + 11181,11182,11183,11184,11185,11186,4958,11187,11188,11189,11190,11191,11192,11193,11194,11195, //11088 + 11196,11197,11198,11199,11200,3678,11201,11202,11203,11204,11205,11206,4191,11207,11208,11209, //11104 + 11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,11220,11221,11222,11223,11224,11225, //11120 + 11226,11227,11228,11229,11230,11231,11232,11233,11234,11235,11236,11237,11238,11239,11240,11241, //11136 + 11242,11243,11244,11245,11246,11247,11248,11249,11250,11251,4959,11252,11253,11254,11255,11256, //11152 + 11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11271,11272, //11168 + 11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288, //11184 + 11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304, //11200 + 11305,11306,11307,11308,11309,11310,11311,11312,11313,11314,3679,11315,11316,11317,11318,4490, //11216 + 11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334, //11232 + 11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,4960,11348,11349, //11248 + 11350,11351,11352,11353,11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365, //11264 + 11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,3961,4961,11378,11379, //11280 + 11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395, //11296 + 11396,11397,4192,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410, //11312 + 11411,4962,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425, //11328 + 11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441, //11344 + 11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457, //11360 + 11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,4963,11470,11471,4491, //11376 + 11472,11473,11474,11475,4964,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486, //11392 + 11487,11488,11489,11490,11491,11492,4965,11493,11494,11495,11496,11497,11498,11499,11500,11501, //11408 + 11502,11503,11504,11505,11506,11507,11508,11509,11510,11511,11512,11513,11514,11515,11516,11517, //11424 + 11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,3962,11530,11531,11532, //11440 + 11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548, //11456 + 11549,11550,11551,11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564, //11472 + 4193,4194,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578, //11488 + 11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,4966,4195,11592, //11504 + 11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,3090,11605,11606,11607, //11520 + 11608,11609,11610,4967,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622, //11536 + 11623,11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,11636,11637,11638, //11552 + 11639,11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654, //11568 + 11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670, //11584 + 11671,11672,11673,11674,4968,11675,11676,11677,11678,11679,11680,11681,11682,11683,11684,11685, //11600 + 11686,11687,11688,11689,11690,11691,11692,11693,3809,11694,11695,11696,11697,11698,11699,11700, //11616 + 11701,11702,11703,11704,11705,11706,11707,11708,11709,11710,11711,11712,11713,11714,11715,11716, //11632 + 11717,11718,3553,11719,11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,4969, //11648 + 11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,4492,11741,11742,11743,11744,11745, //11664 + 11746,11747,11748,11749,11750,11751,11752,4970,11753,11754,11755,11756,11757,11758,11759,11760, //11680 + 11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,11776, //11696 + 11777,11778,11779,11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,4971,11791, //11712 + 11792,11793,11794,11795,11796,11797,4972,11798,11799,11800,11801,11802,11803,11804,11805,11806, //11728 + 11807,11808,11809,11810,4973,11811,11812,11813,11814,11815,11816,11817,11818,11819,11820,11821, //11744 + 11822,11823,11824,11825,11826,11827,11828,11829,11830,11831,11832,11833,11834,3680,3810,11835, //11760 + 11836,4974,11837,11838,11839,11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850, //11776 + 11851,11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,11864,11865,11866, //11792 + 11867,11868,11869,11870,11871,11872,11873,11874,11875,11876,11877,11878,11879,11880,11881,11882, //11808 + 11883,11884,4493,11885,11886,11887,11888,11889,11890,11891,11892,11893,11894,11895,11896,11897, //11824 + 11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,11912,11913, //11840 + 11914,11915,4975,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928, //11856 + 11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,11940,11941,11942,11943,11944, //11872 + 11945,11946,11947,11948,11949,4976,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959, //11888 + 11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,11975, //11904 + 11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,4196,11988,11989,11990, //11920 + 11991,11992,4977,11993,11994,11995,11996,11997,11998,11999,12000,12001,12002,12003,12004,12005, //11936 + 12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021, //11952 + 12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037, //11968 + 12038,12039,12040,12041,12042,12043,12044,12045,12046,12047,12048,12049,12050,12051,12052,12053, //11984 + 12054,12055,12056,12057,12058,12059,12060,12061,4978,12062,12063,12064,12065,12066,12067,12068, //12000 + 12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,12080,12081,12082,12083,12084, //12016 + 12085,12086,12087,12088,12089,12090,12091,12092,12093,12094,12095,12096,12097,12098,12099,12100, //12032 + 12101,12102,12103,12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,12116, //12048 + 12117,12118,12119,12120,12121,12122,12123,4979,12124,12125,12126,12127,12128,4197,12129,12130, //12064 + 12131,12132,12133,12134,12135,12136,12137,12138,12139,12140,12141,12142,12143,12144,12145,12146, //12080 + 12147,12148,12149,12150,12151,12152,12153,12154,4980,12155,12156,12157,12158,12159,12160,4494, //12096 + 12161,12162,12163,12164,3811,12165,12166,12167,12168,12169,4495,12170,12171,4496,12172,12173, //12112 + 12174,12175,12176,3812,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188, //12128 + 12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,12200,12201,12202,12203,12204, //12144 + 12205,12206,12207,12208,12209,12210,12211,12212,12213,12214,12215,12216,12217,12218,12219,12220, //12160 + 12221,4981,12222,12223,12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235, //12176 + 4982,12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,4983,12246,12247,12248,12249, //12192 + 4984,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,12260,12261,12262,12263,12264, //12208 + 4985,12265,4497,12266,12267,12268,12269,12270,12271,12272,12273,12274,12275,12276,12277,12278, //12224 + 12279,12280,12281,12282,12283,12284,12285,12286,12287,4986,12288,12289,12290,12291,12292,12293, //12240 + 12294,12295,12296,2473,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,12308, //12256 + 12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,3963,12320,12321,12322,12323, //12272 + 12324,12325,12326,12327,12328,12329,12330,12331,12332,4987,12333,12334,12335,12336,12337,12338, //12288 + 12339,12340,12341,12342,12343,12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354, //12304 + 12355,12356,12357,12358,12359,3964,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369, //12320 + 12370,3965,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384, //12336 + 12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400, //12352 + 12401,12402,12403,12404,12405,12406,12407,12408,4988,12409,12410,12411,12412,12413,12414,12415, //12368 + 12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, //12384 + 12432,12433,12434,12435,12436,12437,12438,3554,12439,12440,12441,12442,12443,12444,12445,12446, //12400 + 12447,12448,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462, //12416 + 12463,12464,4989,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477, //12432 + 12478,12479,12480,4990,12481,12482,12483,12484,12485,12486,12487,12488,12489,4498,12490,12491, //12448 + 12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, //12464 + 12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523, //12480 + 12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12539, //12496 + 12540,12541,12542,12543,12544,12545,12546,12547,12548,12549,12550,12551,4991,12552,12553,12554, //12512 + 12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570, //12528 + 12571,12572,12573,12574,12575,12576,12577,12578,3036,12579,12580,12581,12582,12583,3966,12584, //12544 + 12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,12596,12597,12598,12599,12600, //12560 + 12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616, //12576 + 12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632, //12592 + 12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,4499,12647, //12608 + 12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663, //12624 + 12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679, //12640 + 12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,12692,12693,12694,12695, //12656 + 12696,12697,12698,4992,12699,12700,12701,12702,12703,12704,12705,12706,12707,12708,12709,12710, //12672 + 12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726, //12688 + 12727,12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,12740,12741,12742, //12704 + 12743,12744,12745,12746,12747,12748,12749,12750,12751,12752,12753,12754,12755,12756,12757,12758, //12720 + 12759,12760,12761,12762,12763,12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774, //12736 + 12775,12776,12777,12778,4993,2175,12779,12780,12781,12782,12783,12784,12785,12786,4500,12787, //12752 + 12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,12800,12801,12802,12803, //12768 + 12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819, //12784 + 12820,12821,12822,12823,12824,12825,12826,4198,3967,12827,12828,12829,12830,12831,12832,12833, //12800 + 12834,12835,12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,12848,12849, //12816 + 12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,12860,12861,4199,12862,12863,12864, //12832 + 12865,12866,12867,12868,12869,12870,12871,12872,12873,12874,12875,12876,12877,12878,12879,12880, //12848 + 12881,12882,12883,12884,12885,12886,12887,4501,12888,12889,12890,12891,12892,12893,12894,12895, //12864 + 12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911, //12880 + 12912,4994,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926, //12896 + 12927,12928,12929,12930,12931,12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942, //12912 + 12943,12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,1772,12957, //12928 + 12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,12968,12969,12970,12971,12972,12973, //12944 + 12974,12975,12976,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,12989, //12960 + 12990,12991,12992,12993,12994,12995,12996,12997,4502,12998,4503,12999,13000,13001,13002,13003, //12976 + 4504,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018, //12992 + 13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,3449,13030,13031,13032,13033, //13008 + 13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049, //13024 + 13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065, //13040 + 13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081, //13056 + 13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093,13094,13095,13096,13097, //13072 + 13098,13099,13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,13112,13113, //13088 + 13114,13115,13116,13117,13118,3968,13119,4995,13120,13121,13122,13123,13124,13125,13126,13127, //13104 + 4505,13128,13129,13130,13131,13132,13133,13134,4996,4506,13135,13136,13137,13138,13139,4997, //13120 + 13140,13141,13142,13143,13144,13145,13146,13147,13148,13149,13150,13151,13152,13153,13154,13155, //13136 + 13156,13157,13158,13159,4998,13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170, //13152 + 13171,13172,13173,13174,13175,13176,4999,13177,13178,13179,13180,13181,13182,13183,13184,13185, //13168 + 13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,13196,13197,13198,13199,13200,13201, //13184 + 13202,13203,13204,13205,13206,5000,13207,13208,13209,13210,13211,13212,13213,13214,13215,13216, //13200 + 13217,13218,13219,13220,13221,13222,13223,13224,13225,13226,13227,4200,5001,13228,13229,13230, //13216 + 13231,13232,13233,13234,13235,13236,13237,13238,13239,13240,3969,13241,13242,13243,13244,3970, //13232 + 13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,13256,13257,13258,13259,13260, //13248 + 13261,13262,13263,13264,13265,13266,13267,13268,3450,13269,13270,13271,13272,13273,13274,13275, //13264 + 13276,5002,13277,13278,13279,13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290, //13280 + 13291,13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,3813,13303,13304,13305, //13296 + 13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321, //13312 + 13322,13323,13324,13325,13326,13327,13328,4507,13329,13330,13331,13332,13333,13334,13335,13336, //13328 + 13337,13338,13339,13340,13341,5003,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351, //13344 + 13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367, //13360 + 5004,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382, //13376 + 13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398, //13392 + 13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414, //13408 + 13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430, //13424 + 13431,13432,4508,13433,13434,13435,4201,13436,13437,13438,13439,13440,13441,13442,13443,13444, //13440 + 13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,5005,13458,13459, //13456 + 13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,4509,13471,13472,13473,13474, //13472 + 13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490, //13488 + 13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506, //13504 + 13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522, //13520 + 13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538, //13536 + 13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554, //13552 + 13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570, //13568 + 13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586, //13584 + 13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602, //13600 + 13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618, //13616 + 13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634, //13632 + 13635,13636,13637,13638,13639,13640,13641,13642,5006,13643,13644,13645,13646,13647,13648,13649, //13648 + 13650,13651,5007,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664, //13664 + 13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680, //13680 + 13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696, //13696 + 13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712, //13712 + 13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728, //13728 + 13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744, //13744 + 13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760, //13760 + 13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,3273,13775, //13776 + 13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791, //13792 + 13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807, //13808 + 13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823, //13824 + 13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839, //13840 + 13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855, //13856 + 13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871, //13872 + 13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887, //13888 + 13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903, //13904 + 13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919, //13920 + 13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935, //13936 + 13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951, //13952 + 13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967, //13968 + 13968,13969,13970,13971,13972, //13973 + ****************************************************************************************/ + }; + + public BIG5DistributionAnalyser() + { + charToFreqOrder = BIG5_CHAR2FREQ_ORDER; + tableSize = BIG5_TABLE_SIZE; + typicalDistributionRatio = BIG5_TYPICAL_DISTRIBUTION_RATIO; + } + + /// <summary> + /// first byte range: 0xa4 -- 0xfe + /// second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + /// no validation needed here. State machine has done that + /// </summary> + public override int GetOrder(byte[] buf, int offset) + { + if (buf[offset] >= 0xA4) { + if (buf[offset+1] >= 0xA1) + return 157 * (buf[offset] - 0xA4) + buf[offset+1] - 0xA1 + 63; + else + return 157 * (buf[offset] - 0xA4) + buf[offset+1] - 0x40; + } else { + return -1; + } + } + } + + public class SJISDistributionAnalyser : CharDistributionAnalyser + { + //Sampling from about 20M text materials include literature and computer technology + // Japanese frequency table, applied to both S-JIS and EUC-JP + //They are sorted in order. + + /****************************************************************************** + * 128 --> 0.77094 + * 256 --> 0.85710 + * 512 --> 0.92635 + * 1024 --> 0.97130 + * 2048 --> 0.99431 + * + * Idea Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 + * Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 + * + * Typical Distribution Ratio, 25% of IDR + *****************************************************************************/ + + protected static float SJIS_TYPICAL_DISTRIBUTION_RATIO = 3.0f; + + protected static int SJIS_TABLE_SIZE = 4368; + + protected static int[] SJIS_CHAR2FREQ_ORDER = { + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, // 16 + 3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, // 32 + 1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, // 48 + 2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, // 64 + 2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, // 80 + 5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, // 96 + 1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, // 112 + 5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, // 128 + 5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, // 144 + 5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, // 160 + 5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, // 176 + 5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, // 192 + 5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, // 208 + 1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, // 224 + 1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, // 240 + 1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, // 256 + 2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, // 272 + 3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, // 288 + 3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, // 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, // 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, // 336 + 1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, // 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, // 368 + 5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, // 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, // 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, // 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, // 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, // 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, // 464 + 5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, // 480 + 5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, // 496 + 5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, // 512 + 4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, // 528 + 5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, // 544 + 5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, // 560 + 5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, // 576 + 5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, // 592 + 5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, // 608 + 5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, // 624 + 5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, // 640 + 5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, // 656 + 5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, // 672 + 3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, // 688 + 5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, // 704 + 5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, // 720 + 5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, // 736 + 5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, // 752 + 5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, // 768 + 5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, // 784 + 5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, // 800 + 5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, // 816 + 5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, // 832 + 5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, // 848 + 5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, // 864 + 5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, // 880 + 5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, // 896 + 5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, // 912 + 5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, // 928 + 5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, // 944 + 5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, // 960 + 5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, // 976 + 5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, // 992 + 5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, // 1008 + 5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, // 1024 + 5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, // 1040 + 5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, // 1056 + 5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, // 1072 + 5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, // 1088 + 5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, // 1104 + 5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, // 1120 + 5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, // 1136 + 5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, // 1152 + 5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, // 1168 + 5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, // 1184 + 5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, // 1200 + 5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, // 1216 + 5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, // 1232 + 5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, // 1248 + 5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, // 1264 + 5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, // 1280 + 5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, // 1296 + 6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, // 1312 + 6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, // 1328 + 6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, // 1344 + 6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, // 1360 + 6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, // 1376 + 6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, // 1392 + 6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, // 1408 + 6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, // 1424 + 4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, // 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, // 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, // 1472 + 1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, // 1488 + 1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, // 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, // 1520 + 3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, // 1536 + 3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, // 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, // 1568 + 3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, // 1584 + 3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, // 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, // 1616 + 2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, // 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, // 1648 + 3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, // 1664 + 1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, // 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, // 1696 + 1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, // 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, // 1728 + 2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, // 1744 + 2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, // 1760 + 2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, // 1776 + 2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, // 1792 + 1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, // 1808 + 1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, // 1824 + 1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, // 1840 + 1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, // 1856 + 2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, // 1872 + 1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, // 1888 + 2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, // 1904 + 1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, // 1920 + 1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, // 1936 + 1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, // 1952 + 1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, // 1968 + 1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, // 1984 + 1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, // 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, // 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, // 2032 + 1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, // 2048 + 2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, // 2064 + 2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, // 2080 + 2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, // 2096 + 3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, // 2112 + 3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, // 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, // 2144 + 3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, // 2160 + 1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, // 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, // 2192 + 2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, // 2208 + 1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, // 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, // 2240 + 3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, // 2256 + 4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, // 2272 + 2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, // 2288 + 1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, // 2304 + 2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, // 2320 + 1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, // 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, // 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, // 2368 + 1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, // 2384 + 2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, // 2400 + 2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, // 2416 + 2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, // 2432 + 3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, // 2448 + 1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, // 2464 + 2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, // 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, // 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, // 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, // 2528 + 1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, // 2544 + 2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, // 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, // 2576 + 1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, // 2592 + 1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, // 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, // 2624 + 1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, // 2640 + 1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, // 2656 + 1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, // 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, // 2688 + 2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, // 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, // 2720 + 2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, // 2736 + 3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, // 2752 + 2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, // 2768 + 1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, // 2784 + 6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, // 2800 + 1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, // 2816 + 2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, // 2832 + 1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, // 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, // 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, // 2880 + 3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, // 2896 + 3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, // 2912 + 1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, // 2928 + 1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, // 2944 + 1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, // 2960 + 1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, // 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, // 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, // 3008 + 2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, // 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, // 3040 + 3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, // 3056 + 2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, // 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, // 3088 + 1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, // 3104 + 2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, // 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, // 3136 + 1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, // 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, // 3168 + 4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, // 3184 + 2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, // 3200 + 1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, // 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, // 3232 + 1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, // 3248 + 2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, // 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, // 3280 + 6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, // 3296 + 1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, // 3312 + 1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, // 3328 + 2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, // 3344 + 3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, // 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, // 3376 + 3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, // 3392 + 1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, // 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, // 3424 + 1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, // 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, // 3456 + 3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, // 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, // 3488 + 2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, // 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, // 3520 + 4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, // 3536 + 2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, // 3552 + 1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, // 3568 + 1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, // 3584 + 1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, // 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, // 3616 + 1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, // 3632 + 3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, // 3648 + 1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, // 3664 + 3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, // 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, // 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, // 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, // 3728 + 2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, // 3744 + 1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, // 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, // 3776 + 1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, // 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, // 3808 + 1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, // 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, // 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, // 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, // 3872 + 1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, // 3888 + 1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, // 3904 + 2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, // 3920 + 4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, // 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, // 3952 + 1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, // 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, // 3984 + 1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, // 4000 + 3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, // 4016 + 1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, // 4032 + 2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, // 4048 + 2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, // 4064 + 1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, // 4080 + 1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, // 4096 + 2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, // 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, // 4128 + 2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, // 4144 + 1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, // 4160 + 1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, // 4176 + 1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, // 4192 + 1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, // 4208 + 3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, // 4224 + 2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, // 4240 + 2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, // 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, // 4272 + 3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, // 4288 + 3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, // 4304 + 1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, // 4320 + 2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, // 4336 + 1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, // 4352 + 2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, // 4368 //last 512 + + /*************************************************************************************** + *Everything below is of no interest for detection purpose * + *************************************************************************************** + + 2138,2122,3730,2888,1995,1820,1044,6190,6191,6192,6193,6194,6195,6196,6197,6198, // 4384 + 6199,6200,6201,6202,6203,6204,6205,4670,6206,6207,6208,6209,6210,6211,6212,6213, // 4400 + 6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229, // 4416 + 6230,6231,6232,6233,6234,6235,6236,6237,3187,6238,6239,3969,6240,6241,6242,6243, // 4432 + 6244,4671,6245,6246,4672,6247,6248,4133,6249,6250,4364,6251,2923,2556,2613,4673, // 4448 + 4365,3970,6252,6253,6254,6255,4674,6256,6257,6258,2768,2353,4366,4675,4676,3188, // 4464 + 4367,3463,6259,4134,4677,4678,6260,2267,6261,3842,3332,4368,3543,6262,6263,6264, // 4480 + 3013,1954,1928,4135,4679,6265,6266,2478,3091,6267,4680,4369,6268,6269,1699,6270, // 4496 + 3544,4136,4681,6271,4137,6272,4370,2804,6273,6274,2593,3971,3972,4682,6275,2236, // 4512 + 4683,6276,6277,4684,6278,6279,4138,3973,4685,6280,6281,3258,6282,6283,6284,6285, // 4528 + 3974,4686,2841,3975,6286,6287,3545,6288,6289,4139,4687,4140,6290,4141,6291,4142, // 4544 + 6292,6293,3333,6294,6295,6296,4371,6297,3399,6298,6299,4372,3976,6300,6301,6302, // 4560 + 4373,6303,6304,3843,3731,6305,4688,4374,6306,6307,3259,2294,6308,3732,2530,4143, // 4576 + 6309,4689,6310,6311,6312,3048,6313,6314,4690,3733,2237,6315,6316,2282,3334,6317, // 4592 + 6318,3844,6319,6320,4691,6321,3400,4692,6322,4693,6323,3049,6324,4375,6325,3977, // 4608 + 6326,6327,6328,3546,6329,4694,3335,6330,4695,4696,6331,6332,6333,6334,4376,3978, // 4624 + 6335,4697,3979,4144,6336,3980,4698,6337,6338,6339,6340,6341,4699,4700,4701,6342, // 4640 + 6343,4702,6344,6345,4703,6346,6347,4704,6348,4705,4706,3135,6349,4707,6350,4708, // 4656 + 6351,4377,6352,4709,3734,4145,6353,2506,4710,3189,6354,3050,4711,3981,6355,3547, // 4672 + 3014,4146,4378,3735,2651,3845,3260,3136,2224,1986,6356,3401,6357,4712,2594,3627, // 4688 + 3137,2573,3736,3982,4713,3628,4714,4715,2682,3629,4716,6358,3630,4379,3631,6359, // 4704 + 6360,6361,3983,6362,6363,6364,6365,4147,3846,4717,6366,6367,3737,2842,6368,4718, // 4720 + 2628,6369,3261,6370,2386,6371,6372,3738,3984,4719,3464,4720,3402,6373,2924,3336, // 4736 + 4148,2866,6374,2805,3262,4380,2704,2069,2531,3138,2806,2984,6375,2769,6376,4721, // 4752 + 4722,3403,6377,6378,3548,6379,6380,2705,3092,1979,4149,2629,3337,2889,6381,3338, // 4768 + 4150,2557,3339,4381,6382,3190,3263,3739,6383,4151,4723,4152,2558,2574,3404,3191, // 4784 + 6384,6385,4153,6386,4724,4382,6387,6388,4383,6389,6390,4154,6391,4725,3985,6392, // 4800 + 3847,4155,6393,6394,6395,6396,6397,3465,6398,4384,6399,6400,6401,6402,6403,6404, // 4816 + 4156,6405,6406,6407,6408,2123,6409,6410,2326,3192,4726,6411,6412,6413,6414,4385, // 4832 + 4157,6415,6416,4158,6417,3093,3848,6418,3986,6419,6420,3849,6421,6422,6423,4159, // 4848 + 6424,6425,4160,6426,3740,6427,6428,6429,6430,3987,6431,4727,6432,2238,6433,6434, // 4864 + 4386,3988,6435,6436,3632,6437,6438,2843,6439,6440,6441,6442,3633,6443,2958,6444, // 4880 + 6445,3466,6446,2364,4387,3850,6447,4388,2959,3340,6448,3851,6449,4728,6450,6451, // 4896 + 3264,4729,6452,3193,6453,4389,4390,2706,3341,4730,6454,3139,6455,3194,6456,3051, // 4912 + 2124,3852,1602,4391,4161,3853,1158,3854,4162,3989,4392,3990,4731,4732,4393,2040, // 4928 + 4163,4394,3265,6457,2807,3467,3855,6458,6459,6460,3991,3468,4733,4734,6461,3140, // 4944 + 2960,6462,4735,6463,6464,6465,6466,4736,4737,4738,4739,6467,6468,4164,2403,3856, // 4960 + 6469,6470,2770,2844,6471,4740,6472,6473,6474,6475,6476,6477,6478,3195,6479,4741, // 4976 + 4395,6480,2867,6481,4742,2808,6482,2493,4165,6483,6484,6485,6486,2295,4743,6487, // 4992 + 6488,6489,3634,6490,6491,6492,6493,6494,6495,6496,2985,4744,6497,6498,4745,6499, // 5008 + 6500,2925,3141,4166,6501,6502,4746,6503,6504,4747,6505,6506,6507,2890,6508,6509, // 5024 + 6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,3469,4167,6520,6521,6522,4748, // 5040 + 4396,3741,4397,4749,4398,3342,2125,4750,6523,4751,4752,4753,3052,6524,2961,4168, // 5056 + 6525,4754,6526,4755,4399,2926,4169,6527,3857,6528,4400,4170,6529,4171,6530,6531, // 5072 + 2595,6532,6533,6534,6535,3635,6536,6537,6538,6539,6540,6541,6542,4756,6543,6544, // 5088 + 6545,6546,6547,6548,4401,6549,6550,6551,6552,4402,3405,4757,4403,6553,6554,6555, // 5104 + 4172,3742,6556,6557,6558,3992,3636,6559,6560,3053,2726,6561,3549,4173,3054,4404, // 5120 + 6562,6563,3993,4405,3266,3550,2809,4406,6564,6565,6566,4758,4759,6567,3743,6568, // 5136 + 4760,3744,4761,3470,6569,6570,6571,4407,6572,3745,4174,6573,4175,2810,4176,3196, // 5152 + 4762,6574,4177,6575,6576,2494,2891,3551,6577,6578,3471,6579,4408,6580,3015,3197, // 5168 + 6581,3343,2532,3994,3858,6582,3094,3406,4409,6583,2892,4178,4763,4410,3016,4411, // 5184 + 6584,3995,3142,3017,2683,6585,4179,6586,6587,4764,4412,6588,6589,4413,6590,2986, // 5200 + 6591,2962,3552,6592,2963,3472,6593,6594,4180,4765,6595,6596,2225,3267,4414,6597, // 5216 + 3407,3637,4766,6598,6599,3198,6600,4415,6601,3859,3199,6602,3473,4767,2811,4416, // 5232 + 1856,3268,3200,2575,3996,3997,3201,4417,6603,3095,2927,6604,3143,6605,2268,6606, // 5248 + 3998,3860,3096,2771,6607,6608,3638,2495,4768,6609,3861,6610,3269,2745,4769,4181, // 5264 + 3553,6611,2845,3270,6612,6613,6614,3862,6615,6616,4770,4771,6617,3474,3999,4418, // 5280 + 4419,6618,3639,3344,6619,4772,4182,6620,2126,6621,6622,6623,4420,4773,6624,3018, // 5296 + 6625,4774,3554,6626,4183,2025,3746,6627,4184,2707,6628,4421,4422,3097,1775,4185, // 5312 + 3555,6629,6630,2868,6631,6632,4423,6633,6634,4424,2414,2533,2928,6635,4186,2387, // 5328 + 6636,4775,6637,4187,6638,1891,4425,3202,3203,6639,6640,4776,6641,3345,6642,6643, // 5344 + 3640,6644,3475,3346,3641,4000,6645,3144,6646,3098,2812,4188,3642,3204,6647,3863, // 5360 + 3476,6648,3864,6649,4426,4001,6650,6651,6652,2576,6653,4189,4777,6654,6655,6656, // 5376 + 2846,6657,3477,3205,4002,6658,4003,6659,3347,2252,6660,6661,6662,4778,6663,6664, // 5392 + 6665,6666,6667,6668,6669,4779,4780,2048,6670,3478,3099,6671,3556,3747,4004,6672, // 5408 + 6673,6674,3145,4005,3748,6675,6676,6677,6678,6679,3408,6680,6681,6682,6683,3206, // 5424 + 3207,6684,6685,4781,4427,6686,4782,4783,4784,6687,6688,6689,4190,6690,6691,3479, // 5440 + 6692,2746,6693,4428,6694,6695,6696,6697,6698,6699,4785,6700,6701,3208,2727,6702, // 5456 + 3146,6703,6704,3409,2196,6705,4429,6706,6707,6708,2534,1996,6709,6710,6711,2747, // 5472 + 6712,6713,6714,4786,3643,6715,4430,4431,6716,3557,6717,4432,4433,6718,6719,6720, // 5488 + 6721,3749,6722,4006,4787,6723,6724,3644,4788,4434,6725,6726,4789,2772,6727,6728, // 5504 + 6729,6730,6731,2708,3865,2813,4435,6732,6733,4790,4791,3480,6734,6735,6736,6737, // 5520 + 4436,3348,6738,3410,4007,6739,6740,4008,6741,6742,4792,3411,4191,6743,6744,6745, // 5536 + 6746,6747,3866,6748,3750,6749,6750,6751,6752,6753,6754,6755,3867,6756,4009,6757, // 5552 + 4793,4794,6758,2814,2987,6759,6760,6761,4437,6762,6763,6764,6765,3645,6766,6767, // 5568 + 3481,4192,6768,3751,6769,6770,2174,6771,3868,3752,6772,6773,6774,4193,4795,4438, // 5584 + 3558,4796,4439,6775,4797,6776,6777,4798,6778,4799,3559,4800,6779,6780,6781,3482, // 5600 + 6782,2893,6783,6784,4194,4801,4010,6785,6786,4440,6787,4011,6788,6789,6790,6791, // 5616 + 6792,6793,4802,6794,6795,6796,4012,6797,6798,6799,6800,3349,4803,3483,6801,4804, // 5632 + 4195,6802,4013,6803,6804,4196,6805,4014,4015,6806,2847,3271,2848,6807,3484,6808, // 5648 + 6809,6810,4441,6811,4442,4197,4443,3272,4805,6812,3412,4016,1579,6813,6814,4017, // 5664 + 6815,3869,6816,2964,6817,4806,6818,6819,4018,3646,6820,6821,4807,4019,4020,6822, // 5680 + 6823,3560,6824,6825,4021,4444,6826,4198,6827,6828,4445,6829,6830,4199,4808,6831, // 5696 + 6832,6833,3870,3019,2458,6834,3753,3413,3350,6835,4809,3871,4810,3561,4446,6836, // 5712 + 6837,4447,4811,4812,6838,2459,4448,6839,4449,6840,6841,4022,3872,6842,4813,4814, // 5728 + 6843,6844,4815,4200,4201,4202,6845,4023,6846,6847,4450,3562,3873,6848,6849,4816, // 5744 + 4817,6850,4451,4818,2139,6851,3563,6852,6853,3351,6854,6855,3352,4024,2709,3414, // 5760 + 4203,4452,6856,4204,6857,6858,3874,3875,6859,6860,4819,6861,6862,6863,6864,4453, // 5776 + 3647,6865,6866,4820,6867,6868,6869,6870,4454,6871,2869,6872,6873,4821,6874,3754, // 5792 + 6875,4822,4205,6876,6877,6878,3648,4206,4455,6879,4823,6880,4824,3876,6881,3055, // 5808 + 4207,6882,3415,6883,6884,6885,4208,4209,6886,4210,3353,6887,3354,3564,3209,3485, // 5824 + 2652,6888,2728,6889,3210,3755,6890,4025,4456,6891,4825,6892,6893,6894,6895,4211, // 5840 + 6896,6897,6898,4826,6899,6900,4212,6901,4827,6902,2773,3565,6903,4828,6904,6905, // 5856 + 6906,6907,3649,3650,6908,2849,3566,6909,3567,3100,6910,6911,6912,6913,6914,6915, // 5872 + 4026,6916,3355,4829,3056,4457,3756,6917,3651,6918,4213,3652,2870,6919,4458,6920, // 5888 + 2438,6921,6922,3757,2774,4830,6923,3356,4831,4832,6924,4833,4459,3653,2507,6925, // 5904 + 4834,2535,6926,6927,3273,4027,3147,6928,3568,6929,6930,6931,4460,6932,3877,4461, // 5920 + 2729,3654,6933,6934,6935,6936,2175,4835,2630,4214,4028,4462,4836,4215,6937,3148, // 5936 + 4216,4463,4837,4838,4217,6938,6939,2850,4839,6940,4464,6941,6942,6943,4840,6944, // 5952 + 4218,3274,4465,6945,6946,2710,6947,4841,4466,6948,6949,2894,6950,6951,4842,6952, // 5968 + 4219,3057,2871,6953,6954,6955,6956,4467,6957,2711,6958,6959,6960,3275,3101,4843, // 5984 + 6961,3357,3569,6962,4844,6963,6964,4468,4845,3570,6965,3102,4846,3758,6966,4847, // 6000 + 3878,4848,4849,4029,6967,2929,3879,4850,4851,6968,6969,1733,6970,4220,6971,6972, // 6016 + 6973,6974,6975,6976,4852,6977,6978,6979,6980,6981,6982,3759,6983,6984,6985,3486, // 6032 + 3487,6986,3488,3416,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,4853, // 6048 + 6998,6999,4030,7000,7001,3211,7002,7003,4221,7004,7005,3571,4031,7006,3572,7007, // 6064 + 2614,4854,2577,7008,7009,2965,3655,3656,4855,2775,3489,3880,4222,4856,3881,4032, // 6080 + 3882,3657,2730,3490,4857,7010,3149,7011,4469,4858,2496,3491,4859,2283,7012,7013, // 6096 + 7014,2365,4860,4470,7015,7016,3760,7017,7018,4223,1917,7019,7020,7021,4471,7022, // 6112 + 2776,4472,7023,7024,7025,7026,4033,7027,3573,4224,4861,4034,4862,7028,7029,1929, // 6128 + 3883,4035,7030,4473,3058,7031,2536,3761,3884,7032,4036,7033,2966,2895,1968,4474, // 6144 + 3276,4225,3417,3492,4226,2105,7034,7035,1754,2596,3762,4227,4863,4475,3763,4864, // 6160 + 3764,2615,2777,3103,3765,3658,3418,4865,2296,3766,2815,7036,7037,7038,3574,2872, // 6176 + 3277,4476,7039,4037,4477,7040,7041,4038,7042,7043,7044,7045,7046,7047,2537,7048, // 6192 + 7049,7050,7051,7052,7053,7054,4478,7055,7056,3767,3659,4228,3575,7057,7058,4229, // 6208 + 7059,7060,7061,3660,7062,3212,7063,3885,4039,2460,7064,7065,7066,7067,7068,7069, // 6224 + 7070,7071,7072,7073,7074,4866,3768,4867,7075,7076,7077,7078,4868,3358,3278,2653, // 6240 + 7079,7080,4479,3886,7081,7082,4869,7083,7084,7085,7086,7087,7088,2538,7089,7090, // 6256 + 7091,4040,3150,3769,4870,4041,2896,3359,4230,2930,7092,3279,7093,2967,4480,3213, // 6272 + 4481,3661,7094,7095,7096,7097,7098,7099,7100,7101,7102,2461,3770,7103,7104,4231, // 6288 + 3151,7105,7106,7107,4042,3662,7108,7109,4871,3663,4872,4043,3059,7110,7111,7112, // 6304 + 3493,2988,7113,4873,7114,7115,7116,3771,4874,7117,7118,4232,4875,7119,3576,2336, // 6320 + 4876,7120,4233,3419,4044,4877,4878,4482,4483,4879,4484,4234,7121,3772,4880,1045, // 6336 + 3280,3664,4881,4882,7122,7123,7124,7125,4883,7126,2778,7127,4485,4486,7128,4884, // 6352 + 3214,3887,7129,7130,3215,7131,4885,4045,7132,7133,4046,7134,7135,7136,7137,7138, // 6368 + 7139,7140,7141,7142,7143,4235,7144,4886,7145,7146,7147,4887,7148,7149,7150,4487, // 6384 + 4047,4488,7151,7152,4888,4048,2989,3888,7153,3665,7154,4049,7155,7156,7157,7158, // 6400 + 7159,7160,2931,4889,4890,4489,7161,2631,3889,4236,2779,7162,7163,4891,7164,3060, // 6416 + 7165,1672,4892,7166,4893,4237,3281,4894,7167,7168,3666,7169,3494,7170,7171,4050, // 6432 + 7172,7173,3104,3360,3420,4490,4051,2684,4052,7174,4053,7175,7176,7177,2253,4054, // 6448 + 7178,7179,4895,7180,3152,3890,3153,4491,3216,7181,7182,7183,2968,4238,4492,4055, // 6464 + 7184,2990,7185,2479,7186,7187,4493,7188,7189,7190,7191,7192,4896,7193,4897,2969, // 6480 + 4494,4898,7194,3495,7195,7196,4899,4495,7197,3105,2731,7198,4900,7199,7200,7201, // 6496 + 4056,7202,3361,7203,7204,4496,4901,4902,7205,4497,7206,7207,2315,4903,7208,4904, // 6512 + 7209,4905,2851,7210,7211,3577,7212,3578,4906,7213,4057,3667,4907,7214,4058,2354, // 6528 + 3891,2376,3217,3773,7215,7216,7217,7218,7219,4498,7220,4908,3282,2685,7221,3496, // 6544 + 4909,2632,3154,4910,7222,2337,7223,4911,7224,7225,7226,4912,4913,3283,4239,4499, // 6560 + 7227,2816,7228,7229,7230,7231,7232,7233,7234,4914,4500,4501,7235,7236,7237,2686, // 6576 + 7238,4915,7239,2897,4502,7240,4503,7241,2516,7242,4504,3362,3218,7243,7244,7245, // 6592 + 4916,7246,7247,4505,3363,7248,7249,7250,7251,3774,4506,7252,7253,4917,7254,7255, // 6608 + 3284,2991,4918,4919,3219,3892,4920,3106,3497,4921,7256,7257,7258,4922,7259,4923, // 6624 + 3364,4507,4508,4059,7260,4240,3498,7261,7262,4924,7263,2992,3893,4060,3220,7264, // 6640 + 7265,7266,7267,7268,7269,4509,3775,7270,2817,7271,4061,4925,4510,3776,7272,4241, // 6656 + 4511,3285,7273,7274,3499,7275,7276,7277,4062,4512,4926,7278,3107,3894,7279,7280, // 6672 + 4927,7281,4513,7282,7283,3668,7284,7285,4242,4514,4243,7286,2058,4515,4928,4929, // 6688 + 4516,7287,3286,4244,7288,4517,7289,7290,7291,3669,7292,7293,4930,4931,4932,2355, // 6704 + 4933,7294,2633,4518,7295,4245,7296,7297,4519,7298,7299,4520,4521,4934,7300,4246, // 6720 + 4522,7301,7302,7303,3579,7304,4247,4935,7305,4936,7306,7307,7308,7309,3777,7310, // 6736 + 4523,7311,7312,7313,4248,3580,7314,4524,3778,4249,7315,3581,7316,3287,7317,3221, // 6752 + 7318,4937,7319,7320,7321,7322,7323,7324,4938,4939,7325,4525,7326,7327,7328,4063, // 6768 + 7329,7330,4940,7331,7332,4941,7333,4526,7334,3500,2780,1741,4942,2026,1742,7335, // 6784 + 7336,3582,4527,2388,7337,7338,7339,4528,7340,4250,4943,7341,7342,7343,4944,7344, // 6800 + 7345,7346,3020,7347,4945,7348,7349,7350,7351,3895,7352,3896,4064,3897,7353,7354, // 6816 + 7355,4251,7356,7357,3898,7358,3779,7359,3780,3288,7360,7361,4529,7362,4946,4530, // 6832 + 2027,7363,3899,4531,4947,3222,3583,7364,4948,7365,7366,7367,7368,4949,3501,4950, // 6848 + 3781,4951,4532,7369,2517,4952,4252,4953,3155,7370,4954,4955,4253,2518,4533,7371, // 6864 + 7372,2712,4254,7373,7374,7375,3670,4956,3671,7376,2389,3502,4065,7377,2338,7378, // 6880 + 7379,7380,7381,3061,7382,4957,7383,7384,7385,7386,4958,4534,7387,7388,2993,7389, // 6896 + 3062,7390,4959,7391,7392,7393,4960,3108,4961,7394,4535,7395,4962,3421,4536,7396, // 6912 + 4963,7397,4964,1857,7398,4965,7399,7400,2176,3584,4966,7401,7402,3422,4537,3900, // 6928 + 3585,7403,3782,7404,2852,7405,7406,7407,4538,3783,2654,3423,4967,4539,7408,3784, // 6944 + 3586,2853,4540,4541,7409,3901,7410,3902,7411,7412,3785,3109,2327,3903,7413,7414, // 6960 + 2970,4066,2932,7415,7416,7417,3904,3672,3424,7418,4542,4543,4544,7419,4968,7420, // 6976 + 7421,4255,7422,7423,7424,7425,7426,4067,7427,3673,3365,4545,7428,3110,2559,3674, // 6992 + 7429,7430,3156,7431,7432,3503,7433,3425,4546,7434,3063,2873,7435,3223,4969,4547, // 7008 + 4548,2898,4256,4068,7436,4069,3587,3786,2933,3787,4257,4970,4971,3788,7437,4972, // 7024 + 3064,7438,4549,7439,7440,7441,7442,7443,4973,3905,7444,2874,7445,7446,7447,7448, // 7040 + 3021,7449,4550,3906,3588,4974,7450,7451,3789,3675,7452,2578,7453,4070,7454,7455, // 7056 + 7456,4258,3676,7457,4975,7458,4976,4259,3790,3504,2634,4977,3677,4551,4260,7459, // 7072 + 7460,7461,7462,3907,4261,4978,7463,7464,7465,7466,4979,4980,7467,7468,2213,4262, // 7088 + 7469,7470,7471,3678,4981,7472,2439,7473,4263,3224,3289,7474,3908,2415,4982,7475, // 7104 + 4264,7476,4983,2655,7477,7478,2732,4552,2854,2875,7479,7480,4265,7481,4553,4984, // 7120 + 7482,7483,4266,7484,3679,3366,3680,2818,2781,2782,3367,3589,4554,3065,7485,4071, // 7136 + 2899,7486,7487,3157,2462,4072,4555,4073,4985,4986,3111,4267,2687,3368,4556,4074, // 7152 + 3791,4268,7488,3909,2783,7489,2656,1962,3158,4557,4987,1963,3159,3160,7490,3112, // 7168 + 4988,4989,3022,4990,4991,3792,2855,7491,7492,2971,4558,7493,7494,4992,7495,7496, // 7184 + 7497,7498,4993,7499,3426,4559,4994,7500,3681,4560,4269,4270,3910,7501,4075,4995, // 7200 + 4271,7502,7503,4076,7504,4996,7505,3225,4997,4272,4077,2819,3023,7506,7507,2733, // 7216 + 4561,7508,4562,7509,3369,3793,7510,3590,2508,7511,7512,4273,3113,2994,2616,7513, // 7232 + 7514,7515,7516,7517,7518,2820,3911,4078,2748,7519,7520,4563,4998,7521,7522,7523, // 7248 + 7524,4999,4274,7525,4564,3682,2239,4079,4565,7526,7527,7528,7529,5000,7530,7531, // 7264 + 5001,4275,3794,7532,7533,7534,3066,5002,4566,3161,7535,7536,4080,7537,3162,7538, // 7280 + 7539,4567,7540,7541,7542,7543,7544,7545,5003,7546,4568,7547,7548,7549,7550,7551, // 7296 + 7552,7553,7554,7555,7556,5004,7557,7558,7559,5005,7560,3795,7561,4569,7562,7563, // 7312 + 7564,2821,3796,4276,4277,4081,7565,2876,7566,5006,7567,7568,2900,7569,3797,3912, // 7328 + 7570,7571,7572,4278,7573,7574,7575,5007,7576,7577,5008,7578,7579,4279,2934,7580, // 7344 + 7581,5009,7582,4570,7583,4280,7584,7585,7586,4571,4572,3913,7587,4573,3505,7588, // 7360 + 5010,7589,7590,7591,7592,3798,4574,7593,7594,5011,7595,4281,7596,7597,7598,4282, // 7376 + 5012,7599,7600,5013,3163,7601,5014,7602,3914,7603,7604,2734,4575,4576,4577,7605, // 7392 + 7606,7607,7608,7609,3506,5015,4578,7610,4082,7611,2822,2901,2579,3683,3024,4579, // 7408 + 3507,7612,4580,7613,3226,3799,5016,7614,7615,7616,7617,7618,7619,7620,2995,3290, // 7424 + 7621,4083,7622,5017,7623,7624,7625,7626,7627,4581,3915,7628,3291,7629,5018,7630, // 7440 + 7631,7632,7633,4084,7634,7635,3427,3800,7636,7637,4582,7638,5019,4583,5020,7639, // 7456 + 3916,7640,3801,5021,4584,4283,7641,7642,3428,3591,2269,7643,2617,7644,4585,3592, // 7472 + 7645,4586,2902,7646,7647,3227,5022,7648,4587,7649,4284,7650,7651,7652,4588,2284, // 7488 + 7653,5023,7654,7655,7656,4589,5024,3802,7657,7658,5025,3508,4590,7659,7660,7661, // 7504 + 1969,5026,7662,7663,3684,1821,2688,7664,2028,2509,4285,7665,2823,1841,7666,2689, // 7520 + 3114,7667,3917,4085,2160,5027,5028,2972,7668,5029,7669,7670,7671,3593,4086,7672, // 7536 + 4591,4087,5030,3803,7673,7674,7675,7676,7677,7678,7679,4286,2366,4592,4593,3067, // 7552 + 2328,7680,7681,4594,3594,3918,2029,4287,7682,5031,3919,3370,4288,4595,2856,7683, // 7568 + 3509,7684,7685,5032,5033,7686,7687,3804,2784,7688,7689,7690,7691,3371,7692,7693, // 7584 + 2877,5034,7694,7695,3920,4289,4088,7696,7697,7698,5035,7699,5036,4290,5037,5038, // 7600 + 5039,7700,7701,7702,5040,5041,3228,7703,1760,7704,5042,3229,4596,2106,4089,7705, // 7616 + 4597,2824,5043,2107,3372,7706,4291,4090,5044,7707,4091,7708,5045,3025,3805,4598, // 7632 + 4292,4293,4294,3373,7709,4599,7710,5046,7711,7712,5047,5048,3806,7713,7714,7715, // 7648 + 5049,7716,7717,7718,7719,4600,5050,7720,7721,7722,5051,7723,4295,3429,7724,7725, // 7664 + 7726,7727,3921,7728,3292,5052,4092,7729,7730,7731,7732,7733,7734,7735,5053,5054, // 7680 + 7736,7737,7738,7739,3922,3685,7740,7741,7742,7743,2635,5055,7744,5056,4601,7745, // 7696 + 7746,2560,7747,7748,7749,7750,3923,7751,7752,7753,7754,7755,4296,2903,7756,7757, // 7712 + 7758,7759,7760,3924,7761,5057,4297,7762,7763,5058,4298,7764,4093,7765,7766,5059, // 7728 + 3925,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,3595,7777,4299,5060,4094, // 7744 + 7778,3293,5061,7779,7780,4300,7781,7782,4602,7783,3596,7784,7785,3430,2367,7786, // 7760 + 3164,5062,5063,4301,7787,7788,4095,5064,5065,7789,3374,3115,7790,7791,7792,7793, // 7776 + 7794,7795,7796,3597,4603,7797,7798,3686,3116,3807,5066,7799,7800,5067,7801,7802, // 7792 + 4604,4302,5068,4303,4096,7803,7804,3294,7805,7806,5069,4605,2690,7807,3026,7808, // 7808 + 7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824, // 7824 + 7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7840 + 7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856, // 7856 + 7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872, // 7872 + 7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888, // 7888 + 7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904, // 7904 + 7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920, // 7920 + 7921,7922,7923,7924,3926,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, // 7936 + 7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, // 7952 + 7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, // 7968 + 7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, // 7984 + 7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, // 8000 + 8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, // 8016 + 8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, // 8032 + 8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, // 8048 + 8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, // 8064 + 8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, // 8080 + 8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, // 8096 + 8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, // 8112 + 8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, // 8128 + 8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, // 8144 + 8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, // 8160 + 8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, // 8176 + 8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, // 8192 + 8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, // 8208 + 8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, // 8224 + 8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, // 8240 + 8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, // 8256 + 8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, // 8272 + ****************************************************************************************/ + }; + public SJISDistributionAnalyser() + { + charToFreqOrder = SJIS_CHAR2FREQ_ORDER; + tableSize = SJIS_TABLE_SIZE; + typicalDistributionRatio = SJIS_TYPICAL_DISTRIBUTION_RATIO; + } + + /// <summary> + /// first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + /// second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + /// no validation needed here. State machine has done that + /// </summary> + public override int GetOrder(byte[] buf, int offset) + { + int order = 0; + + if (buf[offset] >= 0x81 && buf[offset] <= 0x9F) + order = 188 * (buf[offset] - 0x81); + else if (buf[offset] >= 0xE0 && buf[offset] <= 0xEF) + order = 188 * (buf[offset] - 0xE0 + 31); + else + return -1; + order += buf[offset+1] - 0x40; + + if (buf[offset+1] > 0x7F) + order--; + return order; + } + } + + public class EUCJPDistributionAnalyser : SJISDistributionAnalyser + { + public EUCJPDistributionAnalyser() : base() + { + } + + /// <summary> + /// first byte range: 0xa0 -- 0xfe + /// second byte range: 0xa1 -- 0xfe + /// no validation needed here. State machine has done that + /// </summary> + public override int GetOrder(byte[] buf, int offset) + { + if (buf[offset] >= 0xA0) + return 94 * (buf[offset] - 0xA1) + buf[offset+1] - 0xA1; + else + return -1; + } + } + + +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CharsetProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CharsetProber.cs new file mode 100644 index 000000000..3369dd430 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CharsetProber.cs @@ -0,0 +1,191 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System.IO; + +namespace UniversalDetector.Core +{ + public enum ProbingState { + Detecting = 0, // no sure answer yet, but caller can ask for confidence + FoundIt = 1, // positive answer + NotMe = 2 // negative answer + }; + + public abstract class CharsetProber + { + protected const float SHORTCUT_THRESHOLD = 0.95F; + + protected ProbingState state; + + // ASCII codes + private const byte SPACE = 0x20; + private const byte CAPITAL_A = 0x41; + private const byte CAPITAL_Z = 0x5A; + private const byte SMALL_A = 0x61; + private const byte SMALL_Z = 0x7A; + private const byte LESS_THAN = 0x3C; + private const byte GREATER_THAN = 0x3E; + + /// <summary> + /// Feed data to the prober + /// </summary> + /// <param name="buf">a buffer</param> + /// <param name="offset">offset into buffer</param> + /// <param name="len">number of bytes available into buffer</param> + /// <returns> + /// A <see cref="ProbingState"/> + /// </returns> + public abstract ProbingState HandleData(byte[] buf, int offset, int len); + + /// <summary> + /// Reset prober state + /// </summary> + public abstract void Reset(); + + public abstract string GetCharsetName(); + + public abstract float GetConfidence(); + + public virtual ProbingState GetState() + { + return state; + } + + public virtual void SetOption() + { + + } + + public virtual void DumpStatus() + { + + } + + // + // Helper functions used in the Latin1 and Group probers + // + /// <summary> + /// + /// </summary> + /// <returns>filtered buffer</returns> + protected static byte[] FilterWithoutEnglishLetters(byte[] buf, int offset, int len) + { + byte[] result = null; + + using (MemoryStream ms = new MemoryStream(buf.Length)) { + + bool meetMSB = false; + int max = offset + len; + int prev = offset; + int cur = offset; + + while (cur < max) { + byte b = buf[cur]; + + if ((b & 0x80) != 0) { + meetMSB = true; + } else if (b < CAPITAL_A || (b > CAPITAL_Z && b < SMALL_A) + || b > SMALL_Z) { + if (meetMSB && cur > prev) { + ms.Write(buf, prev, cur - prev); + ms.WriteByte(SPACE); + meetMSB = false; + } + prev = cur + 1; + } + cur++; + } + + if (meetMSB && cur > prev) + ms.Write(buf, prev, cur - prev); + ms.SetLength(ms.Position); + result = ms.ToArray(); + } + return result; + } + + /// <summary> + /// Do filtering to reduce load to probers (Remove ASCII symbols, + /// collapse spaces). This filter applies to all scripts which contain + /// both English characters and upper ASCII characters. + /// </summary> + /// <returns>a filtered copy of the input buffer</returns> + protected static byte[] FilterWithEnglishLetters(byte[] buf, int offset, int len) + { + byte[] result = null; + + using (MemoryStream ms = new MemoryStream(buf.Length)) { + + bool inTag = false; + int max = offset + len; + int prev = offset; + int cur = offset; + + while (cur < max) { + + byte b = buf[cur]; + + if (b == GREATER_THAN) + inTag = false; + else if (b == LESS_THAN) + inTag = true; + + // it's ascii, but it's not a letter + if ((b & 0x80) == 0 && (b < CAPITAL_A || b > SMALL_Z + || (b > CAPITAL_Z && b < SMALL_A))) { + if (cur > prev && !inTag) { + ms.Write(buf, prev, cur - prev); + ms.WriteByte(SPACE); + } + prev = cur + 1; + } + cur++; + } + + // If the current segment contains more than just a symbol + // and it is not inside a tag then keep it. + if (!inTag && cur > prev) + ms.Write(buf, prev, cur - prev); + ms.SetLength(ms.Position); + result = ms.ToArray(); + } + return result; + } + } +} + diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Charsets.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Charsets.cs new file mode 100644 index 000000000..a7c1be92a --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Charsets.cs @@ -0,0 +1,149 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public static class Charsets + { + public const string ASCII = "ASCII"; + + public const string UTF8 = "UTF-8"; + + public const string UTF16_LE = "UTF-16LE"; + + public const string UTF16_BE = "UTF-16BE"; + + public const string UTF32_BE = "UTF-32BE"; + + public const string UTF32_LE = "UTF-32LE"; + + /// <summary> + /// Unusual BOM (3412 order) + /// </summary> + public const string UCS4_3412 = "X-ISO-10646-UCS-4-3412"; + + /// <summary> + /// Unusual BOM (2413 order) + /// </summary> + public const string UCS4_2413 = "X-ISO-10646-UCS-4-2413"; + + /// <summary> + /// Cyrillic (based on bulgarian and russian data) + /// </summary> + public const string WIN1251 = "windows-1251"; + + /// <summary> + /// Latin-1, almost identical to ISO-8859-1 + /// </summary> + public const string WIN1252 = "windows-1252"; + + /// <summary> + /// Greek + /// </summary> + public const string WIN1253 = "windows-1253"; + + /// <summary> + /// Logical hebrew (includes ISO-8859-8-I and most of x-mac-hebrew) + /// </summary> + public const string WIN1255 = "windows-1255"; + + /// <summary> + /// Traditional chinese + /// </summary> + public const string BIG5 = "Big-5"; + + public const string EUCKR = "EUC-KR"; + + public const string EUCJP = "EUC-JP"; + + public const string EUCTW = "EUC-TW"; + + /// <summary> + /// Note: gb2312 is a subset of gb18030 + /// </summary> + public const string GB18030 = "gb18030"; + + public const string ISO2022_JP = "ISO-2022-JP"; + + public const string ISO2022_CN = "ISO-2022-CN"; + + public const string ISO2022_KR = "ISO-2022-KR"; + + /// <summary> + /// Simplified chinese + /// </summary> + public const string HZ_GB_2312 = "HZ-GB-2312"; + + public const string SHIFT_JIS = "Shift-JIS"; + + public const string MAC_CYRILLIC = "x-mac-cyrillic"; + + public const string KOI8R = "KOI8-R"; + + public const string IBM855 = "IBM855"; + + public const string IBM866 = "IBM866"; + + /// <summary> + /// East-Europe. Disabled because too similar to windows-1252 + /// (latin-1). Should use tri-grams models to discriminate between + /// these two charsets. + /// </summary> + public const string ISO8859_2 = "ISO-8859-2"; + + /// <summary> + /// Cyrillic + /// </summary> + public const string ISO8859_5 = "ISO-8859-5"; + + /// <summary> + /// Greek + /// </summary> + public const string ISO_8859_7 = "ISO-8859-7"; + + /// <summary> + /// Visual Hebrew + /// </summary> + public const string ISO8859_8 = "ISO-8859-8"; + + /// <summary> + /// Thai. This recognizer is not enabled yet. + /// </summary> + public const string TIS620 = "TIS620"; + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CodingStateMachine.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CodingStateMachine.cs new file mode 100644 index 000000000..f837dd966 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/CodingStateMachine.cs @@ -0,0 +1,90 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Kohei TAKETA <k-tak@void.in> (Java port) + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + /// <summary> + /// Parallel state machine for the Coding Scheme Method + /// </summary> + public class CodingStateMachine + { + private int currentState; + private SMModel model; + private int currentCharLen; + private int currentBytePos; + + public CodingStateMachine(SMModel model) + { + this.currentState = SMModel.START; + this.model = model; + } + + public int NextState(byte b) + { + // for each byte we get its class, if it is first byte, + // we also get byte length + int byteCls = model.GetClass(b); + if (currentState == SMModel.START) { + currentBytePos = 0; + currentCharLen = model.charLenTable[byteCls]; + } + + // from byte's class and stateTable, we get its next state + currentState = model.stateTable.Unpack( + currentState * model.ClassFactor + byteCls); + currentBytePos++; + return currentState; + } + + public void Reset() + { + currentState = SMModel.START; + } + + public int CurrentCharLen + { + get { return currentCharLen; } + } + + public string ModelName + { + get { return model.Name; } + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCJPProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCJPProber.cs new file mode 100644 index 000000000..050a9d9ce --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCJPProber.cs @@ -0,0 +1,110 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class EUCJPProber : CharsetProber + { + private CodingStateMachine codingSM; + private EUCJPContextAnalyser contextAnalyser; + private EUCJPDistributionAnalyser distributionAnalyser; + private byte[] lastChar = new byte[2]; + + public EUCJPProber() + { + codingSM = new CodingStateMachine(new EUCJPSMModel()); + distributionAnalyser = new EUCJPDistributionAnalyser(); + contextAnalyser = new EUCJPContextAnalyser(); + Reset(); + } + + public override string GetCharsetName() + { + return "EUC-JP"; + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int codingState; + int max = offset + len; + + for (int i = offset; i < max; i++) { + codingState = codingSM.NextState(buf[i]); + if (codingState == SMModel.ERROR) { + state = ProbingState.NotMe; + break; + } + if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + break; + } + if (codingState == SMModel.START) { + int charLen = codingSM.CurrentCharLen; + if (i == offset) { + lastChar[1] = buf[offset]; + contextAnalyser.HandleOneChar(lastChar, 0, charLen); + distributionAnalyser.HandleOneChar(lastChar, 0, charLen); + } else { + contextAnalyser.HandleOneChar(buf, i-1, charLen); + distributionAnalyser.HandleOneChar(buf, i-1, charLen); + } + } + } + lastChar[0] = buf[max-1]; + if (state == ProbingState.Detecting) + if (contextAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + return state; + } + + public override void Reset() + { + codingSM.Reset(); + state = ProbingState.Detecting; + contextAnalyser.Reset(); + distributionAnalyser.Reset(); + } + + public override float GetConfidence() + { + float contxtCf = contextAnalyser.GetConfidence(); + float distribCf = distributionAnalyser.GetConfidence(); + return (contxtCf > distribCf ? contxtCf : distribCf); + } + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCKRProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCKRProber.cs new file mode 100644 index 000000000..67d4b0a72 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCKRProber.cs @@ -0,0 +1,107 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class EUCKRProber : CharsetProber + { + private CodingStateMachine codingSM; + private EUCKRDistributionAnalyser distributionAnalyser; + private byte[] lastChar = new byte[2]; + + public EUCKRProber() + { + codingSM = new CodingStateMachine(new EUCKRSMModel()); + distributionAnalyser = new EUCKRDistributionAnalyser(); + Reset(); + } + + public override string GetCharsetName() + { + return "EUC-KR"; + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int codingState; + int max = offset + len; + + for (int i = offset; i < max; i++) { + codingState = codingSM.NextState(buf[i]); + if (codingState == SMModel.ERROR) { + state = ProbingState.NotMe; + break; + } + if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + break; + } + if (codingState == SMModel.START) { + int charLen = codingSM.CurrentCharLen; + if (i == offset) { + lastChar[1] = buf[offset]; + distributionAnalyser.HandleOneChar(lastChar, 0, charLen); + } else { + distributionAnalyser.HandleOneChar(buf, i-1, charLen); + } + } + } + lastChar[0] = buf[max-1]; + + if (state == ProbingState.Detecting) + if (distributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + return state; + + } + + public override float GetConfidence() + { + return distributionAnalyser.GetConfidence(); + } + + public override void Reset() + { + codingSM.Reset(); + state = ProbingState.Detecting; + distributionAnalyser.Reset(); + //mContextAnalyser.Reset(); + } + + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCTWProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCTWProber.cs new file mode 100644 index 000000000..a4e0b486e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EUCTWProber.cs @@ -0,0 +1,106 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class EUCTWProber : CharsetProber + { + private CodingStateMachine codingSM; + private EUCTWDistributionAnalyser distributionAnalyser; + private byte[] lastChar = new byte[2]; + + public EUCTWProber() + { + this.codingSM = new CodingStateMachine(new EUCTWSMModel()); + this.distributionAnalyser = new EUCTWDistributionAnalyser(); + this.Reset(); + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int codingState; + int max = offset + len; + + for (int i = 0; i < max; i++) { + codingState = codingSM.NextState(buf[i]); + if (codingState == SMModel.ERROR) { + state = ProbingState.NotMe; + break; + } + if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + break; + } + if (codingState == SMModel.START) { + int charLen = codingSM.CurrentCharLen; + if (i == offset) { + lastChar[1] = buf[offset]; + distributionAnalyser.HandleOneChar(lastChar, 0, charLen); + } else { + distributionAnalyser.HandleOneChar(buf, i-1, charLen); + } + } + } + lastChar[0] = buf[max-1]; + + if (state == ProbingState.Detecting) + if (distributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + return state; + } + + public override string GetCharsetName() + { + return "x-euc-tw"; + } + + public override void Reset() + { + codingSM.Reset(); + state = ProbingState.Detecting; + distributionAnalyser.Reset(); + } + + public override float GetConfidence() + { + return distributionAnalyser.GetConfidence(); + } + + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EscCharsetProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EscCharsetProber.cs new file mode 100644 index 000000000..e9cefa9bc --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EscCharsetProber.cs @@ -0,0 +1,105 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class EscCharsetProber : CharsetProber + { + private const int CHARSETS_NUM = 4; + private string detectedCharset; + private CodingStateMachine[] codingSM; + int activeSM; + + public EscCharsetProber() + { + codingSM = new CodingStateMachine[CHARSETS_NUM]; + codingSM[0] = new CodingStateMachine(new HZSMModel()); + codingSM[1] = new CodingStateMachine(new ISO2022CNSMModel()); + codingSM[2] = new CodingStateMachine(new ISO2022JPSMModel()); + codingSM[3] = new CodingStateMachine(new ISO2022KRSMModel()); + Reset(); + } + + public override void Reset() + { + state = ProbingState.Detecting; + for (int i = 0; i < CHARSETS_NUM; i++) + codingSM[i].Reset(); + activeSM = CHARSETS_NUM; + detectedCharset = null; + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int max = offset + len; + + for (int i = offset; i < max && state == ProbingState.Detecting; i++) { + for (int j = activeSM - 1; j >= 0; j--) { + // byte is feed to all active state machine + int codingState = codingSM[j].NextState(buf[i]); + if (codingState == SMModel.ERROR) { + // got negative answer for this state machine, make it inactive + activeSM--; + if (activeSM == 0) { + state = ProbingState.NotMe; + return state; + } else if (j != activeSM) { + CodingStateMachine t = codingSM[activeSM]; + codingSM[activeSM] = codingSM[j]; + codingSM[j] = t; + } + } else if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + detectedCharset = codingSM[j].ModelName; + return state; + } + } + } + return state; + } + + public override string GetCharsetName() + { + return detectedCharset; + } + + public override float GetConfidence() + { + return 0.99f; + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EscSM.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EscSM.cs new file mode 100644 index 000000000..61ac5545f --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/EscSM.cs @@ -0,0 +1,304 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kohei TAKETA <k-tak@void.in> (Java port) + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/// <summary> +/// Escaped charsets state machines +/// </summary> +namespace UniversalDetector.Core +{ + public class HZSMModel : SMModel + { + private readonly static int[] HZ_cls = { + BitPackage.Pack4bits(1,0,0,0,0,0,0,0), // 00 - 07 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 08 - 0f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 10 - 17 + BitPackage.Pack4bits(0,0,0,1,0,0,0,0), // 18 - 1f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 20 - 27 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 28 - 2f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 30 - 37 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 38 - 3f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 40 - 47 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 48 - 4f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 50 - 57 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 58 - 5f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 60 - 67 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 68 - 6f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 70 - 77 + BitPackage.Pack4bits(0,0,0,4,0,5,2,0), // 78 - 7f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 80 - 87 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 88 - 8f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 90 - 97 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 98 - 9f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // a0 - a7 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // a8 - af + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // b0 - b7 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // b8 - bf + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // c0 - c7 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // c8 - cf + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // d0 - d7 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // d8 - df + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // e0 - e7 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // e8 - ef + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // f0 - f7 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1) // f8 - ff + }; + + private readonly static int[] HZ_st = { + BitPackage.Pack4bits(START, ERROR, 3, START, START, START, ERROR, ERROR),//00-07 + BitPackage.Pack4bits(ERROR, ERROR, ERROR, ERROR, ITSME, ITSME, ITSME, ITSME),//08-0f + BitPackage.Pack4bits(ITSME, ITSME, ERROR, ERROR, START, START, 4, ERROR),//10-17 + BitPackage.Pack4bits( 5, ERROR, 6, ERROR, 5, 5, 4, ERROR),//18-1f + BitPackage.Pack4bits( 4, ERROR, 4, 4, 4, ERROR, 4, ERROR),//20-27 + BitPackage.Pack4bits( 4, ITSME, START, START, START, START, START, START) //28-2f + }; + + private readonly static int[] HZCharLenTable = {0, 0, 0, 0, 0, 0}; + + public HZSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, HZ_cls), + 6, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, HZ_st), + HZCharLenTable, "HZ-GB-2312") + { + + } + } + + public class ISO2022CNSMModel : SMModel + { + private readonly static int[] ISO2022CN_cls = { + BitPackage.Pack4bits(2,0,0,0,0,0,0,0), // 00 - 07 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 08 - 0f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 10 - 17 + BitPackage.Pack4bits(0,0,0,1,0,0,0,0), // 18 - 1f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 20 - 27 + BitPackage.Pack4bits(0,3,0,0,0,0,0,0), // 28 - 2f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 30 - 37 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 38 - 3f + BitPackage.Pack4bits(0,0,0,4,0,0,0,0), // 40 - 47 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 48 - 4f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 50 - 57 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 58 - 5f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 60 - 67 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 68 - 6f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 70 - 77 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 78 - 7f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 80 - 87 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 88 - 8f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 90 - 97 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 98 - 9f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a0 - a7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a8 - af + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b0 - b7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b8 - bf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c0 - c7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c8 - cf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d0 - d7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d8 - df + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e0 - e7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e8 - ef + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // f0 - f7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2) // f8 - ff + }; + + private readonly static int[] ISO2022CN_st = { + BitPackage.Pack4bits(START, 3,ERROR,START,START,START,START,START),//00-07 + BitPackage.Pack4bits(START,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//08-0f + BitPackage.Pack4bits(ERROR,ERROR,ITSME,ITSME,ITSME,ITSME,ITSME,ITSME),//10-17 + BitPackage.Pack4bits(ITSME,ITSME,ITSME,ERROR,ERROR,ERROR, 4,ERROR),//18-1f + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ITSME,ERROR,ERROR,ERROR,ERROR),//20-27 + BitPackage.Pack4bits( 5, 6,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//28-2f + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ITSME,ERROR,ERROR,ERROR,ERROR),//30-37 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ITSME,ERROR,START) //38-3f + }; + + private readonly static int[] ISO2022CNCharLenTable = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + + public ISO2022CNSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, ISO2022CN_cls), + 9, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, ISO2022CN_st), + ISO2022CNCharLenTable, "ISO-2022-CN") + { + + } + } + + public class ISO2022JPSMModel : SMModel + { + private readonly static int[] ISO2022JP_cls = { + BitPackage.Pack4bits(2,0,0,0,0,0,0,0), // 00 - 07 + BitPackage.Pack4bits(0,0,0,0,0,0,2,2), // 08 - 0f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 10 - 17 + BitPackage.Pack4bits(0,0,0,1,0,0,0,0), // 18 - 1f + BitPackage.Pack4bits(0,0,0,0,7,0,0,0), // 20 - 27 + BitPackage.Pack4bits(3,0,0,0,0,0,0,0), // 28 - 2f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 30 - 37 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 38 - 3f + BitPackage.Pack4bits(6,0,4,0,8,0,0,0), // 40 - 47 + BitPackage.Pack4bits(0,9,5,0,0,0,0,0), // 48 - 4f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 50 - 57 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 58 - 5f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 60 - 67 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 68 - 6f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 70 - 77 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 78 - 7f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 80 - 87 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 88 - 8f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 90 - 97 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 98 - 9f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a0 - a7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a8 - af + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b0 - b7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b8 - bf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c0 - c7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c8 - cf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d0 - d7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d8 - df + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e0 - e7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e8 - ef + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // f0 - f7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2) // f8 - ff + }; + + private readonly static int[] ISO2022JP_st = { + BitPackage.Pack4bits(START, 3, ERROR,START,START,START,START,START),//00-07 + BitPackage.Pack4bits(START, START, ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//08-0f + BitPackage.Pack4bits(ERROR, ERROR, ERROR,ERROR,ITSME,ITSME,ITSME,ITSME),//10-17 + BitPackage.Pack4bits(ITSME, ITSME, ITSME,ITSME,ITSME,ITSME,ERROR,ERROR),//18-1f + BitPackage.Pack4bits(ERROR, 5, ERROR,ERROR,ERROR, 4,ERROR,ERROR),//20-27 + BitPackage.Pack4bits(ERROR, ERROR, ERROR, 6,ITSME,ERROR,ITSME,ERROR),//28-2f + BitPackage.Pack4bits(ERROR, ERROR, ERROR,ERROR,ERROR,ERROR,ITSME,ITSME),//30-37 + BitPackage.Pack4bits(ERROR, ERROR, ERROR,ITSME,ERROR,ERROR,ERROR,ERROR),//38-3f + BitPackage.Pack4bits(ERROR, ERROR, ERROR,ERROR,ITSME,ERROR,START,START) //40-47 + }; + + private readonly static int[] ISO2022JPCharLenTable = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + public ISO2022JPSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, ISO2022JP_cls), + 10, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, ISO2022JP_st), + ISO2022JPCharLenTable, "ISO-2022-JP") + { + + } + + } + + public class ISO2022KRSMModel : SMModel + { + private readonly static int[] ISO2022KR_cls = { + BitPackage.Pack4bits(2,0,0,0,0,0,0,0), // 00 - 07 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 08 - 0f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 10 - 17 + BitPackage.Pack4bits(0,0,0,1,0,0,0,0), // 18 - 1f + BitPackage.Pack4bits(0,0,0,0,3,0,0,0), // 20 - 27 + BitPackage.Pack4bits(0,4,0,0,0,0,0,0), // 28 - 2f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 30 - 37 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 38 - 3f + BitPackage.Pack4bits(0,0,0,5,0,0,0,0), // 40 - 47 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 48 - 4f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 50 - 57 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 58 - 5f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 60 - 67 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 68 - 6f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 70 - 77 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 78 - 7f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 80 - 87 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 88 - 8f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 90 - 97 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 98 - 9f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a0 - a7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a8 - af + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b0 - b7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b8 - bf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c0 - c7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c8 - cf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d0 - d7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d8 - df + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e0 - e7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e8 - ef + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // f0 - f7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2) // f8 - ff + }; + + private readonly static int[] ISO2022KR_st = { + BitPackage.Pack4bits(START, 3,ERROR,START,START,START,ERROR,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ITSME,ITSME,ITSME,ITSME),//08-0f + BitPackage.Pack4bits(ITSME,ITSME,ERROR,ERROR,ERROR, 4,ERROR,ERROR),//10-17 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR, 5,ERROR,ERROR,ERROR),//18-1f + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ITSME,START,START,START,START) //20-27 + }; + + private readonly static int[] ISO2022KRCharLenTable = {0, 0, 0, 0, 0, 0}; + + public ISO2022KRSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, ISO2022KR_cls), + 6, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, ISO2022KR_st), + ISO2022KRCharLenTable, "ISO-2022-KR") + { + + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/GB18030Prober.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/GB18030Prober.cs new file mode 100644 index 000000000..ac237c5cd --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/GB18030Prober.cs @@ -0,0 +1,111 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + // We use gb18030 to replace gb2312, because 18030 is a superset. + public class GB18030Prober : CharsetProber + { + private CodingStateMachine codingSM; + private GB18030DistributionAnalyser analyser; + private byte[] lastChar; + + public GB18030Prober() + { + lastChar = new byte[2]; + codingSM = new CodingStateMachine(new GB18030SMModel()); + analyser = new GB18030DistributionAnalyser(); + Reset(); + } + + public override string GetCharsetName() + { + return "gb18030"; + } + + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int codingState = SMModel.START; + int max = offset + len; + + for (int i = offset; i < max; i++) { + codingState = codingSM.NextState(buf[i]); + if (codingState == SMModel.ERROR) { + state = ProbingState.NotMe; + break; + } + if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + break; + } + if (codingState == SMModel.START) { + int charLen = codingSM.CurrentCharLen; + if (i == offset) { + lastChar[1] = buf[offset]; + analyser.HandleOneChar(lastChar, 0, charLen); + } else { + analyser.HandleOneChar(buf, i-1, charLen); + } + } + } + + lastChar[0] = buf[max-1]; + + if (state == ProbingState.Detecting) { + if (analyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + } + + return state; + } + + public override float GetConfidence() + { + return analyser.GetConfidence(); + } + + public override void Reset() + { + codingSM.Reset(); + state = ProbingState.Detecting; + analyser.Reset(); + } + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/HebrewProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/HebrewProber.cs new file mode 100644 index 000000000..92974d3a8 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/HebrewProber.cs @@ -0,0 +1,324 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System; + +/** + * General ideas of the Hebrew charset recognition + * + * Four main charsets exist in Hebrew: + * "ISO-8859-8" - Visual Hebrew + * "windows-1255" - Logical Hebrew + * "ISO-8859-8-I" - Logical Hebrew + * "x-mac-hebrew" - ?? Logical Hebrew ?? + * + * Both "ISO" charsets use a completely identical set of code points, whereas + * "windows-1255" and "x-mac-hebrew" are two different proper supersets of + * these code points. windows-1255 defines additional characters in the range + * 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific + * diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. + * x-mac-hebrew defines similar additional code points but with a different + * mapping. + * + * As far as an average Hebrew text with no diacritics is concerned, all four + * charsets are identical with respect to code points. Meaning that for the + * main Hebrew alphabet, all four map the same values to all 27 Hebrew letters + * (including final letters). + * + * The dominant difference between these charsets is their directionality. + * "Visual" directionality means that the text is ordered as if the renderer is + * not aware of a BIDI rendering algorithm. The renderer sees the text and + * draws it from left to right. The text itself when ordered naturally is read + * backwards. A buffer of Visual Hebrew generally looks like so: + * "[last word of first line spelled backwards] [whole line ordered backwards + * and spelled backwards] [first word of first line spelled backwards] + * [end of line] [last word of second line] ... etc' " + * adding punctuation marks, numbers and English text to visual text is + * naturally also "visual" and from left to right. + * + * "Logical" directionality means the text is ordered "naturally" according to + * the order it is read. It is the responsibility of the renderer to display + * the text from right to left. A BIDI algorithm is used to place general + * punctuation marks, numbers and English text in the text. + * + * Texts in x-mac-hebrew are almost impossible to find on the Internet. From + * what little evidence I could find, it seems that its general directionality + * is Logical. + * + * To sum up all of the above, the Hebrew probing mechanism knows about two + * charsets: + * Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are + * backwards while line order is natural. For charset recognition purposes + * the line order is unimportant (In fact, for this implementation, even + * word order is unimportant). + * Logical Hebrew - "windows-1255" - normal, naturally ordered text. + * + * "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be + * specifically identified. + * "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew + * that contain special punctuation marks or diacritics is displayed with + * some unconverted characters showing as question marks. This problem might + * be corrected using another model prober for x-mac-hebrew. Due to the fact + * that x-mac-hebrew texts are so rare, writing another model prober isn't + * worth the effort and performance hit. + * + * *** The Prober *** + * + * The prober is divided between two nsSBCharSetProbers and an nsHebrewProber, + * all of which are managed, created, fed data, inquired and deleted by the + * nsSBCSGroupProber. The two nsSBCharSetProbers identify that the text is in + * fact some kind of Hebrew, Logical or Visual. The final decision about which + * one is it is made by the nsHebrewProber by combining final-letter scores + * with the scores of the two nsSBCharSetProbers to produce a final answer. + * + * The nsSBCSGroupProber is responsible for stripping the original text of HTML + * tags, English characters, numbers, low-ASCII punctuation characters, spaces + * and new lines. It reduces any sequence of such characters to a single space. + * The buffer fed to each prober in the SBCS group prober is pure text in + * high-ASCII. + * The two nsSBCharSetProbers (model probers) share the same language model: + * Win1255Model. + * The first nsSBCharSetProber uses the model normally as any other + * nsSBCharSetProber does, to recognize windows-1255, upon which this model was + * built. The second nsSBCharSetProber is told to make the pair-of-letter + * lookup in the language model backwards. This in practice exactly simulates + * a visual Hebrew model using the windows-1255 logical Hebrew model. + * + * The nsHebrewProber is not using any language model. All it does is look for + * final-letter evidence suggesting the text is either logical Hebrew or visual + * Hebrew. Disjointed from the model probers, the results of the nsHebrewProber + * alone are meaningless. nsHebrewProber always returns 0.00 as confidence + * since it never identifies a charset by itself. Instead, the pointer to the + * nsHebrewProber is passed to the model probers as a helper "Name Prober". + * When the Group prober receives a positive identification from any prober, + * it asks for the name of the charset identified. If the prober queried is a + * Hebrew model prober, the model prober forwards the call to the + * nsHebrewProber to make the final decision. In the nsHebrewProber, the + * decision is made according to the final-letters scores maintained and Both + * model probers scores. The answer is returned in the form of the name of the + * charset identified, either "windows-1255" or "ISO-8859-8". + * + */ +namespace UniversalDetector.Core +{ + + /// <summary> + /// This prober doesn't actually recognize a language or a charset. + /// It is a helper prober for the use of the Hebrew model probers + /// </summary> + public class HebrewProber : CharsetProber + { + // windows-1255 / ISO-8859-8 code points of interest + private const byte FINAL_KAF = 0xEA; + private const byte NORMAL_KAF = 0xEB; + private const byte FINAL_MEM = 0xED; + private const byte NORMAL_MEM = 0xEE; + private const byte FINAL_NUN = 0xEF; + private const byte NORMAL_NUN = 0xF0; + private const byte FINAL_PE = 0xF3; + private const byte NORMAL_PE = 0xF4; + private const byte FINAL_TSADI = 0xF5; + private const byte NORMAL_TSADI = 0xF6; + + // Minimum Visual vs Logical final letter score difference. + // If the difference is below this, don't rely solely on the final letter score distance. + private const int MIN_FINAL_CHAR_DISTANCE = 5; + + // Minimum Visual vs Logical model score difference. + // If the difference is below this, don't rely at all on the model score distance. + private const float MIN_MODEL_DISTANCE = 0.01f; + + protected const string VISUAL_HEBREW_NAME = "ISO-8859-8"; + protected const string LOGICAL_HEBREW_NAME = "windows-1255"; + + // owned by the group prober. + protected CharsetProber logicalProber, visualProber; + protected int finalCharLogicalScore, finalCharVisualScore; + + // The two last bytes seen in the previous buffer. + protected byte prev, beforePrev; + + public HebrewProber() + { + Reset(); + } + + public void SetModelProbers(CharsetProber logical, CharsetProber visual) + { + logicalProber = logical; + visualProber = visual; + } + + /** + * Final letter analysis for logical-visual decision. + * Look for evidence that the received buffer is either logical Hebrew or + * visual Hebrew. + * The following cases are checked: + * 1) A word longer than 1 letter, ending with a final letter. This is an + * indication that the text is laid out "naturally" since the final letter + * really appears at the end. +1 for logical score. + * 2) A word longer than 1 letter, ending with a Non-Final letter. In normal + * Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, should not end with + * the Non-Final form of that letter. Exceptions to this rule are mentioned + * above in isNonFinal(). This is an indication that the text is laid out + * backwards. +1 for visual score + * 3) A word longer than 1 letter, starting with a final letter. Final letters + * should not appear at the beginning of a word. This is an indication that + * the text is laid out backwards. +1 for visual score. + * + * The visual score and logical score are accumulated throughout the text and + * are finally checked against each other in GetCharSetName(). + * No checking for final letters in the middle of words is done since that case + * is not an indication for either Logical or Visual text. + * + * The input buffer should not contain any white spaces that are not (' ') + * or any low-ascii punctuation marks. + */ + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + // Both model probers say it's not them. No reason to continue. + if (GetState() == ProbingState.NotMe) + return ProbingState.NotMe; + + int max = offset + len; + + for (int i = offset; i < max; i++) { + + byte b = buf[i]; + + // a word just ended + if (b == 0x20) { + // *(curPtr-2) was not a space so prev is not a 1 letter word + if (beforePrev != 0x20) { + // case (1) [-2:not space][-1:final letter][cur:space] + if (IsFinal(prev)) + finalCharLogicalScore++; + // case (2) [-2:not space][-1:Non-Final letter][cur:space] + else if (IsNonFinal(prev)) + finalCharVisualScore++; + } + + } else { + // case (3) [-2:space][-1:final letter][cur:not space] + if ((beforePrev == 0x20) && (IsFinal(prev)) && (b != ' ')) + ++finalCharVisualScore; + } + beforePrev = prev; + prev = b; + } + + // Forever detecting, till the end or until both model probers + // return NotMe (handled above). + return ProbingState.Detecting; + } + + // Make the decision: is it Logical or Visual? + public override string GetCharsetName() + { + // If the final letter score distance is dominant enough, rely on it. + int finalsub = finalCharLogicalScore - finalCharVisualScore; + if (finalsub >= MIN_FINAL_CHAR_DISTANCE) + return LOGICAL_HEBREW_NAME; + if (finalsub <= -(MIN_FINAL_CHAR_DISTANCE)) + return VISUAL_HEBREW_NAME; + + // It's not dominant enough, try to rely on the model scores instead. + float modelsub = logicalProber.GetConfidence() - visualProber.GetConfidence(); + if (modelsub > MIN_MODEL_DISTANCE) + return LOGICAL_HEBREW_NAME; + if (modelsub < -(MIN_MODEL_DISTANCE)) + return VISUAL_HEBREW_NAME; + + // Still no good, back to final letter distance, maybe it'll save the day. + if (finalsub < 0) + return VISUAL_HEBREW_NAME; + + // (finalsub > 0 - Logical) or (don't know what to do) default to Logical. + return LOGICAL_HEBREW_NAME; + } + + public override void Reset() + { + finalCharLogicalScore = 0; + finalCharVisualScore = 0; + prev = 0x20; + beforePrev = 0x20; + } + + public override ProbingState GetState() + { + // Remain active as long as any of the model probers are active. + if (logicalProber.GetState() == ProbingState.NotMe && + visualProber.GetState() == ProbingState.NotMe) + return ProbingState.NotMe; + return ProbingState.Detecting; + } + + public override void DumpStatus() + { + //Console.WriteLine(" HEB: {0} - {1} [Logical-Visual score]", finalCharLogicalScore, finalCharVisualScore); + } + + public override float GetConfidence() + { + return 0.0f; + } + + protected static bool IsFinal(byte b) + { + return (b == FINAL_KAF || b == FINAL_MEM || b == FINAL_NUN + || b == FINAL_PE || b == FINAL_TSADI); + } + + protected static bool IsNonFinal(byte b) + { + // The normal Tsadi is not a good Non-Final letter due to words like + // 'lechotet' (to chat) containing an apostrophe after the tsadi. This + // apostrophe is converted to a space in FilterWithoutEnglishLetters causing + // the Non-Final tsadi to appear at an end of a word even though this is not + // the case in the original text. + // The letters Pe and Kaf rarely display a related behavior of not being a + // good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' for + // example legally end with a Non-Final Pe or Kaf. However, the benefit of + // these letters as Non-Final letters outweighs the damage since these words + // are quite rare. + return (b == NORMAL_KAF || b == NORMAL_MEM || b == NORMAL_NUN + || b == NORMAL_PE); + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/JapaneseContextAnalyser.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/JapaneseContextAnalyser.cs new file mode 100644 index 000000000..93b9d7580 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/JapaneseContextAnalyser.cs @@ -0,0 +1,315 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public abstract class JapaneseContextAnalyser + { + protected const int CATEGORIES_NUM = 6; + protected const int ENOUGH_REL_THRESHOLD = 100; + protected const int MAX_REL_THRESHOLD = 1000; + protected const int MINIMUM_DATA_THRESHOLD = 4; + protected const float DONT_KNOW = -1.0f; + + // hiragana frequency category table + // This is hiragana 2-char sequence table, the number in each cell represents its frequency category + protected static byte[,] jp2CharContext = { + { 0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,}, + { 2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4,}, + { 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,}, + { 0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4,}, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, + { 0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4,}, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, + { 0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3,}, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, + { 0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4,}, + { 1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4,}, + { 0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3,}, + { 0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3,}, + { 0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3,}, + { 0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4,}, + { 0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3,}, + { 2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4,}, + { 0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3,}, + { 0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5,}, + { 0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3,}, + { 2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5,}, + { 0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4,}, + { 1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4,}, + { 0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3,}, + { 0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3,}, + { 0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3,}, + { 0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5,}, + { 0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4,}, + { 0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5,}, + { 0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3,}, + { 0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4,}, + { 0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4,}, + { 0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4,}, + { 0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1,}, + { 0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,}, + { 1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3,}, + { 0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0,}, + { 0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3,}, + { 0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3,}, + { 0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5,}, + { 0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4,}, + { 2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5,}, + { 0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3,}, + { 0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3,}, + { 0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3,}, + { 0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3,}, + { 0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4,}, + { 0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4,}, + { 0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2,}, + { 0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3,}, + { 0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3,}, + { 0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3,}, + { 0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3,}, + { 0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4,}, + { 0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3,}, + { 0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4,}, + { 0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3,}, + { 0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3,}, + { 0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4,}, + { 0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4,}, + { 0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3,}, + { 2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4,}, + { 0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4,}, + { 0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3,}, + { 0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4,}, + { 0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4,}, + { 1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4,}, + { 0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3,}, + { 0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,}, + { 0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2,}, + { 0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3,}, + { 0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3,}, + { 0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5,}, + { 0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3,}, + { 0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4,}, + { 1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4,}, + { 0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4,}, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, + { 0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3,}, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1,}, + { 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2,}, + { 0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3,}, + { 0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1,}, + }; + + // category counters, each integer counts sequence in its category + int[] relSample = new int[CATEGORIES_NUM]; + + // total sequence received + int totalRel; + + // The order of previous char + int lastCharOrder; + + // if last byte in current buffer is not the last byte of a character, + // we need to know how many byte to skip in next buffer. + int needToSkipCharNum; + + // If this flag is set to true, detection is done and conclusion has + // been made + bool done; + + public JapaneseContextAnalyser() + { + Reset(); + } + + public float GetConfidence() + { + // This is just one way to calculate confidence. It works well for me. + if (totalRel > MINIMUM_DATA_THRESHOLD) + return ((float)(totalRel - relSample[0]))/totalRel; + else + return DONT_KNOW; + } + + public void HandleData(byte[] buf, int offset, int len) + { + + int charLen = 0; + int max = offset + len; + + if (done) + return; + + // The buffer we got is byte oriented, and a character may span + // more than one buffer. In case the last one or two byte in last + // buffer is not complete, we record how many byte needed to + // complete that character and skip these bytes here. We can choose + // to record those bytes as well and analyse the character once it + // is complete, but since a character will not make much difference, + // skipping it will simplify our logic and improve performance. + for (int i = needToSkipCharNum+offset; i < max; ) { + int order = GetOrder(buf, i, out charLen); + i += charLen; + if (i > max) { + needToSkipCharNum = i - max; + lastCharOrder = -1; + } else { + if (order != -1 && lastCharOrder != -1) { + totalRel ++; + if (totalRel > MAX_REL_THRESHOLD) { + done = true; + break; + } + relSample[jp2CharContext[lastCharOrder, order]]++; + } + lastCharOrder = order; + } + } + } + + public void HandleOneChar(byte[] buf, int offset, int charLen) + { + if (totalRel > MAX_REL_THRESHOLD) + done = true; + if (done) + return; + + // Only 2-bytes characters are of our interest + int order = (charLen == 2) ? GetOrder(buf, offset) : -1; + if (order != -1 && lastCharOrder != -1) { + totalRel++; + // count this sequence to its category counter + relSample[jp2CharContext[lastCharOrder, order]]++; + } + lastCharOrder = order; + } + + public void Reset() + { + totalRel = 0; + for (int i = 0; i < CATEGORIES_NUM; i++) { + relSample[i] = 0; + needToSkipCharNum = 0; + lastCharOrder = -1; + done = false; + } + } + + protected abstract int GetOrder(byte[] buf, int offset, out int charLen); + + protected abstract int GetOrder(byte[] buf, int offset); + + public bool GotEnoughData() + { + return totalRel > ENOUGH_REL_THRESHOLD; + } + + } + + public class SJISContextAnalyser : JapaneseContextAnalyser + { + private const byte HIRAGANA_FIRST_BYTE = 0x82; + + protected override int GetOrder(byte[] buf, int offset, out int charLen) + { + //find out current char's byte length + if (buf[offset] >= 0x81 && buf[offset] <= 0x9F + || buf[offset] >= 0xe0 && buf[offset] <= 0xFC) + charLen = 2; + else + charLen = 1; + + // return its order if it is hiragana + if (buf[offset] == HIRAGANA_FIRST_BYTE) { + byte low = buf[offset+1]; + if (low >= 0x9F && low <= 0xF1) + return low - 0x9F; + } + return -1; + } + + protected override int GetOrder(byte[] buf, int offset) + { + // We are only interested in Hiragana + if (buf[offset] == HIRAGANA_FIRST_BYTE) { + byte low = buf[offset+1]; + if (low >= 0x9F && low <= 0xF1) + return low - 0x9F; + } + return -1; + } + + } + + public class EUCJPContextAnalyser : JapaneseContextAnalyser + { + private const byte HIRAGANA_FIRST_BYTE = 0xA4; + + protected override int GetOrder(byte[] buf, int offset, out int charLen) + { + byte high = buf[offset]; + + //find out current char's byte length + if (high == 0x8E || high >= 0xA1 && high <= 0xFE) + charLen = 2; + else if (high == 0xBF) + charLen = 3; + else + charLen = 1; + + // return its order if it is hiragana + if (high == HIRAGANA_FIRST_BYTE) { + byte low = buf[offset+1]; + if (low >= 0xA1 && low <= 0xF3) + return low - 0xA1; + } + return -1; + } + + protected override int GetOrder(byte[] buf, int offset) + { + // We are only interested in Hiragana + if (buf[offset] == HIRAGANA_FIRST_BYTE) { + byte low = buf[offset+1]; + if (low >= 0xA1 && low <= 0xF3) + return low - 0xA1; + } + return -1; + } + } +} + diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangBulgarianModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangBulgarianModel.cs new file mode 100644 index 000000000..4b6729ed3 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangBulgarianModel.cs @@ -0,0 +1,246 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public abstract class BulgarianModel : SequenceModel + { + //Model Table: + //total sequences: 100% + //first 512 sequences: 96.9392% + //first 1024 sequences:3.0618% + //rest sequences: 0.2992% + //negative sequences: 0.0020% + private static byte[] BULGARIAN_LANG_MODEL = { + 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, + 3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, + 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, + 0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, + 0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, + 0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, + 2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, + 3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, + 3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, + 1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, + 3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, + 1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, + 2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, + 2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, + 3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, + 1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, + 2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, + 2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, + 3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, + 1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, + 2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, + 2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, + 2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, + 1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, + 2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, + 1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, + 3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, + 1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, + 3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, + 1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, + 2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, + 1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, + 2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, + 1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, + 2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, + 1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, + 1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, + 1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, + 2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, + 1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, + 2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, + 1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, + 1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, + 0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, + 1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, + 2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, + 1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, + 1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, + 0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, + 1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, + 0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, + 1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, + 1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, + 1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, + 1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + + }; + + public BulgarianModel(byte[] charToOrderMap, string name) + : base(charToOrderMap, BULGARIAN_LANG_MODEL, 0.969392f, false, name) + { + } + } + + public class Latin5BulgarianModel : BulgarianModel + { + //255: Control characters that usually does not exist in any text + //254: Carriage/Return + //253: symbol (punctuation) that does not belong to word + //252: 0 - 9 + // Character Mapping Table: + // this table is modified base on win1251BulgarianCharToOrderMap, so + // only number <64 is sure valid + private static byte[] LATIN5_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, //40 + 110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, //50 + 253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, //60 + 116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, //70 + 194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, //80 + 210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, //90 + 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, //a0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //b0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, //c0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //d0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, //e0 + 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, //f0 + }; + + public Latin5BulgarianModel() : base(LATIN5_CHAR_TO_ORDER_MAP, "ISO-8859-5") + { + } + } + + public class Win1251BulgarianModel : BulgarianModel + { + private static byte[] WIN1251__CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, //40 + 110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, //50 + 253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, //60 + 116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, //70 + 206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, //80 + 221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, //90 + 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, //a0 + 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, //b0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //c0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, //d0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //e0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, //f0 + }; + + public Win1251BulgarianModel() : base(WIN1251__CHAR_TO_ORDER_MAP, "windows-1251") + { + } + } + +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangCyrillicModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangCyrillicModel.cs new file mode 100644 index 000000000..5e55a4839 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangCyrillicModel.cs @@ -0,0 +1,345 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public abstract class CyrillicModel : SequenceModel + { + // Model Table: + // total sequences: 100% + // first 512 sequences: 97.6601% + // first 1024 sequences: 2.3389% + // rest sequences: 0.1237% + // negative sequences: 0.0009% + protected readonly static byte[] RUSSIAN_LANG_MODEL = { + 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, + 3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, + 0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, + 0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, + 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, + 3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, + 1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, + 2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, + 1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, + 2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, + 1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, + 3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, + 1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, + 2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, + 1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, + 1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, + 1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, + 2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, + 1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, + 3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, + 1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, + 2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, + 1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, + 2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, + 1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, + 1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, + 1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, + 3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, + 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, + 3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, + 1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, + 1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, + 0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, + 2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, + 1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, + 1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, + 0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, + 1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, + 2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, + 1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, + 1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, + 2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, + 1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, + 2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, + 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, + 1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, + 0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, + 0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, + 1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, + 0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, + 0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, + 1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, + 0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, + 2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, + 0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + }; + + public CyrillicModel(byte[] charToOrderMap, string name) + : base(charToOrderMap, RUSSIAN_LANG_MODEL, 0.976601f, false, name) + { + } + } + + public class Koi8rModel : CyrillicModel + { + private readonly static byte[] KOI8R_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 + 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 + 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, //80 + 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, //90 + 223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, //a0 + 238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, //b0 + 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, //c0 + 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, //d0 + 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, //e0 + 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, //f0 + }; + + public Koi8rModel() : base(KOI8R_CHAR_TO_ORDER_MAP, "KOI8-R") + { + } + } + + public class Win1251Model : CyrillicModel + { + private readonly static byte[] WIN1251_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 + 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 + 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, + 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, + 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, + }; + + public Win1251Model() : base(WIN1251_CHAR_TO_ORDER_MAP, "windows-1251") + { + } + } + + public class Latin5Model : CyrillicModel + { + private readonly static byte[] LATIN5_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 + 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 + 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, + 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, + 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, + 239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, + }; + + public Latin5Model() : base(LATIN5_CHAR_TO_ORDER_MAP, "ISO-8859-5") + { + } + } + + public class MacCyrillicModel : CyrillicModel + { + private readonly static byte[] MACCYRILLIC_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 + 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 + 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, + 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, + 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, + }; + + public MacCyrillicModel() : base(MACCYRILLIC_CHAR_TO_ORDER_MAP, + "x-mac-cyrillic") + { + } + } + + public class Ibm855Model : CyrillicModel + { + private readonly static byte[] IBM855_BYTE_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 + 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 + 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, + 206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, + 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, + 220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, + 230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, + 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, + 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, + 250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, + }; + + public Ibm855Model() : base(IBM855_BYTE_TO_ORDER_MAP, "IBM855") + { + } + } + + public class Ibm866Model : CyrillicModel + { + private readonly static byte[] IBM866_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, //40 + 155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, //50 + 253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, //60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, //70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, + 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, + 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, + 239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, + }; + + public Ibm866Model() : base(IBM866_CHAR_TO_ORDER_MAP, "IBM866") + { + } + } + + + +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangGreekModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangGreekModel.cs new file mode 100644 index 000000000..563ba52c2 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangGreekModel.cs @@ -0,0 +1,244 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public abstract class GreekModel : SequenceModel + { + // Model Table: + // total sequences: 100% + // first 512 sequences: 98.2851% + // first 1024 sequences:1.7001% + // rest sequences: 0.0359% + // negative sequences: 0.0148% + private readonly static byte[] GREEK_LANG_MODEL = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, + 3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, + 0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, + 2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, + 0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, + 2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, + 2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, + 0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, + 2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, + 0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, + 3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, + 3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, + 2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, + 2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, + 0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, + 0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, + 0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, + 0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, + 0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, + 0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, + 0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, + 0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, + 0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, + 0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, + 0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, + 0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, + 0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, + 0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, + 0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, + 0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, + 0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, + 0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, + 0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, + 0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, + 0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, + 0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, + 0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, + 0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, + 0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, + 0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, + 0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, + 0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, + 0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, + 0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + }; + + public GreekModel(byte[] charToOrderMap, string name) + : base(charToOrderMap, GREEK_LANG_MODEL, 0.982851f, false, name) + { + } + } + + public class Latin7Model : GreekModel + { + /**************************************************************** + 255: Control characters that usually does not exist in any text + 254: Carriage/Return + 253: symbol (punctuation) that does not belong to word + 252: 0 - 9 + *****************************************************************/ + //Character Mapping Table: + private readonly static byte[] LATIN7_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, //40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, //50 + 253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, //60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, //70 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //80 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //90 + +253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, //a0 + 253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, //b0 + 110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, //d0 + 124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, //f0 + }; + + public Latin7Model() : base(LATIN7_CHAR_TO_ORDER_MAP, "ISO-8859-7") + { + } + } + + public class Win1253Model : GreekModel + { + private readonly static byte[] WIN1253__CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, //40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, //50 + 253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, //60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, //70 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //80 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //90 + +253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, //a0 + 253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, //b0 + 110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, //d0 + 124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, //f0 + }; + + public Win1253Model() : base(WIN1253__CHAR_TO_ORDER_MAP, "windows-1253") + { + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangHebrewModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangHebrewModel.cs new file mode 100644 index 000000000..030fcc598 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangHebrewModel.cs @@ -0,0 +1,220 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public abstract class HebrewModel : SequenceModel + { + //Model Table: + //total sequences: 100% + //first 512 sequences: 98.4004% + //first 1024 sequences: 1.5981% + //rest sequences: 0.087% + //negative sequences: 0.0015% + private readonly static byte[] HEBREW_LANG_MODEL = { + 0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, + 3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, + 1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, + 1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, + 1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, + 1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, + 1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, + 0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, + 0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, + 1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, + 3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, + 0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, + 0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, + 0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, + 0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, + 0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, + 3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, + 0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, + 0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, + 0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, + 0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, + 0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, + 0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, + 3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, + 0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, + 0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, + 0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, + 1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, + 0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, + 3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, + 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, + 3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, + 0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, + 0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, + 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, + 0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, + 0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, + 0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, + 2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, + 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, + 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, + 0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, + 0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, + 1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, + 0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, + 2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, + 1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, + 2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, + 1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, + 2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, + 0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, + 1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, + 0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, + }; + + public HebrewModel(byte[] charToOrderMap, string name) + : base(charToOrderMap, HEBREW_LANG_MODEL, 0.984004f, false, name) + { + } + } + + public class Win1255Model : HebrewModel + { + /* + 255: Control characters that usually does not exist in any text + 254: Carriage/Return + 253: symbol (punctuation) that does not belong to word + 252: 0 - 9 + */ + //Windows-1255 language model + //Character Mapping Table: + private readonly static byte[] WIN1255_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, //40 + 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, //50 + 253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, //60 + 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, //70 + 124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, + 215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, + 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, + 106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, + 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, + 238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, + 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, + 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, + }; + + public Win1255Model() : base(WIN1255_CHAR_TO_ORDER_MAP, "windows-1255") + { + } + } + +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangHungarianModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangHungarianModel.cs new file mode 100644 index 000000000..d7eee2251 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangHungarianModel.cs @@ -0,0 +1,238 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public abstract class HungarianModel : SequenceModel + { + //Model Table: + //total sequences: 100% + //first 512 sequences: 94.7368% + //first 1024 sequences:5.2623% + //rest sequences: 0.8894% + //negative sequences: 0.0009% + private readonly static byte[] HUNGARIAN_LANG_MODEL = { + 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, + 3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, + 3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, + 3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, + 0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, + 3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, + 3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, + 3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, + 2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, + 1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, + 1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, + 1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, + 3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, + 2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, + 2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, + 2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, + 2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, + 2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, + 3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, + 2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, + 2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, + 2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, + 1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, + 1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, + 3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, + 1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, + 1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, + 2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, + 2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, + 2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, + 3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, + 2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, + 1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, + 1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, + 2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, + 2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, + 1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, + 1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, + 2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, + 1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, + 1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, + 2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, + 2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, + 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, + 1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, + 1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, + 1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, + 0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, + 2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, + 2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, + 1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, + 2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, + 1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, + 1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, + 2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, + 2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, + 2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, + 1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, + 2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, + 0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, + 1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, + 0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, + 1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, + 2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, + }; + + public HungarianModel(byte[] charToOrderMap, string name) + : base(charToOrderMap, HUNGARIAN_LANG_MODEL, 0.947368f, + false, name) + { + } + } + + public class Latin2HungarianModel : HungarianModel + { + private readonly static byte[] LATIN2_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, + 253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, + 159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, + 175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, + 191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, + 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, + 221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, + 232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, + 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, + 245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, + }; + + public Latin2HungarianModel() : base(LATIN2_CHAR_TO_ORDER_MAP, "ISO-8859-2") + { + } + } + + public class Win1250HungarianModel : HungarianModel + { + private readonly static byte[] WIN1250_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, + 253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, + 161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, + 177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, + 191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, + 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, + 221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, + 232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, + 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, + 245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, + }; + + public Win1250HungarianModel() : base(WIN1250_CHAR_TO_ORDER_MAP, "windows-1250") + { + } + } + +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangThaiModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangThaiModel.cs new file mode 100644 index 000000000..bdda20f14 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/LangThaiModel.cs @@ -0,0 +1,213 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class ThaiModel : SequenceModel + { + /**************************************************************** + 255: Control characters that usually does not exist in any text + 254: Carriage/Return + 253: symbol (punctuation) that does not belong to word + 252: 0 - 9 + *****************************************************************/ + // The following result for thai was collected from a limited sample (1M) + private readonly static byte[] TIS620_CHAR_TO_ORDER_MAP = { + 255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, //00 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //10 + +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, //20 + 252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, //30 + 253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, //40 + 188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, //50 + 253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, //60 + 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, //70 + 209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, + 223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, + 236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, + 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, + 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, + 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, + 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, + 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, + }; + + //Model Table: + //total sequences: 100% + //first 512 sequences: 92.6386% + //first 1024 sequences:7.3177% + //rest sequences: 1.0230% + //negative sequences: 0.0436% + private readonly static byte[] THAI_LANG_MODEL = { + 0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, + 0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, + 3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, + 0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, + 3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, + 3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, + 3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, + 3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, + 3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, + 3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, + 3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, + 2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, + 3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, + 0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, + 3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, + 0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, + 3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, + 1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, + 3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, + 3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, + 1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, + 0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, + 2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, + 0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, + 3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, + 2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, + 3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, + 0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, + 3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, + 2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, + 3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, + 2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, + 3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, + 3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, + 3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, + 3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, + 3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, + 1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, + 0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, + 0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, + 3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, + 3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, + 1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, + 3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, + 3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, + 0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, + 0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, + 1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, + 1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, + 3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, + 0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, + 0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, + 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, + 3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, + 3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, + 0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, + 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, + 0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, + 0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, + 0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, + 0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, + 3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, + 0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, + 0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, + 3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, + 2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, + 0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, + 3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, + 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, + 1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, + 1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, + 1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, + 1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + }; + + public ThaiModel(byte[] charToOrderMap, string name) + : base(TIS620_CHAR_TO_ORDER_MAP, THAI_LANG_MODEL, + 0.926386f, false, "TIS-620") + { + } + } + +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Latin1Prober.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Latin1Prober.cs new file mode 100644 index 000000000..c79a10aa7 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/Latin1Prober.cs @@ -0,0 +1,180 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System; + +namespace UniversalDetector.Core +{ + // TODO: Using trigrams the detector should be able to discriminate between + // latin-1 and iso8859-2 + public class Latin1Prober : CharsetProber + { + private const int FREQ_CAT_NUM = 4; + + private const int UDF = 0; // undefined + private const int OTH = 1; // other + private const int ASC = 2; // ascii capital letter + private const int ASS = 3; // ascii small letter + private const int ACV = 4; // accent capital vowel + private const int ACO = 5; // accent capital other + private const int ASV = 6; // accent small vowel + private const int ASO = 7; // accent small other + + private const int CLASS_NUM = 8; // total classes + + private readonly static byte[] Latin1_CharToClass = { + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, // 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, // 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, // 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, // 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, // 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, // C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, // C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, // D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, // D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, // E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, // E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, // F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, // F8 - FF + }; + + /* 0 : illegal + 1 : very unlikely + 2 : normal + 3 : very likely + */ + private readonly static byte[] Latin1ClassModel = { + /* UDF OTH ASC ASS ACV ACO ASV ASO */ + /*UDF*/ 0, 0, 0, 0, 0, 0, 0, 0, + /*OTH*/ 0, 3, 3, 3, 3, 3, 3, 3, + /*ASC*/ 0, 3, 3, 3, 3, 3, 3, 3, + /*ASS*/ 0, 3, 3, 3, 1, 1, 3, 3, + /*ACV*/ 0, 3, 3, 3, 1, 2, 1, 2, + /*ACO*/ 0, 3, 3, 3, 3, 3, 3, 3, + /*ASV*/ 0, 3, 1, 3, 1, 1, 1, 3, + /*ASO*/ 0, 3, 1, 3, 1, 1, 3, 3, + }; + + private byte lastCharClass; + private int[] freqCounter = new int[FREQ_CAT_NUM]; + + public Latin1Prober() + { + Reset(); + } + + public override string GetCharsetName() + { + return "windows-1252"; + } + + public override void Reset() + { + state = ProbingState.Detecting; + lastCharClass = OTH; + for (int i = 0; i < FREQ_CAT_NUM; i++) + freqCounter[i] = 0; + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + byte[] newbuf = FilterWithEnglishLetters(buf, offset, len); + byte charClass, freq; + + for (int i = 0; i < newbuf.Length; i++) { + charClass = Latin1_CharToClass[newbuf[i]]; + freq = Latin1ClassModel[lastCharClass * CLASS_NUM + charClass]; + if (freq == 0) { + state = ProbingState.NotMe; + break; + } + freqCounter[freq]++; + lastCharClass = charClass; + } + return state; + } + + public override float GetConfidence() + { + if (state == ProbingState.NotMe) + return 0.01f; + + float confidence = 0.0f; + int total = 0; + for (int i = 0; i < FREQ_CAT_NUM; i++) { + total += freqCounter[i]; + } + + if (total <= 0) { + confidence = 0.0f; + } else { + confidence = freqCounter[3] * 1.0f / total; + confidence -= freqCounter[1] * 20.0f / total; + } + + // lower the confidence of latin1 so that other more accurate detector + // can take priority. + return confidence < 0.0f ? 0.0f : confidence * 0.5f; + } + + public override void DumpStatus() + { + //Console.WriteLine(" Latin1Prober: {0} [{1}]", GetConfidence(), GetCharsetName()); + } + } +} + diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/MBCSGroupProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/MBCSGroupProber.cs new file mode 100644 index 000000000..abf49aacd --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/MBCSGroupProber.cs @@ -0,0 +1,175 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System; + +namespace UniversalDetector.Core +{ + /// <summary> + /// Multi-byte charsets probers + /// </summary> + public class MBCSGroupProber : CharsetProber + { + private const int PROBERS_NUM = 7; + private readonly static string[] ProberName = + { "UTF8", "SJIS", "EUCJP", "GB18030", "EUCKR", "Big5", "EUCTW" }; + private CharsetProber[] probers = new CharsetProber[PROBERS_NUM]; + private bool[] isActive = new bool[PROBERS_NUM]; + private int bestGuess; + private int activeNum; + + public MBCSGroupProber() + { + probers[0] = new UTF8Prober(); + probers[1] = new SJISProber(); + probers[2] = new EUCJPProber(); + probers[3] = new GB18030Prober(); + probers[4] = new EUCKRProber(); + probers[5] = new Big5Prober(); + probers[6] = new EUCTWProber(); + Reset(); + } + + public override string GetCharsetName() + { + if (bestGuess == -1) { + GetConfidence(); + if (bestGuess == -1) + bestGuess = 0; + } + return probers[bestGuess].GetCharsetName(); + } + + public override void Reset() + { + activeNum = 0; + for (int i = 0; i < probers.Length; i++) { + if (probers[i] != null) { + probers[i].Reset(); + isActive[i] = true; + ++activeNum; + } else { + isActive[i] = false; + } + } + bestGuess = -1; + state = ProbingState.Detecting; + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + // do filtering to reduce load to probers + byte[] highbyteBuf = new byte[len]; + int hptr = 0; + //assume previous is not ascii, it will do no harm except add some noise + bool keepNext = true; + int max = offset + len; + + for (int i = offset; i < max; i++) { + if ((buf[i] & 0x80) != 0) { + highbyteBuf[hptr++] = buf[i]; + keepNext = true; + } else { + //if previous is highbyte, keep this even it is a ASCII + if (keepNext) { + highbyteBuf[hptr++] = buf[i]; + keepNext = false; + } + } + } + + ProbingState st = ProbingState.NotMe; + + for (int i = 0; i < probers.Length; i++) { + if (!isActive[i]) + continue; + st = probers[i].HandleData(highbyteBuf, 0, hptr); + if (st == ProbingState.FoundIt) { + bestGuess = i; + state = ProbingState.FoundIt; + break; + } else if (st == ProbingState.NotMe) { + isActive[i] = false; + activeNum--; + if (activeNum <= 0) { + state = ProbingState.NotMe; + break; + } + } + } + return state; + } + + public override float GetConfidence() + { + float bestConf = 0.0f; + float cf = 0.0f; + + if (state == ProbingState.FoundIt) { + return 0.99f; + } else if (state == ProbingState.NotMe) { + return 0.01f; + } else { + for (int i = 0; i < PROBERS_NUM; i++) { + if (!isActive[i]) + continue; + cf = probers[i].GetConfidence(); + if (bestConf < cf) { + bestConf = cf; + bestGuess = i; + } + } + } + return bestConf; + } + + public override void DumpStatus() + { + float cf; + GetConfidence(); + for (int i = 0; i < PROBERS_NUM; i++) { + if (!isActive[i]) { + //Console.WriteLine(" MBCS inactive: {0} (confidence is too low).", ProberName[i]); + } else { + cf = probers[i].GetConfidence(); + //Console.WriteLine(" MBCS {0}: [{1}]", cf, ProberName[i]); + } + } + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/MBCSSM.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/MBCSSM.cs new file mode 100644 index 000000000..7aa8581bc --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/MBCSSM.cs @@ -0,0 +1,640 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class UTF8SMModel : SMModel + { + private readonly static int[] UTF8_cls = { + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 00 - 07 + BitPackage.Pack4bits(1,1,1,1,1,1,0,0), // 08 - 0f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 10 - 17 + BitPackage.Pack4bits(1,1,1,0,1,1,1,1), // 18 - 1f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 20 - 27 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 28 - 2f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 30 - 37 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 38 - 3f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 40 - 47 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 48 - 4f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 50 - 57 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 58 - 5f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 60 - 67 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 68 - 6f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 70 - 77 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 78 - 7f + BitPackage.Pack4bits(2,2,2,2,3,3,3,3), // 80 - 87 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 88 - 8f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 90 - 97 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 98 - 9f + BitPackage.Pack4bits(5,5,5,5,5,5,5,5), // a0 - a7 + BitPackage.Pack4bits(5,5,5,5,5,5,5,5), // a8 - af + BitPackage.Pack4bits(5,5,5,5,5,5,5,5), // b0 - b7 + BitPackage.Pack4bits(5,5,5,5,5,5,5,5), // b8 - bf + BitPackage.Pack4bits(0,0,6,6,6,6,6,6), // c0 - c7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // c8 - cf + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // d0 - d7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // d8 - df + BitPackage.Pack4bits(7,8,8,8,8,8,8,8), // e0 - e7 + BitPackage.Pack4bits(8,8,8,8,8,9,8,8), // e8 - ef + BitPackage.Pack4bits(10,11,11,11,11,11,11,11), // f0 - f7 + BitPackage.Pack4bits(12,13,13,13,14,15,0,0) // f8 - ff + }; + + private readonly static int[] UTF8_st = { + BitPackage.Pack4bits(ERROR,START,ERROR,ERROR,ERROR,ERROR, 12, 10),//00-07 + BitPackage.Pack4bits( 9, 11, 8, 7, 6, 5, 4, 3),//08-0f + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//10-17 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//18-1f + BitPackage.Pack4bits(ITSME,ITSME,ITSME,ITSME,ITSME,ITSME,ITSME,ITSME),//20-27 + BitPackage.Pack4bits(ITSME,ITSME,ITSME,ITSME,ITSME,ITSME,ITSME,ITSME),//28-2f + BitPackage.Pack4bits(ERROR,ERROR, 5, 5, 5, 5,ERROR,ERROR),//30-37 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//38-3f + BitPackage.Pack4bits(ERROR,ERROR,ERROR, 5, 5, 5,ERROR,ERROR),//40-47 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//48-4f + BitPackage.Pack4bits(ERROR,ERROR, 7, 7, 7, 7,ERROR,ERROR),//50-57 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//58-5f + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR, 7, 7,ERROR,ERROR),//60-67 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//68-6f + BitPackage.Pack4bits(ERROR,ERROR, 9, 9, 9, 9,ERROR,ERROR),//70-77 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//78-7f + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR, 9,ERROR,ERROR),//80-87 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//88-8f + BitPackage.Pack4bits(ERROR,ERROR, 12, 12, 12, 12,ERROR,ERROR),//90-97 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//98-9f + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR, 12,ERROR,ERROR),//a0-a7 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//a8-af + BitPackage.Pack4bits(ERROR,ERROR, 12, 12, 12,ERROR,ERROR,ERROR),//b0-b7 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR),//b8-bf + BitPackage.Pack4bits(ERROR,ERROR,START,START,START,START,ERROR,ERROR),//c0-c7 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR) //c8-cf + }; + + private readonly static int[] UTF8CharLenTable = + {0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6 }; + + public UTF8SMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, UTF8_cls), + 16, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, UTF8_st), + UTF8CharLenTable, "UTF-8") + { + + } + } + + public class GB18030SMModel : SMModel + { + private readonly static int[] GB18030_cls = { + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 00 - 07 + BitPackage.Pack4bits(1,1,1,1,1,1,0,0), // 08 - 0f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 10 - 17 + BitPackage.Pack4bits(1,1,1,0,1,1,1,1), // 18 - 1f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 20 - 27 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 28 - 2f + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // 30 - 37 + BitPackage.Pack4bits(3,3,1,1,1,1,1,1), // 38 - 3f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 40 - 47 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 48 - 4f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 50 - 57 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 58 - 5f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 60 - 67 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 68 - 6f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 70 - 77 + BitPackage.Pack4bits(2,2,2,2,2,2,2,4), // 78 - 7f + BitPackage.Pack4bits(5,6,6,6,6,6,6,6), // 80 - 87 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // 88 - 8f + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // 90 - 97 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // 98 - 9f + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // a0 - a7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // a8 - af + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // b0 - b7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // b8 - bf + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // c0 - c7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // c8 - cf + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // d0 - d7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // d8 - df + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // e0 - e7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // e8 - ef + BitPackage.Pack4bits(6,6,6,6,6,6,6,6), // f0 - f7 + BitPackage.Pack4bits(6,6,6,6,6,6,6,0) // f8 - ff + }; + + private readonly static int[] GB18030_st = { + BitPackage.Pack4bits(ERROR,START,START,START,START,START, 3,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ITSME,ITSME),//08-0f + BitPackage.Pack4bits(ITSME,ITSME,ITSME,ITSME,ITSME,ERROR,ERROR,START),//10-17 + BitPackage.Pack4bits( 4,ERROR,START,START,ERROR,ERROR,ERROR,ERROR),//18-1f + BitPackage.Pack4bits(ERROR,ERROR, 5,ERROR,ERROR,ERROR,ITSME,ERROR),//20-27 + BitPackage.Pack4bits(ERROR,ERROR,START,START,START,START,START,START) //28-2f + }; + + // To be accurate, the length of class 6 can be either 2 or 4. + // But it is not necessary to discriminate between the two since + // it is used for frequency analysis only, and we are validating + // each code range there as well. So it is safe to set it to be + // 2 here. + private readonly static int[] GB18030CharLenTable = {0, 1, 1, 1, 1, 1, 2}; + + public GB18030SMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, GB18030_cls), + 7, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, GB18030_st), + GB18030CharLenTable, "GB18030") + { + + } + } + + public class BIG5SMModel : SMModel + { + private readonly static int[] BIG5_cls = { + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 00 - 07 + BitPackage.Pack4bits(1,1,1,1,1,1,0,0), // 08 - 0f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 10 - 17 + BitPackage.Pack4bits(1,1,1,0,1,1,1,1), // 18 - 1f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 20 - 27 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 28 - 2f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 30 - 37 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 38 - 3f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 40 - 47 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 48 - 4f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 50 - 57 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 58 - 5f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 60 - 67 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 68 - 6f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 70 - 77 + BitPackage.Pack4bits(2,2,2,2,2,2,2,1), // 78 - 7f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 80 - 87 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 88 - 8f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 90 - 97 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 98 - 9f + BitPackage.Pack4bits(4,3,3,3,3,3,3,3), // a0 - a7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // a8 - af + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // b0 - b7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // b8 - bf + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // c0 - c7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // c8 - cf + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // d0 - d7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // d8 - df + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // e0 - e7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // e8 - ef + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // f0 - f7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,0) // f8 - ff + }; + + private readonly static int[] BIG5_st = { + BitPackage.Pack4bits(ERROR,START,START, 3,ERROR,ERROR,ERROR,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ITSME,ITSME,ITSME,ITSME,ITSME,ERROR),//08-0f + BitPackage.Pack4bits(ERROR,START,START,START,START,START,START,START) //10-17 + }; + + private readonly static int[] BIG5CharLenTable = {0, 1, 1, 2, 0}; + + public BIG5SMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, BIG5_cls), + 5, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, BIG5_st), + BIG5CharLenTable, "Big5") + { + + } + } + + public class EUCJPSMModel : SMModel + { + private readonly static int[] EUCJP_cls = { + //BitPacket.Pack4bits(5,4,4,4,4,4,4,4), // 00 - 07 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 00 - 07 + BitPackage.Pack4bits(4,4,4,4,4,4,5,5), // 08 - 0f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 10 - 17 + BitPackage.Pack4bits(4,4,4,5,4,4,4,4), // 18 - 1f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 20 - 27 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 28 - 2f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 30 - 37 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 38 - 3f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 40 - 47 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 48 - 4f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 50 - 57 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 58 - 5f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 60 - 67 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 68 - 6f + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 70 - 77 + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // 78 - 7f + BitPackage.Pack4bits(5,5,5,5,5,5,5,5), // 80 - 87 + BitPackage.Pack4bits(5,5,5,5,5,5,1,3), // 88 - 8f + BitPackage.Pack4bits(5,5,5,5,5,5,5,5), // 90 - 97 + BitPackage.Pack4bits(5,5,5,5,5,5,5,5), // 98 - 9f + BitPackage.Pack4bits(5,2,2,2,2,2,2,2), // a0 - a7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a8 - af + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b0 - b7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b8 - bf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c0 - c7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c8 - cf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d0 - d7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d8 - df + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // e0 - e7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // e8 - ef + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // f0 - f7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,5) // f8 - ff + }; + + private readonly static int[] EUCJP_st = { + BitPackage.Pack4bits( 3, 4, 3, 5,START,ERROR,ERROR,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ITSME,ITSME,ITSME,ITSME),//08-0f + BitPackage.Pack4bits(ITSME,ITSME,START,ERROR,START,ERROR,ERROR,ERROR),//10-17 + BitPackage.Pack4bits(ERROR,ERROR,START,ERROR,ERROR,ERROR, 3,ERROR),//18-1f + BitPackage.Pack4bits( 3,ERROR,ERROR,ERROR,START,START,START,START) //20-27 + }; + + private readonly static int[] EUCJPCharLenTable = { 2, 2, 2, 3, 1, 0 }; + + public EUCJPSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, EUCJP_cls), + 6, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, EUCJP_st), + EUCJPCharLenTable, "EUC-JP") + { + + } + } + + public class EUCKRSMModel : SMModel + { + private readonly static int[] EUCKR_cls = { + //BitPacket.Pack4bits(0,1,1,1,1,1,1,1), // 00 - 07 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 00 - 07 + BitPackage.Pack4bits(1,1,1,1,1,1,0,0), // 08 - 0f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 10 - 17 + BitPackage.Pack4bits(1,1,1,0,1,1,1,1), // 18 - 1f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 20 - 27 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 28 - 2f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 30 - 37 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 38 - 3f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 40 - 47 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 48 - 4f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 50 - 57 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 58 - 5f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 60 - 67 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 68 - 6f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 70 - 77 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 78 - 7f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 80 - 87 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 88 - 8f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 90 - 97 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 98 - 9f + BitPackage.Pack4bits(0,2,2,2,2,2,2,2), // a0 - a7 + BitPackage.Pack4bits(2,2,2,2,2,3,3,3), // a8 - af + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b0 - b7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b8 - bf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c0 - c7 + BitPackage.Pack4bits(2,3,2,2,2,2,2,2), // c8 - cf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d0 - d7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d8 - df + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e0 - e7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // e8 - ef + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // f0 - f7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,0) // f8 - ff + }; + + private readonly static int[] EUCKR_st = { + BitPackage.Pack4bits(ERROR,START, 3,ERROR,ERROR,ERROR,ERROR,ERROR),//00-07 + BitPackage.Pack4bits(ITSME,ITSME,ITSME,ITSME,ERROR,ERROR,START,START) //08-0f + }; + + private readonly static int[] EUCKRCharLenTable = { 0, 1, 2, 0 }; + + public EUCKRSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, EUCKR_cls), + 4, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, EUCKR_st), + EUCKRCharLenTable, "EUC-KR") + { + + } + } + + public class EUCTWSMModel : SMModel + { + private readonly static int[] EUCTW_cls = { + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 00 - 07 + BitPackage.Pack4bits(2,2,2,2,2,2,0,0), // 08 - 0f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 10 - 17 + BitPackage.Pack4bits(2,2,2,0,2,2,2,2), // 18 - 1f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 20 - 27 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 28 - 2f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 30 - 37 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 38 - 3f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 40 - 47 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 48 - 4f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 50 - 57 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 58 - 5f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 60 - 67 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 68 - 6f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 70 - 77 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 78 - 7f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 80 - 87 + BitPackage.Pack4bits(0,0,0,0,0,0,6,0), // 88 - 8f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 90 - 97 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 98 - 9f + BitPackage.Pack4bits(0,3,4,4,4,4,4,4), // a0 - a7 + BitPackage.Pack4bits(5,5,1,1,1,1,1,1), // a8 - af + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // b0 - b7 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // b8 - bf + BitPackage.Pack4bits(1,1,3,1,3,3,3,3), // c0 - c7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // c8 - cf + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // d0 - d7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // d8 - df + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // e0 - e7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // e8 - ef + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // f0 - f7 + BitPackage.Pack4bits(3,3,3,3,3,3,3,0) // f8 - ff + }; + + private readonly static int[] EUCTW_st = { + BitPackage.Pack4bits(ERROR,ERROR,START, 3, 3, 3, 4,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ITSME,ITSME),//08-0f + BitPackage.Pack4bits(ITSME,ITSME,ITSME,ITSME,ITSME,ERROR,START,ERROR),//10-17 + BitPackage.Pack4bits(START,START,START,ERROR,ERROR,ERROR,ERROR,ERROR),//18-1f + BitPackage.Pack4bits( 5,ERROR,ERROR,ERROR,START,ERROR,START,START),//20-27 + BitPackage.Pack4bits(START,ERROR,START,START,START,START,START,START) //28-2f + }; + + private readonly static int[] EUCTWCharLenTable = { 0, 0, 1, 2, 2, 2, 3 }; + + public EUCTWSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, EUCTW_cls), + 7, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, EUCTW_st), + EUCTWCharLenTable, "EUC-TW") + { + + } + } + + public class SJISSMModel : SMModel + { + private readonly static int[] SJIS_cls = { + //BitPacket.Pack4bits(0,1,1,1,1,1,1,1), // 00 - 07 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 00 - 07 + BitPackage.Pack4bits(1,1,1,1,1,1,0,0), // 08 - 0f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 10 - 17 + BitPackage.Pack4bits(1,1,1,0,1,1,1,1), // 18 - 1f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 20 - 27 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 28 - 2f + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 30 - 37 + BitPackage.Pack4bits(1,1,1,1,1,1,1,1), // 38 - 3f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 40 - 47 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 48 - 4f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 50 - 57 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 58 - 5f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 60 - 67 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 68 - 6f + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // 70 - 77 + BitPackage.Pack4bits(2,2,2,2,2,2,2,1), // 78 - 7f + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // 80 - 87 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // 88 - 8f + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // 90 - 97 + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // 98 - 9f + //0xa0 is illegal in sjis encoding, but some pages does + //contain such byte. We need to be more error forgiven. + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a0 - a7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // a8 - af + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b0 - b7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // b8 - bf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c0 - c7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // c8 - cf + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d0 - d7 + BitPackage.Pack4bits(2,2,2,2,2,2,2,2), // d8 - df + BitPackage.Pack4bits(3,3,3,3,3,3,3,3), // e0 - e7 + BitPackage.Pack4bits(3,3,3,3,3,4,4,4), // e8 - ef + BitPackage.Pack4bits(4,4,4,4,4,4,4,4), // f0 - f7 + BitPackage.Pack4bits(4,4,4,4,4,0,0,0) // f8 - ff + }; + + private readonly static int[] SJIS_st = { + BitPackage.Pack4bits(ERROR,START,START, 3,ERROR,ERROR,ERROR,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ITSME,ITSME,ITSME,ITSME),//08-0f + BitPackage.Pack4bits(ITSME,ITSME,ERROR,ERROR,START,START,START,START) //10-17 + }; + + private readonly static int[] SJISCharLenTable = { 0, 1, 1, 2, 0, 0 }; + + public SJISSMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, SJIS_cls), + 6, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, SJIS_st), + SJISCharLenTable, "Shift_JIS") + { + + } + } + + public class UCS2BESMModel : SMModel + { + private readonly static int[] UCS2BE_cls = { + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 00 - 07 + BitPackage.Pack4bits(0,0,1,0,0,2,0,0), // 08 - 0f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 10 - 17 + BitPackage.Pack4bits(0,0,0,3,0,0,0,0), // 18 - 1f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 20 - 27 + BitPackage.Pack4bits(0,3,3,3,3,3,0,0), // 28 - 2f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 30 - 37 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 38 - 3f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 40 - 47 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 48 - 4f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 50 - 57 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 58 - 5f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 60 - 67 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 68 - 6f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 70 - 77 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 78 - 7f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 80 - 87 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 88 - 8f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 90 - 97 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 98 - 9f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // a0 - a7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // a8 - af + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // b0 - b7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // b8 - bf + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // c0 - c7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // c8 - cf + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // d0 - d7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // d8 - df + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // e0 - e7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // e8 - ef + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // f0 - f7 + BitPackage.Pack4bits(0,0,0,0,0,0,4,5) // f8 - ff + }; + + private readonly static int[] UCS2BE_st = { + BitPackage.Pack4bits( 5, 7, 7,ERROR, 4, 3,ERROR,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ITSME,ITSME,ITSME,ITSME),//08-0f + BitPackage.Pack4bits(ITSME,ITSME, 6, 6, 6, 6,ERROR,ERROR),//10-17 + BitPackage.Pack4bits( 6, 6, 6, 6, 6,ITSME, 6, 6),//18-1f + BitPackage.Pack4bits( 6, 6, 6, 6, 5, 7, 7,ERROR),//20-27 + BitPackage.Pack4bits( 5, 8, 6, 6,ERROR, 6, 6, 6),//28-2f + BitPackage.Pack4bits( 6, 6, 6, 6,ERROR,ERROR,START,START) //30-37 + }; + + private readonly static int[] UCS2BECharLenTable = { 2, 2, 2, 0, 2, 2 }; + + public UCS2BESMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, UCS2BE_cls), + 6, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, UCS2BE_st), + UCS2BECharLenTable, "UTF-16BE") + { + + } + } + + public class UCS2LESMModel : SMModel + { + private readonly static int[] UCS2LE_cls = { + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 00 - 07 + BitPackage.Pack4bits(0,0,1,0,0,2,0,0), // 08 - 0f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 10 - 17 + BitPackage.Pack4bits(0,0,0,3,0,0,0,0), // 18 - 1f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 20 - 27 + BitPackage.Pack4bits(0,3,3,3,3,3,0,0), // 28 - 2f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 30 - 37 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 38 - 3f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 40 - 47 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 48 - 4f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 50 - 57 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 58 - 5f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 60 - 67 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 68 - 6f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 70 - 77 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 78 - 7f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 80 - 87 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 88 - 8f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 90 - 97 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // 98 - 9f + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // a0 - a7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // a8 - af + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // b0 - b7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // b8 - bf + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // c0 - c7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // c8 - cf + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // d0 - d7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // d8 - df + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // e0 - e7 + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // e8 - ef + BitPackage.Pack4bits(0,0,0,0,0,0,0,0), // f0 - f7 + BitPackage.Pack4bits(0,0,0,0,0,0,4,5) // f8 - ff + }; + + private readonly static int[] UCS2LE_st = { + BitPackage.Pack4bits( 6, 6, 7, 6, 4, 3,ERROR,ERROR),//00-07 + BitPackage.Pack4bits(ERROR,ERROR,ERROR,ERROR,ITSME,ITSME,ITSME,ITSME),//08-0f + BitPackage.Pack4bits(ITSME,ITSME, 5, 5, 5,ERROR,ITSME,ERROR),//10-17 + BitPackage.Pack4bits( 5, 5, 5,ERROR, 5,ERROR, 6, 6),//18-1f + BitPackage.Pack4bits( 7, 6, 8, 8, 5, 5, 5,ERROR),//20-27 + BitPackage.Pack4bits( 5, 5, 5,ERROR,ERROR,ERROR, 5, 5),//28-2f + BitPackage.Pack4bits( 5, 5, 5,ERROR, 5,ERROR,START,START) //30-37 + }; + + private readonly static int[] UCS2LECharLenTable = { 2, 2, 2, 2, 2, 2 }; + + public UCS2LESMModel() : base( + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, UCS2LE_cls), + 6, + new BitPackage(BitPackage.INDEX_SHIFT_4BITS, + BitPackage.SHIFT_MASK_4BITS, + BitPackage.BIT_SHIFT_4BITS, + BitPackage.UNIT_MASK_4BITS, UCS2LE_st), + UCS2LECharLenTable, "UTF-16LE") + { + + } + } + + +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SBCSGroupProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SBCSGroupProber.cs new file mode 100644 index 000000000..d8f496474 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SBCSGroupProber.cs @@ -0,0 +1,180 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System; + +namespace UniversalDetector.Core +{ + public class SBCSGroupProber : CharsetProber + { + private const int PROBERS_NUM = 13; + private CharsetProber[] probers = new CharsetProber[PROBERS_NUM]; + private bool[] isActive = new bool[PROBERS_NUM]; + private int bestGuess; + private int activeNum; + + public SBCSGroupProber() + { + probers[0] = new SingleByteCharSetProber(new Win1251Model()); + probers[1] = new SingleByteCharSetProber(new Koi8rModel()); + probers[2] = new SingleByteCharSetProber(new Latin5Model()); + probers[3] = new SingleByteCharSetProber(new MacCyrillicModel()); + probers[4] = new SingleByteCharSetProber(new Ibm866Model()); + probers[5] = new SingleByteCharSetProber(new Ibm855Model()); + probers[6] = new SingleByteCharSetProber(new Latin7Model()); + probers[7] = new SingleByteCharSetProber(new Win1253Model()); + probers[8] = new SingleByteCharSetProber(new Latin5BulgarianModel()); + probers[9] = new SingleByteCharSetProber(new Win1251BulgarianModel()); + HebrewProber hebprober = new HebrewProber(); + probers[10] = hebprober; + // Logical + probers[11] = new SingleByteCharSetProber(new Win1255Model(), false, hebprober); + // Visual + probers[12] = new SingleByteCharSetProber(new Win1255Model(), true, hebprober); + hebprober.SetModelProbers(probers[11], probers[12]); + // disable latin2 before latin1 is available, otherwise all latin1 + // will be detected as latin2 because of their similarity. + //probers[13] = new SingleByteCharSetProber(new Latin2HungarianModel()); + //probers[14] = new SingleByteCharSetProber(new Win1250HungarianModel()); + Reset(); + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + ProbingState st = ProbingState.NotMe; + + //apply filter to original buffer, and we got new buffer back + //depend on what script it is, we will feed them the new buffer + //we got after applying proper filter + //this is done without any consideration to KeepEnglishLetters + //of each prober since as of now, there are no probers here which + //recognize languages with English characters. + byte[] newBuf = FilterWithoutEnglishLetters(buf, offset, len); + if (newBuf.Length == 0) + return state; // Nothing to see here, move on. + + for (int i = 0; i < PROBERS_NUM; i++) { + if (!isActive[i]) + continue; + st = probers[i].HandleData(newBuf, 0, newBuf.Length); + + if (st == ProbingState.FoundIt) { + bestGuess = i; + state = ProbingState.FoundIt; + break; + } else if (st == ProbingState.NotMe) { + isActive[i] = false; + activeNum--; + if (activeNum <= 0) { + state = ProbingState.NotMe; + break; + } + } + } + return state; + } + + public override float GetConfidence() + { + float bestConf = 0.0f, cf; + switch (state) { + case ProbingState.FoundIt: + return 0.99f; //sure yes + case ProbingState.NotMe: + return 0.01f; //sure no + default: + for (int i = 0; i < PROBERS_NUM; i++) + { + if (!isActive[i]) + continue; + cf = probers[i].GetConfidence(); + if (bestConf < cf) + { + bestConf = cf; + bestGuess = i; + } + } + break; + } + return bestConf; + } + + public override void DumpStatus() + { + float cf = GetConfidence(); + // Console.WriteLine(" SBCS Group Prober --------begin status"); + for (int i = 0; i < PROBERS_NUM; i++) { + if (isActive[i]) + probers[i].DumpStatus(); + //else + //Console.WriteLine(" inactive: [{0}] (i.e. confidence is too low).", probers[i].GetCharsetName()); + + } + //Console.WriteLine(" SBCS Group found best match [{0}] confidence {1}.", probers[bestGuess].GetCharsetName(), cf); + } + + public override void Reset () + { + int activeNum = 0; + for (int i = 0; i < PROBERS_NUM; i++) { + if (probers[i] != null) { + probers[i].Reset(); + isActive[i] = true; + activeNum++; + } else { + isActive[i] = false; + } + } + bestGuess = -1; + state = ProbingState.Detecting; + } + + public override string GetCharsetName() + { + //if we have no answer yet + if (bestGuess == -1) { + GetConfidence(); + //no charset seems positive + if (bestGuess == -1) + bestGuess = 0; + } + return probers[bestGuess].GetCharsetName(); + } + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SBCharsetProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SBCharsetProber.cs new file mode 100644 index 000000000..5a3496075 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SBCharsetProber.cs @@ -0,0 +1,170 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System; + +namespace UniversalDetector.Core +{ + + public class SingleByteCharSetProber : CharsetProber + { + private const int SAMPLE_SIZE = 64; + private const int SB_ENOUGH_REL_THRESHOLD = 1024; + private const float POSITIVE_SHORTCUT_THRESHOLD = 0.95f; + private const float NEGATIVE_SHORTCUT_THRESHOLD = 0.05f; + private const int SYMBOL_CAT_ORDER = 250; + private const int NUMBER_OF_SEQ_CAT = 4; + private const int POSITIVE_CAT = NUMBER_OF_SEQ_CAT-1; + private const int NEGATIVE_CAT = 0; + + protected SequenceModel model; + + // true if we need to reverse every pair in the model lookup + bool reversed; + + // char order of last character + byte lastOrder; + + int totalSeqs; + int totalChar; + int[] seqCounters = new int[NUMBER_OF_SEQ_CAT]; + + // characters that fall in our sampling range + int freqChar; + + // Optional auxiliary prober for name decision. created and destroyed by the GroupProber + CharsetProber nameProber; + + public SingleByteCharSetProber(SequenceModel model) + : this(model, false, null) + { + + } + + public SingleByteCharSetProber(SequenceModel model, bool reversed, + CharsetProber nameProber) + { + this.model = model; + this.reversed = reversed; + this.nameProber = nameProber; + Reset(); + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int max = offset + len; + + for (int i = offset; i < max; i++) { + byte order = model.GetOrder(buf[i]); + + if (order < SYMBOL_CAT_ORDER) + totalChar++; + + if (order < SAMPLE_SIZE) { + freqChar++; + + if (lastOrder < SAMPLE_SIZE) { + totalSeqs++; + if (!reversed) + ++(seqCounters[model.GetPrecedence(lastOrder*SAMPLE_SIZE+order)]); + else // reverse the order of the letters in the lookup + ++(seqCounters[model.GetPrecedence(order*SAMPLE_SIZE+lastOrder)]); + } + } + lastOrder = order; + } + + if (state == ProbingState.Detecting) { + if (totalSeqs > SB_ENOUGH_REL_THRESHOLD) { + float cf = GetConfidence(); + if (cf > POSITIVE_SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + else if (cf < NEGATIVE_SHORTCUT_THRESHOLD) + state = ProbingState.NotMe; + } + } + return state; + } + + public override void DumpStatus() + { + //Console.WriteLine(" SBCS: {0} [{1}]", GetConfidence(), GetCharsetName()); + } + + public override float GetConfidence() + { + /* + NEGATIVE_APPROACH + if (totalSeqs > 0) { + if (totalSeqs > seqCounters[NEGATIVE_CAT] * 10) + return (totalSeqs - seqCounters[NEGATIVE_CAT] * 10)/totalSeqs * freqChar / mTotalChar; + } + return 0.01f; + */ + // POSITIVE_APPROACH + float r = 0.0f; + + if (totalSeqs > 0) { + r = 1.0f * seqCounters[POSITIVE_CAT] / totalSeqs / model.TypicalPositiveRatio; + r = r * freqChar / totalChar; + if (r >= 1.0f) + r = 0.99f; + return r; + } + return 0.01f; + } + + public override void Reset() + { + state = ProbingState.Detecting; + lastOrder = 255; + for (int i = 0; i < NUMBER_OF_SEQ_CAT; i++) + seqCounters[i] = 0; + totalSeqs = 0; + totalChar = 0; + freqChar = 0; + } + + public override string GetCharsetName() + { + return (nameProber == null) ? model.CharsetName + : nameProber.GetCharsetName(); + } + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SJISProber.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SJISProber.cs new file mode 100644 index 000000000..515cd2498 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SJISProber.cs @@ -0,0 +1,116 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + /// <summary> + /// for S-JIS encoding, observe characteristic: + /// 1, kana character (or hankaku?) often have hight frequency of appereance + /// 2, kana character often exist in group + /// 3, certain combination of kana is never used in japanese language + /// </summary> + public class SJISProber : CharsetProber + { + private CodingStateMachine codingSM; + private SJISContextAnalyser contextAnalyser; + private SJISDistributionAnalyser distributionAnalyser; + private byte[] lastChar = new byte[2]; + + public SJISProber() + { + codingSM = new CodingStateMachine(new SJISSMModel()); + distributionAnalyser = new SJISDistributionAnalyser(); + contextAnalyser = new SJISContextAnalyser(); + Reset(); + } + + public override string GetCharsetName() + { + return "Shift-JIS"; + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int codingState; + int max = offset + len; + + for (int i = offset; i < max; i++) { + codingState = codingSM.NextState(buf[i]); + if (codingState == SMModel.ERROR) { + state = ProbingState.NotMe; + break; + } + if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + break; + } + if (codingState == SMModel.START) { + int charLen = codingSM.CurrentCharLen; + if (i == offset) { + lastChar[1] = buf[offset]; + contextAnalyser.HandleOneChar(lastChar, 2-charLen, charLen); + distributionAnalyser.HandleOneChar(lastChar, 0, charLen); + } else { + contextAnalyser.HandleOneChar(buf, i+1-charLen, charLen); + distributionAnalyser.HandleOneChar(buf, i-1, charLen); + } + } + } + lastChar[0] = buf[max-1]; + if (state == ProbingState.Detecting) + if (contextAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + return state; + } + + public override void Reset() + { + codingSM.Reset(); + state = ProbingState.Detecting; + contextAnalyser.Reset(); + distributionAnalyser.Reset(); + } + + public override float GetConfidence() + { + float contxtCf = contextAnalyser.GetConfidence(); + float distribCf = distributionAnalyser.GetConfidence(); + return (contxtCf > distribCf ? contxtCf : distribCf); + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SMModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SMModel.cs new file mode 100644 index 000000000..2321ecad2 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SMModel.cs @@ -0,0 +1,83 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kohei TAKETA <k-tak@void.in> (Java port) + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System; + +namespace UniversalDetector.Core +{ + /// <summary> + /// State machine model + /// </summary> + public abstract class SMModel + { + public const int START = 0; + public const int ERROR = 1; + public const int ITSME = 2; + + public BitPackage classTable; + public BitPackage stateTable; + public int[] charLenTable; + + private string name; + + public string Name { + get { return name; } + } + + private int classFactor; + + public int ClassFactor { + get { return classFactor; } + } + + public SMModel(BitPackage classTable, int classFactor, + BitPackage stateTable, int[] charLenTable, String name) + { + this.classTable = classTable; + this.classFactor = classFactor; + this.stateTable = stateTable; + this.charLenTable = charLenTable; + this.name = name; + } + + public int GetClass(byte b) + { + return classTable.Unpack((int)b); + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SequenceModel.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SequenceModel.cs new file mode 100644 index 000000000..9048796b5 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/SequenceModel.cs @@ -0,0 +1,97 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System; + +namespace UniversalDetector.Core +{ + public abstract class SequenceModel + { + // [256] table use to find a char's order + protected byte[] charToOrderMap; + + // [SAMPLE_SIZE][SAMPLE_SIZE] table to find a 2-char sequence's + // frequency + protected byte[] precedenceMatrix; + + // freqSeqs / totalSeqs + protected float typicalPositiveRatio; + + public float TypicalPositiveRatio { + get { return typicalPositiveRatio; } + } + + // not used + protected bool keepEnglishLetter; + + public bool KeepEnglishLetter { + get { return keepEnglishLetter; } + } + + protected String charsetName; + + public string CharsetName { + get { return charsetName; } + } + + public SequenceModel( + byte[] charToOrderMap, + byte[] precedenceMatrix, + float typicalPositiveRatio, + bool keepEnglishLetter, + String charsetName) + { + this.charToOrderMap = charToOrderMap; + this.precedenceMatrix = precedenceMatrix; + this.typicalPositiveRatio = typicalPositiveRatio; + this.keepEnglishLetter = keepEnglishLetter; + this.charsetName = charsetName; + } + + public byte GetOrder(byte b) + { + return charToOrderMap[b]; + } + + public byte GetPrecedence(int pos) + { + return precedenceMatrix[pos]; + } + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/UTF8Prober.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/UTF8Prober.cs new file mode 100644 index 000000000..084797c5e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/UTF8Prober.cs @@ -0,0 +1,112 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + public class UTF8Prober : CharsetProber + { + private static float ONE_CHAR_PROB = 0.50f; + private CodingStateMachine codingSM; + private int numOfMBChar; + + public UTF8Prober() + { + numOfMBChar = 0; + codingSM = new CodingStateMachine(new UTF8SMModel()); + Reset(); + } + + public override string GetCharsetName() { + return "UTF-8"; + } + + public override void Reset() + { + codingSM.Reset(); + numOfMBChar = 0; + state = ProbingState.Detecting; + } + + public override ProbingState HandleData(byte[] buf, int offset, int len) + { + int codingState = SMModel.START; + int max = offset + len; + + for (int i = offset; i < max; i++) { + + codingState = codingSM.NextState(buf[i]); + + if (codingState == SMModel.ERROR) { + state = ProbingState.NotMe; + break; + } + + if (codingState == SMModel.ITSME) { + state = ProbingState.FoundIt; + break; + } + + if (codingState == SMModel.START) { + if (codingSM.CurrentCharLen >= 2) + numOfMBChar++; + } + } + + if (state == ProbingState.Detecting) + if (GetConfidence() > SHORTCUT_THRESHOLD) + state = ProbingState.FoundIt; + return state; + } + + public override float GetConfidence() + { + float unlike = 0.99f; + float confidence = 0.0f; + + if (numOfMBChar < 6) { + for (int i = 0; i < numOfMBChar; i++) + unlike *= ONE_CHAR_PROB; + confidence = 1.0f - unlike; + } else { + confidence = 0.99f; + } + return confidence; + + } + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/UniversalDetector.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/UniversalDetector.cs new file mode 100644 index 000000000..0c9a4ee60 --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/Core/UniversalDetector.cs @@ -0,0 +1,257 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector.Core +{ + + enum InputState { PureASCII=0, EscASCII=1, Highbyte=2 }; + + public abstract class UniversalDetector + { + protected const int FILTER_CHINESE_SIMPLIFIED = 1; + protected const int FILTER_CHINESE_TRADITIONAL = 2; + protected const int FILTER_JAPANESE = 4; + protected const int FILTER_KOREAN = 8; + protected const int FILTER_NON_CJK = 16; + protected const int FILTER_ALL = 31; + protected static int FILTER_CHINESE = + FILTER_CHINESE_SIMPLIFIED | FILTER_CHINESE_TRADITIONAL; + protected static int FILTER_CJK = + FILTER_JAPANESE | FILTER_KOREAN | FILTER_CHINESE_SIMPLIFIED + | FILTER_CHINESE_TRADITIONAL; + + protected const float SHORTCUT_THRESHOLD = 0.95f; + protected const float MINIMUM_THRESHOLD = 0.20f; + + internal InputState inputState; + protected bool start; + protected bool gotData; + protected bool done; + protected byte lastChar; + protected int bestGuess; + protected const int PROBERS_NUM = 3; + protected int languageFilter; + protected CharsetProber[] charsetProbers = new CharsetProber[PROBERS_NUM]; + protected CharsetProber escCharsetProber; + protected string detectedCharset; + + public UniversalDetector(int languageFilter) { + this.start = true; + this.inputState = InputState.PureASCII; + this.lastChar = 0x00; + this.bestGuess = -1; + this.languageFilter = languageFilter; + } + + public virtual void Feed(byte[] buf, int offset, int len) + { + if (done) { + return; + } + + if (len > 0) + gotData = true; + + // If the data starts with BOM, we know it is UTF + if (start) { + start = false; + if (len > 3) { + switch (buf[0]) { + case 0xEF: + if (0xBB == buf[1] && 0xBF == buf[2]) + detectedCharset = "UTF-8"; + break; + case 0xFE: + if (0xFF == buf[1] && 0x00 == buf[2] && 0x00 == buf[3]) + // FE FF 00 00 UCS-4, unusual octet order BOM (3412) + detectedCharset = "X-ISO-10646-UCS-4-3412"; + else if (0xFF == buf[1]) + detectedCharset = "UTF-16BE"; + break; + case 0x00: + if (0x00 == buf[1] && 0xFE == buf[2] && 0xFF == buf[3]) + detectedCharset = "UTF-32BE"; + else if (0x00 == buf[1] && 0xFF == buf[2] && 0xFE == buf[3]) + // 00 00 FF FE UCS-4, unusual octet order BOM (2143) + detectedCharset = "X-ISO-10646-UCS-4-2143"; + break; + case 0xFF: + if (0xFE == buf[1] && 0x00 == buf[2] && 0x00 == buf[3]) + detectedCharset = "UTF-32LE"; + else if (0xFE == buf[1]) + detectedCharset = "UTF-16LE"; + break; + } // switch + } + if (detectedCharset != null) { + done = true; + return; + } + } + + for (int i = 0; i < len; i++) { + + // other than 0xa0, if every other character is ascii, the page is ascii + if ((buf[i] & 0x80) != 0 && buf[i] != 0xA0) { + // we got a non-ascii byte (high-byte) + if (inputState != InputState.Highbyte) { + inputState = InputState.Highbyte; + + // kill EscCharsetProber if it is active + if (escCharsetProber != null) { + escCharsetProber = null; + } + + // start multibyte and singlebyte charset prober + if (charsetProbers[0] == null) + charsetProbers[0] = new MBCSGroupProber(); + if (charsetProbers[1] == null) + charsetProbers[1] = new SBCSGroupProber(); + if (charsetProbers[2] == null) + charsetProbers[2] = new Latin1Prober(); + } + } else { + if (inputState == InputState.PureASCII && + (buf[i] == 0x33 || (buf[i] == 0x7B && lastChar == 0x7E))) { + // found escape character or HZ "~{" + inputState = InputState.EscASCII; + } + lastChar = buf[i]; + } + } + + ProbingState st = ProbingState.NotMe; + + switch (inputState) { + case InputState.EscASCII: + if (escCharsetProber == null) { + escCharsetProber = new EscCharsetProber(); + } + st = escCharsetProber.HandleData(buf, offset, len); + if (st == ProbingState.FoundIt) { + done = true; + detectedCharset = escCharsetProber.GetCharsetName(); + } + break; + case InputState.Highbyte: + for (int i = 0; i < PROBERS_NUM; i++) { + if (charsetProbers[i] != null) { + st = charsetProbers[i].HandleData(buf, offset, len); + #if DEBUG + charsetProbers[i].DumpStatus(); + #endif + if (st == ProbingState.FoundIt) { + done = true; + detectedCharset = charsetProbers[i].GetCharsetName(); + return; + } + } + } + break; + default: + // pure ascii + break; + } + return; + } + + /// <summary> + /// Notify detector that no further data is available. + /// </summary> + public virtual void DataEnd() + { + if (!gotData) { + // we haven't got any data yet, return immediately + // caller program sometimes call DataEnd before anything has + // been sent to detector + return; + } + + if (detectedCharset != null) { + done = true; + Report(detectedCharset, 1.0f); + return; + } + + if (inputState == InputState.Highbyte) { + float proberConfidence = 0.0f; + float maxProberConfidence = 0.0f; + int maxProber = 0; + for (int i = 0; i < PROBERS_NUM; i++) { + if (charsetProbers[i] != null) { + proberConfidence = charsetProbers[i].GetConfidence(); + if (proberConfidence > maxProberConfidence) { + maxProberConfidence = proberConfidence; + maxProber = i; + } + } + } + + if (maxProberConfidence > MINIMUM_THRESHOLD) { + Report(charsetProbers[maxProber].GetCharsetName(), maxProberConfidence); + } + + } else if (inputState == InputState.PureASCII) { + Report("ASCII", 1.0f); + } + } + + /// <summary> + /// Clear internal state of charset detector. + /// In the original interface this method is protected. + /// </summary> + public virtual void Reset() + { + done = false; + start = true; + detectedCharset = null; + gotData = false; + bestGuess = -1; + inputState = InputState.PureASCII; + lastChar = 0x00; + if (escCharsetProber != null) + escCharsetProber.Reset(); + for (int i = 0; i < PROBERS_NUM; i++) + if (charsetProbers[i] != null) + charsetProbers[i].Reset(); + } + + protected abstract void Report(string charset, float confidence); + + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/DetectionConfidence.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/DetectionConfidence.cs new file mode 100644 index 000000000..6dfa55f6c --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/DetectionConfidence.cs @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +namespace UniversalDetector +{ + /// <summary> + /// Indicate how confident the detection module about the return result. + /// + /// NoAnswerYet: the detector have not find out a answer yet based on + /// the data it received. + /// + /// BestAnswer: the answer the detector returned is the best one within + /// the knowledge of the detector. In other words, the test to all + /// other candidates fail. + /// For example, the (Shift_JIS/EUC-JP/ISO-2022-JP) detection + /// module may return this with answer "Shift_JIS " if it receive + /// bytes > 0x80 (which make ISO-2022-JP test failed) and byte + /// 0x82 (which may EUC-JP test failed) + /// + /// SureAnswer: the detector is 100% sure about the answer. + /// + /// Example 1: the Shift_JIS/ISO-2022-JP/EUC-JP detector return + /// this w/ ISO-2022-JP when it hit one of the following ESC seq + /// ESC ( J + /// ESC $ @ + /// ESC $ B + /// + /// Example 2: the detector which can detect UCS2 return w/ UCS2 + /// when the first 2 byte are BOM mark. + /// Example 3: the Korean detector return ISO-2022-KR when it + /// hit ESC $ ) C + /// </summary> + public enum DetectionConfidence + { + NoAnswerYet = 0, + BestAnswer, + SureAnswer, + NoAnswerMatch + } +} diff --git a/Emby.Server.Implementations/TextEncoding/UniversalDetector/ICharsetDetector.cs b/Emby.Server.Implementations/TextEncoding/UniversalDetector/ICharsetDetector.cs new file mode 100644 index 000000000..c0c35a59e --- /dev/null +++ b/Emby.Server.Implementations/TextEncoding/UniversalDetector/ICharsetDetector.cs @@ -0,0 +1,88 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Shy Shalom <shooshX@gmail.com> + * Rudi Pettazzi <rudi.pettazzi@gmail.com> (C# port) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +using System.IO; + +namespace UniversalDetector +{ + public interface ICharsetDetector + { + + /// <summary> + /// The detected charset. It can be null. + /// </summary> + string Charset { get; } + + /// <summary> + /// The confidence of the detected charset, if any + /// </summary> + float Confidence { get; } + + /// <summary> + /// Feed a block of bytes to the detector. + /// </summary> + /// <param name="buf">input buffer</param> + /// <param name="offset">offset into buffer</param> + /// <param name="len">number of available bytes</param> + void Feed(byte[] buf, int offset, int len); + + /// <summary> + /// Feed a bytes stream to the detector. + /// </summary> + /// <param name="stream">an input stream</param> + void Feed(Stream stream); + + /// <summary> + /// Resets the state of the detector. + /// </summary> + void Reset(); + + /// <summary> + /// Returns true if the detector has found a result and it is sure about it. + /// </summary> + /// <returns>true if the detector has detected the encoding</returns> + bool IsDone(); + + /// <summary> + /// Tell the detector that there is no more data and it must take its + /// decision. + /// </summary> + void DataEnd(); + + } +} diff --git a/Emby.Server.Implementations/Threading/CommonTimer.cs b/Emby.Server.Implementations/Threading/CommonTimer.cs new file mode 100644 index 000000000..bb67325d1 --- /dev/null +++ b/Emby.Server.Implementations/Threading/CommonTimer.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.Threading +{ + public class CommonTimer : ITimer + { + private readonly Timer _timer; + + public CommonTimer(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period) + { + _timer = new Timer(new TimerCallback(callback), state, dueTime, period); + } + + public CommonTimer(Action<object> callback, object state, int dueTimeMs, int periodMs) + { + _timer = new Timer(new TimerCallback(callback), state, dueTimeMs, periodMs); + } + + public void Change(TimeSpan dueTime, TimeSpan period) + { + _timer.Change(dueTime, period); + } + + public void Change(int dueTimeMs, int periodMs) + { + _timer.Change(dueTimeMs, periodMs); + } + + public void Dispose() + { + _timer.Dispose(); + GC.SuppressFinalize(this); + } + } +} diff --git a/Emby.Server.Implementations/Threading/TimerFactory.cs b/Emby.Server.Implementations/Threading/TimerFactory.cs new file mode 100644 index 000000000..4ab6f6fc4 --- /dev/null +++ b/Emby.Server.Implementations/Threading/TimerFactory.cs @@ -0,0 +1,18 @@ +using System; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.Threading +{ + public class TimerFactory : ITimerFactory + { + public ITimer Create(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period) + { + return new CommonTimer(callback, state, dueTime, period); + } + + public ITimer Create(Action<object> callback, object state, int dueTimeMs, int periodMs) + { + return new CommonTimer(callback, state, dueTimeMs, periodMs); + } + } +} diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 6e37c1dc1..180463040 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -122,7 +122,10 @@ namespace Emby.Server.Implementations.Updates private readonly ICryptoProvider _cryptographyProvider; - public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider) + // netframework or netcore + private readonly string _packageRuntime; + + public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, string packageRuntime) { if (logger == null) { @@ -140,6 +143,7 @@ namespace Emby.Server.Implementations.Updates _config = config; _fileSystem = fileSystem; _cryptographyProvider = cryptographyProvider; + _packageRuntime = packageRuntime; _logger = logger; } @@ -157,7 +161,7 @@ namespace Emby.Server.Implementations.Updates /// Gets all available packages. /// </summary> /// <returns>Task{List{PackageInfo}}.</returns> - public async Task<IEnumerable<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken, + public async Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken, bool withRegistration = true, string packageType = null, Version applicationVersion = null) @@ -171,11 +175,11 @@ namespace Emby.Server.Implementations.Updates { "systemid", _applicationHost.SystemId } }; - using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall", data, cancellationToken).ConfigureAwait(false)) + using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall?includeAllRuntimes=true", data, cancellationToken).ConfigureAwait(false)) { cancellationToken.ThrowIfCancellationRequested(); - var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(json).ToList(); + var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(json); return FilterPackages(packages, packageType, applicationVersion); } @@ -184,7 +188,7 @@ namespace Emby.Server.Implementations.Updates { var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); - return FilterPackages(packages.ToList(), packageType, applicationVersion); + return FilterPackages(packages, packageType, applicationVersion); } } @@ -195,21 +199,21 @@ namespace Emby.Server.Implementations.Updates /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{List{PackageInfo}}.</returns> - public async Task<IEnumerable<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken) + public async Task<List<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken) { _logger.Info("Opening {0}", PackageCachePath); try { using (var stream = _fileSystem.OpenRead(PackageCachePath)) { - var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList(); + var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream); if (DateTime.UtcNow - _lastPackageUpdateTime > GetCacheLength()) { UpdateCachedPackages(CancellationToken.None, false); } - return packages; + return FilterPackages(packages); } } catch (Exception) @@ -221,7 +225,7 @@ namespace Emby.Server.Implementations.Updates await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false); using (var stream = _fileSystem.OpenRead(PackageCachePath)) { - return _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList(); + return FilterPackages(_jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream)); } } @@ -244,7 +248,7 @@ namespace Emby.Server.Implementations.Updates var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions { - Url = "https://www.mb3admin.com/admin/service/MB3Packages.json", + Url = "https://www.mb3admin.com/admin/service/EmbyPackages.json", CancellationToken = cancellationToken, Progress = new SimpleProgress<Double>() @@ -277,57 +281,77 @@ namespace Emby.Server.Implementations.Updates private TimeSpan GetCacheLength() { - switch (GetSystemUpdateLevel()) - { - case PackageVersionClass.Beta: - return TimeSpan.FromMinutes(30); - case PackageVersionClass.Dev: - return TimeSpan.FromMinutes(3); - default: - return TimeSpan.FromHours(24); - } + return TimeSpan.FromMinutes(3); } - protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages) + protected List<PackageInfo> FilterPackages(IEnumerable<PackageInfo> packages) { + var list = new List<PackageInfo>(); + foreach (var package in packages) { - package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl)) - .OrderByDescending(GetPackageVersion).ToList(); + var versions = new List<PackageVersionInfo>(); + foreach (var version in package.versions) + { + if (string.IsNullOrWhiteSpace(version.sourceUrl)) + { + continue; + } + + if (string.IsNullOrWhiteSpace(version.runtimes) || version.runtimes.IndexOf(_packageRuntime, StringComparison.OrdinalIgnoreCase) == -1) + { + continue; + } + + versions.Add(version); + } + + package.versions = versions + .OrderByDescending(GetPackageVersion) + .ToArray(); + + if (package.versions.Length == 0) + { + continue; + } + + list.Add(package); } // Remove packages with no versions - packages = packages.Where(p => p.versions.Any()).ToList(); - - return packages; + return list; } - protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages, string packageType, Version applicationVersion) + protected List<PackageInfo> FilterPackages(IEnumerable<PackageInfo> packages, string packageType, Version applicationVersion) { - foreach (var package in packages) - { - package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl)) - .OrderByDescending(GetPackageVersion).ToList(); - } + var packagesList = FilterPackages(packages); - if (!string.IsNullOrWhiteSpace(packageType)) - { - packages = packages.Where(p => string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase)).ToList(); - } + var returnList = new List<PackageInfo>(); - // If an app version was supplied, filter the versions for each package to only include supported versions - if (applicationVersion != null) + var filterOnPackageType = !string.IsNullOrWhiteSpace(packageType); + + foreach (var p in packagesList) { - foreach (var package in packages) + if (filterOnPackageType && !string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase)) { - package.versions = package.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToList(); + continue; } - } - // Remove packages with no versions - packages = packages.Where(p => p.versions.Any()).ToList(); + // If an app version was supplied, filter the versions for each package to only include supported versions + if (applicationVersion != null) + { + p.versions = p.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToArray(); + } - return packages; + if (p.versions.Length == 0) + { + continue; + } + + returnList.Add(p); + } + + return returnList; } /// <summary> @@ -418,30 +442,24 @@ namespace Emby.Server.Implementations.Updates /// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns> public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(Version applicationVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken) { - var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); - - var plugins = _applicationHost.Plugins.ToList(); - - if (withAutoUpdateEnabled) + if (!_config.CommonConfiguration.EnableAutoUpdate) { - plugins = plugins - .Where(p => _config.CommonConfiguration.EnableAutoUpdate) - .ToList(); + return new PackageVersionInfo[] { }; } + var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); + var systemUpdateLevel = GetSystemUpdateLevel(); // Figure out what needs to be installed - var packages = plugins.Select(p => + return _applicationHost.Plugins.Select(p => { var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Id.ToString(), applicationVersion, systemUpdateLevel); return latestPluginInfo != null && GetPackageVersion(latestPluginInfo) > p.Version ? latestPluginInfo : null; - }).Where(i => i != null).ToList(); - - return packages - .Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase))); + }).Where(i => i != null) + .Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase))); } /// <summary> @@ -704,6 +722,7 @@ namespace Emby.Server.Implementations.Updates public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } } } diff --git a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs index f54613384..fa1d5b74e 100644 --- a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs +++ b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs @@ -28,7 +28,7 @@ namespace Emby.Server.Implementations.UserViews { } - public override IEnumerable<ImageType> GetSupportedImages(IHasImages item) + public override IEnumerable<ImageType> GetSupportedImages(IHasMetadata item) { return new List<ImageType> { @@ -36,13 +36,13 @@ namespace Emby.Server.Implementations.UserViews }; } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var view = (CollectionFolder)item; var recursive = !new[] { CollectionType.Playlists, CollectionType.Channels }.Contains(view.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - var result = view.GetItems(new InternalItemsQuery + var result = view.GetItemList(new InternalItemsQuery { CollapseBoxSetItems = false, Recursive = recursive, @@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.UserViews }); - var items = result.Items.Select(i => + var items = result.Select(i => { var episode = i as Episode; if (episode != null) @@ -91,15 +91,15 @@ namespace Emby.Server.Implementations.UserViews }).DistinctBy(i => i.Id); - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8); + return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)), 8); } - protected override bool Supports(IHasImages item) + protected override bool Supports(IHasMetadata item) { return item is CollectionFolder; } - protected override string CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); @@ -126,7 +126,7 @@ namespace Emby.Server.Implementations.UserViews _libraryManager = libraryManager; } - public override IEnumerable<ImageType> GetSupportedImages(IHasImages item) + public override IEnumerable<ImageType> GetSupportedImages(IHasMetadata item) { return new List<ImageType> { @@ -134,7 +134,7 @@ namespace Emby.Server.Implementations.UserViews }; } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var view = (ManualCollectionsFolder)item; @@ -145,19 +145,19 @@ namespace Emby.Server.Implementations.UserViews Recursive = recursive, IncludeItemTypes = new[] { typeof(BoxSet).Name }, Limit = 20, - SortBy = new[] { ItemSortBy.Random }, + OrderBy = new [] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, DtoOptions = new DtoOptions(false) }); - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8); + return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)), 8); } - protected override bool Supports(IHasImages item) + protected override bool Supports(IHasMetadata item) { return item is ManualCollectionsFolder; } - protected override string CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); diff --git a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs index cd2c4728f..885dfec58 100644 --- a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -31,7 +31,7 @@ namespace Emby.Server.Implementations.UserViews _libraryManager = libraryManager; } - public override IEnumerable<ImageType> GetSupportedImages(IHasImages item) + public override IEnumerable<ImageType> GetSupportedImages(IHasMetadata item) { var view = (UserView)item; if (IsUsingCollectionStrip(view)) @@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.UserViews }; } - protected override List<BaseItem> GetItemsWithImages(IHasImages item) + protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) { var view = (UserView)item; @@ -62,27 +62,27 @@ namespace Emby.Server.Implementations.UserViews IsMovie = true, DtoOptions = new DtoOptions(false) - }).ToList(); + }); - return GetFinalItems(programs).ToList(); + return GetFinalItems(programs); } if (string.Equals(view.ViewType, SpecialFolder.MovieGenre, StringComparison.OrdinalIgnoreCase) || string.Equals(view.ViewType, SpecialFolder.TvGenre, StringComparison.OrdinalIgnoreCase)) { - var userItemsResult = view.GetItems(new InternalItemsQuery + var userItemsResult = view.GetItemList(new InternalItemsQuery { CollapseBoxSetItems = false, DtoOptions = new DtoOptions(false) }); - return userItemsResult.Items.ToList(); + return userItemsResult.ToList(); } var isUsingCollectionStrip = IsUsingCollectionStrip(view); var recursive = isUsingCollectionStrip && !new[] { CollectionType.Channels, CollectionType.BoxSets, CollectionType.Playlists }.Contains(view.ViewType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - var result = view.GetItems(new InternalItemsQuery + var result = view.GetItemList(new InternalItemsQuery { User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null, CollapseBoxSetItems = false, @@ -91,7 +91,7 @@ namespace Emby.Server.Implementations.UserViews DtoOptions = new DtoOptions(false) }); - var items = result.Items.Select(i => + var items = result.Select(i => { var episode = i as Episode; if (episode != null) @@ -133,13 +133,13 @@ namespace Emby.Server.Implementations.UserViews if (isUsingCollectionStrip) { - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8); + return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)), 8); } - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary)).ToList()); + return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary))); } - protected override bool Supports(IHasImages item) + protected override bool Supports(IHasMetadata item) { var view = item as UserView; if (view != null) @@ -163,7 +163,7 @@ namespace Emby.Server.Implementations.UserViews return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); } - protected override string CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { if (itemsWithImages.Count == 0) { diff --git a/Emby.Server.Implementations/Xml/XmlReaderSettingsFactory.cs b/Emby.Server.Implementations/Xml/XmlReaderSettingsFactory.cs new file mode 100644 index 000000000..0f4e8af3c --- /dev/null +++ b/Emby.Server.Implementations/Xml/XmlReaderSettingsFactory.cs @@ -0,0 +1,20 @@ +using System.Xml; +using MediaBrowser.Model.Xml; + +namespace Emby.Server.Implementations.Xml +{ + public class XmlReaderSettingsFactory : IXmlReaderSettingsFactory + { + public XmlReaderSettings Create(bool enableValidation) + { + var settings = new XmlReaderSettings(); + + if (!enableValidation) + { + settings.ValidationType = ValidationType.None; + } + + return settings; + } + } +} diff --git a/Emby.Server.Implementations/packages.config b/Emby.Server.Implementations/packages.config index 03336c936..5b869221a 100644 --- a/Emby.Server.Implementations/packages.config +++ b/Emby.Server.Implementations/packages.config @@ -1,7 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Emby.XmlTv" version="1.0.9" targetFramework="net46" /> - <package id="MediaBrowser.Naming" version="1.0.5" targetFramework="portable45-net45+win8" /> + <package id="Emby.XmlTv" version="1.0.10" targetFramework="net46" /> + <package id="MediaBrowser.Naming" version="1.0.7" targetFramework="net46" /> + <package id="ServiceStack.Text" version="4.5.8" targetFramework="net46" /> + <package id="SharpCompress" version="0.14.0" targetFramework="net46" /> + <package id="SimpleInjector" version="4.0.8" targetFramework="net46" /> <package id="SQLitePCL.pretty" version="1.1.0" targetFramework="portable45-net45+win8" /> - <package id="SQLitePCLRaw.core" version="1.1.7" targetFramework="net46" /> + <package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net46" /> </packages>
\ No newline at end of file |
